首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

Linux捉包程序

2012-06-26 
Linux抓包程序#include stdio.h#include stdlib.h#include sys/socket.h#include netinet/in.h#in

Linux抓包程序

#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/ip.h>#include <string.h>#include <netdb.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <net/if.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/if_ether.h>#include <net/ethernet.h>void die(char *why, int n){    perror(why);    exit(n);}int do_promisc(char *nif, int sock ){    struct ifreq ifr;    strncpy(ifr.ifr_name, nif,strlen(nif)+1);    if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) //获得flag    {        die("ioctl", 2);    }    ifr.ifr_flags |= IFF_PROMISC; //重置flag标志    if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) //改变模式    {        die("ioctl", 3);    }    return 0;}//修改网卡成PROMISC(混杂)模式/*   =============================================================================================================下面是实现捕获和分析UDP协议数据包的函数定义  =============================================================================================================*/   void udp_protocol_packet_callback( u_char *packet_content)   {       struct udphdr *udp_protocol;       // UDP协议数据变量       u_short source_port;       // 源端口号     u_short destination_port;       // 目的端口号        udp_protocol = (struct udphdr*)(packet_content + 14+20);       // 获得UDP协议数据内容     source_port = ntohs(udp_protocol->source);       // 获得源端口号     destination_port = ntohs(udp_protocol->dest);       // 获得目的端口号      printf("----------  UDP Protocol  (Transport  Layer)  ----------\n");       printf("Source port:%d\n", source_port);       printf("Destination port:%d\n", destination_port);       switch (destination_port)       //根据端口号判断应用层协议类型       {       case 138:           printf("NETBIOS Datagram Service\n");           break;           // 端口号为138,表示上层协议为NETBIOS 数据报服务        case 137:           printf("NETBIOS Name Service\n");           break;           // 端口号为137,表示上层协议为NETBIOS 名字服务        case 139:           printf("NETBIOS session service\n");           break;           // 端口号为139,表示上层协议为NETBIOS 会话服务        case 53:           printf("name-domain server \n");           break;           // 端口号为53,表示上层协议为域名服务     case 4000:           printf("QQ server \n");           break;     case 1863:           printf("MSN server \n");           break;     case 9001:           printf("OTHERS \n");           break;         default:           printf("NOT WELL-KNOWN PROTOCOL.\n");        break; //其他没有分析     }   }    /*   =============================================================================================================下面是实现捕获和分析TCP协议数据包的函数定义  =============================================================================================================*/   void tcp_protocol_packet_callback( u_char *packet_content)   {       struct tcphdr *tcp_protocol;       // TCP协议数据变量       u_short source_port;       // 源端口号     u_short destination_port;       // 目的端口号        tcp_protocol = (struct tcphdr*)(packet_content + 14+20);       // 获得UDP协议数据内容     source_port = ntohs(tcp_protocol->source);       // 获得源端口号     destination_port = ntohs(tcp_protocol->dest);       // 获得目的端口号      printf("----------  TCP Protocol  (Transport  Layer)  ----------\n");       printf("Source port:%d\n", source_port);       printf("Destination port:%d\n", destination_port);       switch (destination_port)       //根据端口号判断应用层协议类型       {       case 7:        printf("ECHO server \n");        break;    case 21:        printf("FTP server \n");        break;    case 23:        printf("TELNET server \n");        break;    case 25:        printf("SMTP server \n");        break;    case 53:        printf("DNS server \n");        break;    case 80:        printf("HTTP server \n");        break;        case 2049:        printf("NFS server \n");        break;    case 6667:        printf("IRCD server \n");        break;    default:           printf("NOT WELL-KNOWN PROTOCOL.\n");        break; //其他没有分析     }   }   /*  =============================================================================================================下面是分析IP协议的函数的定义  ============================================================================================================= */   void ip_protocol_packet_callback(  u_char *packet_content)   {       struct iphdr *ip_protocol;    // IP协议变量      printf("----------  IP Protocol  (Network Layer)  ----------\n");       ip_protocol = (struct iphdr*)(packet_content + 14);   //获得IP协议数据内容     printf("Protocol:%d\n", ip_protocol->protocol);    //获得协议类型    switch (ip_protocol->protocol) // 根据协议类型判断    {    case IPPROTO_TCP:        printf("The Transport Layer Protocol is TCP\n");           break;           /* 上层协议为TCP协议 */       case IPPROTO_UDP:           printf("The Transport Layer Protocol is UDP\n");           break;           /* 上层协议为UDP协议 */       case IPPROTO_ICMP:           printf("The Transport Layer Protocol is ICMP\n");           break;           /* 上层协议为ICMP协议 */       case IPPROTO_IGMP:        printf("The Transport Layer Protocol is IGMP\n");        break;    default:           break;       }       printf("TCP pkt :FORM:[%s]\n",inet_ntoa(*(struct in_addr*)&(ip_protocol->saddr)));    printf("TCP pkt :TO:  [%s]\n",inet_ntoa(*(struct in_addr*)&(ip_protocol->daddr)));    switch (ip_protocol->protocol)       {       case IPPROTO_TCP:          tcp_protocol_packet_callback(packet_content);        break;       case IPPROTO_UDP:        udp_protocol_packet_callback(packet_content);           break;        default:        break;    }   } /*=============================================================================================================下面是分析以太网协议的回调函数的定义  =============================================================================================================*/   void ethernet_protocol_packet_callback( u_char *packet_content)   {       u_short ethernet_type;   /* 以太网类型 */       struct ether_header *ethernet_protocol;   /* 以太网协议变量 */       u_char *mac_string;   /* 以太网地址 */       static int packet_number = 1;       printf("**************************************************\n");       printf("The %d   packet is captured.\n", packet_number);       printf("--------   Ehternet Protocol (Link Layer)    --------\n");       ethernet_protocol = (struct ether_header*)packet_content;       /* 获得以太网协议数据内容 */       printf("Ethernet type is :\n");       ethernet_type = ntohs(ethernet_protocol->ether_type);       /* 获得以太网类型 */       printf("%04x\n", ethernet_type);       switch (ethernet_type)       {       case 0x0800:           printf("The network layer is IP protocol\n");           break;           /* 上层协议为IP协议 */       case 0x0806:           printf("The network layer is ARP protocol\n");           printf("----------  ARP Protocol   (Network Layer)  ----------\n");           break;           /* 上层协议为ARP协议 */       case 0x8035:           printf("The network layer is RARP protocol\n");           printf("----------  RARP Protocol   (Network Layer)  ----------\n");           break;           /* 上层协议为RARP协议 */       default:           break;       }       switch (ethernet_type)       {       case 0x0800:           ip_protocol_packet_callback( packet_content);           break;           // 上层协议为IP协议,就调用分析IP 协议的函数,注意参数的传递       default:           printf("Mac Source Address is : \n");           mac_string = ethernet_protocol->ether_shost;           printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));           //获得源以太网地址         printf("Mac Destination Address is : \n");           mac_string = ethernet_protocol->ether_dhost;           printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));           // 获得目的以太网地址          break;       }       printf("**************************************************\n");       packet_number++;   }   char buf[40960];int main(){    struct sockaddr_in addr;    int sock;    int r = 0;        socklen_t len = 0;    u_char *ptemp;    if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) //建立socket ,man socket可以看到上面几个宏的意思    {        die("socket", 1);    }    do_promisc("eth0", sock); //eth0为网卡名称    system("ifconfig");    for(;;)    {            len = sizeof(addr);        if(recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len) > 0){        }        else{            continue;        }            //成功则返回接收到的字符数,失败返回-1,调试的时候可以增加一个输出r的语句判断是否抓到包        buf[r] = 0;        ptemp = buf;        ethernet_protocol_packet_callback(ptemp);//调用以太网协议的回调函数        usleep(1000);    //        perror("dump");    }    return 0;}
?

热点排行