linux下c语言抓包库libpcap

安装命令:sudo apt-get install libpcap-dev

由于自己还没仔细研究过,暂时也只是想在这里留个记录,方便以后需要时使用。下面是百度百科里的例子。

#include <pcap.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
        pcap_if_t *alldevs;
        pcap_if_t *device;
        char errbuf[PCAP_ERRBUF_SIZE];

        if(pcap_findalldevs(&alldevs, errbuf) == -1)
        {
                fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
                exit(EXIT_FAILURE);
        }
        device = alldevs;
        for(; device != NULL; device = device->next)
        {
                printf("Device name: %s\n", device->name);
                printf("Description: %s\n", device->description);
        }
        /* 不再需要设备列表了,释放它 */
        pcap_freealldevs(alldevs);
        return 0;
}
~          

gcc pcap.c -o pcap -lpcap

sudo ./pcap   //记住一定要root权限,因为涉及了访问底层硬件了。


下面是抓包并以二进制方式打印的,对于调试网络包可能会经常使用到。

#include <pcap.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
{
		int * id = (int *)arg;

		printf("id: %d\n", ++(*id));
		printf("Packet length: %d\n", pkthdr->len);
		printf("Number of bytes: %d\n", pkthdr->caplen);
		printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec)); 

		int i;
		for(i=0; i<pkthdr->len; ++i)
		{
				printf(" %02x", packet[i]);
				if( (i + 1) % 16 == 0 )
				{
						printf("\n");
				}
		}

		printf("\n\n");
}

int main()
{
		char errBuf[PCAP_ERRBUF_SIZE], * devStr;

		/* get a device */
		devStr = pcap_lookupdev(errBuf);

		if(devStr)
		{
				printf("success: device: %s\n", devStr);
		}
		else
		{
				printf("error: %s\n", errBuf);
				exit(1);
		}

		/* open a device, wait until a packet arrives */
		pcap_t * device = pcap_open_live(devStr, 65535, 1, 0, errBuf);

		if(!device)
		{
				printf("error: pcap_open_live(): %s\n", errBuf);
				exit(1);
		}

		/* wait loop forever */
		int id = 0;
		pcap_loop(device, -1, getPacket, (u_char*)&id);

		pcap_close(device);

		return 0;
}
下面是抓取数据包并解析网络包,解析为物理层、网络层等。

#include <pcap.h>
#include <stdio.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>

void tcp_packet_callback(unsigned char *argument,const struct pcap_pkthdr* pcap_header,const unsigned char *packet_content) {
		struct tcphdr *tcpptr=(struct tcphdr *)(packet_content+14+20);
                printf("----tcp protocol-----\n");
                printf("source port:%d\n",ntohs(tcpptr->source));
                printf("dest port:%d\n",ntohs(tcpptr->dest));

                printf("sequence number:%u\n",ntohl(tcpptr->seq));
                printf("acknowledgement number:%u\n",ntohl(tcpptr->ack_seq));
                printf("header length:%d\n",tcpptr->doff*4);
                printf("check sum:%d\n",ntohs(tcpptr->check));
                printf("window size:%d\n",ntohs(tcpptr->window));
                printf("urgent pointer:%d\n",ntohs(tcpptr->urg_ptr));
}

void ip_packet_callback(unsigned char *argument,const struct pcap_pkthdr* pcap_header,const unsigned char *packet_content) {
		struct in_addr s,d;
		struct iphdr *ipptr;
		ipptr=(struct iphdr *)(packet_content+14);

                printf("-----IP Protocol (network layer)-----\n");
                printf("version:%d\n",ipptr->version);
                printf("header length:%d\n",ipptr->ihl*4);
                printf("tos:%d\n",ipptr->tos);
                printf("total length:%d\n",ntohs(ipptr->tot_len));
                printf("identification:%d\n",ntohs(ipptr->id));
                printf("offset:%d\n",ntohs((ipptr->frag_off&0x1fff)*8));
                printf("TTL:%d\n",ipptr->ttl);
                printf("checksum:%d\n",ntohs(ipptr->check));
                printf("protocol:%d\n",ipptr->protocol);
		s.s_addr=ipptr->saddr;
		d.s_addr=ipptr->daddr;
                printf("source address:%s\n",inet_ntoa(s));
                printf("destination address:%s\n",inet_ntoa(d));

		switch(ipptr->protocol) {
				case 6:
                                                printf("tcp protocol\n");
						tcp_packet_callback(argument,pcap_header,packet_content);
						break;
				case 1:
                                                printf("icmp protocol\n");
						break;
				case 17:
                                                printf("udp protocol\n");
						break;
				default:
						break;
		}

}

