linux c 无线网卡抓包,LINUX C网络抓包分析

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

//#include 

typedef unsigned char BYTE;

typedef struct _iphdr //定义IP首部

{

unsigned char h_verlen; //4位首部长度+4位IP版本号

unsigned char tos; //8位服务类型TOS

unsigned short total_len; //16位总长度(字节)

unsigned short ident; //16位标识

unsigned short frag_and_flags; //3位标志位

unsigned char ttl; //8位生存时间 TTL

unsigned char proto; //8位协议 (TCP, UDP 或其他)

unsigned short checksum; //16位IP首部校验和

unsigned int sourceIP; //32位源IP地址

unsigned int destIP; //32位目的IP地址

}IP_HEADER;

typedef struct _udphdr //定义UDP首部

{

unsigned short uh_sport;    //16位源端口

unsigned short uh_dport;    //16位目的端口

unsigned int uh_len;//16位UDP包长度

unsigned int uh_sum;//16位校验和

}UDP_HEADER;

typedef struct _tcphdr //定义TCP首部

{

unsigned short th_sport; //16位源端口

unsigned short th_dport; //16位目的端口

unsigned int th_seq; //32位序列号

unsigned int th_ack; //32位确认号

unsigned char th_lenres;//4位首部长度/6位保留字

unsigned char th_flag; //6位标志位

unsigned short th_win; //16位窗口大小

unsigned short th_sum; //16位校验和

unsigned short th_urp; //16位紧急数据偏移量

}TCP_HEADER;

typedef struct _icmphdr {

unsigned char  icmp_type;

unsigned char icmp_code; /* type sub code */

unsigned short icmp_cksum;

unsigned short icmp_id;

unsigned short icmp_seq;

/* This is not the std header, but we reserve space for time */

unsigned short icmp_timestamp;

}ICMP_HEADER;

/* ip首部长度 */

#define IP_HEADER_LEN sizeof(IP_HEADER)

/* tcp首部长度 */

#define TCP_HEADER_LEN sizeof(TCP_HEADER)

/* ip首部 + tcp首部长度 */

#define IP_TCP_HEADER_LEN IP_HEADER_LEN + TCP_HEADER_LEN

void analyseIP(IP_HEADER *ip);

void analyseTCP(IP_HEADER *ip,TCP_HEADER *tcp);

void analyseUDP(UDP_HEADER *udp);

void analyseICMP(ICMP_HEADER *icmp);

#define ETH_NAME    "eth0"

int revlen=0;

int iphlen=0;

int tcphlen=0;

BYTE buf[1024*1024];

int byteCount=0;

//ifconfig  eth0 promisc 设置好网卡混杂模式则不需要编程实现,否则需要编程实现。

int do_promisc(void) {

int f, s;

struct ifreq ifr;

if ( (f=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))<0){

return -1;

}

strcpy(ifr.ifr_name, ETH_NAME);

if ((s = ioctl(f, SIOCGIFFLAGS, &ifr))<0){

close(f);

return-1;

}

if(ifr.ifr_flags & IFF_RUNNING){

printf("eth link up\n");

}else{

printf("eth link down\n");

}

ifr.ifr_flags |= IFF_PROMISC;

if ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) 

return -1;

}

printf("Setting interface ::: %s ::: to promisc\n\n", ifr.ifr_name);

return 0;

}

int check_nic(void)

