learn more about tcp/ip-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 3977347
  • 博文数量: 536
  • 博客积分: 10470
  • 博客等级: 上将
  • 技术积分: 4825
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-26 14:08
文章分类

全部博文(536)

文章存档

2024年(3)

2021年(1)

2019年(1)

2017年(1)

2016年(2)

2013年(2)

2012年(10)

2011年(43)

2010年(10)

2009年(17)

2008年(121)

2007年(252)

2006年(73)

分类:

2007-08-23 16:25:19

learn ieee802.3 tcp/ip udp protocol format

compile method:
$gcc -wall -o sniffer sniffer.c

run with root user for test:
$./sinffer

test environment:
$gcc -v
gcc version 3.2.2 20030222 (red hat linux 3.2.2-5)

code filename: sniffer.c
----------

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdint.h>
#include <sys/types.h>

#include <signal.h>
#include <string.h>
#include <errno.h>

#include <sys/socket.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>

#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>

#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>

#define    snif_buffer_size    8192

struct recv_packet
{
  struct ether_header    *ethdr;        /* ieee802.3 ethernet header */
  struct iphdr        *iphdr;        /* ip packet header */
  struct udphdr        *udphdr;    /* udp packet header */
  struct tcphdr        *tcphdr;    /* tcp packet header */
  uint8_t        *data;        /* pointer to data */
  uint32_t        len;        /* data length */
};

/**
 * print ip packet information
 */

static void print_eth_header(struct ether_header *etp);
static void print_ip_header(struct iphdr *ip);
static void print_udp_header(struct udphdr *up);
static void print_tcp_header(struct tcphdr *up);
static void print_data(uint8_t *p, uint32_t len);
static int is_filter(struct recv_packet *rcv);

/**
 * ctrl c for exit
 */

static int isc;
static void exit_while(int signo)
{
  isc = 0;
}

int main(int argc, char **argv)
{
  int            sd, rlen;
  unsigned char        buf[snif_buffer_size], *p, *pe;
  struct ifreq        ethreq;
  struct recv_packet    rcv;

  /* ctrl c */
  signal(sigint, exit_while);

  if ((sd = socket(pf_packet, sock_raw, htons(eth_p_ip))) < 0)
  {
    fprintf(stderr, "socket create error: %s\n", strerror(errno));
    goto err_1;
  }

  strncpy(ethreq.ifr_name, "eth0", ifnamsiz);
  ioctl(sd, siocgifflags, &ethreq);
  ethreq.ifr_flags |= iff_promisc;
  ioctl(sd, siocsifflags, &ethreq);

  p = buf;
  rcv.ethdr = (struct ether_header *)p;
  p = sizeof(struct ether_header);

  rcv.iphdr = (struct iphdr *)p;
  p = sizeof(struct iphdr);

  rcv.udphdr = (struct udphdr *)p;
  rcv.tcphdr = (struct tcphdr *)p;


  isc = 1;
  while (isc)
  {
    rlen = recvfrom(sd, buf, snif_buffer_size, 0, null, null);
    if (rlen < 42)
    {
      fprintf(stderr, "recv incomplete header information. \n");
      continue;
    }
    /* pointer to data end */
    pe = buf rlen;
  
    if (is_filter(&rcv) == 1)
      continue;

    print_eth_header(rcv.ethdr);
    print_ip_header(rcv.iphdr);
    switch (rcv.iphdr->protocol)
    {
      case ipproto_udp:
        print_udp_header(rcv.udphdr);
        rcv.data = (uint8_t *)rcv.udphdr sizeof(struct udphdr);
        break;

      case ipproto_tcp:
        print_tcp_header(rcv.tcphdr);
        rcv.data = (uint8_t *)rcv.tcphdr sizeof(struct tcphdr);
        break;
    }

    rcv.len = pe - rcv.data;
    print_data(rcv.data, rcv.len);

    printf("\n");
  }

  close(sd);

  return (0);

err_1:
  return (-1);
}

static int is_filter(struct recv_packet *rcv)
{
  uint32_t    saddr, daddr;
#if 0
  uint32_t    spip;
#endif

  saddr = ntohl(rcv->iphdr->saddr);
  daddr = ntohl(rcv->iphdr->daddr);

#if 0
  /* set your sniffer ip */
  spip    = ntohl(inet_addr("192.168.1.84"));
#endif

  /* filter the loopback packet */
  if (saddr == inaddr_loopback || daddr == inaddr_loopback)
    return (1);

#if 0
  if (saddr == spip || daddr == spip)
    return (0);
  else
    return (1);
#endif

  return (0);
}

