1 | /* ARP */ |
---|
2 | #include <netinet/ether.h> |
---|
3 | #include <netinet/in.h> |
---|
4 | #include <stdio.h> |
---|
5 | #include <inttypes.h> |
---|
6 | #include <dlfcn.h> |
---|
7 | #include <map> |
---|
8 | #include "libpacketdump.h" |
---|
9 | #include <sys/socket.h> |
---|
10 | #include <netinet/in.h> |
---|
11 | #include <netinet/ip.h> |
---|
12 | #include <net/if_arp.h> |
---|
13 | #include <arpa/inet.h> |
---|
14 | |
---|
15 | #define DISPLAY_EXP(x,fmt,exp) \ |
---|
16 | if ((unsigned int)len>=((char*)&ip->x-(char*)ip+sizeof(ip->x))) \ |
---|
17 | printf(fmt,exp); \ |
---|
18 | else \ |
---|
19 | return; |
---|
20 | |
---|
21 | #define DISPLAY(x,fmt) DISPLAY_EXP(x,fmt,ip->x) |
---|
22 | |
---|
23 | #define DISPLAYS(x,fmt) DISPLAY_EXP(x,fmt,htons(ip->x)) |
---|
24 | #define DISPLAYIP(x,fmt) DISPLAY_EXP(x,fmt,inet_ntoa(*(struct in_addr*)&ip->x)) |
---|
25 | |
---|
26 | static char *format(struct arphdr *arp, char *hrd, char *pro) |
---|
27 | { |
---|
28 | static char buffer[1024]; |
---|
29 | if (hrd==NULL) |
---|
30 | return "Truncated (Truncated)"; |
---|
31 | switch(arp->ar_hrd) { |
---|
32 | case ARPHRD_ETHER: |
---|
33 | strcpy(buffer,ether_ntoa((struct ether_addr*)&hrd)); |
---|
34 | break; |
---|
35 | default: |
---|
36 | int i; |
---|
37 | for (i=0;i<arp->ar_hln;i++) { |
---|
38 | snprintf(buffer,sizeof(buffer),"%s %02x", |
---|
39 | buffer,(unsigned char)hrd[i]); |
---|
40 | } |
---|
41 | } |
---|
42 | if (pro==NULL) { |
---|
43 | strncat(buffer," (Truncated)",sizeof(buffer)); |
---|
44 | return buffer; |
---|
45 | } |
---|
46 | switch(arp->ar_pro) { |
---|
47 | case 0x0800: |
---|
48 | snprintf(buffer,sizeof(buffer),"%s (%s)", |
---|
49 | buffer,inet_ntoa(*(struct in_addr*)&pro)); |
---|
50 | break; |
---|
51 | default: |
---|
52 | int i; |
---|
53 | strncat(buffer," (",sizeof(buffer)); |
---|
54 | for (i=0;i<arp->ar_pln;i++) { |
---|
55 | snprintf(buffer,sizeof(buffer),"%s %02x", |
---|
56 | buffer,(unsigned char)pro[i]); |
---|
57 | } |
---|
58 | strncat(buffer,")",sizeof(buffer)); |
---|
59 | break; |
---|
60 | } |
---|
61 | return buffer; |
---|
62 | } |
---|
63 | |
---|
64 | extern "C" |
---|
65 | void decode(int link_type,char *packet,int len) |
---|
66 | { |
---|
67 | struct arphdr *arp = (struct arphdr*)packet; |
---|
68 | char *source_hrd = NULL; |
---|
69 | char *source_pro = NULL; |
---|
70 | char *dest_hrd = NULL; |
---|
71 | char *dest_pro = NULL; |
---|
72 | if (len<8) |
---|
73 | return; |
---|
74 | if (sizeof(*arp)<=(unsigned int)len) |
---|
75 | source_hrd=packet+sizeof(arp); |
---|
76 | if (source_hrd && source_hrd-packet+arp->ar_hln<=len) |
---|
77 | source_pro =source_hrd+arp->ar_hln; |
---|
78 | if (source_pro && source_pro-packet+arp->ar_pln<=len) |
---|
79 | dest_hrd =source_pro +arp->ar_pln; |
---|
80 | if (dest_hrd && dest_hrd-packet+arp->ar_pln<=len) |
---|
81 | dest_pro =dest_hrd +arp->ar_hln; |
---|
82 | switch(arp->ar_op) { |
---|
83 | case ARPOP_REQUEST: |
---|
84 | printf(" ARP: Who-has %s", |
---|
85 | format(arp,source_hrd,source_pro)); |
---|
86 | printf(" please tell %s", |
---|
87 | format(arp,dest_hrd,dest_pro)); |
---|
88 | break; |
---|
89 | default: |
---|
90 | printf(" ARP: Unknown opcode (%i) from %s", |
---|
91 | arp->ar_op, |
---|
92 | format(arp,source_hrd,source_pro)); |
---|
93 | printf(" to %s", |
---|
94 | format(arp,dest_hrd,dest_pro)); |
---|
95 | break; |
---|
96 | } |
---|
97 | return; |
---|
98 | } |
---|