void arp_packet_callback(unsigned char *argument,const struct pcap_pkthdr* pcap_header,const unsigned char *packet_content) {
                printf("------ARP Protocol-------\n");
}

void ethernet_packet_callback(unsigned char *argument,const struct pcap_pkthdr* pcap_header,const unsigned char *packet_content) {
		struct ethhdr *ethptr;
		struct iphdr *ipptr;
		unsigned char *mac;
		printf("--------------------------context----------\n");
		//printf("%s\n", packet_content);
		ethptr=(struct ethhdr *)packet_content;
                printf("\n----ethernet protocol(phydical layer)-----\n");
                printf("MAC source Address:\n");
		mac=ethptr->h_source;
                printf("%02x:%02x:%02x:%02x:%02x:%02x\n",*mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5));
                printf("MAC destination Address:\n");
		mac=ethptr->h_dest;
                printf("%02x:%02x:%02x:%02x:%02x:%02x\n",*mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5));
                printf("protocol:%04x\n",ntohs(ethptr->h_proto));

		switch(ntohs(ethptr->h_proto)) {
				case 0x0800:
                                                printf("this is a IP protocol\n");
						ip_packet_callback(argument,pcap_header,packet_content);
						break;
				case 0x0806:
                                                printf("this is a ARP protocol\n");
						arp_packet_callback(argument,pcap_header,packet_content);
						break;
				case 0x8035:
                                                printf("this is a RARP protocol\n");
						break;
				default:
						break;

		}
}

int main(){
		pcap_t *pt;
		char *dev;
		char errbuf[128];
		struct bpf_program fp;
		bpf_u_int32 maskp,netp;
		int ret,i=0,inum;
		int pcap_time_out=5;
		char filter[128];
		unsigned char *packet;
		struct pcap_pkthdr hdr;
		pcap_if_t *alldevs,*d;

		if(pcap_findalldevs(&alldevs,errbuf)==-1) {
                                fprintf(stderr,"find interface failed!\n");
				return;
		}
		for(d=alldevs;d;d=d->next){
                                printf("%d. %s\n",++i,d->name);
				if(d->description)
                                          printf("(%s)\n",d->description);
				else
                                          printf("(no description available)\n");
		}

		if(i==1)
			  dev=alldevs->name;
		else {
				printf("input a interface:(1-%d)",i);
				scanf("%d",&inum);
				if(inum<1||inum>i) {
                                                printf("interface number out of range\n");
						return;
				}

				for(d=alldevs,i=1;i<inum;d=d->next,i++);
				dev=d->name;
		}

		/*
		   dev=pcap_lookupdev(errbuf);
		   if(dev==NULL){
                   fprintf(stderr,"%s\n",errbuf);
		   return;
		   }
		 */
                printf("dev:%s\n",dev);
		ret=pcap_lookupnet(dev,&netp,&maskp,errbuf);
		if(ret==-1){
                                fprintf(stderr,"%s\n",errbuf);
				return;
		}
		pcap_dump_open(pt, "t.pcap");
		pt=pcap_open_live(dev,BUFSIZ,1,pcap_time_out,errbuf);
		if(pt==NULL){
                                fprintf(stderr,"open error :%s\n",errbuf);
				return;
		}
		sprintf(filter,"");
		if(pcap_compile(pt,&fp,filter,0,netp)==-1) {
                                fprintf(stderr,"compile error\n");
				return;
		}
		if(pcap_setfilter(pt,&fp)==-1) {
                                fprintf(stderr,"setfilter error\n");
				return;
		}

		pcap_loop(pt,-1,ethernet_packet_callback,NULL);
		/*
		   while(1) {
                   printf("wait packet:filter %s\n",filter);
		   packet=(char *)pcap_next(pt,&hdr);
		   if(packet==NULL)
		   continue;
		   else
                   printf("get a packet\n");
		   }
		 */
		pcap_close(pt);
		return 0;
}


下面这个网址有一些例子:

http://blog.csdn.net/htttw/article/details/7521053

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值