libpcap - capture packets from all interfaces - linux

I need to capture packets from all network interfaces on Linux machine.
In order to do it I'm planning to use pcap_open_live() API and pass "any" as a device argument.
I have different types of ports: Ethernet ports (say eth0) and GRE tunnels (say tun0)
The packets that coming from different types of interfaces has different headers format:
Packets from Ethernet port has MAC header
Packets from tunnel coming with a Linux "cooked" capture encapsulation (16 bytes) header
How can I check into pcap_loop() callback handler what type of packet header I got?

All packets you receive get the same type of packet header; that's the type you get when you call pcap_datalink() on the pcap_t. The values that pcap_datalink() returns are the DLT_ values as shown in the Link-Layer Header Types page on the tcpdump.org site.
If you've opened the any device, pcap_datalink() will return DLT_LINUX_SLL, meaning that ALL packets you capture will have the "cooked" capture header - even the ones from eth0! You'd have to capture on eth0, rather than any, to get Ethernet headers for those packets.

Related

About sendmmsg msg_len fields with raw IP socket

I'm trying to send raw UDP datagrams using a raw IP socket on Linux (I specify both IP and UDP headers).
Should I check the mmsghdr.msg_len field after sendmmsg? This field designates a number of bytes of a datagram sent, but since I send IP datagrams I think it should always equal to a length of a whole datagram (or not?).
Notes
I construct a UDP datagram completely by myself. Only one UDP packet (UDP header + data) is encapsulated into an IP datagram.

Can IP header be at different offset across different machines?

I'm writing a tool with libpcap to analyze TCP traffic. The problem I'm facing is that inside a pcap file that was provided to me for testing, I see the IP header starts at offset 0x10 (hence after 16 bytes), while all the documentation + live capture show me that it's always at 0xE (like the documentation claims).
How I try to get a hold of the ip and tcp header:
struct iphdr *ip;
struct tcphdr *tcp;
ip = (struct iphdr *)(packet + sizeof(struct ethhdr));
tcp = (struct tcphdr *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr)
Some wireshark images:
Live capture -
As you can see it starts after 14 bytes, like it should
offline dump file -
Dump file ip header starts after 16 bytes
What is the correct way to parse the IP and TCP header?
Thanks
Ron Maupin is 100% correct. To give some more details:
The problem I'm facing is that inside a pcap file that was provided to me for testing
The pcap-savefile(5) man page indicates that one of the fields in the pcap file header is the "Link-layer header type" field; as the man page says:
a 4-byte number giving the link-layer header type for packets in the capture; see pcap-linktype(7) for the LINKTYPE_ values that can appear in this field.
If you have opened a capture file with pcap_open_offline() or one of the variants thereof, the pcap_datalink() routine in libpcap will return the link-layer header type.
The link-layer header type is a requirement for interpreting the contents of a packet. For IP packets, for example, the IP header comes after any metadata headers and the link-layer header, and not all metadata headers (if present) and not all link-layer headers have the same length, so you must know what link-layer header is present in order to know where the IP header begins - or, in fact, to even determine whether the packet is an IP packet! For Ethernet packets, for example, you must look at the Ethernet type/length field to see whether it's 0x0800 (for IPv4) or 0x86dd (for IPv6).
The tcpdump.org list of link-layer header types indicates what link-layer types exist. The numerical values given are those that appear in the "Link-layer header type" field of the file (or in the LinkType field of an Interface Description Block in a pcapng file - libpcap can read some pcapng files, all of the Interface Description Blocks of which must have the same LinkType, and will return the link-layer type in a pcap_datalink() call).
The values returned by pcap_datalink() are the DLT_ values from the list of link-layer header types, so an Ethernet file (or Ethernet Interface Description Block) will have a value of 1, or LINKTYPE_ETHERNET, in the header, which will be mapped to DLT_EN10MB in the value returned by pcap_datalink(). (In most cases, the LINKTYPE_ values and the corresponding DLT_ values are numerically the same, but there are some exceptions in cases where different operating systems have different numerical values for the same DLT_ type.) The second capture has LINKTYPE_LINUX_SLL in the capture file, so pcap_datalink() would return DLT_LINUX_SLL.
The link-layer header type page's descriptions of link-layer header types should help you write code to interpret that link-layer header type's header data.
In addition, as Ron Maupin noted, there may also be VLAN headers after the Ethernet header but before the IP header.
(And, as this is a question by somebody writing a program to read capture files, rather than by somebody designing or maintaining a network, it seems more appropriate for Stack Overflow than Network Engineering.)

