Sherman wrote:
> Måns Rullgård <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
>
>>(E-Mail Removed) (Sherman) writes:
>>
>>
>>>My specific question is, how should the application talk to
>>>the ether driver to transmit an ether frame, and get notified
>>>when an ether frame is received? Thanks,
>>
>>raw sockets
>
> raw socket is fine but it involves the ip stack in kernel. I would like to
> dis-associate the kernel ip stack with the ether driver, and intercept the
> packets with my customized ip stack, for performance reason. Is there any
> way to do that? Do I have to rewrite the device driver for the particular
> NIC card, or there is any universal driver interface to do that?
As you have been told you may use raw sockets:
int fd;
int if_index;
struct sockaddr_ll sockaddr;
socklen_t len = sizeof (struct sockaddr_ll);
fd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (fd == -1) {
return -1;
}
// Obtain interface index number
if_index = if_nametoindex ("eth0");
memset (&sockaddr, 0, sizeof (struct sockaddr_ll));
sockaddr.sll_family = AF_PACKET;
// ETH_P_ALL means listen to ALL ethernet protocols
sockaddr.sll_protocol = htons (ETH_P_ALL);
sockaddr.sll_ifindex = if_index;
// Bind raw socket to ethernet device
if (bind (s, (struct sockaddr *)&sockaddr, len) == -1) {
return -1;
}
Now by using socket fd in a poll() or blocking read() you will get all
ethernet packets (including the ethernet header) coming in from your
interface "eth0".
The packets received by eth0 device driver is first filtered by the BPF
(packet filter) in Linux before one copy of the packet is sendt to the
standard network stack and another copy is sent to your socket fd from
code above. And you may do whatever you vant to do with this packet.
Link:
http://www.fedchik.org.ua/linux/netf...ing-bytes.html
Quote from this page:
"In recent versions of the Linux kernel (post-2.0 releases) a new
protocol family has been introduced, named PF_PACKET. This family allows
an application to send and receive packets dealing directly with the
network card driver, thus avoiding the usual protocol stack-handling
(e.g., IP/TCP or IP/UDP processing). That is, any packet sent through
the socket will be directly passed to the Ethernet interface, and any
packet received through the interface will be directly passed to the
application.
The PF_PACKET family supports two slightly different socket types,
SOCK_DGRAM and SOCK_RAW. The former leaves to the kernel the burden of
adding and removing Ethernet level headers. The latter gives the
application complete control over the Ethernet header. The protocol
field in the socket() call must match one of the Ethernet IDs defined in
/usr/include/linux/if_ether.h, which represents the registered protocols
that can be shipped in an Ethernet frame. Unless dealing with very
specific protocols, you typically use ETH_P_IP, which encompasses all of
the IP-suite protocols (e.g., TCP, UDP, ICMP, raw IP and so on)."
Otherwise, Google is your friend...
(I have seen at least one project to implement a TCP/IP stack in
userspace on Linux using raw sockets, but don't have a link ready or
time to search for it again..).
--
Roar B. Rotvik