2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
9 #include <netinet/in.h> /* for ntohs() */
10 #include <linux/if_ether.h>
19 uint16_t ar_hrd
; /* format of hardware address */
20 uint16_t ar_pro
; /* format of protocol address */
21 uint8_t ar_hln
; /* length of hardware address */
22 uint8_t ar_pln
; /* length of protocol address */
23 uint16_t ar_op
; /* ARP opcode (command) */
24 uint8_t ar_sha
[6]; /* sender hardware address */
25 uint8_t ar_sip
[4]; /* sender IP address */
26 uint8_t ar_tha
[6]; /* target hardware address */
27 uint8_t ar_tip
[4]; /* target IP address */
30 #define ARPHRD_ETHER 1
31 #define ARPHRD_IEEE802 6
32 #define ARPHRD_ARCNET 7
34 #define ARPHRD_ATM2 19
35 #define ARPHRD_SERIAL 20
36 #define ARPHRD_ATM3 21
37 #define ARPHRD_IEEE1394 24
39 #define ARPOP_REQUEST 1 /* ARP request */
40 #define ARPOP_REPLY 2 /* ARP reply */
41 #define ARPOP_RREQUEST 3 /* RARP request */
42 #define ARPOP_RREPLY 4 /* RARP reply */
43 #define ARPOP_InREQUEST 8 /* InARP request */
44 #define ARPOP_InREPLY 9 /* InARP reply */
45 #define ARPOP_NAK 10 /* (ATM)ARP NAK */
52 static void arp_print_addrs(struct arphdr
*arp
, enum addr_direct addr_dir
)
54 const char *dir
= addr_dir
== ADDR_SENDER
? "Sender" : "Target";
56 if (ntohs(arp
->ar_hrd
) == ARPHRD_ETHER
) {
59 mac
= addr_dir
== ADDR_SENDER
? &arp
->ar_sha
[0] : &arp
->ar_tha
[0];
61 tprintf(", %s MAC (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x)",
62 dir
, mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
65 if (ntohs(arp
->ar_pro
) == ETH_P_IP
) {
66 char ip_str
[INET_ADDRSTRLEN
];
69 if (addr_dir
== ADDR_SENDER
)
70 ip
= *(uint32_t *)&arp
->ar_sip
[0];
72 ip
= *(uint32_t *)&arp
->ar_tip
[0];
74 inet_ntop(AF_INET
, &ip
, ip_str
, sizeof(ip_str
));
76 tprintf(", %s IP (%s)", dir
, ip_str
);
80 static void arp(struct pkt_buff
*pkt
)
85 struct arphdr
*arp
= (struct arphdr
*) pkt_pull(pkt
, sizeof(*arp
));
90 switch (ntohs(arp
->ar_hrd
)) {
108 case ARPHRD_IEEE1394
:
109 hrd
= "IEEE 1394.1995";
116 pro
= lookup_ether_type(ntohs(arp
->ar_pro
));
120 switch (ntohs(arp
->ar_op
)) {
122 opcode
= "ARP request";
125 opcode
= "ARP reply";
128 opcode
= "RARP request";
131 opcode
= "RARP reply";
133 case ARPOP_InREQUEST
:
134 opcode
= "InARP request";
137 opcode
= "InARP reply";
140 opcode
= "(ATM) ARP NAK";
148 tprintf("Format HA (%u => %s), ", ntohs(arp
->ar_hrd
), hrd
);
149 tprintf("Format Proto (0x%.4x => %s), ", ntohs(arp
->ar_pro
), pro
);
150 tprintf("HA Len (%u), ", arp
->ar_hln
);
151 tprintf("Proto Len (%u), ", arp
->ar_pln
);
152 tprintf("Opcode (%u => %s)", ntohs(arp
->ar_op
), opcode
);
154 arp_print_addrs(arp
, ADDR_SENDER
);
155 arp_print_addrs(arp
, ADDR_TARGET
);
160 static void arp_less(struct pkt_buff
*pkt
)
163 struct arphdr
*arp
= (struct arphdr
*) pkt_pull(pkt
, sizeof(*arp
));
168 switch (ntohs(arp
->ar_op
)) {
170 opcode
= "ARP request";
173 opcode
= "ARP reply";
176 opcode
= "RARP request";
179 opcode
= "RARP reply";
181 case ARPOP_InREQUEST
:
182 opcode
= "InARP request";
185 opcode
= "InARP reply";
188 opcode
= "(ATM) ARP NAK";
195 tprintf(" Op %s", opcode
);
198 struct protocol arp_ops
= {
201 .print_less
= arp_less
,