How to use libpcap to receive ethernet frame with poll() - c

I have a project which uses poll() to handle the network communication including TCP and Ethernet. Poll is used to support TCP or UDP conneciton. Recenctly I want to use libpcap to receive frames and integrate libpcap into this code with poll().
The poll() needs to know the file descriptor, but the pcap does not returns the file descriptor. How to manage pcap with poll() system.
The project is in C code on linux. The reason I do not want to use raw socket is for the pcap's high efficiency.

If, on a UN*X, you have a pcap_t * from a call such as pcap_open_live() or pcap_create()/pcap_activate(), you can get a file descriptor to hand to poll() or select() or something such as that by calling pcap_get_selectable_fd(). Note that it can return -1, which means that select()/poll()/etc. aren't supported on that particular device on the OS version you're using. (The OS version shouldn't matter for Linux, but it might matter for some BSDs.)

According to Linux manual. You can use pcap_get_selectable_fd. But it's not reliable on most BSDs. Some network devices opened with pcap_create() and pcap_activate(), or with pcap_open_live(), do not support select() or poll() (for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace DAG devices), so -1 is returned for those devices. Refer to manual for more details.

Related

I do I have socket file from my program's single socket() call and it exists in /proc/pid/fd/3 or some number . Now How to open and write to it

I like to write tcp packets to socket file of my program by opening/or not opening(I dont care) and just write packets to it. so my program socket can read packets and proceed with where ever it is in connection. Is it possible in C and Linux
On Man page from linux it says
O_ASYNC
Enable ... This
feature is available only for terminals, pseudoterminals,
sockets[SO ITS AVAILABLE TO OPEN A SOCKET --HOW?], and (since Linux 2.6) pipes and FIFOs. See
fcntl(2)[DO I NEED TO USE fcntl] for further details. See also BUGS, below.
The above is for open system call in Linux on Man page
So I like to know how to open socket file on my system in /proc/my_pid/fd/3 or any number. Does anyone know this please tell

Working of Raw Sockets in the Linux kernel

I'm working on integrating the traffic control layer of the linux kernel to a custom user-level network stack. I'm using raw sockets to do the same. My question is if we use raw sockets with AF_PACKET, RAW_SOCK, and IPPROTO_RAW, will the dev_queue_xmit (the function which is the starting point of the Queueing layer as far as I've read) be called? Or does the sockets interface directly call the network card driver?
SOCK_RAW indicates that the userspace program should receive the L2 (link-layer) header in the message.
IPPROTO_RAW applies the same for the L3 (IP) header.
A userspace program sets SOCK_RAW, IPPROTO_RAW to manually parse or/and compose protocol headers of a packet. It guarantees that the kernel doesn't modify the corresponding layer header on the way to/from the userspace. The raw socket doesn't change the way the packet gets received or transmitted - those are queued as usual. From the network driver perspective, it doesn't matter who set the headers - the userspace (raw sockets) or the kernel (e.g., SOCK_DGRAM).
Keep in mind that getting raw packets requires CAP_NET_RAW capability - usually, the program needs to run with superuser privileges.

How bind works internally in kernel space?

Can anyone help me in tracing bind() system call in socket programming. I would like to know what happens when bind() is called, in kernel space. Like which are the structures it updates and what functions are invoked in lower level
The bind(2) system call just configures the local side's address parameters that a socket will use once you have connected (or sendto(2)). If you don't use it, the kernel selects defaults for it, depending on the underlying protocol.
The exact procedure bind(2) follows depends on the protocol family you are working on, as bind will behave differently depending if you are using PF_UNIX, PF_INET, PF_PACKET, PF_XNS, etc.
For example, in Unix sockets, you'll get your socket associated to an inode in the filesystem (an inode that supports unix sockets, of course), so clients have a path to connect to (in Unix sockets, addresses are paths in the filesystem). In TCP/IP sockets, you can fix the local IP address or the local IP port your socket can listen on (to accept connections) or you can force a IP address and/or port to connect from, to a server.
For a deeper understanding of networking sockets internals, I recommend you reading the excellent book from W.R. Stevens "TCP/IP Illustrated Vol 2. The implementation," describing the implementation of BSD sockets in NET2. It's old, but still the best explanation ever made. For a good introduction of the BSD socket system calls use, there's also an excellent book (for a long time it was indeed also the best system call reference for BSD unix system calls) by W.R.Stevens: "UNIX network programming, Vol 1 (2ND Ed): The sockets API." Both are two jewels everyone should have available at work.

Buffering characteristics of Unix Sockets

Does anyone know the buffering characteristics of Unix sockets when sending small chunks of data (a few bytes)?
When I am using TCP sockets, I can disable the Nagle algorithm to prevent latency in data transit. But there's no equivalent functionality (that I know of) for Unix Domain sockets.
There is no nagle algorithm available on unix domain sockets.
Unix sockets are normally implemented as a memory buffer in the operating system kernel. Once you've written/sent data on the socket, it is copied into that buffer, and becomes immediately available to the peer.

get an ioctl file descriptor for ethernet port

I need to get the file descriptor to use in ioctl() calls for an ethernet port in Linux. Not sure how to do this.
Just use the file descriptor of an open socket, using the name of the device in the ifreq structure passed to ioctl(), assuming your program has adequate permissions to do so.
From the docs:
Linux supports some standard ioctls to
configure network devices. They can
be used on any socket's file
descriptor regardless of the family or
type. They pass an ifreq structure:
The socket need not be bound to the target device, or be of any specific family. Any open socket fd will do (again, with appropriate privileges), just open one for your specific task, wait for ioctl() to return and close it.
See man 7 netdevice for more, or here if you don't have the appropriate documentation packages installed (hint, the package is usually named manpages-dev or manpages-devel, depending on your distro)
You can also take a look at the source to the net-tools package, which may be named differently depending on your distro. That's the source to ifconfig (Debian / Ubuntu here).
Sorry for the original ambiguity, I thought you were trying to configure a special multi function device (not sure why now, perhaps lack of sleep).
You can do something like this fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)
Use strace to see what functions ifconfig calls.

Resources