您的位置:首页 > 运维架构 > Linux

linux下c语言抓包库libpcap

2012-11-14 15:56 337 查看
安装命令: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: