C Language implementation of Linux network sniffer

Source: Internet
Author: User
Tags clear screen readable

C Language Implementation Linux Network Sniffer 0x01 experiment Introduction

A network sniffer is a program that intercepts incoming and outgoing data through a network interface. So if you are browsing the Internet, the sniffer catches it in the form of a packet and displays it. In this experiment, we implemented a network sniffer using C language.

0X02 program Framework and function description

This program uses the C language programming, realizes the network sniffing function under the Linux environment, and realizes the docking receives the UDP datagram to parse.

0X03 Program code

Sniffer.h

#ifndef __SNIFFER_H__#define __SNIFFER_H__typedef struct  s_protocol{    int tcp;    int udp;    int icmp;    int igmp;    int others;    int total;} t_protocol;typedef struct  s_sniffer{    FILE *logfile;    t_protocol *prot;} t_sniffer;void ProcessPacket(unsigned char*, int, t_sniffer *);void print_ip_header(unsigned char* , int, t_sniffer *);void print_tcp_packet(unsigned char* , int, t_sniffer *);void print_udp_packet(unsigned char * , int, t_sniffer *);void print_icmp_packet(unsigned char* , int, t_sniffer *);void PrintData (unsigned char* , int, t_sniffer *);void display_time_and_date();void getting_started();void signal_white_now(int);#endif

Tools.h

#ifndef __COLOR_H__#define __COLOR_H__#include <stdio.h>#define CLEARSCREEN() printf("\033[H\033[2J")#define INITCOLOR(color) printf("\033[%sm", color)#define RED_COLOR "31"#define GREEN_COLOR "32"#define YELLOW_COLOR "33"#define BLUE_COLOR "34"#define ZERO_COLOR "0"#endif      

Tools.c

#include    <signal.h>#include    <stdio.h>/* 信号处理函数 */void signal_white_now(int signum){    printf("Bye Bye !\n");}

Show_data.c

