Bruno Randolf wrote:
>
> hi there!
>
> can anybody here tell me how can i send and receive ethernet packets
> directly on layer 2 under linux?
[snip]
> any other suggsetions?
> help would be greatly appreciated!
>
> Br1
This was my problem some time ago, too. As suggested, I started with
pcap, but it doesn't helped too much. After fiddleing an evening with
this stuff, here is, what I found out:
open a socket:
fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (fd < 0) {
sprintf(ebuf, "socket: %s", strerror(errno));
goto failed;
}
/* check device type */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 ) {
sprintf(ebuf, "SIOCGIFHWADDR: %s", strerror(errno));
goto failed;
}
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
sprintf(ebuf, "unsupported physical layer type 0x%x (ethernet
only)",
ifr.ifr_hwaddr.sa_family);
goto failed;
}
memcpy(ethaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
if you need promisc mode, don't forget to restore device flags.
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0 ) {
sprintf(ebuf, "SIOCSIFFLAGS: %s", strerror(errno));
goto failed;
}
atexit(restore_ifr);
/****/
void restore_ifr(void)
{
int fd;
fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
if (fd < 0)
fprintf(stderr, "linux socket: %s", strerror(errno));
else if (ioctl(fd, SIOCSIFFLAGS, &saved_ifr) < 0)
fprintf(stderr, "linux SIOCSIFFLAGS: %s", strerror(errno));
}
So much for initialisation.
To receive/send stuff, use recvmsg/sendmsg, so no need/use of
bind, but you need to understand the concepts of the structs:
msghdr, ethhdr, iovec, and sockaddr_pkt to build/decode packages.
Take this as example code, and it may be inconsistent. But I think,
it's worth to get the concepts, without the need to look
into the kernel code (what I have done, though).
Hope this helps.
Cheers,
Hans-Peter
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]