经典珍藏小代码(数据包解析)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h> /* For ETH_P_ALL */
#include <net/if_arp.h>

#include "sniffer.h"

#define BUFSIZE 2048
#define SNIFFER_VERSION "sniffer-1.0"

static void hex_print(const u_char *buf, int len, int offset);
static int decode_eth(const u_char *buf);
static int decode_ip(const u_char *buf);
static int decode_arp(const u_char *buf);
static int decode_tcp(const u_char *buf);
static int decode_udp(const u_char *buf);
void show_nowtime();//显示当前时间
void print_usage (int exit_status);//显示命令帮助

static char *destip = NULL;//在命令参数中得到要过滤地目的IP
static char *sourceip = NULL;//在命令参数中得到要过滤源的IP
static int globe_argnum = 0;
static int pag_length = 0;

int main( int argc, char **argv )
{
 int listenfd;
 int n;
 char buf[BUFSIZE];
 int arg_num = 1;
 int old_arg_num = 0;
 globe_argnum = argc;
 printf( "command number: %d/n", argc );
 
 while( arg_num < argc )
 {
  old_arg_num = arg_num;
  if (strncmp ("-d", argv[arg_num], 2) == 0)
  {
   arg_num++;
   destip = argv[arg_num];
   printf( " /n destIP = %s /n", argv[arg_num] );
  }
  else if (strncmp ("-s", argv[arg_num], 2) == 0)
  {
   arg_num++;
   sourceip = argv[arg_num];
   printf( " /n sourceIP = %s /n", argv[arg_num] );
  }
  else if ((strncmp ("-v", argv[arg_num], 2) == 0)||
    (strncmp("--version", argv[arg_num], strlen ("--version")) == 0) )
  {
   printf ("version: " SNIFFER_VERSION "/n");
   exit (EXIT_SUCCESS);
  }
  else if (old_arg_num == arg_num)
  {
   fprintf (stderr, "ERROR: bad arguments/n");
   print_usage (EXIT_FAILURE);
   //return -1;
  }
  
  arg_num++;
 }
 
 if ((listenfd = socket(PF_PACKET, SOCK_RAW,  htons(ETH_P_ALL))) < 0)
 {
  perror("socket");
  exit(1);
 }
 
 for (;;)
 {
  if ((n = recv(listenfd, buf, BUFSIZE, 0)) > 0)
  {
   //printf( "/n/n------------------------------------------------------/n/n" );
   decode_eth(buf);
   pag_length = n;
   //printf("/nNowTime : %s/n",asctime(timenow));
  }
 }
 
 return 0;
}

