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 ) );
}
}