Merge pull request #59 from electronjoe/graceful-SIGTERM-handling
[netsniff-ng-old.git] / proto_arp.c
blobd6c0eecf2417bb8c2275e2f96769b5b00ccc885a
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdint.h>
8 #include <netinet/in.h> /* for ntohs() */
10 #include "proto.h"
11 #include "protos.h"
12 #include "dissector_eth.h"
13 #include "pkt_buff.h"
14 #include "built_in.h"
16 struct arphdr {
17 uint16_t ar_hrd; /* format of hardware address */
18 uint16_t ar_pro; /* format of protocol address */
19 uint8_t ar_hln; /* length of hardware address */
20 uint8_t ar_pln; /* length of protocol address */
21 uint16_t ar_op; /* ARP opcode (command) */
22 uint8_t ar_sha[6]; /* sender hardware address */
23 uint8_t ar_sip[4]; /* sender IP address */
24 uint8_t ar_tha[6]; /* target hardware address */
25 uint8_t ar_tip[4]; /* target IP address */
26 } __packed;
28 #define ARPHRD_ETHER 1
29 #define ARPHRD_IEEE802 6
30 #define ARPHRD_ARCNET 7
31 #define ARPHRD_ATM 16
32 #define ARPHRD_ATM2 19
33 #define ARPHRD_SERIAL 20
34 #define ARPHRD_ATM3 21
35 #define ARPHRD_IEEE1394 24
37 #define ARPOP_REQUEST 1 /* ARP request */
38 #define ARPOP_REPLY 2 /* ARP reply */
39 #define ARPOP_RREQUEST 3 /* RARP request */
40 #define ARPOP_RREPLY 4 /* RARP reply */
41 #define ARPOP_InREQUEST 8 /* InARP request */
42 #define ARPOP_InREPLY 9 /* InARP reply */
43 #define ARPOP_NAK 10 /* (ATM)ARP NAK */
45 static void arp(struct pkt_buff *pkt)
47 char *hrd;
48 char *pro;
49 char *opcode;
50 struct arphdr *arp = (struct arphdr *) pkt_pull(pkt, sizeof(*arp));
52 if (arp == NULL)
53 return;
55 switch (ntohs(arp->ar_hrd)) {
56 case ARPHRD_ETHER:
57 hrd = "Ethernet";
58 break;
59 case ARPHRD_IEEE802:
60 hrd = "IEEE 802";
61 break;
62 case ARPHRD_ARCNET:
63 hrd = "ARCNET";
64 break;
65 case ARPHRD_ATM:
66 case ARPHRD_ATM2:
67 case ARPHRD_ATM3:
68 hrd = "ATM";
69 break;
70 case ARPHRD_SERIAL:
71 hrd = "Serial Line";
72 break;
73 case ARPHRD_IEEE1394:
74 hrd = "IEEE 1394.1995";
75 break;
76 default:
77 hrd = "Unknown";
78 break;
81 pro = lookup_ether_type(ntohs(arp->ar_pro));
82 if (pro == NULL)
83 pro = "Unknown";
85 switch (ntohs(arp->ar_op)) {
86 case ARPOP_REQUEST:
87 opcode = "ARP request";
88 break;
89 case ARPOP_REPLY:
90 opcode = "ARP reply";
91 break;
92 case ARPOP_RREQUEST:
93 opcode = "RARP request";
94 break;
95 case ARPOP_RREPLY:
96 opcode = "RARP reply";
97 break;
98 case ARPOP_InREQUEST:
99 opcode = "InARP request";
100 break;
101 case ARPOP_InREPLY:
102 opcode = "InARP reply";
103 break;
104 case ARPOP_NAK:
105 opcode = "(ATM) ARP NAK";
106 break;
107 default:
108 opcode = "Unknown";
109 break;
112 tprintf(" [ ARP ");
113 tprintf("Format HA (%u => %s), ", ntohs(arp->ar_hrd), hrd);
114 tprintf("Format Proto (0x%.4x => %s), ", ntohs(arp->ar_pro), pro);
115 tprintf("HA Len (%u), ", arp->ar_hln);
116 tprintf("Proto Len (%u), ", arp->ar_pln);
117 tprintf("Opcode (%u => %s)", ntohs(arp->ar_op), opcode);
118 tprintf(" ]\n");
121 static void arp_less(struct pkt_buff *pkt)
123 char *opcode = NULL;
124 struct arphdr *arp = (struct arphdr *) pkt_pull(pkt, sizeof(*arp));
126 if (arp == NULL)
127 return;
129 switch (ntohs(arp->ar_op)) {
130 case ARPOP_REQUEST:
131 opcode = "ARP request";
132 break;
133 case ARPOP_REPLY:
134 opcode = "ARP reply";
135 break;
136 case ARPOP_RREQUEST:
137 opcode = "RARP request";
138 break;
139 case ARPOP_RREPLY:
140 opcode = "RARP reply";
141 break;
142 case ARPOP_InREQUEST:
143 opcode = "InARP request";
144 break;
145 case ARPOP_InREPLY:
146 opcode = "InARP reply";
147 break;
148 case ARPOP_NAK:
149 opcode = "(ATM) ARP NAK";
150 break;
151 default:
152 opcode = "Unknown";
153 break;
156 tprintf(" Op %s", opcode);
159 struct protocol arp_ops = {
160 .key = 0x0806,
161 .print_full = arp,
162 .print_less = arp_less,