第一:需要了解libcap的基本架构!
第二:需要了解TCP/IP协议头部结构体(网摘小结)
第三:下面的图示概念需要了解
67 | bootps | 引导协议(BOOTP)服务;还被动态主机配置协议(DHCP)服务使用 |
68 | bootpc | Bootstrap(BOOTP)客户;还被动态主机配置协议(DHCP)客户使用 |
#define SPERW (7 * 24 * 3600)
#define SPERD (24 * 3600)
#define SPERH (3600)
#define SPERM (60)
#define LARGESTRING 1024
// header variables
u_char timestamp[40]; // timestamp on header
u_char mac_origin[40]; // mac address of origin
u_char mac_destination[40]; // mac address of destination
u_char ip_origin[40]; // ip address of origin
u_char ip_destination[40]; // ip address of destination
int max_data_len; // maximum size of a packet
int tcpdump_style = -1;
char errbuf[PCAP_ERRBUF_SIZE];
char *hmask = NULL;
regex_t preg;
int check_ch(u_char *data, int data_len);
int readheader(u_char *buf);
int readdata(u_char *buf, u_char *data, int *data_len);
int printdata(u_char *data, int data_len);
void pcap_callback(u_char *user, const struct pcap_pkthdr *h,
const u_char *sp);
void printIPaddress(u_char *data);
void printIPaddressAddress(u_char *data);
void printIPaddressMask(u_char *data);
void print8bits(u_char *data);
void print16bits(u_char *data);
void print32bits(u_char *data);
void printTime8(u_char *data);
void printTime32(u_char *data);
void printReqParmList(u_char *data, int len);
void printHexColon(u_char *data, int len);
void printHex(u_char *data, int len);
void printHexString(u_char *data, int len);
void usage() {
printf("Usage: $0 <-i interface> [-h macaddress]\n");
exit(0);
}
int main(int argc, char **argv) {
int i;
pcap_t *cap;
struct bpf_program fp;
char *interface = NULL;
for (i = 1; i < argc; i++) {
if (argv[i] == NULL || argv[i][0] != '-') break;
switch (argv[i][1]) {
case 'h':
hmask = argv[++i];
break;
case 'i':
interface = argv[++i];
break;
default:
fprintf(stderr, "%s: %c: uknown option\n",
argv[0], argv[i][1]);
usage();
}
}
if (interface == NULL) usage();
if (hmask)
regcomp(&preg, hmask, REG_EXTENDED | REG_ICASE | REG_NOSUB);
if ((cap = pcap_open_live(interface, 1500, 1, 100, errbuf)) == NULL)
errx(1, "pcap_open_live(): %s", errbuf);
if (pcap_compile(cap, &fp, "udp and (port bootpc or port bootps)", 0, 0) < 0)
errx(1,"pcap_compile: %s", pcap_geterr(cap));
if (pcap_setfilter(cap, &fp) < 0)
errx(1,"pcap_setfilter: %s", pcap_geterr(cap));
if (pcap_loop(cap, 0, pcap_callback, NULL) < 0)
errx(1,"pcap_loop(%s): %s", interface, pcap_geterr(cap));
return 0;
}
void pcap_callback(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) {
struct ether_header *eh;
struct ip *ip;
struct udphdr *udp;
int offset = 0;
if (h->caplen < ETHER_HDR_LEN) {
printf("Ignored too short ethernet packet: %d bytes\n",
h->caplen);
return;
}
//获取eth的头部
eh = (struct ether_header *)(sp + offset);
offset += ETHER_HDR_LEN;
// Check for IPv4 packets
if (eh->ether_type != 8) {
printf("Ignored non IPv4 packet: %d\n", eh->ether_type);
return;
}
// Check for length
if (h->caplen < offset + sizeof(struct ip)) {
printf("Ignored too short IPv4 packet: %d bytes\n", h->caplen);
return;
}
//获取ip的头部
ip = (struct ip *)(sp + offset);
offset += sizeof(struct ip);
//获取udp的头部
udp = (struct udphdr *)(sp + offset);
offset += sizeof(struct udphdr);
{
struct timeval tp;
gettimeofday(&tp, NULL);
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S.",
localtime(&(tp.tv_sec)));
sprintf(timestamp + strlen(timestamp), "%03ld",
tp.tv_usec / 1000);
}
strcpy(mac_origin, ether_ntoa((struct ether_addr *)eh->ether_shost));
strcpy(mac_destination,
ether_ntoa((struct ether_addr *)eh->ether_dhost));
strcpy(ip_origin, (u_char *)inet_ntoa(ip->ip_src));
strcpy(ip_destination, (u_char *)inet_ntoa(ip->ip_dst));
if (hmask && check_ch((u_char *)(sp + offset), ntohs(udp->len))) return;
//这里拿到了udp,也就是dhcp协议头部,根据http://blog.csdn.net/jl2011/article/details/49334297
可以很容易的了解结果!
printdata((u_char *)(sp + offset), ntohs(udp->len));
}
这里是dhcp的字段
通过运行程序,可以
发现是ok的!
---------------------------------------------------------------------------
TIME: 2007-01-04 19:15:21.921
IP: 172.21.18.69 (28:80:23:f8:b1:56) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 4ede74e9
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
^Z TIME: 2007-01-04 19:15:27.033
IP: 172.21.18.57 (34:e6:d7:29:2f:f8) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: feabbf46
SECS: 0
FLAGS: 7f80
CIADDR: 172.21.18.57
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 34:e6:d7:29:2f:f8:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 8 (DHCPINFORM)
OPTION: 61 ( 7) Client-identifier 01:34:e6:d7:29:2f:f8
OPTION: 12 ( 9) Host name sznb01404
OPTION: 60 ( 8) Vendor class identifier MSFT 5.0
OPTION: 55 ( 13) Parameter Request List 1 (Subnet mask)
15 (Domainname)
3 (Routers)
6 (DNS server)
44 (NetBIOS name server)
46 (NetBIOS node type)
47 (NetBIOS scope)
31 (Perform router discovery)
33 (Static route)
121 (Classless Static Route)
249 (MSFT - Classless route)
43 (Vendor specific info)
252 (MSFT - WinSock Proxy Auto Detect)
---------------------------------------------------------------------------
TIME: 2007-01-04 19:15:27.036
IP: 172.21.18.254 (00:22:56:a5:75:c4) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: feabbf46
SECS: 0
FLAGS: 7f80
CIADDR: 172.21.18.57
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 172.21.18.254
CHADDR: 34:e6:d7:29:2f:f8:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)
OPTION: 54 ( 4) Server identifier 172.21.80.51
OPTION: 1 ( 4) Subnet mask 255.255.254.0
OPTION: 43 ( 5) Vendor specific info dc034e4150 ?NAP
OPTION: 15 ( 17) Domainname **********************
OPTION: 3 ( 4) Routers 172.21.18.254
OPTION: 6 ( 8) DNS server 172.21.80.100,172.21.80.51
---------------------------------------------------------------------------