static int decode_eth(const u_char *buf)
{
 
 struct ethhdr *eth = (struct ethhdr *) buf;
 //struct iphdr *ipp = (struct iphdr *) buf;
 struct iphdr *ipp = (struct iphdr *) (u_char *)&eth[1];
 struct ether_arp *arpp = (struct ether_arp *) buf;
 char sip[ 16 ];
 char dip[ 16 ];
 memset( sip, 0, sizeof( sip ) );
 memset( dip, 0, sizeof( dip ) );
 //int cpm = 0;
 
 switch (ntohs(eth->h_proto))
 {
  
  case ETH_P_IP:
   //printf("/nSource IP Address: %d.%d.%d.%d", NIPQUAD(iph->saddr));
   //printf("/nDestination IP Address: %d.%d.%d.%d", NIPQUAD(iph->daddr));
   sprintf( sip, "%d.%d.%d.%d", NIPQUAD(ipp->saddr));
   sprintf( dip, "%d.%d.%d.%d", NIPQUAD(ipp->daddr));
   sip[ 15 ] = '/0';
   dip[ 15 ] = '/0';
   //printf( "filter sip %s dip %s /n", sip, dip );
   if ( globe_argnum == 1 )
   {
    printf( " --------------------start--------------------/n" );
    printf("/nMAC header");
    printf("/nDestination Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_dest));
    printf("/nSource Address:%02X: %02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_source));
    printf("/nType: %02X-%02X", PWORD(eth->h_proto));
    return decode_ip((u_char *)&eth[1]);
   }
   else if ( globe_argnum == 3 )
   {
    //printf( "globe_argnum %d/n ", globe_argnum );
    if( destip )
    {
     //cpm = strcmp( dip, destip );
     //printf( "cmp == %d dip : %s /t destip:%s/n", cpm );
     if( 0 == strcmp( dip, destip ) )
     {
      printf( "/n--------------------start--------------------/n" );
      printf("/nMAC header");
      printf("/nDestination Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_dest));
      printf("/nSource Address:%02X: %02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_source));
      printf("/nType: %02X-%02X", PWORD(eth->h_proto));
      return decode_ip((u_char *)&eth[1]);
     }
    }
    else if( sourceip )
    {
     if( 0 == strcmp( sip, sourceip ) )
     {
      printf( "/n--------------------start--------------------/n" );
      printf("/nMAC header");
      printf("/nDestination Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_dest));
      printf("/nSource Address:%02X: %02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_source));
      printf("/nType: %02X-%02X", PWORD(eth->h_proto));
      return decode_ip((u_char *)&eth[1]);
     }
    }
   }
   else if ( globe_argnum == 5 )
   {
    if( ( 0 == strcmp( sip, destip ) ) && ( 0 == strcmp( sip, sourceip ) ) )
    {
     printf( "/n--------------------start--------------------/n" );
     printf("/nMAC header");
     printf("/nDestination Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_dest));
     printf("/nSource Address:%02X: %02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_source));
     printf("/nType: %02X-%02X", PWORD(eth->h_proto));
     return decode_ip((u_char *)&eth[1]);
    }
   }
   break;
  case ETH_P_ARP:
   //sprintf( sip, "%d.%d.%d.%d", NIPQUAD(arpp->saddr));
   //sprintf( dip, "%d.%d.%d.%d", NIPQUAD(arpp->daddr));
   return decode_arp((u_char *)&eth[1]);
  default:
   return -1;
 }
 
 return 0;
}

static int decode_arp(const u_char *buf)
{
 struct ether_arp *arph = (struct ether_arp *) buf;
 
 printf("/nAddress Resolution Protocol");
 printf("/nHardware Type: %d", ntohs(arph->arp_hrd));
 printf("/nProtocol Type: %02X-%02X", PWORD(arph->arp_pro));
 printf("/nLength of Hardware Address: %d", arph->arp_hln);
 printf("/nLength of Protocol Address: %d", arph->arp_pln);
 printf("/nOperation Code: %d", ntohs(arph->arp_op));
 printf("/nSender`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X",
  HWADDR(arph->arp_sha));
 printf("/nSender`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_spa));
 printf("/nTarget`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X",
  HWADDR(arph->arp_tha));
 printf("/nTarget`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_tpa));
 hex_print(buf, pag_length, 0);
 return 0;
}

static int decode_ip(const u_char *buf)
{
 struct iphdr *iph = (struct iphdr *) buf;
 
 printf("/nIPv4 header");
 printf("/nVersion: %d", iph->version);
 printf("/nHeader length: %d (%d bytes)", iph->ihl, iph->ihl*4);
 printf("/nType of service (TOS):0x%02X", iph->tos);
 printf("/nTotal length: %d", ntohs(iph->tot_len));
 printf("/nIdentification: %d", ntohs(iph->id));
 printf("/nFlags: %02X %02X", PWORD(iph->frag_off));
 printf("/nTime to Live (TTL): %d hops", iph->ttl);
 printf("/nProtocol: %d", iph->protocol);
 printf("/nChecksum: 0x%02X%02X", PWORD(iph->check));
 printf("/nSource IP Address: %d.%d.%d.%d", NIPQUAD(iph->saddr));
 printf("/nDestination IP Address: %d.%d.%d.%d", NIPQUAD(iph->daddr));
 
 switch (iph->protocol)
 {
  case IPPROTO_TCP:
   return decode_tcp((u_char *)&iph[1]);
  case IPPROTO_UDP:
   return decode_udp((u_char *)&iph[1]);
  case  IPPROTO_ICMP:
   printf("/ICMP header");
   printf("/nICMP pkt:%s/n",inet_ntoa(*(struct in_addr*)&(iph->saddr)));
   hex_print(buf, pag_length, 0);
   show_nowtime();
   break;
   
  case  IPPROTO_IGMP:
   printf("/nIGMP pkt:/n");
   hex_print(buf, pag_length, 0);
   show_nowtime();
   break;
  default:
   return -1;
 }
 return 0;
}

static int decode_tcp(const u_char *buf)
{
 struct tcphdr *tcph = (struct tcphdr *) buf;
 
 printf("/nTCP header");
 printf("/nSource port: %d", ntohs(tcph->source));
 printf("/nDestination port: %d", ntohs(tcph->dest));
 printf("/nSequence number: %u", ntohl(tcph->seq));
 printf("/nAcknowledegment number: %u", ntohl(tcph->ack_seq));
 printf("/nHeader length: %d (%d bytes)", tcph->doff, tcph->doff*4);
 printf("/nReserved: 0x%X", tcph->res1);
 printf("/nFlags: r:%d,u:%d,a:%d,p:%d,r:%d,s:%d,f:%d",
  tcph->res2, tcph->urg, tcph->ack, tcph->psh,
  tcph->rst, tcph->syn, tcph->fin);
 printf("/nWindow size: %d", ntohs(tcph->window));
 printf("/nChecksum: 0x%02X%02X", PWORD(tcph->check));
 printf("/nUrgent pointer: %d", ntohs(tcph->urg_ptr));
 
 hex_print(buf, pag_length, 0);
 show_nowtime();
 
 return 0;
}

static int decode_udp(const u_char *buf)
{
 struct udphdr *udph = (struct udphdr *) buf;
 
 printf("/nUDP header");
 printf("/nSource Port: %d", ntohs(udph->source));
 printf("/nDestination Port: %d", ntohs(udph->dest));
 printf("/nLength: %d bytes", ntohs(udph->len));
 printf("/nChecksum: 0x%X", udph->check);
 hex_print(buf, pag_length, 0);
 show_nowtime();
 
 return 0;
}

static void hex_print(const u_char *buf, int len, int offset)
{
 
 u_int i, j, jm;
 int c;
 
 printf("/n");
 for (i = 0; i < len; i += 0x10)
 {
  printf(" %04x: ", (u_int)(i + offset));
  jm = len - i;
  jm = jm > 16 ? 16 : jm;
  
  for (j = 0; j < jm; j++)
  {
   if ((j % 2) == 1)
   {
    printf("%02x ", (u_int) buf[i+j]);
   }
   
   else
   {
    printf("%02x", (u_int) buf[i+j]);
   }
  }
  
  for (; j < 16; j++)
  {
   if ((j % 2) == 1)
   {
    printf("   ");
   }
   else
   {
    printf(" ");
   }
  }
  
  printf(" ");
  
  for (j = 0; j < jm; j++)
  {
   c = buf[i+j];
   c = isprint(c) ? c : '.';
   printf("%c", c);
  }
  
  printf("/n");
 }
}
void print_usage (int exit_status)
{
 fprintf (stdout, "/n/t usage: sniffer [-d destip] [-s sourip] /n/
  -d  destip           Filter Destination IP Address/n/
  -s  sipaddress       Filter Source IP Address/n/n");
   exit(exit_status);
}

void show_nowtime()
{
 time_t now;
 struct tm *timenow;
 time(&now);
 timenow = localtime(&now);
 printf("%s/n",asctime(timenow));
 printf( "--------------------end--------------------/n" );
}

你可能感兴趣的:(socket,tcp,struct,header,filter,hex)