Linux Raw Socket

来源:互联网 发布:找人脉的软件 编辑:程序博客网 时间:2024/05/21 13:54
/*说明 本程序是使用原始套接字编写的简单抓包程序,将网卡设置为混杂模式,可以接收到网络上任意的数据包可以获取ETHERNET包头/IP包头ARP包头/RARP包头/TCP包头/UDP包头ICMP包头的数据时间 20111228邮箱 lxgwm2008@foxmail.com1、增加filter过滤功能,使用BPF(BSD packet filter)码,类似于tcpdump的过滤机制,直接在底层过滤,减少上层过滤引起的压力*/

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>#include <net/ethernet.h>#include <net/if_arp.h>#include <net/if.h>#include <arpa/inet.h>#include <linux/filter.h>#include <errno.h>#define EXIT_FIILURE -1#define EXIT_SUCCESS 0extern int errno;void DisplayEthernet(struct ether_header *_pEtherheader){#if 0struct ether_header{  u_int8_t  ether_dhost[ETH_ALEN];// destination eth addr  u_int8_t  ether_shost[ETH_ALEN];// source ether addru_int16_t ether_type;        // packet type ID field} __attribute__ ((__packed__));#endifchar *ethertypeStr = NULL;unsigned short ethertype = ntohs(_pEtherheader->ether_type);switch(ethertype){case 0x0200:ethertypeStr = "ETHERTYPE_PUP";break;case 0x0800:ethertypeStr = "ETHERTYPE_IP";break;case 0x0806:ethertypeStr = "ETHERTYPE_ARP";break;case 0x0835:ethertypeStr = "ETHERTYPE_REVARP";break;default:ethertypeStr = "Unrecognized";break;}fprintf(stdout, "------this is a ethernet header------\n");fprintf(stdout, "ether_dhost= %02X:%02X:%02X:%02X:%02X:%02X\n", _pEtherheader->ether_dhost[0], _pEtherheader->ether_dhost[1], _pEtherheader->ether_dhost[2], _pEtherheader->ether_dhost[3], _pEtherheader->ether_dhost[4], _pEtherheader->ether_dhost[5]);fprintf(stdout, "ether_shost= %02X:%02X:%02X:%02X:%02X:%02X\n", _pEtherheader->ether_shost[0], _pEtherheader->ether_shost[1], _pEtherheader->ether_shost[2], _pEtherheader->ether_shost[3], _pEtherheader->ether_shost[4], _pEtherheader->ether_shost[5]);fprintf(stdout, "ether_type= %#04x(%s)\n", ethertype, ethertypeStr);fprintf(stdout, "------end---------------------------\n");}void DisplayIp(struct ip *_pIPheader){#if 0struct ip  {#if __BYTE_ORDER == __LITTLE_ENDIAN    unsigned int ip_hl:4;/* header length */    unsigned int ip_v:4;/* version */#endif#if __BYTE_ORDER == __BIG_ENDIAN    unsigned int ip_v:4;/* version */    unsigned int ip_hl:4;/* header length */#endif    u_int8_t ip_tos;/* type of service */    u_short ip_len;/* total length */    u_short ip_id;/* identification */    u_short ip_off;/* fragment offset field */#defineIP_RF 0x8000/* reserved fragment flag */#defineIP_DF 0x4000/* dont fragment flag */#defineIP_MF 0x2000/* more fragments flag */#defineIP_OFFMASK 0x1fff/* mask for fragmenting bits */    u_int8_t ip_ttl;/* time to live */    u_int8_t ip_p;/* protocol */    u_short ip_sum;/* checksum */    struct in_addr ip_src, ip_dst;/* source and dest address */  };#endifchar *pStr = NULL;unsigned char p = _pIPheader->ip_p;switch(p){case 0:pStr = "IPPROTO_IP";break;case 1:pStr = "IPPROTO_ICMP";break;case 2:pStr = "IPPROTO_IGMP";break;case 6:pStr = "IPPROTO_TCP";break;case 17:pStr = "IPPROTO_UDP";break;default:pStr = "Unrecognized";break;}fprintf(stdout, "------this is a IP header------\n");fprintf(stdout, "ip_hl = %u\n", _pIPheader->ip_hl << 2);fprintf(stdout, "ip_v  = %u\n", _pIPheader->ip_v);fprintf(stdout, "ip_tos  = %u\n", _pIPheader->ip_tos);fprintf(stdout, "ip_len  = %u\n", ntohs(_pIPheader->ip_len));fprintf(stdout, "ip_id  = %u\n", ntohs(_pIPheader->ip_id));fprintf(stdout, "ip_off  = %u\n", ntohs(_pIPheader->ip_off));fprintf(stdout, "ip_ttl  = %u\n", _pIPheader->ip_ttl);fprintf(stdout, "ip_p  = %u(%s)\n", p, pStr);fprintf(stdout, "ip_sum  = %u\n", ntohs(_pIPheader->ip_sum));fprintf(stdout, "ip_src  = %s\n", inet_ntoa(_pIPheader->ip_src));fprintf(stdout, "ip_dst  = %s\n", inet_ntoa(_pIPheader->ip_dst));fprintf(stdout, "------end---------------------------\n");}void DisplayArp(struct arphdr *_pArpheader){#if 0struct arphdr  {    unsigned short int ar_hrd;// Format of hardware address.  unsigned short int ar_pro;// Format of protocol address.   unsigned char ar_hln;// Length of hardware address.  unsigned char ar_pln;// Length of protocol address.unsigned short int ar_op;// ARP opcode (command).};#endifstatic const char *hardwaretype[] = {"ARPHRD_NETROM", "ARPHRD_ETHER","ARPHRD_EETHER","ARPHRD_AX25","ARPHRD_PRONET","ARPHRD_CHAOS","ARPHRD_IEEE802","ARPHRD_ARCNET","ARPHRD_APPLETLK"};char *ptStr = NULL;unsigned short ht = ntohs(_pArpheader->ar_hrd);unsigned short pt = ntohs(_pArpheader->ar_pro);switch(pt){case 0x0800:ptStr = "IP";break;case 0x0806:ptStr = "ARP";break;case 0x0835:ptStr = "REVARP";break;default:ptStr = "Unrecognized";break;}char *opStr = NULL;unsigned short op = ntohs(_pArpheader->ar_op);switch(op){case 1:opStr = "ARPOP_REQUEST";break;case 2:opStr = "ARPOP_REPLY";break;default:opStr = "Unrecognized";break;}fprintf(stdout, "------this is a arp header------\n");fprintf(stdout, "ar_hrd = %#02X(%s)\n", ht, hardwaretype[ht]);fprintf(stdout, "ar_pro  = %#02X(%s)\n", pt, ptStr);fprintf(stdout, "ar_hln  = %u\n", _pArpheader->ar_hln);fprintf(stdout, "ar_pln  = %u\n", _pArpheader->ar_pln);fprintf(stdout, "ar_op  = %#02X(%s)\n", op, opStr);fprintf(stdout, "------end---------------------------\n");}void DisplayRarp(struct arphdr *_pRarpheader){static const char *hardwaretype[] = {"ARPHRD_NETROM", "ARPHRD_ETHER","ARPHRD_EETHER","ARPHRD_AX25","ARPHRD_PRONET","ARPHRD_CHAOS","ARPHRD_IEEE802","ARPHRD_ARCNET","ARPHRD_APPLETLK"};char *ptStr = NULL;unsigned short ht = ntohs(_pRarpheader->ar_hrd);unsigned short pt = ntohs(_pRarpheader->ar_pro);switch(pt){case 0x0800:ptStr = "IP";break;case 0x0806:ptStr = "ARP";break;case 0x0835:ptStr = "REVARP";break;default:ptStr = "Unrecognized";break;}char *opStr = NULL;unsigned short op = ntohs(_pRarpheader->ar_op);switch(op){case 3:opStr = "ARPOP_RREQUEST";break;case 4:opStr = "ARPOP_RREPLY";break;default:opStr = "Unrecognized";break;}fprintf(stdout, "------this is a rarp header------\n");fprintf(stdout, "ar_hrd = %#02X(%s)\n", ht, hardwaretype[ht]);fprintf(stdout, "ar_pro  = %#02X(%s)\n", pt, ptStr);fprintf(stdout, "ar_hln  = %u\n", _pRarpheader->ar_hln);fprintf(stdout, "ar_pln  = %u\n", _pRarpheader->ar_pln);fprintf(stdout, "ar_op  = %#02X(%s)\n", op, opStr);fprintf(stdout, "------end---------------------------\n");}void DisplayTcp(struct tcphdr *_pTcpheader){#if 0struct tcphdr  {    u_int16_t source;    u_int16_t dest;    u_int32_t seq;    u_int32_t ack_seq;#  if __BYTE_ORDER == __LITTLE_ENDIAN    u_int16_t res1:4;    u_int16_t doff:4;    u_int16_t fin:1;    u_int16_t syn:1;    u_int16_t rst:1;    u_int16_t psh:1;    u_int16_t ack:1;    u_int16_t urg:1;    u_int16_t res2:2;#  elif __BYTE_ORDER == __BIG_ENDIAN    u_int16_t doff:4;    u_int16_t res1:4;    u_int16_t res2:2;    u_int16_t urg:1;    u_int16_t ack:1;    u_int16_t psh:1;    u_int16_t rst:1;    u_int16_t syn:1;    u_int16_t fin:1;#  else#   error "Adjust your <bits/endian.h> defines"#  endif    u_int16_t window;    u_int16_t check;    u_int16_t urg_ptr;};#endiffprintf(stdout, "------this is a tcp header------\n");fprintf(stdout, "source  = %u\n", ntohs(_pTcpheader->source));fprintf(stdout, "dest  = %u\n", ntohs(_pTcpheader->dest));fprintf(stdout, "seq  = %u\n", ntohl(_pTcpheader->seq));fprintf(stdout, "ack_seq= %u\n", ntohl(_pTcpheader->ack_seq));fprintf(stdout, "res1  = %u\n", _pTcpheader->res1);fprintf(stdout, "doff  = %u\n", _pTcpheader->doff);fprintf(stdout, "fin  = %u\n", _pTcpheader->fin);fprintf(stdout, "syn  = %u\n", _pTcpheader->syn);fprintf(stdout, "rst  = %u\n", _pTcpheader->rst);fprintf(stdout, "psh  = %u\n", _pTcpheader->psh);fprintf(stdout, "ack  = %u\n", _pTcpheader->ack);fprintf(stdout, "urg  = %u\n", _pTcpheader->urg);fprintf(stdout, "res2  = %u\n", _pTcpheader->res2);fprintf(stdout, "window  = %u\n", ntohs(_pTcpheader->window));fprintf(stdout, "check  = %u\n", ntohs(_pTcpheader->check));fprintf(stdout, "urg  = %u\n", ntohs(_pTcpheader->urg_ptr));fprintf(stdout, "------end---------------------------\n");}void DisplayUdp(struct udphdr *_pUdpheader){#if 0struct udphdr{  u_int16_t source;  u_int16_t dest;  u_int16_t len;  u_int16_t check;};#endiffprintf(stdout, "------this is a udp header------\n");fprintf(stdout, "source  = %u\n", ntohs(_pUdpheader->source));fprintf(stdout, "dest  = %u\n", ntohs(_pUdpheader->dest));fprintf(stdout, "len  = %u\n", ntohs(_pUdpheader->len));fprintf(stdout, "check= %u\n", ntohs(_pUdpheader->check));fprintf(stdout, "------end---------------------------\n");}void DisplayIcmp(struct icmphdr *_pIcmpheader){#if 0struct icmphdr{  u_int8_t type;/* message type */  u_int8_t code;/* type sub-code */  u_int16_t checksum;  union{    struct{      u_int16_tid;      u_int16_tsequence;    } echo;/* echo datagram */    u_int32_tgateway;/* gateway address */    struct{      u_int16_t__unused;      u_int16_tmtu;    } frag;/* path mtu discovery */  }un;};#endifconst char *typeStr = NULL;const char *codeStr = NULL;static const char *codeDestUnreachStr[] = {"ICMP_UNREACH_NET","ICMP_UNREACH_HOST","ICMP_UNREACH_PROTOCOL","ICMP_UNREACH_PORT","ICMP_UNREACH_NEEDFRAG","ICMP_UNREACH_SRCFAIL","ICMP_UNREACH_NET_UNKNOWN","ICMP_UNREACH_HOST_UNKNOWN","ICMP_UNREACH_ISOLATED","ICMP_UNREACH_NET_PROHIB","ICMP_UNREACH_HOST_PROHIB","ICMP_UNREACH_TOSNET","ICMP_UNREACH_TOSHOST","ICMP_UNREACH_FILTER_PROHIB","ICMP_UNREACH_HOST_PRECEDENCE","ICMP_UNREACH_PRECEDENCE_CUTOFF"};static const char *codeRedirectStr[] = {"ICMP_REDIRECT_NET","ICMP_REDIRECT_HOST","ICMP_REDIRECT_TOSNET","ICMP_REDIRECT_TOSHOST"};static const char *codeTimeExceedStr[] = {"ICMP_TIMXCEED_INTRANS","ICMP_TIMXCEED_REASS"};static const char *codeParaProb[] = {"ICMP_PARAMPROB_BADIP","ICMP_PARAMPROB_OPTABSENT"};switch(_pIcmpheader->type){case 0:typeStr = "ICMP_ECHOREPLY";break;case 3:typeStr = "ICMP_DEST_UNREACH";if(_pIcmpheader->code <= 15){codeStr = codeDestUnreachStr[_pIcmpheader->code];}else{codeStr = "Unrecognized";}break;case 4:typeStr = "ICMP_SOURCE_QUENCH";break;case 5:typeStr = "ICMP_REDIRECT";if(_pIcmpheader->code <= 3){codeStr = codeRedirectStr[_pIcmpheader->code];}else{codeStr = "Unrecognized";}break;case 8:typeStr = "ICMP_ECHO";break;case 11:typeStr = "ICMP_TIME_EXCEEDED";if(_pIcmpheader->code <= 1){codeStr = codeTimeExceedStr[_pIcmpheader->code];}else{codeStr = "Unrecognized";}break;case 12:typeStr = "ICMP_PARAMETERPROB";if(_pIcmpheader->code <= 1){codeStr = codeParaProb[_pIcmpheader->code];}else{codeStr = "Unrecognized";}break;case 13:typeStr = "ICMP_TIMESTAMP";break;case 14:typeStr = "ICMP_TIMESTAMPREPLY";break;case 15:typeStr = "ICMP_INFO_REQUEST";break;case 16:typeStr = "ICMP_INFO_REPLY";break;case 17:typeStr = "ICMP_ADDRESS";break;case 18:typeStr = "ICMP_ADDRESSREPLY";break;default:typeStr = "Unrecognized";break;}fprintf(stdout, "------this is a icmp header------\n");fprintf(stdout, "type  = %u(%s)\n", _pIcmpheader->type, typeStr);fprintf(stdout, "code  = %u(%s)\n", _pIcmpheader->code, codeStr);fprintf(stdout, "checksum  = %u\n", ntohs(_pIcmpheader->checksum));fprintf(stdout, "------end---------------------------\n");}/*设置网卡为混杂模式*/int SetIfPromisc(int _sockfd, char *_pcIfname){struct ifreq ifr;memset(&ifr, 0, sizeof(ifr));strncpy(ifr.ifr_name, _pcIfname, IF_NAMESIZE);if(ioctl(_sockfd, SIOCGIFFLAGS, &ifr) < 0){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));return EXIT_FIILURE;}ifr.ifr_flags |= IFF_PROMISC;if(ioctl(_sockfd, SIOCSIFFLAGS, &ifr) < 0){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));return EXIT_FIILURE;}return EXIT_SUCCESS;}/*取消网卡的混杂模式*/int UnsetIfPromisc(int _sockfd, char *_pcIfname){struct ifreq ifr;memset(&ifr, 0, sizeof(ifr));strncpy(ifr.ifr_name, _pcIfname, IF_NAMESIZE);if(ioctl(_sockfd, SIOCGIFFLAGS, &ifr) < 0){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));return EXIT_FIILURE;}ifr.ifr_flags &= ~IFF_PROMISC;if(ioctl(_sockfd, SIOCSIFFLAGS, &ifr) < 0){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));return EXIT_FIILURE;}return EXIT_SUCCESS;}/*设置过滤器*/int SetFilter(int _sockfd){/*BPF code generated by tcpdump -dd host 150.150.150.15{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 4, 0x00000800 },{ 0x20, 0, 0, 0x0000001a },{ 0x15, 8, 0, 0x96969610 },{ 0x20, 0, 0, 0x0000001e },{ 0x15, 6, 7, 0x96969610 },{ 0x15, 1, 0, 0x00000806 },{ 0x15, 0, 5, 0x00008035 },{ 0x20, 0, 0, 0x0000001c },{ 0x15, 2, 0, 0x96969610 },{ 0x20, 0, 0, 0x00000026 },{ 0x15, 0, 1, 0x96969610 },{ 0x6, 0, 0, 0x00000060 },{ 0x6, 0, 0, 0x00000000 },*/struct sock_filter BPF_code[]= {{ 0x28, 0, 0, 0x0000000c },{ 0x15, 0, 4, 0x00000800 },{ 0x20, 0, 0, 0x0000001a },{ 0x15, 8, 0, 0x96969610 },{ 0x20, 0, 0, 0x0000001e },{ 0x15, 6, 7, 0x96969610 },{ 0x15, 1, 0, 0x00000806 },{ 0x15, 0, 5, 0x00008035 },{ 0x20, 0, 0, 0x0000001c },{ 0x15, 2, 0, 0x96969610 },{ 0x20, 0, 0, 0x00000026 },{ 0x15, 0, 1, 0x96969610 },{ 0x6, 0, 0, 0x00000060  },{ 0x6, 0, 0, 0x00000000  }};struct sock_fprog Filter;Filter.len = 14;Filter.filter = BPF_code;if(setsockopt(_sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter))<0){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));return EXIT_FIILURE;}return EXIT_SUCCESS;}int main(){int sockfd;char buf[2048];ssize_t nRet;struct ether_header *etherheader;unsigned short ethertype;struct ip *ipheader;struct arphdr *arpheader;struct tcphdr *tcpheader;struct udphdr *udpheader;struct icmphdr *icmpheader;//sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);//sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));if(-1 == sockfd){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));exit(EXIT_FIILURE);}if(EXIT_SUCCESS != SetIfPromisc(sockfd, "eth0")){exit(EXIT_FIILURE);}//if(EXIT_SUCCESS != SetFilter(sockfd)){//exit(EXIT_FIILURE);//}while(1){memset(buf, 0, 2048);nRet = recvfrom(sockfd, buf, 2048, 0, NULL, NULL);if(-1 == nRet){fprintf(stdout, "%03d----%02d----%s\n", __LINE__, errno, strerror(errno));exit(EXIT_FIILURE);}if(nRet < sizeof(struct ether_header)){continue;}etherheader = (struct ether_header *)buf;DisplayEthernet(etherheader);ethertype = ntohs(etherheader->ether_type);if(ethertype == ETHERTYPE_IP){if(nRet < sizeof(struct ether_header) + sizeof(struct ip)){continue;}ipheader = (struct ip *)(buf + sizeof(struct ether_header));DisplayIp(ipheader);if(ipheader->ip_p == IPPROTO_TCP){if(nRet < sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct tcphdr)){continue;}tcpheader = (struct tcphdr *)(buf + sizeof(struct ether_header) + sizeof(struct ip));DisplayTcp(tcpheader);}else if(ipheader->ip_p == IPPROTO_UDP){if(nRet < sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct udphdr)){continue;}udpheader = (struct udphdr *)(buf + sizeof(struct ether_header) + sizeof(struct ip));DisplayUdp(udpheader);}else if(ipheader->ip_p == IPPROTO_ICMP){if(nRet < sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct icmphdr)){continue;}icmpheader = (struct icmphdr *)(buf + sizeof(struct ether_header) + sizeof(struct ip));DisplayIcmp(icmpheader);}}else if(ethertype == ETHERTYPE_ARP){if(nRet < sizeof(struct ether_header) + sizeof(struct arphdr)){continue;}arpheader = (struct arphdr *)(buf + sizeof(struct ether_header));DisplayArp(arpheader);}else if(ethertype == ETHERTYPE_REVARP){if(nRet < sizeof(struct ether_header) + sizeof(struct arphdr)){continue;}arpheader = (struct arphdr *)(buf + sizeof(struct ether_header));DisplayRarp(arpheader);}else{fprintf(stdout, "ethertype not support:%#02x\n", ethertype);}sleep(1);}exit(EXIT_SUCCESS);


原创粉丝点击