#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include < netinet/ip_icmp.h> #include <netinet/udp.h> #include <netinet/tcp.h> #include <netinet/ip.h># Include <sys/socket.h> #include <arpa/inet.h> #include "sniffer.h" #include "tools.h"/* Write IP header to log file */void    Print_ip_header (unsigned char *buf, int size, t_sniffer *sniffer) {unsigned short iphdrlen;    struct IPHDR *iph;    struct sockaddr_in source;    struct sockaddr_in dest;    Iph = (struct IPHDR *) buf;     Iphdrlen = iph->ihl*4;    (void) Iphdrlen;    (void) size;    memset (&source, 0, sizeof (source));      SOURCE.SIN_ADDR.S_ADDR = iph->saddr;    memset (&dest, 0, sizeof (dest));      DEST.SIN_ADDR.S_ADDR = iph->daddr;    fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "IP header\n");    fprintf (Sniffer->logfile, "|-ip Version:%d\n", (unsigned int) iph->version); fprintf (Sniffer->logfile, "|-ip HEader Length:%d DWORDS or%d bytes\n ", (unsigned int) IPH-&GT;IHL, ((unsigned int) (IPH-&GT;IHL)));    fprintf (Sniffer->logfile, "|-type of Service:%d\n", (unsigned int) iph->tos);    fprintf (Sniffer->logfile, "|-ip total Length:%d Bytes (size of Packet) \ n", Ntohs (Iph->tot_len));    fprintf (Sniffer->logfile, "|-identification:%d\n", Ntohs (Iph->id));    fprintf (Sniffer->logfile, "|-ttl:%d\n", (unsigned int) iph->ttl);    fprintf (Sniffer->logfile, "|-protocol:%d\n", (unsigned int) iph->protocol);    fprintf (Sniffer->logfile, "|-checksum:%d\n", Ntohs (Iph->check));    fprintf (Sniffer->logfile, "|-source IP:%s\n", Inet_ntoa (SOURCE.SIN_ADDR)); fprintf (Sniffer->logfile, "|-destination IP:%s\n", Inet_ntoa (DEST.SIN_ADDR));}    /* Write TCP packets to the log file */void print_tcp_packet (unsigned char *buf, int size, t_sniffer *sniffer) {unsigned short iphdrlen;    struct IPHDR *iph;      struct TCPHDR *tcph; IPH = (struct IPHDR *) buf;      Iphdrlen = IPH-&GT;IHL * 4;    TCPH = (struct tcphdr*) (buf + Iphdrlen);        Print_ip_header (buf, size, sniffer);    /* Write the TCP header information to the log file */fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "TCP header\n");    fprintf (Sniffer->logfile, "|-source Port:%u\n", Ntohs (Tcph->source));    fprintf (Sniffer->logfile, "|-destination Port:%u\n", Ntohs (tcph->dest));    fprintf (Sniffer->logfile, "|-sequence number:%u\n", Ntohl (TCPH-&GT;SEQ));    fprintf (Sniffer->logfile, "|-acknowledge number:%u\n", Ntohl (TCPH-&GT;ACK_SEQ)); fprintf (Sniffer->logfile, "|-header Length:%d DWORDS or%d bytes\n", (unsigned int) tcph->doff, (unsigned int    ) tcph->doff*4);    fprintf (Sniffer->logfile, "|-urgent Flag:%d\n", (unsigned int) Tcph->urg);    fprintf (Sniffer->logfile, "|-acknowledgement Flag:%d\n", (unsigned int) tcph->ack); fprintf (Sniffer->logfile, "|-push Flag:%d\n", (Unsigned int) tcph->psh);    fprintf (Sniffer->logfile, "|-reset Flag:%d\n", (unsigned int) tcph->rst);    fprintf (Sniffer->logfile, "|-synchronise Flag:%d\n", (unsigned int) tcph->syn);    fprintf (Sniffer->logfile, "|-finish Flag:%d\n", (unsigned int) tcph->fin);    fprintf (Sniffer->logfile, "|-window:%d\n", Ntohs (Tcph->window));    fprintf (Sniffer->logfile, "|-checksum:%d\n", Ntohs (Tcph->check));    fprintf (Sniffer->logfile, "|-urgent Pointer:%d\n", tcph->urg_ptr);    fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "DATA Dump");      fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "IP header\n");      Printdata (buf, Iphdrlen, sniffer);    fprintf (Sniffer->logfile, "TCP header\n");      Printdata (Buf+iphdrlen, tcph->doff*4, sniffer);    fprintf (Sniffer->logfile, "Data payload\n"); /* Write user data to log file */Printdata(buf + Iphdrlen + tcph->doff*4, (size-tcph->doff*4-iph->ihl*4), sniffer); fprintf (Sniffer->logfile, "\n###########################################################");}    /* Write UDP packet to log file */void print_udp_packet (unsigned char *buf, int size, t_sniffer *sniffer) {unsigned short iphdrlen;    struct IPHDR *iph;    struct UDPHDR *UDPH;    Iph = (struct IPHDR *) buf;    Iphdrlen = iph->ihl*4;    UDPH = (struct udphdr*) (buf + Iphdrlen);      fprintf (Sniffer->logfile, "\n\n***********************udp packet*************************\n");        Print_ip_header (buf, size, sniffer);    /* Write the UDP header information into the log file */fprintf (sniffer->logfile, "\nudp header\n");    fprintf (Sniffer->logfile, "|-source Port:%d\n", Ntohs (Udph->source));    fprintf (Sniffer->logfile, "|-destination Port:%d\n", Ntohs (udph->dest));    fprintf (Sniffer->logfile, "|-udp Length:%d\n", Ntohs (Udph->len)); fprintf (Sniffer->logfile, "|-udp CheckSum:%d\n ", Ntohs (Udph->check));    fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "IP header\n");      Printdata (buf, Iphdrlen, sniffer);    fprintf (Sniffer->logfile, "UDP header\n");      Printdata (Buf+iphdrlen, sizeof (UDPH), sniffer);    fprintf (Sniffer->logfile, "Data payload\n"); /* Write user data to log file */printdata (buf + iphdrlen + sizeof UDPH, (size-sizeof UDPH-IPH-&GT;IHL * 4), sniffer      ); fprintf (Sniffer->logfile, "\n###########################################################");} /* Write ICMP packet to log file */void print_icmp_packet (unsigned char *buf, int size, t_sniffer *sniffer) {unsigned short Iphdrlen    ;    struct IPHDR *iph;      struct ICMPHDR *icmph;    Iph = (struct IPHDR *) buf;    Iphdrlen = IPH-&GT;IHL * 4;    icmph = (struct ICMPHDR *) (buf + Iphdrlen); /* Write the ICMP header information to the log file */fprintf (sniffer->logfile, "\n\n***********************icmp packet*************************      \ n "); Print_ip_header (buf, size, SniffeR);    fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "ICMP header\n");      fprintf (Sniffer->logfile, "|-type:%d", (unsigned int) (icmph->type));    if ((unsigned int) (icmph->type) = = one) fprintf (Sniffer->logfile, "(TTL Expired) \ n");    else if ((unsigned int) (icmph->type) = = icmp_echoreply) fprintf (Sniffer->logfile, "(ICMP Echo Reply) \ n");    fprintf (Sniffer->logfile, "|-code:%d\n", (unsigned int) (icmph->code));    fprintf (Sniffer->logfile, "|-checksum:%d\n", Ntohs (Icmph->checksum));    fprintf (sniffer->logfile, "\ n");    fprintf (Sniffer->logfile, "IP header\n");    Printdata (buf, Iphdrlen, sniffer);    fprintf (Sniffer->logfile, "UDP header\n");      Printdata (buf + iphdrlen, sizeof (icmph), sniffer);      fprintf (Sniffer->logfile, "Data payload\n");        /* Finally write the user data to the log file */printdata (buf + iphdrlen + sizeof (icmph), (size-sizeof (icmph)-IPH-&GT;IHL * 4),      Sniffer); fprintf (SNIFFER-&GT;LOGFIle, "\n###########################################################");}  /* Write user data to log file */void printdata (unsigned char *buf, int size, t_sniffer *sniffer) {int i;        for (i = 0; i < size; i++) {if (i% = = 0) fprintf (sniffer->logfile, "\ n");              fprintf (Sniffer->logfile, "%02x", (unsigned int) buf[i]);    if (i = = size-1) fprintf (sniffer->logfile, "\ n"); }}