How many bits of codification G.711 sends in each datagrama?

I am learning about codecs,and I get this question that I didnt understood the answers.
Assuming CODEC G.711 where each datagram carries 20ms of voice, indicate:
3) [E] How many bytes of G.711 encoding does each datagram carry?
A- 20ms/8*0,02=160
4) What is the byte size of each frame carrying G.711 on an Ethernet network?
Note: The dimensions (in bytes) of the base headers of some of the protocols that might be involved in the communication: Ethernet = 18, IP = 20, TCP = 20, UDP = 8, ICMP = 8, RTP = 12
A-18+20+8+12+160=218
I didnt get this math..
g711 codecs pure bandwidth(codec only) is 64kbit, exact
g711 packet length can be 10,20(default),30.. upto 150ms.
So for default settings you have 20ms packet(50 packet/sec) at 64kbit = 160Bytes without udp packet header
Full length of g711(default 20ms) packet is
TPS = 18 bytes+20 bytes+8 bytes+12 bytes+160 bytes
You have 160 bytes of raw data, first you make it rtp packet(timestamp mostly), see packet size at https://en.wikipedia.org/wiki/Real-time_Transport_Protocol
RTP required fore reorder when you get two packet in different order(sometimes happens).
Now you have rtp, BUT it not suitable for send, need know where to send, need address and port. For port part you use UDP packet https://en.wikipedia.org/wiki/User_Datagram_Protocol
For address you use IP packet header, without address it not go destination machine
https://en.wikipedia.org/wiki/Internet_Protocol
Okay, now you have packet. But you still need actually send it. For send you use some hardware level protocol, in this case it is ETHERNET. Ethernet have mac address, which allow fast switching without parse of IP. That is last 18 bytes
https://scialert.net/fulltext/?doi=ajsr.2017.110.115
In some cases you can prefer TCP(when you have packet loss or complex networking), in this case you not use UDP, use TCP instead of it. So you swap 8bytes UDP for 20 bytes TCP.

Inserting ethernet frames of a particular ethertype in ahead of TCP/IP frames in netdev_queue

