项目作者: Arjunumesh11

项目描述 :
Network Sniffer implemented in C and stores result in .pcap format
高级语言: C
项目地址: git://github.com/Arjunumesh11/sniffer.git
创建时间: 2020-07-04T14:13:28Z
项目社区:https://github.com/Arjunumesh11/sniffer

开源协议:

下载


INTRODUCTION

Network sniffers take snapshot copies of the data flowing over a network without redirecting or altering it. Some sniffers work only with TCP/IP packets, but the more sophisticated tools work with many other net

HOW NETWORK SNIFFING WORK

A packet sniffer connected to any network intercepts all data flowing over that network.
On a local area network (LAN), computers typically communicate directly with other computers or devices on the network. Anything connected to that network is exposed to all of that traffic. Computers are programmed to ignore all network traffic not intended for it.Network sniffing software opens up to all traffic by opening up the computer’s network interface card (NIC) to listen to that traffic. The software reads that data and performs analysis or data extraction on it.

NETWORK SNIFFING USING C

Network packets and packet sniffers
When an application sends data into the network, it is processed by various network layers. Before sending data, it is wrapped in various headers of the network layer. The wrapped form of data, which contains all the information like the source and destination address, is called a network packet. According to Ethernet protocols, there are various types of network packets like Internet Protocol packets, Xerox PUP packets, Ethernet Loopback packets, etc.

RAW SOCKET

Programming using TCP or UDP implies that only the application protocol header and data are provided by the application.The headers of IP , TCP or UDP protocols are automatically created by the O.S, using information provided by the application ( IP address, port numbers and protocol family) . The O.S. uses default values to fields such as TTL. It is up to the O.S. to compute the checksum, sockets like stream sockets and datagram sockets receive data from the transport layer that contains no headers but only the payload. This means that there is no information about the source IP address and MAC address. If applications running on the same machine or on different machines are communicating, then they are only exchanging data.when present.Raw sockets programming, on the other hand, allows headers of lower level protocols to be constructed by the application.

Opening a RAW Socket

  1. int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

As explained above raw socket can capture every packets
ETH_P_ALL specifies to capture all,if u want only IP packet u can use ETH_P_IP

Reception of the network packet

  1. // Read the next packet, blocking forever.
  2. int rc = recv(sock_raw, (char *)buffer + BUFFER_OFFSET_ETH, BUFFER_SIZE_PKT, 0);
  3. if (rc < 0)
  4. {
  5. fprintf(stderr, "recv() failed: %s", strerror(errno));
  6. exit(-1);
  7. }
  8. // End of file for some strange reason, so stop reading packets.
  9. if (rc == 0)
  10. break;

Here BUFFER_SIZE_PKT specifies the size of packer

define BUFFER_SIZE_PKT ((256 * 256) - 1)

STORING DATA in trace FILE (pcap)

Pcap file format

The first part of the file is the global header, which is inserted only once in the file, at the start. The global header has a fixed size of 24 bytes.

GLOBAL HEADER

  1. //pcap Global header
  2. struct pcap_file_header
  3. {
  4. uint32_t magic; //used to detect the file format itself and the byte ordering.
  5. uint16_t version_major; //version number
  6. uint16_t version_minor;
  7. int32_t thiszone; //GMT timezone offset
  8. uint32_t sigfigs;
  9. uint32_t snaplen; //"snapshot length" for the capture (typically 65535 or even more, but might be limited by the user)
  10. uint32_t linktype; //link-layer header type, specifying the type of headers at the beginning of the packet.
  11. };

magic_number: used to detect the file format itself and the byte ordering.
version_major, version_minor: the version number of this file format.
thiszone: the correction time in seconds between GMT (UTC) and the local timezone of the following packet header timestamps.
sigfigs: In theory, the accuracy of time stamps in the capture; in practice, all tools set it to 0
snaplen: the “snapshot length” for the capture (typically 65535 or even more, but might be limited by the user), see: incl_len vs. orig_len below
network: link-layer header type, specifying the type of headers at the beginning of the packet.

PACKET HEADER

```
//pcap packet header
struct pcap_sf_pkthdr
{
struct pcap_timeval ts; //he date and time when this packet was captured.
uint32_t caplen; //the number of bytes of packet data actually captured and saved in the file
uint32_t len; //the length of the packet as it appeared on the network when it was captured.
};

//time header
struct pcap_timeval
{
int32_t tv_sec;
int32_t tv_usec;
};

  1. ts_sec: the date and time when this packet was captured.
  2. ts_usec: in regular pcap files, the microseconds when this packet was captured.
  3. incl_len: the number of bytes of packet data actually captured and saved in the file.
  4. orig_len: the length of the packet as it appeared on the network when it was captured.
  5. ### Creating Header
  6. #### Global header

struct pcap_file_header hdr;
hdr.magic = 0xa1b2c3d4;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = 0;
hdr.snaplen = BUFFER_SIZE_PKT;
hdr.sigfigs = 0;
hdr.linktype = DLT_EN10MB;

  1. #### Packet header for each packet in the capture loop

gettimeofday(&time, NULL);
pkt->ts.tv_sec = (int32_t)time.tv_sec;
pkt->ts.tv_usec = (int32_t)time.tv_usec;
pkt->caplen = rc + BUFFER_SIZE_ETH;
pkt->len = rc + BUFFER_SIZE_ETH;
```
Gettimeofday return high precision time