main.c

#include <signal.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include    <string.h> #include <netinet/ip.h> #include <sys/socket.h> #include <sys/select.h> #include <fcntl.h> #include <sys/types.h> #include <sys/time.h> #include <errno.h> #include SNI Ffer.h "#include" tools.h "#define ETH_P_IP 0x0800int exec_cmd (char *buffer, int len) {if (strncmp (buffer," quit ", 4)    = = 0) return (1); return (0);}    int command_interpreter (int sd) {int len;    Char buf[512];    Len = Read (0, BUF, 512);    if (Len > 0) {if (Exec_cmd (buf, len) = = 1) return (1); } return (0);}    void Display_time_and_date () {initcolor (red_color); printf ("[%s]", __date__);    /* Print Date */Initcolor (Green_color); printf ("[%s]", __time__); /* Print time */Initcolor (zero_color);}    void getting_started () {clearscreen ();/* Clear screen */display_time_and_date (); PrinTF ("Getting started of the Network sniffer\n\n");    }/* Main Function Entry */int main () {/* Declaration part */INT SD;    int res;    int saddr_size;    int data_size;    struct SOCKADDR saddr; unsigned char *buffer; /* Save data for packet */T_sniffer sniffer;    /* Save information such as type of packet and log file */Fd_set Fd_read;     Buffer = malloc (sizeof (unsigned char *) * 65536);    /* Create a log file in the current folder in a writable manner */Sniffer.logfile = fopen ("Log.txt", "w");    fprintf (Sniffer.logfile, "***logfile (%s-%s) ***\n", __date__, __time__);        if (Sniffer.logfile = = NULL) {perror ("fopen ():");    return (exit_failure);      } Sniffer.prot = malloc (sizeof (T_PROTOCOL *));     /* Create the original socket, Eth_p_all represents the Ethernet frame that listens for the payload as an IP datagram */SD = socket (Pf_packet, Sock_raw, htons (ETH_P_IP));        if (SD < 0) {perror ("socket ():");    return (exit_failure);    } getting_started ();    Signal (SIGINT, &signal_white_now);    Signal (Sigquit, &signal_white_now); /* Loop over the Ethernet frame and call the Processpacket function to parse */while (1) {Fd_zero (&Amp;fd_read);        Fd_set (0, &fd_read);        Fd_set (SD, &fd_read);        /* Multiplexing detects readable sockets and standard inputs */RES = SELECT (SD + 1, &fd_read, NULL, NULL, NULL);                if (Res < 0) {close (SD);                if (errno! = eintr) perror ("Select ()");            return (exit_failure); } else {/* If the standard input is readable, go to the command line handler Command_interpreter, temporarily only support ' quit ' command */IF                 (Fd_isset (0, &fd_read))                {if (command_interpreter (SD) = = 1) break; }/* If the socket is readable, read the contents of the Ethernet data frame and call the Processpacket function to parse out the type of packet */else if (Fd_isset (SD, &fd_re                        AD) {/* Read the contents of the Ethernet data frame */saddr_size = sizeof (SADDR); Data_size = recvfrom (SD, buffer, 65536, 0, &saddr, (socklen_t*) &saddr_size);                     /* Read the contents of the Ethernet data frame */   if (data_size <= 0) {close (SD);                                Perror ("Recvfrom ():");                            return (exit_failure); } processpacket (buffer, data_size, &sniffer);    /* Call the Processpacket function to parse out the packet type */}}} close (SD); return (exit_success);} void Processpacket (unsigned char* buffer, int size, T_sniffer *sniffer) {buffer = buffer + 6 + 6 + 2;/* According to the frame structure of the network, the first 6 B is    The destination MAC address, followed by the source MAC address, the next 2B is the frame length, the rest is the load (upper IP datagram) */struct IPHDR *iph = (struct iphdr*) buffer; ++sniffer->prot->total;            /* Total number of packets plus 1 */* The packet type of the upper layer is judged based on the value of the Protocol field in the IP data header specified by the TCP/IP protocol */switch (IPH-&GT;PROTOCOL) {                /* 1 means ICMP protocol */Case 1: ++sniffer->prot->icmp;                Print_icmp_packet (buffer, size, sniffer);                            Break /* 2 Represents the IGMP protocol */Case 2: ++sniffer->prot->igmp;                            Break                /* 6 means TCP protocol */Case 6: ++sniffer->prot->tcp;                Print_tcp_packet (buffer, size, sniffer);                            Break                /* 17 means UDP protocol */Case: ++sniffer->prot->udp;                Print_udp_packet (buffer, size, sniffer);                  Break                Default: ++sniffer->prot->others;        Break } display_time_and_date ();     /* Show time */* print information in sniffer */printf ("TCP:%d UDP:%d ICMP:%d IGMP:%d Others:%d total:%d\n", Sniffer->prot->tcp, SNIFFER-&GT;PROT-&GT;UDP, sniffer->prot->icmp, Sniffer->prot->igmp, Sniffe R->prot->others, sniffer->prot->total);}
0X04 Data Report Analysis

