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