QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 953|回复: 5

请问怎样从捕捉到的数据包中按协议分类?

[复制链接]
发表于 2004-3-25 14:47:29 | 显示全部楼层 |阅读模式
谢谢!
发表于 2004-3-25 16:27:55 | 显示全部楼层
如果是Internet的话,在ip之下有Ethernet,802.11,FDDI等(当然,当你上网时你所在的网络就把这一层定了),在网络层有ARP,IP,RARP等,IP之上有tcp,udp等,在tcp和udp上又有http等应用层协议,这样,你要的那一个协议就要看是哪一层?还有你用什么工具抓包?不同的工具产生不同的包结构。
回复

使用道具 举报

 楼主| 发表于 2004-3-26 08:35:58 | 显示全部楼层
我用libpcap抓的包,现在想解析包头的信息,然后给包按协议分类,就是不知道怎样解析包头信息!
回复

使用道具 举报

发表于 2004-3-26 11:13:43 | 显示全部楼层
移入下层
回复

使用道具 举报

发表于 2004-3-26 22:40:34 | 显示全部楼层
以下代码为在默难所写代码基础上改写以符合特定的要求
[code:1]
#include <pcap.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/if_ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>

#define PROTO_IPV6HOP    0
#define PROTO_ICMP       1
#define PROTO_IGMP       2
#define PROTO_GGP        3
#define PROTO_IPENCAP    4
#define PROTO_ST         5
#define PROTO_TCP        6
#define PROTO_CBT        7
#define PROTO_EGP        8
#define PROTO_IGP        9
#define PROTO_PUP        12
#define PROTO_UDP        17
#define PROTO_HMP        20
#define PROTO_XNSIDP     22
#define PROTO_RDP        27
#define PROTO_IPV6       41
#define PROTO_IPV6ROUTE  43
#define PROTO_IPV6FRAG   44
#define PROTO_IDRP       45
#define PROTO_RSVP       46
#define PROTO_GRE        47
#define PROTO_ESP        50
#define PROTO_AH         51
#define PROTO_NARP       54
#define PROTO_IPV6ICMP   58
#define PROTO_IPV6NONEXT 59
#define PROTO_IPV6OPTS   60
#define PROTO_RSPF       73
#define PROTO_VMTP       81
#define PROTO_OSPF       89
#define PROTO_IPIP       94
#define PROTO_ENCAP      98


#define ETHERTYPE_IP        0x0800  /* IPv4 */
#define ETHERTYPE_ARP       0x0806  /* Addr. resolution protocol */
#define ETHERTYPE_RARP      0x8035  /* Reverse addr. resolution protocol */
#define ETHERTYPE_IPX       0x8137  /* IPX family */
#define ETHERTYPE_IPV6      0x86dd  /* IPv6 */
#define ETHERTYPE_PPP       0x880b  /* PPP */
#define ETHERTYPE_PPPOED    0x8863  /* PPPoE discovery */
#define ETHERTYPE_PPPOES    0x8864  /* PPPoE session */
#define ETHERTYPE_PPPHDLC   0x8881  /* CDMA2000 PPP with HDLC framing in GRE */

#define FTP_data 20 // file transfer protocol
#define FTP_ctrl 21 //file transfer protocol
#define SSH  22    // secure shell
#define Telnet 23  // telecommunications networking
#define SMTP 25    // simple mail transfer protocol
#define DNS  53    // domain name server
#define BOOTPS 67  // bootstrap protocol server / DHCP
#define BOOTPC 68  // bootstrap protocol client / DHCP
#define TFTP  69   // trivial file transfer protocol
#define HTTP 80    //      hypertext transfer protocol
#define ISO_TSAP 102      //iso on tcp
#define POP3 110     //  post office protocol version 3
#define NNTP 119   //   network news transfer protocol
#define NTP 123    //   network time protocol
#define NETBIOS_NS 137//   name service
#define NETBIOS_DG 138//   datagram
#define NETBIOS_SE 139//   session
#define IMAP 143   //    interim mail access protocol v2
#define SNMP 161   //   simple network management protocol
#define IRC 194    //   internet relay chat protocol
#define LDAP 389   //   lightweight directory access protocol
#define HTTPS 443  //   http through SSL
#define CVSPSERVER  2401//concurrent versioning system

char errbuf[PCAP_ERRBUF_SIZE];
char *dev;


void dealtcp(u_char* payload){
  //you can deal tcp packet in this funtion
  struct tcphdr* tcp_hdr;
  tcp_hdr = (struct tcphdr*)payload;
  switch(ntohs(tcp_hdr->dest)){
  case HTTP:
    printf(" HTTP ");
    break;
  case HTTPS:
    printf(" HTTPS ");
    break;

    //add case you want to capture

  default:
    printf(" 其它的\n");
    break;

  }

}

