Raw ethernet help

Jim Anderson james.anderson@intelx.com
Wed Nov 11 11:48:06 1998


Looking for some help/information.

I am using an Adaptec Cogent Quartet Series board with Redhat Linux 5.1
(using the tulip driver).  I want to use one port ("eth0") to talk
sockets and run x-terms etc.  The other 3-ports are going to be
connected to dedicated devices which talk raw ethernet (i.e send/receive
ethernet frames).  I have attempted to use the code below, plugging in
the correct device name.  I get the correct ethernet hardware address,
but am having problems with the get.  It receives data destined for all
4 devices.  I think (but haven't really confirmed) that the send is
working properly.  I sort of suspect that socket connection requests are
going to go to all devices though.

My guess is that I need to open "eth1" through "eth3" independently and
bypass the sockets layer all together.  Only problem, there are no
devices in the /dev directory to use.

Is there a super slick function or method to send/receive ethernet
frames from one particular device?  Or possibly a way to install the
driver to give me a /dev entry instead of the virtual eth1-3 devices?

Thanks in advance for your help.

===========================

Here is what we are doing now.  We call get_raw_interface() to set up a
socket and get_raw_pakcet() and send_raw_pkt() to send and receive data
to the device.

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/if_ether.h>

#include "rawnet.h"

int ethfd;
ethbuff buff;

//**********************************************************************
*******
int get_raw_interface(char *device_name, unsigned char my_eaddr[])
//**********************************************************************
*******
{
   struct ifreq ifreq;

   if ((ethfd = socket(AF_INET,SOCK_PACKET,htons(SOCK_RAW))) == -1)
   {
      perror("Couldn't open driver");
      return -1;
   }

   strcpy(ifreq.ifr_name, device_name);

   if (ioctl(ethfd, SIOCGIFHWADDR, &ifreq) < 0)
   {
      perror("Couldn't get address");
      return -1;
   }

   memcpy(my_eaddr, ifreq.ifr_hwaddr.sa_data, ETH_ALEN);

   return 0;
}

//**********************************************************************
*******
// struct ethbuff * get_raw_packet(void)
void get_raw_packet(void)
//**********************************************************************
*******
{
  buff.length = recvfrom(ethfd, &buff.buffer,sizeof(buff.buffer),0,
NULL, NULL);
  return;
}

//**********************************************************************
*******
void send_raw_pkt(eth_pkt_typ *pkt_ptr, char *device_name )
//**********************************************************************
*******
{
  struct sockaddr usin={AF_INET, device_name};

  if(sendto(ethfd, pkt_ptr, pkt_ptr->e_hdr.h_proto, 0,
         &usin, sizeof(struct sockaddr)) < 0)
  {
     fprintf( stderr,"sendto failed with: %s\n", strerror( errno ) );
  }
}