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]

Reply via email to