Take a UDP packet as an example

***LOGFILE(Dec 14 2017 - 21:41:38)**************************UDP Packet*************************IP Header   |-IP Version        : 4   |-IP Header Length  : 5 DWORDS or 20 Bytes   |-Type Of Service   : 0   |-IP Total Length   : 213  Bytes(size of Packet)   |-Identification    : 6639   |-TTL      : 64   |-Protocol : 17   |-Checksum : 31927   |-Source IP        : 172.16.69.82   |-Destination IP   : 172.16.69.255UDP Header   |-Source Port      : 138   |-Destination Port : 138   |-UDP Length       : 193   |-UDP Checksum     : 26258IP Header保护隐私,这部分我删除了 AC 10 45 FFUDP Header保护隐私,这部分我删除了Data Payload保护隐私,这部分我删除了###########################################################
0x05 attached

I think the highlight of this experiment is the use of script control, it is necessary to learn the script programming
launcher.sh

#!/bin/shsigint(){    printf ‘\nQUIT !\n‘    exit 1}main(){    clear    printf "\t\t\t\t\tWelcome to Sniffer Project r\n\n"    while [ 1 ]; do    printf "Select option: \n\n"    printf "1 : Build Project\n"    printf "2 : Launch Project\n"    printf "3 : Remove Object files\n"    printf "4 : Rebuild\n"    printf "0 : Exit\n"    printf "\nYou choose: "    read option        if [ $option = 0 ]    then        exit    fi    if [ $option -ge 1 ] && [ $option -le 4 ]    then        if [ $option = 1 ]        then        make "network_sniffer"        fi        if [ $option = 2 ]        then        "./network_sniffer"        fi        if [ $option = 3 ]        then        make clean        fi        if [ $option = 4 ]        then        make re        fi          else        printf "This option does not exist\n"    fi    done}trap ‘sigint‘ 2main

C Language implementation of Linux network sniffer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.