Christoffer Hall-Frederiksen wrote:
>
> I have a rather special situation, where I want to read and write raw
> ethernet-frames from an ethernet interface. The deal is: I have a
> machine with a NICs on to LANs. I need to brigde traffic between these
> interfaces, but I basicly need to manipulate it first. And I need
> promisc-mode because I also have to listen to everything on this
> network. The protocol (a level up from ethernet) is not a common one
> (long and boring story), so I really need access to the raw frames for
> both reading and writing. I've looked at netlink, but there doesn't
> seem to be access to the ethernet-frames.
>
> My question is (naturally) how?
>
> PS:
>
> If the answer answer is RTFM, then I will politely ask WFM (which
> f*%?ing manual ;).
Try searching for SOCK_PACKET. Here's a snippet of code that might
give you ideas...
int createPacketSocket(const char* dev_name, int ether_type) {
LF_TRC_IN;
VLOG << "dev_name -:" << dev_name << ":- type: " << ether_type << endl;
int s = socket(AF_INET, SOCK_PACKET, htons(ether_type));
int r; //retval
if (s < 0) {
cerr << "ERROR: socket: " << strerror(errno) << endl;
VLOG << "ERROR: socket: " << strerror(errno) << endl;
return s;
}
struct sockaddr myaddr;
memset(&myaddr, '\0', sizeof(myaddr));
myaddr.sa_family = AF_INET;
strcpy(myaddr.sa_data, dev_name);
r = bind(s, &myaddr, sizeof(struct sockaddr));
if (r < 0) {
cerr << "ERROR: bind: " << strerror(errno) << endl;
VLOG << "ERROR: bind: " << strerror(errno) << endl;
return r;
}
nonblock(s);
return s;
}
This reads it:
/** msg should be large enough to hold the entire pkt */
int slurpLANforgeDevSocket(int sd, struct sockaddr& from, char* msg) {
//LF_TRC_IN;
int r = 0;
int cnt = 0;
unsigned int fromlen;
while (cnt < 25) { //only read MAX 25 pkts at a time
cnt++;
fromlen = sizeof(struct sockaddr);
memset(&from, 0, fromlen);
r = recvfrom(sd, msg, RCV_MSG_SIZE, 0, &from, &fromlen);
if (mudlog.ofLevel(DBG2)) {
VLOG << "recvfrom val: " << r << endl;
}
if (r < 0) {
if (errno != EAGAIN) {
if (mudlog.ofLevel(ERR)) {
VLOG << "ERROR: rcvfrom: " << strerror(errno) << endl;
}
LANforgeMgr::getProto()->handleDevRcvError(r, from.sa_data);
}
else {
// No more to read
//if (mudlog.ofLevel(DBG2)) {
// VLOG << "no more to read.\n";
//}
break;
}
}//if an error
else {
LANforgeMgr::getProto()->handleDevPkt(msg, r, from.sa_data);
}//else
}//while
return 0;
}//slurpLANforgeDevSocket
Ben
--
Ben Greear ([EMAIL PROTECTED]) http://scry.wanfear.com/~greear
Author of ScryMUD: scry.wanfear.com 4444 (Released under GPL)
http://scry.wanfear.com
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]