首页 > 代码库 > libpcap编程实例
libpcap编程实例
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pcap.h> 4 #include <errno.h> 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 #include <arpa/inet.h> 8 9 int main(int argc, char **argv) 10 { 11 char *dev; 12 char *net; 13 char *mask; 14 int ret; 15 char errbuf[PCAP_ERRBUF_SIZE]; 16 bpf_u_int32 netp; 17 bpf_u_int32 maskp; 18 struct in_addr addr; 19 20 21 dev = pcap_lookupdev(errbuf); 22 23 24 if(dev == NULL) 25 { 26 printf("%s\n",errbuf); 27 exit(1); 28 } 29 30 31 printf("DEV: %s\n",dev); 32 33 34 ret = pcap_lookupnet(dev,&netp,&maskp,errbuf); 35 36 if(ret == -1) 37 { 38 printf("%s\n",errbuf); 39 exit(1); 40 } 41 42 43 addr.s_addr = netp; 44 net = inet_ntoa(addr); 45 46 if(net == NULL) 47 { 48 perror("inet_ntoa"); 49 exit(1); 50 } 51 52 printf("NET: %s\n",net); 53 54 55 addr.s_addr = maskp; 56 mask = inet_ntoa(addr); 57 58 if(mask == NULL) 59 { 60 perror("inet_ntoa"); 61 exit(1); 62 } 63 64 printf("MASK: %s\n",mask); 65 66 return 0; 67 } 68 然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-lpcap参数) 69 编译ok~,执行./pcap_1,可以看到: 70 DEV: eth0 71 NET: 192.168.12.0 72 MASK: 255.255.255.0 73 好了,第一个pcap程序出炉了。。。。。 74 75 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。 76 77 #include <stdio.h> 78 #include <stdlib.h> 79 #include <pcap.h> 80 #include <errno.h> 81 #include <sys/socket.h> 82 #include <netinet/in.h> 83 #include <arpa/inet.h> 84 #include <netinet/if_ether.h> 85 86 int main(int argc, char **argv) 87 { 88 int i; 89 char *dev; 90 char errbuf[PCAP_ERRBUF_SIZE]; 91 pcap_t* descr; 92 const u_char *packet; 93 struct pcap_pkthdr hdr; 94 struct ether_header *eptr; 95 96 u_char *ptr; 97 98 99 dev = pcap_lookupdev(errbuf);100 101 if(dev == NULL)102 {103 printf("%s\n",errbuf);104 exit(1);105 }106 107 printf("DEV: %s\n",dev);108 109 110 111 descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);112 113 if(descr == NULL)114 {115 printf("pcap_open_live(): %s\n",errbuf);116 exit(1);117 }118 119 120 121 122 packet = pcap_next(descr,&hdr);123 124 if(packet == NULL)125 {126 printf("Didn‘t grab packet\n");127 exit(1);128 }129 130 131 132 printf("Grabbed packet of length %d\n",hdr.len);133 printf("Recieved at ..... %s\n",ctime((const time_t*)&hdr.ts.tv_sec));134 printf("Ethernet address length is %d\n",ETHER_HDR_LEN);135 136 137 eptr = (struct ether_header *) packet;138 139 140 if (ntohs (eptr->ether_type) == ETHERTYPE_IP)141 {142 printf("Ethernet type hex:%x dec:%d is an IP packet\n",143 ntohs(eptr->ether_type),144 ntohs(eptr->ether_type));145 }else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP)146 {147 printf("Ethernet type hex:%x dec:%d is an ARP packet\n",148 ntohs(eptr->ether_type),149 ntohs(eptr->ether_type));150 }else {151 printf("Ethernet type %x not IP", ntohs(eptr->ether_type));152 exit(1);153 }154 155 156 ptr = eptr->ether_dhost;157 i = ETHER_ADDR_LEN;158 printf(" Destination Address: ");159 do{160 printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);161 }while(--i>0);162 printf("\n");163 164 ptr = eptr->ether_shost;165 i = ETHER_ADDR_LEN;166 printf(" Source Address: ");167 do{168 printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);169 }while(--i>0);170 printf("\n");171 172 return 0;173 }174 175 好了,编译运行!176 [root@norman libpcap]# ./pcap_2177 DEV: eth0178 Grabbed packet of length 76179 Recieved at time..... Mon Mar 12 22:23:29 2001180 181 Ethernet address length is 14182 Ethernet type hex:800 dec:2048 is an IP packet183 Destination Address: 0:20:78:d1:e8:1184 Source Address: 0:a0:cc:56:c2:91185 [root@pepe libpcap]#186 187 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~,呵呵188 马上就有反应了~~189 190 这个程序是一个老外写的,大家看看注释应该没有问题吧~191 但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:192 int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);193 这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。194 195 #include <pcap.h>196 #include <stdio.h>197 #include <stdlib.h>198 #include <errno.h>199 #include <sys/socket.h>200 #include <netinet/in.h>201 #include <arpa/inet.h>202 #include <netinet/if_ether.h>203 204 205 void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*206 packet)207 {208 static int count = 1;209 fprintf(stdout,"%d, ",count);210 if(count == 4)211 fprintf(stdout,"Come on baby sayyy you love me!!! ");212 if(count == 7)213 fprintf(stdout,"Tiiimmmeesss!! ");214 fflush(stdout);215 count++;216 }217 218 int main(int argc,char **argv)219 {220 int i;221 char *dev;222 char errbuf[PCAP_ERRBUF_SIZE];223 pcap_t* descr;224 const u_char *packet;225 struct pcap_pkthdr hdr; 226 struct ether_header *eptr; 227 228 if(argc != 2){ fprintf(stdout,"Usage: %s numpackets\n",argv[0]);return 0;}229 230 231 dev = pcap_lookupdev(errbuf);232 if(dev == NULL)233 { printf("%s\n",errbuf); exit(1); }234 235 descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);236 if(descr == NULL)237 { printf("pcap_open_live(): %s\n",errbuf); exit(1); }238 239 240 241 pcap_loop(descr,atoi(argv[1]),my_callback,NULL);242 243 fprintf(stdout,"\nDone processing packets... wheew!\n");244 return 0;245 }246 247 运行./pcap_3 7248 1, 2, 3, 4, Come on baby sayyy you love me!!! 5, 6, 7, Tiiimmmeesss!! 249 Done processing packets... wheew!250 251 pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:252 pcap_dispatch() is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of -1 processes all the packets received in one buffer. A cnt of 0 processes all packets until an error occurs, EOF is reached, or the read times out (when doing live reads and a non-zero read timeout is specified). callback specifies a routine to be called with three arguments: a u_char pointer which is passed in from pcap_dispatch(), a pointer to the pcap_pkthdr struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read is returned. Zero is returned when EOF is reached in a ``savefile.‘‘ A return of -1 indicates an error in which case pcap_perror() or pcap_geterr() may be used to display the error text. 253 254 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。255 256 #include <pcap.h>257 #include <stdio.h>258 #include <stdlib.h>259 #include <errno.h>260 #include <sys/socket.h>261 #include <netinet/in.h>262 #include <arpa/inet.h>263 #include <netinet/if_ether.h>264 265 266 void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*267 packet)268 {269 static int count = 1;270 fprintf(stdout,"%d, ",count);271 fflush(stdout);272 count++;273 }274 275 int main(int argc,char **argv)276 {277 int i;278 char *dev;279 char errbuf[PCAP_ERRBUF_SIZE];280 pcap_t* descr;281 const u_char *packet;282 struct pcap_pkthdr hdr; 283 struct ether_header *eptr; 284 struct bpf_program fp; 285 bpf_u_int32 maskp; 286 bpf_u_int32 netp; 287 288 289 if(argc != 2){ fprintf(stdout,"Usage: %s \"filter program\"\n"290 ,argv[0]);return 0;}291 292 293 dev = pcap_lookupdev(errbuf);294 if(dev == NULL)295 { fprintf(stderr,"%s\n",errbuf); exit(1); }296 297 298 pcap_lookupnet(dev,&netp,&maskp,errbuf);299 300 301 descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);302 if(descr == NULL)303 { printf("pcap_open_live(): %s\n",errbuf); exit(1); }304 305 306 if(pcap_compile(descr,&fp,argv[1],0,netp) == -1)307 { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }308 309 310 if(pcap_setfilter(descr,&fp) == -1)311 { fprintf(stderr,"Error setting filter\n"); exit(1); }312 313 314 pcap_loop(descr,-1,my_callback,NULL);315 316 return 0;317 }318 319 运行./pcap_4.c "host www.google.com" 320 然后在另外一个控制台下面ping www.baidu.com321 哈哈322 没有反应吧323 接着再ping www.google.com324 就看到1, 2, 3, 4, 5, 6,325 ok326 you got it!!
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pcap.h> 4 #include <errno.h> 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 #include <arpa/inet.h> 8 9 int main(int argc, char **argv) 10 { 11 char *dev; 12 char *net; 13 char *mask; 14 int ret; 15 char errbuf[PCAP_ERRBUF_SIZE]; 16 bpf_u_int32 netp; 17 bpf_u_int32 maskp; 18 struct in_addr addr; 19 20 21 dev = pcap_lookupdev(errbuf); 22 23 24 if(dev == NULL) 25 { 26 printf("%s\n",errbuf); 27 exit(1); 28 } 29 30 31 printf("DEV: %s\n",dev); 32 33 34 ret = pcap_lookupnet(dev,&netp,&maskp,errbuf); 35 36 if(ret == -1) 37 { 38 printf("%s\n",errbuf); 39 exit(1); 40 } 41 42 43 addr.s_addr = netp; 44 net = inet_ntoa(addr); 45 46 if(net == NULL) 47 { 48 perror("inet_ntoa"); 49 exit(1); 50 } 51 52 printf("NET: %s\n",net); 53 54 55 addr.s_addr = maskp; 56 mask = inet_ntoa(addr); 57 58 if(mask == NULL) 59 { 60 perror("inet_ntoa"); 61 exit(1); 62 } 63 64 printf("MASK: %s\n",mask); 65 66 return 0; 67 } 68 然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-lpcap参数) 69 编译ok~,执行./pcap_1,可以看到: 70 DEV: eth0 71 NET: 192.168.12.0 72 MASK: 255.255.255.0 73 好了,第一个pcap程序出炉了。。。。。 74 75 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。 76 77 #include <stdio.h> 78 #include <stdlib.h> 79 #include <pcap.h> 80 #include <errno.h> 81 #include <sys/socket.h> 82 #include <netinet/in.h> 83 #include <arpa/inet.h> 84 #include <netinet/if_ether.h> 85 86 int main(int argc, char **argv) 87 { 88 int i; 89 char *dev; 90 char errbuf[PCAP_ERRBUF_SIZE]; 91 pcap_t* descr; 92 const u_char *packet; 93 struct pcap_pkthdr hdr; 94 struct ether_header *eptr; 95 96 u_char *ptr; 97 98 99 dev = pcap_lookupdev(errbuf);100 101 if(dev == NULL)102 {103 printf("%s\n",errbuf);104 exit(1);105 }106 107 printf("DEV: %s\n",dev);108 109 110 111 descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);112 113 if(descr == NULL)114 {115 printf("pcap_open_live(): %s\n",errbuf);116 exit(1);117 }118 119 120 121 122 packet = pcap_next(descr,&hdr);123 124 if(packet == NULL)125 {126 printf("Didn‘t grab packet\n");127 exit(1);128 }129 130 131 132 printf("Grabbed packet of length %d\n",hdr.len);133 printf("Recieved at ..... %s\n",ctime((const time_t*)&hdr.ts.tv_sec));134 printf("Ethernet address length is %d\n",ETHER_HDR_LEN);135 136 137 eptr = (struct ether_header *) packet;138 139 140 if (ntohs (eptr->ether_type) == ETHERTYPE_IP)141 {142 printf("Ethernet type hex:%x dec:%d is an IP packet\n",143 ntohs(eptr->ether_type),144 ntohs(eptr->ether_type));145 }else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP)146 {147 printf("Ethernet type hex:%x dec:%d is an ARP packet\n",148 ntohs(eptr->ether_type),149 ntohs(eptr->ether_type));150 }else {151 printf("Ethernet type %x not IP", ntohs(eptr->ether_type));152 exit(1);153 }154 155 156 ptr = eptr->ether_dhost;157 i = ETHER_ADDR_LEN;158 printf(" Destination Address: ");159 do{160 printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);161 }while(--i>0);162 printf("\n");163 164 ptr = eptr->ether_shost;165 i = ETHER_ADDR_LEN;166 printf(" Source Address: ");167 do{168 printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);169 }while(--i>0);170 printf("\n");171 172 return 0;173 }174 175 好了,编译运行!176 [root@norman libpcap]# ./pcap_2177 DEV: eth0178 Grabbed packet of length 76179 Recieved at time..... Mon Mar 12 22:23:29 2001180 181 Ethernet address length is 14182 Ethernet type hex:800 dec:2048 is an IP packet183 Destination Address: 0:20:78:d1:e8:1184 Source Address: 0:a0:cc:56:c2:91185 [root@pepe libpcap]#186 187 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~,呵呵188 马上就有反应了~~189 190 这个程序是一个老外写的,大家看看注释应该没有问题吧~191 但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:192 int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);193 这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。194 195 #include <pcap.h>196 #include <stdio.h>197 #include <stdlib.h>198 #include <errno.h>199 #include <sys/socket.h>200 #include <netinet/in.h>201 #include <arpa/inet.h>202 #include <netinet/if_ether.h>203 204 205 void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*206 packet)207 {208 static int count = 1;209 fprintf(stdout,"%d, ",count);210 if(count == 4)211 fprintf(stdout,"Come on baby sayyy you love me!!! ");212 if(count == 7)213 fprintf(stdout,"Tiiimmmeesss!! ");214 fflush(stdout);215 count++;216 }217 218 int main(int argc,char **argv)219 {220 int i;221 char *dev;222 char errbuf[PCAP_ERRBUF_SIZE];223 pcap_t* descr;224 const u_char *packet;225 struct pcap_pkthdr hdr; 226 struct ether_header *eptr; 227 228 if(argc != 2){ fprintf(stdout,"Usage: %s numpackets\n",argv[0]);return 0;}229 230 231 dev = pcap_lookupdev(errbuf);232 if(dev == NULL)233 { printf("%s\n",errbuf); exit(1); }234 235 descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);236 if(descr == NULL)237 { printf("pcap_open_live(): %s\n",errbuf); exit(1); }238 239 240 241 pcap_loop(descr,atoi(argv[1]),my_callback,NULL);242 243 fprintf(stdout,"\nDone processing packets... wheew!\n");244 return 0;245 }246 247 运行./pcap_3 7248 1, 2, 3, 4, Come on baby sayyy you love me!!! 5, 6, 7, Tiiimmmeesss!! 249 Done processing packets... wheew!250 251 pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:252 pcap_dispatch() is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of -1 processes all the packets received in one buffer. A cnt of 0 processes all packets until an error occurs, EOF is reached, or the read times out (when doing live reads and a non-zero read timeout is specified). callback specifies a routine to be called with three arguments: a u_char pointer which is passed in from pcap_dispatch(), a pointer to the pcap_pkthdr struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read is returned. Zero is returned when EOF is reached in a ``savefile.‘‘ A return of -1 indicates an error in which case pcap_perror() or pcap_geterr() may be used to display the error text. 253 254 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。255 256 #include <pcap.h>257 #include <stdio.h>258 #include <stdlib.h>259 #include <errno.h>260 #include <sys/socket.h>261 #include <netinet/in.h>262 #include <arpa/inet.h>263 #include <netinet/if_ether.h>264 265 266 void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*267 packet)268 {269 static int count = 1;270 fprintf(stdout,"%d, ",count);271 fflush(stdout);272 count++;273 }274 275 int main(int argc,char **argv)276 {277 int i;278 char *dev;279 char errbuf[PCAP_ERRBUF_SIZE];280 pcap_t* descr;281 const u_char *packet;282 struct pcap_pkthdr hdr; 283 struct ether_header *eptr; 284 struct bpf_program fp; 285 bpf_u_int32 maskp; 286 bpf_u_int32 netp; 287 288 289 if(argc != 2){ fprintf(stdout,"Usage: %s \"filter program\"\n"290 ,argv[0]);return 0;}291 292 293 dev = pcap_lookupdev(errbuf);294 if(dev == NULL)295 { fprintf(stderr,"%s\n",errbuf); exit(1); }296 297 298 pcap_lookupnet(dev,&netp,&maskp,errbuf);299 300 301 descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);302 if(descr == NULL)303 { printf("pcap_open_live(): %s\n",errbuf); exit(1); }304 305 306 if(pcap_compile(descr,&fp,argv[1],0,netp) == -1)307 { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }308 309 310 if(pcap_setfilter(descr,&fp) == -1)311 { fprintf(stderr,"Error setting filter\n"); exit(1); }312 313 314 pcap_loop(descr,-1,my_callback,NULL);315 316 return 0;317 }318 319 运行./pcap_4.c "host www.google.com" 320 然后在另外一个控制台下面ping www.baidu.com321 哈哈322 没有反应吧323 接着再ping www.google.com324 就看到1, 2, 3, 4, 5, 6,325 ok326 you got it!!
libpcap编程实例
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。