/**
 * ieee 802.3
 */

static void print_eth_header(struct ether_header *etp)
{
#define    _xff(t)            ((t)&0xff)
#define    snif_addr_mac(p)     \
    _xff((p)[0]),_xff((p)[1]),_xff((p)[2]),_xff((p)[3]),_xff((p)[4]),_xff((p)[5])


    /* dest mac addr [6] | src mac addr [6] | type [2]
     * | ip data packet
     */

   printf("mac: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ==> %.2x:%.2x:%.2x:%.2x:%.2x:%.2x "
    , snif_addr_mac(etp->ether_shost)
    , snif_addr_mac(etp->ether_dhost));

   printf("type.");
   switch (ntohs(etp->ether_type))
   {
     case ethertype_pup:     printf("xerox pup ");     break;
     case ethertype_ip:     printf("ip ");         break;
     case ethertype_arp:     printf("arp ");     break;
     case ethertype_revarp:     printf("rarp ");     break;
     default:            printf("unkown type ");    break;
   }

   printf("\n");
}

/**
 * ip data packet header
 */

static void print_ip_header(struct iphdr *ip)
{
  struct in_addr    saddr, daddr;
  char            sip[24], dip[24];

    /* ver 4bit | header length 4bits | tos 8bits | total length 16 bits
     * flags identification 16bits | flags 3bits | offset 13bits
     * ttl 8 bits | protocol type 8bits | checksum 16bits
     * src ip address 32bits
     * dest ip address 32bits
     * options values
     *
     * tcp/udp data packet
     */


  saddr.s_addr = ip->saddr;
  strcpy(sip, inet_ntoa(saddr));

  daddr.s_addr = ip->daddr;
  strcpy(dip, inet_ntoa(daddr));

  printf("ip %s ==> %s \n", sip, dip);
  printf("ip packet: ver.%d header-length.%d tos.x total-len.%d ttl.%d \n"
    "id.%d offset.%d checksum.%d "
    , ip->version, ip->ihl, ip->tos, ntohs(ip->tot_len), ip->ttl
    , ntohs(ip->id), ntohs(ip->frag_off), ntohs(ip->check)
    );

  printf("protocol.");
  switch (ip->protocol)
  {
    case ipproto_icmp: printf("icmp "); break;
    case ipproto_igmp: printf("igmp "); break;
    case ipproto_ipip: printf("ipip "); break;
    case ipproto_raw: printf("raw "); break;

    case ipproto_tcp: printf("tcp "); break;
    case ipproto_udp: printf("udp "); break;
    default:
      printf("unkown protocol type.%d ", ip->protocol);
  }

  printf("\n");
}

/**
 * udp data packet header
 */

static void print_udp_header(struct udphdr *up)
{
  printf("udp src-port.%d dest-port.%d len.%d checksum.%d "
    , ntohs(up->source), ntohs(up->dest)
    , ntohs(up->len), ntohs(up->check));

  printf("\n");
}

/**
 * tcp data packet header
 */

static void print_tcp_header(struct tcphdr *tp)
{
  printf("tcp src-port.%d dest-port.%d seq.%u ack_seq.%u \n"
    "windows.%d checksum.%d pointer.%d "
    , ntohs(tp->source), ntohs(tp->dest)
    , ntohl(tp->seq), ntohl(tp->ack_seq)
    , ntohs(tp->window), ntohs(tp->check), ntohs(tp->urg_ptr));

  if (tp->syn)    printf("syn ");
  if (tp->rst)    printf("rst ");
  if (tp->ack)    printf("ack ");
  if (tp->psh)    printf("psh ");
  if (tp->fin)    printf("fin ");
  if (tp->urg)    printf("urg ");

  printf("\n");
}

/**
 * dump data information
 */

static void print_data(uint8_t *p, uint32_t len)
{
  int    i, nlen, j;
  int    flg, ll;
  char    cch[62];

  printf("data.%p data-len.%d \n", p, len);
  nlen = ll = 20;

  for (i = j = 0; i < len; i, j)
  {
    printf("x", p[i]);
    if ((i1) % 4 == 0)
    {
      flg = 1;
      printf(" ");
    }
    else
      flg = 0;

    cch[j] = (isprint(p[i])) ? p[i] : '.';    

    if (j >= nlen && flg == 1)
    {
      ll = j;

      cch[j1] = '\0';
      printf(" %s\n", cch);
      j = -1;
    }
  }

  cch[j] = '\0';
  for (; j <= ll; j)
  {
    printf(" ");
    if ((j1) % 4 == 0) printf(" ");
  }

  printf(" %s\n", cch);
}

阅读(2643) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图