2017-2018-1 20179202 "Linux kernel Fundamentals and analysis" 12th week assignment

Source: Internet
Author: User
Tags clear screen readable

C Language implementation of Linux network sniffer one, knowledge preparation

1. In general, all machines on the network can "listen" to the traffic that passes through, but will not respond to packets that do not belong to them. If a workstation's network interface is in promiscuous mode, it can capture all the packets and frames on the network.

2. In order to bypass the standard TCP/IP stack, the NIC must be set to promiscuous mode. In general, to activate this mode, the kernel requires root privileges to run the program, so sniffer needs to be installed as root.

3. When a hacker successfully compromised a host and got root privileges, and would like to use this host to attack other hosts on the same network segment, the sniffer software is installed on the host, and the packets transmitted on the Ethernet device are intercepted to discover the packages of interest.

The 4.socket socket is used to describe IP addresses and ports, and is a handle to a communication chain that can be used to communicate between different virtual machines or different computers.

5. A network sniffer is a program that intercepts incoming and outgoing data through a network interface. In this experiment, C language is used to implement a network sniffer. Program Framework and function Description:

Second, source code analysis

1.sniffer.h

This header defines the S_protocol and s_sniffer two structures and declares functions that write to the log file of IP headers, TCP packets, UDP packets, ICMP packets, and user packet data, functions that parse out the packet type (processpacket), and so on:

#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

2.main.c

The file contains the main function, creates a socket listener, parses the packet, and writes the parsing result to Log.txt:

#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");    }int Main () {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_IP 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 processing function */signal (sigquit, &signal_white_now);  /* Loop over the Ethernet frame and call the Processpacket function to parse */while (1) {Fd_zero (&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) {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 means 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);}

3.show_data.c

The file is to write the packet information to the Log.txt:

#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"); }}

4.tools.h and TOOLS.C define color, signal processing functions:

#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
#include <signal.h>#include <stdio.h>void signal_white_now(int signum){    printf("Bye Bye !\n");}
Third, the experiment

1. Running Results

A UDP packet in the 2.log.txt

Four, off-topic

There is a. sh file in the source code, I don't know what it is? After checking the data and knowing that it is a shell script file, the shell script is a collection of commands. If you implement such an operation:

    • Enter into the/tmp/directory;
    • Lists all filenames in the current directory;
    • Copy all current files to the/root/directory;
    • Deletes all files in the current directory.

A simple 4 step in the shell window needs to knock 4 times and press ENTER 4 times. Isn't that a lot of trouble? Of course, this 4-step operation is very simple, if it is more complex command setup requires dozens of operations? In that case it would be troublesome to knock on the keyboard once. So it's a matter of recording all the operations into a document and then calling the commands in the document so that one step can be done. This document is a shell script. The shell script can easily manage the server because you can specify a task schedule to execute a shell script to fulfill the requirements.

2017-2018-1 20179202 "Linux kernel Fundamentals and analysis" 12th week assignment

Related Article

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.