void dealudp(u_char* payload){

  struct udphdr* udp_hdr;
  udp_hdr = (struct udphdr*)payload;

  //note: I print the protocol message of application layer
  //whose port number come from the knowledge that these
  //protocol have well known port number.This will not always true.

  switch(ntohs(udp_hdr->dest)){
  case HTTP:
    printf(" HTTP ");
    break;

    //add case which you want to capture

  default:
    printf(" 其它的\n");
    break;
  }
}
  
typedef struct ether_header eth_hdr;

void err_exit(char *str,int i)
{
   fprintf(stderr,"%s%s\n",str,errbuf);
   exit(i);
}

void dis_ip_hdr(u_char* ip_payload){
  u_char* ip_packet;
  u_char* packet;
  
  struct iphdr *ip_hdr;
  struct tcphdr *tcp_hdr;
  struct udphdr *udp_hdr;
  
  ip_hdr = (struct iphdr*)(ip_payload);
  int header_proto = ip_hdr->protocol;
  switch(header_proto){
  case PROTO_ICMP:
    printf(" ICMP ");
    break;
  case PROTO_IGMP:
    printf(" IGMP ");
    break;
  case PROTO_TCP:
    printf(" TCP ");
    packet = (u_char*)(ip_payload+sizeof(struct iphdr));
    dealtcp(packet);
    break;
  case PROTO_UDP:
    printf(" UDP ");
    packet = (u_char*)(ip_payload + sizeof(struct iphdr));
    dealudp(packet);
    break;
    //you should add case which you want to know
  default:
    printf(" 不能识别的或错误的!");
    break;
  
  }
}

void call_back(u_char *usr,const struct pcap_pkthdr *pkthdr,const u_char *packet){
  /*the struct below  is useful when you want more information
  struct timeval tv;
  tv.tv_sec = pkthdr->ts.tv_sec;
  tv.tv_usec = pkthdr->ts.tv_usec;
  int capture_len = pkthdr->len;
  struct in_addr addr;
  */
  struct ether_header *e_hdr;
  struct iphdr *ip_hdr;
  u_char* ip_packet;
  //  u_char* payload;

  //  payload = (u_char*)packet;


  e_hdr = (eth_hdr*)packet;
  e_hdr->ether_type = ntohs(e_hdr->ether_type);

  switch(e_hdr->ether_type){
  case ETHERTYPE_IP:
    printf("网络层协议类型:IP    ");
    ip_packet= (u_char *)(packet+sizeof(eth_hdr));
    dis_ip_hdr(ip_packet);
    printf("\n");
   
    break;
  case ETHERTYPE_ARP:
    printf("网络层协议类型:ARP  \n\n");
    break;
  case ETHERTYPE_REVARP:
    printf("网络层协议类型:RARP \n\n");
    break;
  default:
    // printf("网络层协议类型:未知的或本软件不能识别的或错误的包\n");
    return;
  }

  return;
}

int main(int argc,char *argv[])
{
   pcap_t *hdl;
   bpf_u_int32 netp;
   bpf_u_int32 maskp;
   struct in_addr addr;

   dev=pcap_lookupdev(errbuf);
   if(NULL==dev)
      err_exit("pcap_loopupdev():",-1);
   printf("%s\n",dev);
   
   if(pcap_lookupnet(dev,&netp,&maskp,errbuf)<0)
      err_exit("pcap_lookupnet():",-1);
   addr.s_addr=netp;
   printf("NET:%s\n",inet_ntoa(addr));
   addr.s_addr=maskp;
   printf("MASK:%s\n",inet_ntoa(addr));

   printf("\n");

   hdl=pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
   if(NULL==hdl)
      err_exit("pcap_open_live():",-1);
   
   if((argc!=2)||(!isdigit(*argv[1])))
      pcap_loop(hdl,-1,call_back,NULL);
   else
      pcap_loop(hdl,atoi(argv[1]),call_back,NULL);
   printf("END....\n");
   return 0;
}

[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-3-29 10:35:09 | 显示全部楼层
首先很感谢你给我这么多的帮助,但是试了你给的程序,结果除了和以前一样的乱码之外,在中间有这样的东西,我有点糊涂了!
%s
^@ ICMP ^@ IGMP ^@ TCP ^@ UDP ^@ 不能识别的或错误的!^@网络层协议类型:IP    ^@
^@网络层协议类型:ARP
                                                                                
^@网络层协议类型:RARP
                                                                                
^@pcap_loopupdev():^@%s
^@pcap_lookupnet():^@NET:%s
^@MASK:%s
^@pcap_open_live():^@END....
^@^@^@^@^@^@^@^@^@^@^@^@^@^@?~\^D^H^A^@^@^@^A^@^@^@^A^@^@^@h^@^@^@^L^@^@^@?~D^D^H^M^@^@^@?~J^D^H^D^@^@^@(~A^D^H^E^@^@^@^X~C^D^H^F^@^@^@?~A^D^H
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 16:53 , Processed in 0.042702 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表