|
最近有几位网友谈到如何实现分析数据包,如何来捕捉数据等问题比较迷惑,我写了一个简单的程序帮助大家理解,这个程序并不能完全完成大家的问题,还需要阅读者自己根据自己的需要编写自己的代码。
本程序在linux下编写的,主要实现捕捉数据包,分析eth头,arp,ip,udp,tcp头部分信息。 包括三个文件,Makefile,sniffer.c,sniffer.h
下面是程序的源代码 -------------------------------------------------------------------------------------------------------- Makefile CC = gcc -Wall -O2 LIBS = INCLUDE = TARGET = sniffer all:$(TARGET) sniffer: sniffer.o $(CC) -o sniffer sniffer.o $(LIBS)
.c.o: $(CC) -c $(INCLUDE) $<
clean: @rm *.o @rm sniffer --------------------------------------------------------------------------------------------------------- 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> /* For ETH_P_ALL */ #include <net/if_arp.h>
#include "sniffer.h"
#define BUFSIZE 2048
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];
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("\nMAC header"); printf("\nDestination Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_dest)); printf("\nSource Address:%02X: %02X:%02X:%02X:%02X:%02X", HWADDR(eth->h_source)); printf("\nType: %02X-%02X", PWORD(eth->h_proto));
switch (ntohs(eth->h_proto)) { 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; }
static int decode_arp(const u_char *buf) { struct ether_arp *arph = (struct ether_arp *) buf;
printf("\nAddress Resolution Protocol"); printf("\nHardware Type: %d", ntohs(arph->arp_hrd)); printf("\nProtocol Type: %02X-%02X", PWORD(arph->arp_pro)); printf("\nLength of Hardware Address: %d", arph->arp_hln); printf("\nLength of Protocol Address: %d", arph->arp_pln); printf("\nOperation Code: %d", ntohs(arph->arp_op)); printf("\nSender`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(arph->arp_sha)); printf("\nSender`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_spa)); printf("\nTarget`s Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X", HWADDR(arph->arp_tha)); printf("\nTarget`s IP Address: %d.%d.%d.%d", NIPQUAD(arph->arp_tpa));
return 0; }
static int decode_ip(const u_char *buf) { struct iphdr *iph = (struct iphdr *) buf;
printf("\nIPv4 header"); printf("\nVersion: %d", iph->version); printf("\nHeader length: %d (%d bytes)", iph->ihl, iph->ihl*4); printf("\nType of service (TOS):0x%02X", iph->tos); printf("\nTotal length: %d", ntohs(iph->tot_len)); printf("\nIdentification: %d", ntohs(iph->id)); printf("\nFlags: %02X %02X", PWORD(iph->frag_off)); printf("\nTime to Live (TTL): %d hops", iph->ttl); printf("\nProtocol: %d", iph->protocol); printf("\nChecksum: 0x%02X%02X", PWORD(iph->check)); printf("\nSource IP Address: %d.%d.%d.%d", NIPQUAD(iph->saddr)); printf("\nDestination IP Address: %d.%d.%d.%d", NIPQUAD(iph->daddr));
switch (iph->protocol) { 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) { struct tcphdr *tcph = (struct tcphdr *) buf;
printf("\nTCP header"); printf("\nSource port: %d", ntohs(tcph->source)); printf("\nDestination port: %d", ntohs(tcph->dest)); printf("\nSequence number: %u", ntohl(tcph->seq)); printf("\nAcknowledegment number: %u", ntohl(tcph->ack_seq)); printf("\nHeader length: %d (%d bytes)", tcph->doff, tcph->doff*4); printf("\nReserved: 0x%X", tcph->res1); printf("\nFlags: 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("\nWindow size: %d", ntohs(tcph->window)); printf("\nChecksum: 0x%02X%02X", PWORD(tcph->check)); printf("\nUrgent pointer: %d", ntohs(tcph->urg_ptr));
return 0; }
static int decode_udp(const u_char *buf) { struct udphdr *udph = (struct udphdr *) buf;
printf("\nUDP header"); printf("\nSource Port: %d", ntohs(udph->source)); printf("\nDestination Port: %d", ntohs(udph->dest)); printf("\nLength: %d bytes", ntohs(udph->len)); printf("\nChecksum: 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"); } }
--------------------------------------------------------------------------------------------------- sniffer.h #ifndef _SNIFFER_H #define _SNIFFER_H
/* * Display an MAC address in readable format. */ #define HWADDR(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3], \ ((unsigned char *)&addr)[4], \ ((unsigned char *)&addr)[5]
/* * Display an IP address in readable format. */ #define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3]
#define HIPQUAD(addr) \ ((unsigned char *)&add [1] [2] 下一页
|