We have developed an Application Specific Integrated Circuit for power line communications. The chip has an ethernet interface. If the ASIC receives an ethernet frame containing TCP/IP or ARP payload (ethertypes 0x0800 IPv4, 0x0806 ARP and 0x86DD IPv6), it simply forwards the frame onto the power line and does the same in the other direction. We call such frames data frames.
If the ASIC receives an ethernet frame of a specific ethertype (we use 0x88b5 which is allocated for experimental//public use on local networks), it consumes this frame itself. These frames contain configuration settings for the ASIC. We call these configuration frames.
The chip is connected to an Ethernet LAN on one side and to power line on the other end. So it basically bridges the two network. The ASIC requires throttling of the data frames passing through it. This is due to the fact that the speeds over power line are 100 times less than the 100 Mbps Ethernet and also because the number of data frames that the ASIC can handle per second are limited.
We use raw sockets to form the configuration frames and send it via ethernet to the ASIC. Is there a way in which whenever configuration frame (0x88b5), it is queued in front of all the pending data frames (ethertypes 0x0800, 0x0806, 0x86dd) in the netdev_queue?
Can this be done via some supporting functionality implemented using hacks & hooks in a kernel module?
We came across a similar question (although improperly tagged) here: Setting up priority of packets that are being transmitted over the network

Details of /proc/net/ip_conntrack and /proc/net/nf_conntrack

I'm looking for a detailed documentation about content of files /proc/net/nf_conntrack and/or /proc/net/ip_contrack on Linux systems.
Yes, I know, there are many utilities which can show me the content of these files in human readable format, but... I'd like to do it on a SOHO router, with Tomato USB firmware (by Shibby).
The optware AFAIK deprecated and the entware doesn't contain any of these utilities, so I'd like to write a script instead of them, but I didn't find a detailed description of these files :(
The format of a line from /proc/net/ip_conntrack is the same as for /proc/net/nf_conntrack, except the first two columns are missing.
I'll try to summarize the format of the latter file, as I understand it from the net/netfilter/nf_conntrack_standalone.c, net/netfilter/nf_conntrack_acct.c and the net/netfilter/nf_conntrack_proto_*.c kernel source files. The term layer refers to the OSI protocol layer model.
First column: The network layer protocol name (eg. ipv4).
Second column: The network layer protocol number.
Third column: The transmission layer protocol name (eg. tcp).
Fourth column: The transmission layer protocol number.
Fifth column: The seconds until the entry is invalidated.
Sixth column (Not all protocols): The connection state.
All other columns are named (key=value) or represent flags ([UNREPLIED], [ASSURED], ...). A line can contain up to two columns having the same name (eg. src and dst). Then, the first occurrence relates to the request direction and the second occurrence relates to the response direction.
Meaning of the flags:
[ASSURED]: Traffic has been seen in both (ie. request and response) direction.
[UNREPLIED]: Traffic has not been seen in response direction yet. In case the connection tracking cache overflows, these connections are dropped first.
Please note that some column names appear only for specific protocols (eg. sport and dport for TCP and UDP, type and code for ICMP). Other column names (eg. mark) appear only if the kernel was built with specific options.
Examples:
ipv4 2 tcp 6 300 ESTABLISHED src=1.1.1.2 dst=2.2.2.2 sport=2000 dport=80 src=2.2.2.2 dst=1.1.1.1 sport=80 dport=12000 [ASSURED] mark=0 use=2 belongs to an established TCP connection from host 1.1.1.2, port 2000, to host 2.2.2.2, port 80, from which responses are sent to host 1.1.1.1, port 12000, timing out in five minutes. For this connection, packets have been seen in both directions.
ipv4 2 icmp 1 3 src=1.1.1.2 dst=1.1.1.1 type=8 code=0 id=32354 src=1.1.1.1 dst=1.1.1.2 type=0 code=0 id=32354 mark=0 use=2 belongs to an ICMP echo request packet from host 1.1.1.2 to host 1.1.1.1 with an expected echo reply packet from host 1.1.1.1 to host 1.1.1.2, timing out in three seconds.
The response destination host is not necessarily the same as the request source host, as the request source address may have been masqueraded by the response destination host.
Please note that the following information might not be up-to-date!
Fields available for all entries:
bytes (if accounting is enabled, request and response)
delta-time (if CONFIG_NF_CONNTRACK_TIMESTAMP is enabled)
dst (request and response)
mark (if CONFIG_NF_CONNTRACK_MARK is enabled)
packets (if accounting is enabled, request and response)
secctx (if CONFIG_NF_CONNTRACK_SECMARK is enabled)
src (request and response)
use
zone (if CONFIG_NF_CONNTRACK_ZONES is enabled)
Fields available for dccp, sctp, tcp, udp and udplite transmission layer protocols:
dport (request and response)
sport (request and response)
Fields available for icmp transmission layer protocol:
code (request and response)
id (request and response)
type (request and response)
Fields available for gre transmission layer protocol:
dstkey (request and response)
srckey (request and response)
stream_timeout
timeout
Allowed values for the sixth field:
dccp transmission layer protocol
CLOSEREQ
CLOSING
IGNORE
INVALID
NONE
OPEN
PARTOPEN
REQUEST
RESPOND
TIME_WAIT
sctp transmission layer protocol
CLOSED
COOKIE_ECHOED
COOKIE_WAIT
ESTABLISHED
NONE
SHUTDOWN_ACK_SENT
SHUTDOWN_RECD
SHUTDOWN_SENT
tcp transmission layer protocol
CLOSE
CLOSE_WAIT
ESTABLISHED
FIN_WAIT
LAST_ACK
NONE
SYN_RECV
SYN_SENT
SYN_SENT2
TIME_WAIT
The file ip_conntrack contains only ipv4 specific conntrack entries whereas nf_conntrack includes both ipv4 and ipv6 protocol conntrack entries.
nf_conntrack file is registered with proc file system using code in
net/netfilter/nf_conntrack_standalone.c
whereas ip_conntrack file is registered with proc file system through the code in
net/netfilter/nf_conntrack_l3proto_ipv4_compat.c

Resources