{

struct ifreq ifr;

int skfd = socket(AF_INET, SOCK_DGRAM, 0);

strcpy(ifr.ifr_name, ETH_NAME);

if (ioctl(skfd, SIOCGIFFLAGS, &ifr) 

{

close(skfd);

return -1;

}

if(ifr.ifr_flags & IFF_RUNNING){

printf("link up\n");

close(skfd);

return 0; // 网卡已插上网线

}else {

printf("link down\n");

close(skfd);

return -1;

}

}

void savefile()

{

FILE *f;

char file[64];

time_t t;

if(byteCount>5){

sprintf(file,"tcp_%d.prn",time(&t)); //这里相对于当前工作路径

f=fopen(file,"wb");

if(f!=NULL)

{

fwrite(buf,byteCount,1,f);

fclose(f);

printf("save prn file:%s %d byte\n",file,byteCount);

}else

{

printf("can not create file:%s \n",file);

}

}else{

printf("invial data: %u bytes\n",byteCount);

}

byteCount=0;

}

int main(int32_t argc, char **argv)

{

int32_t opt = 0;

int sockfd;

IP_HEADER *ip;

char buf[1024*1000];

ssize_t n;

int sport=-1;

int dport=-1;

//如optstring="ab:c::d::",命令行为getopt.exe -a -b host -ckeke -d haha

while ((opt = getopt(argc, argv, "d:s:")) != -1) {

switch (opt) {

case 'd':

dport=atoi(optarg);

printf("dport=%s\n",optarg);

break;

case 's':

sport=atoi(optarg);

printf("sport=%s\n",optarg);

break;

default:

break;;

}

}

do_promisc();

/* capture ip datagram without ethernet header */

if ((sockfd = socket(PF_PACKET,  SOCK_DGRAM, htons(ETH_P_IP)))== -1)

{

printf("socket error!\n");

return 1;

}

while (1)

{

n = recv(sockfd, buf, sizeof(buf), 0);

if (n == -1)

{

printf("recv error!\n");

break;

}

else if (n<20)

continue;

//接收数据不包括数据链路帧头

ip = ( IP_HEADER *)(buf);

revlen=ntohs(ip->total_len);

//analyseIP(ip);

size_t iplen =  (ip->h_verlen&0x0f)*4;

iphlen=iplen;

TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen);

if (ip->proto == IPPROTO_TCP)

{

TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen);

if(22==ntohs(tcp->th_dport))continue;

if((sport>0 && sport==ntohs(tcp->th_sport)) ||  (dport>0 && dport==ntohs(tcp->th_dport)) )

{

printf("revlen len:%u total len:%u\n",n,ntohs(ip->total_len));

analyseTCP(ip,tcp);

}

}

/* else if (ip->proto == IPPROTO_UDP)

{

UDP_HEADER *udp = (UDP_HEADER *)(buf + iplen);

analyseUDP(udp);

}    /*

else if (ip->proto == IPPROTO_ICMP)

{

ICMP_HEADER *icmp = (ICMP_HEADER *)(buf + iplen);

analyseICMP(icmp);

}

else if (ip->proto == IPPROTO_IGMP)

{

printf("IGMP----\n");

}

else

{

printf("other protocol!\n");

}

*/

//printf(".");

}

close(sockfd);

return 0;

}

void analyseIP(IP_HEADER *ip)

{

unsigned char* p = (unsigned char*)&ip->sourceIP;

unsigned char* p2;

p2 = (unsigned char*)&ip->destIP;

printf("IPP:\t: %u.%u.%u.%u -->\t: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3], p2[0],p2[1],p2[2],p2[3]);

}

//https://wenku.baidu.com/view/04b0d780e53a580216fcfeaa.html

void analyseTCP(IP_HEADER *ip,TCP_HEADER *tcp)

{

#define FIN 0x01 //FIN:标记数据是否发送完毕

#define SYN 0x02 //当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接

#define RST 0x04 //说明你与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接

#define PSH 0x08 //PSH:告诉对方收到该报文段后是否应该立即把数据推送给上层

#define ACK 0x10 //TCP规定,连接建立后,ACK必须为1。

#define URG 0x20

int len;

BYTE *pData;

unsigned char* p = (unsigned char*)&ip->sourceIP;

unsigned char* p2;

short int flag;

flag=tcp->th_flag;

p2 = (unsigned char*)&ip->destIP;

printf("tcp:\t %u.%u.%u.%u:%d -->%u.%u.%u.%u:%d   flag=0x%x[%s %s %s %s %s %s]  SEQ:%u ACKNUM:%u\n",p[0],p[1],p[2],p[3],ntohs(tcp->th_sport),  p2[0],p2[1],p2[2],p2[3],ntohs(tcp->th_dport),flag,(flag & ACK)?"ACK":"",(flag & SYN)?"SYN":"",(flag & FIN)?"FIN":"",(flag & PSH)?"PSH":"",(flag & RST)?"RST":"",(flag & URG)?"URG":"",ntohl(tcp->th_seq),ntohl(tcp->th_ack));

if((flag & SYN) && !(flag & ACK))

{

printf("request connect\n");

}

if(  (flag & ACK))

{

// printf("ack\n");

}

if(flag & FIN )

{

printf("FINISH & disconnected\n");

savefile();

}

if(flag & RST )

{

printf("connection reset\n");

byteCount=0;

}

if(flag & PSH )

{

}

len =(tcp->th_lenres)>>4;

len *=4;

tcphlen=len;

pData = ( (BYTE *)tcp )+len;

if(revlen-iphlen-tcphlen>0)

{

int datalen=revlen-iphlen-tcphlen;

printf("====get data byte:%d-%d-%d=%d  \n", revlen,iphlen,tcphlen,datalen);

if(byteCount+datalen<=sizeof(buf))

{

memcpy(buf+byteCount,pData,datalen);

byteCount+=datalen;

}

}

}

void analyseUDP(UDP_HEADER *udp)

{

printf("UDP  Source port: %u--> Dest port: %u\n", ntohs(udp->uh_sport),ntohs(udp->uh_dport));

}

void analyseICMP(ICMP_HEADER *icmp)

{

printf("ICMP -----\n");

printf("type: %u\n", icmp->icmp_type);

printf("sub code: %u\n", icmp->icmp_code);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值