📄 sniffer.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <netinet/tcp.h>#include <netinet/if_ether.h> /* 用于 ETH_P_ALL */#include <net/if_arp.h>#define BUFSIZE 2048 #include "sniffer.h"/********函数声明部分************************/ static void hex_print(const u_char *buf, int len, int offset);static int decode_eth(const u_char *buf);static int decode_ip(const u_char *buf);static int decode_arp(const u_char *buf);static int decode_tcp(const u_char *buf);static int decode_udp(const u_char *buf);/*********************************************/int main(){ int listenfd; int n; char buf[BUFSIZE]; /*PF_PACKET LPF(linux packet filter)*/ if ((listenfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror("socket"); exit(1); } for (;;) { if ((n = recv(listenfd, buf, BUFSIZE, 0)) > 0) { hex_print(buf, n, 0); decode_eth(buf); } } return 0;}//显示获取的数据帧的帧头信息static int decode_eth(const u_char *buf){ struct ethhdr *eth = (struct ethhdr *) buf; printf("\n MAC header"); printf("\n Destination Address: %02X:%02X:%02X:%02X:%02X:%02X",/*显示目标MAC地址*/ HWADDR(eth->h_dest)); printf("\n Source Address: %02X:%02X:%02X:%02X:%02X:%02X",/*显示源MAC地址*/ HWADDR(eth->h_source)); printf("\n Type: %02X-%02X", PWORD(eth->h_proto));/*显示协议类型*/ switch (ntohs(eth->h_proto))//判断帧内是IP报文还是ARP报文 { case ETH_P_IP: return decode_ip((u_char *)ð[1]); case ETH_P_ARP: return decode_arp((u_char *)ð[1]); default: return -1; } return 0;}//分解显示ARP报头信息static int decode_arp(const u_char *buf){ struct ether_arp *arph = (struct ether_arp *) buf;//定义指针ARPH指向数据帧中的ARP报头进行分解 printf("\n Address Resolution Protocol"); printf("\n Hardware Type: %d", ntohs(arph->arp_hrd)); printf("\n Protocol Type: %02X-%02X", PWORD(arph->arp_pro)); printf("\n Length of Hardware Address: %d", arph->arp_hln); printf("\n Length of Protocol Address: %d", arph->arp_pln); printf("\n Operation Code: %d", ntohs(arph->arp_op)); printf("\n Sender`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(arph->arp_sha)); printf("\n Sender`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_spa)); printf("\n Target`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(arph->arp_tha)); printf("\n Target`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_tpa)); return 0;}//分解显示IP报头信息 static int decode_ip(const u_char *buf){ struct iphdr *iph = (struct iphdr *) buf;//定义指针IPH指向数据帧中的IP数据报报头进行分解 printf("\n IPv4 header"); printf("\n Version: %d", iph->version); printf("\n Header length: %d (%d bytes)", iph->ihl, iph->ihl*4); printf("\n Type of service (TOS):0x%02X", iph->tos); printf("\n Total length: %d", ntohs(iph->tot_len)); printf("\n Identification: %d", ntohs(iph->id)); printf("\n Flags: %02X %02X", PWORD(iph->frag_off)); printf("\n Time to Live (TTL): %d hops", iph->ttl); printf("\n Protocol: %d", iph->protocol); printf("\n Checksum: 0x%02X%02X", PWORD(iph->check)); printf("\n Source IP Address: %d.%d.%d.%d", NIPQUAD(iph->saddr)); printf("\n Destination IP Address: %d.%d.%d.%d", NIPQUAD(iph->daddr)); switch (iph->protocol) //判断IP包中数据部分报文的类型 { case IPPROTO_TCP: return decode_tcp((u_char *)&iph[1]); case IPPROTO_UDP: return decode_udp((u_char *)&iph[1]); default: return -1; } return 0;} static int decode_tcp(const u_char *buf)//分解TCP报文报头信息{ struct tcphdr *tcph = (struct tcphdr *) buf; printf("\n TCP header"); printf("\n Source port: %d", ntohs(tcph->source)); printf("\n Destination port: %d", ntohs(tcph->dest)); printf("\n Sequence number: %u", ntohl(tcph->seq)); printf("\n Acknowledegment number: %u", ntohl(tcph->ack_seq)); printf("\n Header length: %d (%d bytes)", tcph->doff, tcph->doff*4); printf("\n Reserved: 0x%X", tcph->res1); printf("\n Flags: r:%d,u:%d,a:%d,p:%d,r:%d,s:%d,f:%d",tcph->res2, tcph->urg, tcph->ack, tcph->psh,tcph->rst, tcph->syn, tcph->fin); printf("\n Window size: %d", ntohs(tcph->window)); printf("\n Checksum: 0x%02X%02X", PWORD(tcph->check)); printf("\n Urgent pointer: %d", ntohs(tcph->urg_ptr)); return 0;} static int decode_udp(const u_char *buf)//分解UDP报文报头信息{ struct udphdr *udph = (struct udphdr *) buf; printf("\n UDP header"); printf("\n Source Port: %d", ntohs(udph->source)); printf("\n Destination Port: %d", ntohs(udph->dest)); printf("\n Length: %d bytes", ntohs(udph->len)); printf("\n Checksum: 0x%X", udph->check); return 0;}//显示接收到的数据帧头部内容static void hex_print(const u_char *buf, int len, int offset){ u_int i, j, jm; int c; printf("\n"); for (i = 0; i < len; i += 0x10) { printf(" %04x: ", (u_int)(i + offset)); jm = len - i; jm = jm > 16 ? 16 : jm; for (j = 0; j < jm; j++) { if ((j % 2) == 1) printf("%02x ", (u_int) buf[i+j]); else printf("%02x", (u_int) buf[i+j]); } for (; j < 16; j++) { if ((j % 2) == 1) printf(" "); else printf(" "); } printf(" "); for (j = 0; j < jm; j++) { c = buf[i+j]; c = isprint(c) ? c : '.'; printf("%c", c); } printf("\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -