HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-arp.c
blobb0b2e7d1399c9d40bbb0e6f320f8521aa563881f
1 /* packet-arp.c
2 * Routines for ARP packet disassembly (RFC 826)
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * By Deepti Ragha <dlragha@ncsu.edu>
11 * Copyright 2012 Deepti Ragha
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include "config.h"
30 #include <string.h>
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/strutil.h>
34 #include <epan/arptypes.h>
35 #include <epan/addr_resolv.h>
36 #include <epan/wmem/wmem.h>
37 #include "packet-arp.h"
38 #include <epan/etypes.h>
39 #include <epan/arcnet_pids.h>
40 #include <epan/ax25_pids.h>
41 #include <epan/prefs.h>
42 #include <epan/expert.h>
44 void proto_register_arp(void);
45 void proto_reg_handoff_arp(void);
47 static int proto_arp = -1;
48 static int hf_arp_hard_type = -1;
49 static int hf_arp_proto_type = -1;
50 static int hf_arp_hard_size = -1;
51 static int hf_atmarp_sht = -1;
52 static int hf_atmarp_shl = -1;
53 static int hf_atmarp_sst = -1;
54 static int hf_atmarp_ssl = -1;
55 static int hf_arp_proto_size = -1;
56 static int hf_arp_opcode = -1;
57 static int hf_arp_isgratuitous = -1;
58 static int hf_atmarp_spln = -1;
59 static int hf_atmarp_tht = -1;
60 static int hf_atmarp_thl = -1;
61 static int hf_atmarp_tst = -1;
62 static int hf_atmarp_tsl = -1;
63 static int hf_atmarp_tpln = -1;
64 static int hf_arp_src_hw = -1;
65 static int hf_arp_src_hw_mac = -1;
66 static int hf_arp_src_proto = -1;
67 static int hf_arp_src_proto_ipv4 = -1;
68 static int hf_arp_dst_hw = -1;
69 static int hf_arp_dst_hw_mac = -1;
70 static int hf_arp_dst_proto = -1;
71 static int hf_arp_dst_proto_ipv4 = -1;
72 static int hf_drarp_error_status = -1;
73 static int hf_arp_duplicate_ip_address_earlier_frame = -1;
74 static int hf_arp_duplicate_ip_address_seconds_since_earlier_frame = -1;
76 static int hf_atmarp_src_atm_num_e164 = -1;
77 static int hf_atmarp_src_atm_num_nsap = -1;
78 static int hf_atmarp_src_atm_subaddr = -1;
79 static int hf_atmarp_dst_atm_num_e164 = -1;
80 static int hf_atmarp_dst_atm_num_nsap = -1;
81 static int hf_atmarp_dst_atm_subaddr = -1;
83 static int hf_arp_dst_hw_ax25 = -1;
84 static int hf_arp_src_hw_ax25 = -1;
86 static gint ett_arp = -1;
87 static gint ett_atmarp_nsap = -1;
88 static gint ett_atmarp_tl = -1;
89 static gint ett_arp_duplicate_address = -1;
91 static expert_field ei_seq_arp_dup_ip = EI_INIT;
92 static expert_field ei_seq_arp_storm = EI_INIT;
94 static dissector_handle_t arp_handle;
96 static dissector_handle_t atmarp_handle;
97 static dissector_handle_t ax25arp_handle;
99 /* Used for determining if frequency of ARP requests constitute a storm */
100 #define STORM 1
101 #define NO_STORM 2
103 /* Preference settings */
104 static gboolean global_arp_detect_request_storm = FALSE;
105 static guint32 global_arp_detect_request_storm_packets = 30;
106 static guint32 global_arp_detect_request_storm_period = 100;
108 static gboolean global_arp_detect_duplicate_ip_addresses = TRUE;
110 static guint32 arp_request_count = 0;
111 static nstime_t time_at_start_of_count;
114 /* Map of (IP address -> MAC address) to detect duplicate IP addresses
115 Key is unsigned32 */
116 static GHashTable *address_hash_table = NULL;
118 typedef struct address_hash_value {
119 guint8 mac[6];
120 guint frame_num;
121 time_t time_of_entry;
122 } address_hash_value;
124 /* Map of ((frame Num, IP address) -> MAC address) */
125 static GHashTable *duplicate_result_hash_table = NULL;
127 typedef struct duplicate_result_key {
128 guint32 frame_number;
129 guint32 ip_address;
130 } duplicate_result_key;
133 /* Definitions taken from Linux "linux/if_arp.h" header file, and from
135 http://www.iana.org/assignments/arp-parameters
140 /* ARP / RARP structs and definitions */
141 #ifndef ARPOP_REQUEST
142 #define ARPOP_REQUEST 1 /* ARP request. */
143 #endif
144 #ifndef ARPOP_REPLY
145 #define ARPOP_REPLY 2 /* ARP reply. */
146 #endif
147 /* Some OSes have different names, or don't define these at all */
148 #ifndef ARPOP_RREQUEST
149 #define ARPOP_RREQUEST 3 /* RARP request. */
150 #endif
151 #ifndef ARPOP_RREPLY
152 #define ARPOP_RREPLY 4 /* RARP reply. */
153 #endif
155 /*Additional parameters as per http://www.iana.org/assignments/arp-parameters*/
156 #ifndef ARPOP_DRARPREQUEST
157 #define ARPOP_DRARPREQUEST 5 /* DRARP request. */
158 #endif
160 #ifndef ARPOP_DRARPREPLY
161 #define ARPOP_DRARPREPLY 6 /* DRARP reply. */
162 #endif
164 #ifndef ARPOP_DRARPERROR
165 #define ARPOP_DRARPERROR 7 /* DRARP error. */
166 #endif
168 #ifndef ARPOP_IREQUEST
169 #define ARPOP_IREQUEST 8 /* Inverse ARP (RFC 1293) request. */
170 #endif
171 #ifndef ARPOP_IREPLY
172 #define ARPOP_IREPLY 9 /* Inverse ARP reply. */
173 #endif
174 #ifndef ATMARPOP_NAK
175 #define ATMARPOP_NAK 10 /* ATMARP NAK. */
176 #endif
178 /*Additional parameters as per http://www.iana.org/assignments/arp-parameters*/
179 #ifndef ARPOP_MARS_REQUEST
180 #define ARPOP_MARS_REQUEST 11 /*MARS request message. */
181 #endif
183 #ifndef ARPOP_MARS_MULTI
184 #define ARPOP_MARS_MULTI 12 /*MARS-Multi message. */
185 #endif
187 #ifndef ARPOP_MARS_MSERV
188 #define ARPOP_MARS_MSERV 13 /*MARS-Mserv message. */
189 #endif
191 #ifndef ARPOP_MARS_JOIN
192 #define ARPOP_MARS_JOIN 14 /*MARS-Join request. */
193 #endif
195 #ifndef ARPOP_MARS_LEAVE
196 #define ARPOP_MARS_LEAVE 15 /*MARS Leave request. */
197 #endif
199 #ifndef ARPOP_MARS_NAK
200 #define ARPOP_MARS_NAK 16 /*MARS nak message.*/
201 #endif
203 #ifndef ARPOP_MARS_UNSERV
204 #define ARPOP_MARS_UNSERV 17 /*MARS Unserv message. */
205 #endif
207 #ifndef ARPOP_MARS_SJOIN
208 #define ARPOP_MARS_SJOIN 18 /*MARS Sjoin message. */
209 #endif
211 #ifndef ARPOP_MARS_SLEAVE
212 #define ARPOP_MARS_SLEAVE 19 /*MARS Sleave message. */
213 #endif
215 #ifndef ARPOP_MARS_GROUPLIST_REQUEST
216 #define ARPOP_MARS_GROUPLIST_REQUEST 20 /*MARS Grouplist request message. */
217 #endif
219 #ifndef ARPOP_MARS_GROUPLIST_REPLY
220 #define ARPOP_MARS_GROUPLIST_REPLY 21 /*MARS Grouplist reply message. */
221 #endif
223 #ifndef ARPOP_MARS_REDIRECT_MAP
224 #define ARPOP_MARS_REDIRECT_MAP 22 /*MARS Grouplist request message. */
225 #endif
227 #ifndef ARPOP_MAPOS_UNARP
228 #define ARPOP_MAPOS_UNARP 23 /*MAPOS UNARP*/
229 #endif
231 #ifndef ARPOP_EXP1
232 #define ARPOP_EXP1 24 /* Experimental 1 */
233 #endif
234 #ifndef ARPOP_EXP2
235 #define ARPOP_EXP2 25 /* Experimental 2 */
236 #endif
238 #ifndef ARPOP_RESERVED1
239 #define ARPOP_RESERVED1 0 /*Reserved opcode 1*/
240 #endif
242 #ifndef ARPOP_RESERVED2
243 #define ARPOP_RESERVED2 65535 /*Reserved opcode 2*/
244 #endif
246 #ifndef DRARPERR_RESTRICTED
247 #define DRARPERR_RESTRICTED 1
248 #endif
250 #ifndef DRARPERR_NOADDRESSES
251 #define DRARPERR_NOADDRESSES 2
252 #endif
254 #ifndef DRARPERR_SERVERDOWN
255 #define DRARPERR_SERVERDOWN 3
256 #endif
258 #ifndef DRARPERR_MOVED
259 #define DRARPERR_MOVED 4
260 #endif
262 #ifndef DRARPERR_FAILURE
263 #define DRARPERR_FAILURE 5
264 #endif
268 static const value_string op_vals[] = {
269 {ARPOP_REQUEST, "request" },
270 {ARPOP_REPLY, "reply" },
271 {ARPOP_RREQUEST, "reverse request" },
272 {ARPOP_RREPLY, "reverse reply" },
273 {ARPOP_DRARPREQUEST, "drarp request" },
274 {ARPOP_DRARPREPLY, "drarp reply" },
275 {ARPOP_DRARPERROR, "drarp error" },
276 {ARPOP_IREQUEST, "inverse request" },
277 {ARPOP_IREPLY, "inverse reply" },
278 {ATMARPOP_NAK, "arp nak" },
279 {ARPOP_MARS_REQUEST, "mars request" },
280 {ARPOP_MARS_MULTI, "mars multi" },
281 {ARPOP_MARS_MSERV, "mars mserv" },
282 {ARPOP_MARS_JOIN, "mars join" },
283 {ARPOP_MARS_LEAVE, "mars leave" },
284 {ARPOP_MARS_NAK, "mars nak" },
285 {ARPOP_MARS_UNSERV, "mars unserv" },
286 {ARPOP_MARS_SJOIN, "mars sjoin" },
287 {ARPOP_MARS_SLEAVE, "mars sleave" },
288 {ARPOP_MARS_GROUPLIST_REQUEST, "mars grouplist request" },
289 {ARPOP_MARS_GROUPLIST_REPLY, "mars gruoplist reply" },
290 {ARPOP_MARS_REDIRECT_MAP, "mars redirect map" },
291 {ARPOP_MAPOS_UNARP, "mapos unarp" },
292 {ARPOP_EXP1, "experimental 1" },
293 {ARPOP_EXP2, "experimental 2" },
294 {ARPOP_RESERVED1, "reserved" },
295 {ARPOP_RESERVED2, "reserved" },
296 {0, NULL}};
298 static const value_string drarp_status[]={
299 {DRARPERR_RESTRICTED, "restricted" },
300 {DRARPERR_NOADDRESSES, "no address" },
301 {DRARPERR_SERVERDOWN, "serverdown" },
302 {DRARPERR_MOVED, "moved" },
303 {DRARPERR_FAILURE, "failure" },
304 {0, NULL}};
306 static const value_string atmop_vals[] = {
307 {ARPOP_REQUEST, "request" },
308 {ARPOP_REPLY, "reply" },
309 {ARPOP_IREQUEST, "inverse request" },
310 {ARPOP_IREPLY, "inverse reply" },
311 {ATMARPOP_NAK, "nak" },
312 {ARPOP_MARS_REQUEST, "mars request" },
313 {ARPOP_MARS_MULTI, "mars multi" },
314 {ARPOP_MARS_MSERV, "mars mserv" },
315 {ARPOP_MARS_JOIN, "mars join" },
316 {ARPOP_MARS_LEAVE, "mars leave" },
317 {ARPOP_MARS_NAK, "mars nak" },
318 {ARPOP_MARS_UNSERV, "mars unserv" },
319 {ARPOP_MARS_SJOIN, "mars sjoin" },
320 {ARPOP_MARS_SLEAVE, "mars sleave" },
321 {ARPOP_MARS_GROUPLIST_REQUEST, "mars grouplist request" },
322 {ARPOP_MARS_GROUPLIST_REPLY, "mars gruoplist reply" },
323 {ARPOP_MARS_REDIRECT_MAP, "mars redirect map" },
324 {ARPOP_MAPOS_UNARP, "mapos unarp" },
325 {ARPOP_EXP1, "experimental 1" },
326 {ARPOP_EXP2, "experimental 2" },
327 {ARPOP_RESERVED1, "reserved" },
328 {ARPOP_RESERVED2, "reserved" },
329 {0, NULL} };
331 #define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */
332 #define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */
335 * Given the hardware address type and length, check whether an address
336 * is an Ethernet address - the address must be of type "Ethernet" or
337 * "IEEE 802.x", and the length must be 6 bytes.
339 #define ARP_HW_IS_ETHER(ar_hrd, ar_hln) \
340 (((ar_hrd) == ARPHRD_ETHER || (ar_hrd) == ARPHRD_IEEE802) \
341 && (ar_hln) == 6)
344 * Given the hardware address type and length, check whether an address
345 * is an AX.25 address - the address must be of type "AX.25" and the
346 * length must be 7 bytes.
348 #define ARP_HW_IS_AX25(ar_hrd, ar_hln) \
349 ((ar_hrd) == ARPHRD_AX25 && (ar_hln) == 7)
352 * Given the protocol address type and length, check whether an address
353 * is an IPv4 address - the address must be of type "IP", and the length
354 * must be 4 bytes.
356 #define ARP_PRO_IS_IPv4(ar_pro, ar_pln) \
357 (((ar_pro) == ETHERTYPE_IP || (ar_pro) == AX25_P_IP) && (ar_pln) == 4)
359 const gchar *
360 tvb_arphrdaddr_to_str(tvbuff_t *tvb, gint offset, int ad_len, guint16 type)
362 if (ad_len == 0)
363 return "<No address>";
364 if (ARP_HW_IS_ETHER(type, ad_len)) {
365 /* Ethernet address (or IEEE 802.x address, which is the same type of
366 address). */
367 return tvb_ether_to_str(tvb, offset);
369 return tvb_bytes_to_str(tvb, offset, ad_len);
372 static const gchar *
373 arpproaddr_to_str(const guint8 *ad, int ad_len, guint16 type)
375 if (ad_len == 0)
376 return "<No address>";
377 if (ARP_PRO_IS_IPv4(type, ad_len)) {
378 /* IPv4 address. */
379 return ip_to_str(ad);
381 if (ARP_HW_IS_AX25(type, ad_len)) {
382 /* AX.25 address */
383 return get_ax25_name(ad);
384 /*return ax25_to_str(ad);*/
386 return bytes_to_str(ad, ad_len);
389 #define MAX_E164_STR_LEN 20
391 static const gchar *
392 atmarpnum_to_str(const guint8 *ad, int ad_tl)
394 int ad_len = ad_tl & ATMARP_LEN_MASK;
395 gchar *cur;
397 if (ad_len == 0)
398 return "<No address>";
400 if (ad_tl & ATMARP_IS_E164) {
402 * I'm assuming this means it's an ASCII (IA5) string.
404 cur = (gchar *)wmem_alloc(wmem_packet_scope(), MAX_E164_STR_LEN+3+1);
405 if (ad_len > MAX_E164_STR_LEN) {
406 /* Can't show it all. */
407 memcpy(cur, ad, MAX_E164_STR_LEN);
408 g_snprintf(&cur[MAX_E164_STR_LEN], 3+1, "...");
409 } else {
410 memcpy(cur, ad, ad_len);
411 cur[ad_len + 1] = '\0';
413 return cur;
414 } else {
416 * NSAP.
418 * XXX - break down into subcomponents.
420 return bytes_to_str(ad, ad_len);
424 static const gchar *
425 atmarpsubaddr_to_str(const guint8 *ad, int ad_tl)
427 int ad_len = ad_tl & ATMARP_LEN_MASK;
429 if (ad_len == 0)
430 return "<No address>";
433 * E.164 isn't considered legal in subaddresses (RFC 2225 says that
434 * a null or unknown ATM address is indicated by setting the length
435 * to 0, in which case the type must be ignored; we've seen some
436 * captures in which the length of a subaddress is 0 and the type
437 * is E.164).
439 * XXX - break down into subcomponents?
441 return bytes_to_str(ad, ad_len);
444 const value_string arp_hrd_vals[] = {
445 {ARPHRD_NETROM, "NET/ROM pseudo" },
446 {ARPHRD_ETHER, "Ethernet" },
447 {ARPHRD_EETHER, "Experimental Ethernet" },
448 {ARPHRD_AX25, "AX.25" },
449 {ARPHRD_PRONET, "ProNET" },
450 {ARPHRD_CHAOS, "Chaos" },
451 {ARPHRD_IEEE802, "IEEE 802" },
452 {ARPHRD_ARCNET, "ARCNET" },
453 {ARPHRD_HYPERCH, "Hyperchannel" },
454 {ARPHRD_LANSTAR, "Lanstar" },
455 {ARPHRD_AUTONET, "Autonet Short Address" },
456 {ARPHRD_LOCALTLK, "Localtalk" },
457 {ARPHRD_LOCALNET, "LocalNet" },
458 {ARPHRD_ULTRALNK, "Ultra link" },
459 {ARPHRD_SMDS, "SMDS" },
460 {ARPHRD_DLCI, "Frame Relay DLCI" },
461 {ARPHRD_ATM, "ATM" },
462 {ARPHRD_HDLC, "HDLC" },
463 {ARPHRD_FIBREC, "Fibre Channel" },
464 {ARPHRD_ATM2225, "ATM (RFC 2225)" },
465 {ARPHRD_SERIAL, "Serial Line" },
466 {ARPHRD_ATM2, "ATM" },
467 {ARPHRD_MS188220, "MIL-STD-188-220" },
468 {ARPHRD_METRICOM, "Metricom STRIP" },
469 {ARPHRD_IEEE1394, "IEEE 1394.1995" },
470 {ARPHRD_MAPOS, "MAPOS" },
471 {ARPHRD_TWINAX, "Twinaxial" },
472 {ARPHRD_EUI_64, "EUI-64" },
473 {ARPHRD_HIPARP, "HIPARP" },
474 {ARPHRD_IP_ARP_ISO_7816_3, "IP and ARP over ISO 7816-3" },
475 {ARPHRD_ARPSEC, "ARPSec" },
476 {ARPHRD_IPSEC_TUNNEL, "IPsec tunnel" },
477 {ARPHRD_INFINIBAND, "InfiniBand" },
478 {ARPHRD_TIA_102_PRJ_25_CAI, "TIA-102 Project 25 CAI" },
479 {ARPHRD_WIEGAND_INTERFACE, "Wiegand Interface" },
480 {ARPHRD_PURE_IP, "Pure IP" },
481 {ARPHDR_HW_EXP1, "Experimental 1" },
482 {ARPHDR_HFI, "HFI" },
483 {ARPHDR_HW_EXP2, "Experimental 2" },
484 {0, NULL } };
486 /* Offsets of fields within an ARP packet. */
487 #define AR_HRD 0
488 #define AR_PRO 2
489 #define AR_HLN 4
490 #define AR_PLN 5
491 #define AR_OP 6
492 #define MIN_ARP_HEADER_SIZE 8
494 /* Offsets of fields within an ATMARP packet. */
495 #define ATM_AR_HRD 0
496 #define ATM_AR_PRO 2
497 #define ATM_AR_SHTL 4
498 #define ATM_AR_SSTL 5
499 #define ATM_AR_OP 6
500 #define ATM_AR_SPLN 8
501 #define ATM_AR_THTL 9
502 #define ATM_AR_TSTL 10
503 #define ATM_AR_TPLN 11
504 #define MIN_ATMARP_HEADER_SIZE 12
506 static void
507 dissect_atm_number(tvbuff_t *tvb, int offset, int tl, int hf_e164,
508 int hf_nsap, proto_tree *tree)
510 int len = tl & ATMARP_LEN_MASK;
511 proto_item *ti;
512 proto_tree *nsap_tree;
514 if (tl & ATMARP_IS_E164)
515 proto_tree_add_item(tree, hf_e164, tvb, offset, len, ENC_BIG_ENDIAN);
516 else {
517 ti = proto_tree_add_item(tree, hf_nsap, tvb, offset, len, ENC_BIG_ENDIAN);
518 if (len >= 20) {
519 nsap_tree = proto_item_add_subtree(ti, ett_atmarp_nsap);
520 dissect_atm_nsap(tvb, offset, len, nsap_tree);
526 * XXX - shouldn't there be a centralized routine for dissecting NSAPs?
527 * See also "dissect_nsap()" in epan/dissectors/packet-isup.c and
528 * "print_nsap_net_buf()" and "print_nsap_net()" in epan/osi=utils.c.
530 void
531 dissect_atm_nsap(tvbuff_t *tvb, int offset, int len, proto_tree *tree)
533 guint8 afi;
535 afi = tvb_get_guint8(tvb, offset);
536 switch (afi) {
538 case 0x39: /* DCC ATM format */
539 case 0xBD: /* DCC ATM group format */
540 proto_tree_add_text(tree, tvb, offset + 0, 3,
541 "Data Country Code%s: 0x%04X",
542 (afi == 0xBD) ? " (group)" : "",
543 tvb_get_ntohs(tvb, offset + 1));
544 proto_tree_add_text(tree, tvb, offset + 3, 10,
545 "High Order DSP: %s",
546 tvb_bytes_to_str(tvb, offset + 3, 10));
547 proto_tree_add_text(tree, tvb, offset + 13, 6,
548 "End System Identifier: %s",
549 tvb_bytes_to_str(tvb, offset + 13, 6));
550 proto_tree_add_text(tree, tvb, offset + 19, 1,
551 "Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
552 break;
554 case 0x47: /* ICD ATM format */
555 case 0xC5: /* ICD ATM group format */
556 proto_tree_add_text(tree, tvb, offset + 0, 3,
557 "International Code Designator%s: 0x%04X",
558 (afi == 0xC5) ? " (group)" : "",
559 tvb_get_ntohs(tvb, offset + 1));
560 proto_tree_add_text(tree, tvb, offset + 3, 10,
561 "High Order DSP: %s",
562 tvb_bytes_to_str(tvb, offset + 3, 10));
563 proto_tree_add_text(tree, tvb, offset + 13, 6,
564 "End System Identifier: %s",
565 tvb_bytes_to_str(tvb, offset + 13, 6));
566 proto_tree_add_text(tree, tvb, offset + 19, 1,
567 "Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
568 break;
570 case 0x45: /* E.164 ATM format */
571 case 0xC3: /* E.164 ATM group format */
572 proto_tree_add_text(tree, tvb, offset + 0, 9,
573 "E.164 ISDN%s: %s",
574 (afi == 0xC3) ? " (group)" : "",
575 tvb_bytes_to_str(tvb, offset + 1, 8));
576 proto_tree_add_text(tree, tvb, offset + 9, 4,
577 "High Order DSP: %s",
578 tvb_bytes_to_str(tvb, offset + 3, 10));
579 proto_tree_add_text(tree, tvb, offset + 13, 6,
580 "End System Identifier: %s",
581 tvb_bytes_to_str(tvb, offset + 13, 6));
582 proto_tree_add_text(tree, tvb, offset + 19, 1,
583 "Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
584 break;
586 default:
587 proto_tree_add_text(tree, tvb, offset, 1,
588 "Unknown AFI: 0x%02X", afi);
589 proto_tree_add_text(tree, tvb, offset + 1, len - 1,
590 "Rest of address: %s",
591 tvb_bytes_to_str(tvb, offset + 1, len - 1));
592 break;
596 /* l.s. 32 bits are ipv4 address */
597 static guint
598 address_hash_func(gconstpointer v)
600 return GPOINTER_TO_UINT(v);
603 /* Compare 2 ipv4 addresses */
604 static gint
605 address_equal_func(gconstpointer v, gconstpointer v2)
607 return v == v2;
610 static guint
611 duplicate_result_hash_func(gconstpointer v)
613 const duplicate_result_key *key = (const duplicate_result_key*)v;
614 return (key->frame_number + key->ip_address);
617 static gint
618 duplicate_result_equal_func(gconstpointer v, gconstpointer v2)
620 const duplicate_result_key *key1 = (const duplicate_result_key*)v;
621 const duplicate_result_key *key2 = (const duplicate_result_key*)v2;
623 return (memcmp(key1, key2, sizeof(duplicate_result_key)) == 0);
629 /* Check to see if this mac & ip pair represent 2 devices trying to share
630 the same IP address - report if found (+ return TRUE and set out param) */
631 static gboolean
632 check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree,
633 tvbuff_t *tvb,
634 const guint8 *mac, guint32 ip,
635 guint32 *duplicate_ip)
637 address_hash_value *value;
638 address_hash_value *result = NULL;
639 duplicate_result_key result_key = {pinfo->fd->num, ip};
641 /* Look up existing result */
642 if (pinfo->fd->flags.visited) {
643 result = (address_hash_value *)g_hash_table_lookup(duplicate_result_hash_table,
644 &result_key);
646 else {
647 /* First time around, need to work out if represents duplicate and
648 store result */
650 /* Look up current assignment of IP address */
651 value = (address_hash_value *)g_hash_table_lookup(address_hash_table, GUINT_TO_POINTER(ip));
653 /* If MAC matches table, just update details */
654 if (value != NULL)
656 if (pinfo->fd->num > value->frame_num)
658 if ((memcmp(value->mac, mac, 6) == 0))
660 /* Same MAC as before - update existing entry */
661 value->frame_num = pinfo->fd->num;
662 value->time_of_entry = pinfo->fd->abs_ts.secs;
664 else
666 /* Create result and store in result table */
667 duplicate_result_key *persistent_key = wmem_new(wmem_file_scope(), duplicate_result_key);
668 memcpy(persistent_key, &result_key, sizeof(duplicate_result_key));
670 result = wmem_new(wmem_file_scope(), address_hash_value);
671 memcpy(result, value, sizeof(address_hash_value));
673 g_hash_table_insert(duplicate_result_hash_table, persistent_key, result);
677 else
679 /* No existing entry. Prepare one */
680 value = wmem_new(wmem_file_scope(), struct address_hash_value);
681 memcpy(value->mac, mac, 6);
682 value->frame_num = pinfo->fd->num;
683 value->time_of_entry = pinfo->fd->abs_ts.secs;
685 /* Add it */
686 g_hash_table_insert(address_hash_table, GUINT_TO_POINTER(ip), value);
690 /* Add report to tree if we found a duplicate */
691 if (result != NULL) {
692 proto_tree *duplicate_tree;
694 /* Create subtree */
695 proto_item *ti = proto_tree_add_text(tree, tvb, 0, 0,
696 "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
697 arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP),
698 ether_to_str(mac),
699 ether_to_str(result->mac),
700 result->frame_num);
701 PROTO_ITEM_SET_GENERATED(ti);
702 duplicate_tree = proto_item_add_subtree(ti, ett_arp_duplicate_address);
704 /* Add item for navigating to earlier frame */
705 ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame,
706 tvb, 0, 0, result->frame_num);
707 PROTO_ITEM_SET_GENERATED(ti);
708 expert_add_info_format(pinfo, ti,
709 &ei_seq_arp_dup_ip,
710 "Duplicate IP address configured (%s)",
711 arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP));
713 /* Time since that frame was seen */
714 ti = proto_tree_add_uint(duplicate_tree,
715 hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
716 tvb, 0, 0,
717 (guint32)(pinfo->fd->abs_ts.secs - result->time_of_entry));
718 PROTO_ITEM_SET_GENERATED(ti);
720 /* Set out parameter */
721 *duplicate_ip = ip;
725 return (result != NULL);
730 /* Initializes the hash table each time a new
731 * file is loaded or re-loaded in wireshark */
732 static void
733 arp_init_protocol(void)
735 /* Destroy any existing hashes. */
736 if (address_hash_table) {
737 g_hash_table_destroy(address_hash_table);
739 if (duplicate_result_hash_table) {
740 g_hash_table_destroy(duplicate_result_hash_table);
744 /* Now create it over */
745 address_hash_table = g_hash_table_new(address_hash_func, address_equal_func);
746 duplicate_result_hash_table = g_hash_table_new(duplicate_result_hash_func,
747 duplicate_result_equal_func);
753 /* Take note that a request has been seen */
754 static void
755 request_seen(packet_info *pinfo)
757 /* Don't count frame again after already recording first time around. */
758 if (p_get_proto_data(pinfo->fd, proto_arp, 0) == 0)
760 arp_request_count++;
764 /* Has storm request rate been exceeded with this request? */
765 static void
766 check_for_storm_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
768 gboolean report_storm = FALSE;
770 if (p_get_proto_data(pinfo->fd, proto_arp, 0) != 0)
772 /* Read any previous stored packet setting */
773 report_storm = (p_get_proto_data(pinfo->fd, proto_arp, 0) == (void*)STORM);
775 else
777 /* Seeing packet for first time - check against preference settings */
778 gint seconds_delta = (gint) (pinfo->fd->abs_ts.secs - time_at_start_of_count.secs);
779 gint nseconds_delta = pinfo->fd->abs_ts.nsecs - time_at_start_of_count.nsecs;
780 gint gap = (seconds_delta*1000) + (nseconds_delta / 1000000);
782 /* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */
783 if ((gap > (gint)global_arp_detect_request_storm_period) ||
784 (gap < 0))
786 /* Time period elapsed without threshold being exceeded */
787 arp_request_count = 1;
788 time_at_start_of_count = pinfo->fd->abs_ts;
789 p_add_proto_data(pinfo->fd, proto_arp, 0, (void*)NO_STORM);
790 return;
792 else
793 if (arp_request_count > global_arp_detect_request_storm_packets)
795 /* Storm detected, record and reset start time. */
796 report_storm = TRUE;
797 p_add_proto_data(pinfo->fd, proto_arp, 0, (void*)STORM);
798 time_at_start_of_count = pinfo->fd->abs_ts;
800 else
802 /* Threshold not exceeded yet - no storm */
803 p_add_proto_data(pinfo->fd, proto_arp, 0, (void*)NO_STORM);
807 if (report_storm)
809 /* Report storm and reset counter */
810 proto_item *ti = proto_tree_add_text(tree, tvb, 0, 0,
811 "Packet storm detected (%u packets in < %u ms)",
812 global_arp_detect_request_storm_packets,
813 global_arp_detect_request_storm_period);
814 PROTO_ITEM_SET_GENERATED(ti);
815 expert_add_info_format(pinfo, ti,
816 &ei_seq_arp_storm,
817 "ARP packet storm detected (%u packets in < %u ms)",
818 global_arp_detect_request_storm_packets,
819 global_arp_detect_request_storm_period);
820 arp_request_count = 0;
826 * RFC 2225 ATMARP - it's just like ARP, except where it isn't.
828 static void
829 dissect_atmarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
831 guint16 ar_hrd;
832 guint16 ar_pro;
833 guint8 ar_shtl;
834 guint8 ar_shl;
835 guint8 ar_sstl;
836 guint8 ar_ssl;
837 guint16 ar_op;
838 guint8 ar_spln;
839 guint8 ar_thtl;
840 guint8 ar_thl;
841 guint8 ar_tstl;
842 guint8 ar_tsl;
843 guint8 ar_tpln;
844 int tot_len;
845 proto_tree *arp_tree;
846 proto_item *ti;
847 const gchar *op_str;
848 int sha_offset, ssa_offset, spa_offset;
849 int tha_offset, tsa_offset, tpa_offset;
850 const guint8 *sha_val, *ssa_val, *spa_val;
851 const guint8 *tha_val, *tsa_val, *tpa_val;
852 const gchar *sha_str, *ssa_str, *spa_str;
853 const gchar *tha_str, *tsa_str, *tpa_str;
854 proto_tree *tl_tree;
855 proto_item *tl;
857 /* Override the setting to "ARP/RARP". */
858 pinfo->current_proto = "ATMARP";
860 ar_hrd = tvb_get_ntohs(tvb, ATM_AR_HRD);
861 ar_pro = tvb_get_ntohs(tvb, ATM_AR_PRO);
862 ar_shtl = tvb_get_guint8(tvb, ATM_AR_SHTL);
863 ar_shl = ar_shtl & ATMARP_LEN_MASK;
864 ar_sstl = tvb_get_guint8(tvb, ATM_AR_SSTL);
865 ar_ssl = ar_sstl & ATMARP_LEN_MASK;
866 ar_op = tvb_get_ntohs(tvb, AR_OP);
867 ar_spln = tvb_get_guint8(tvb, ATM_AR_SPLN);
868 ar_thtl = tvb_get_guint8(tvb, ATM_AR_THTL);
869 ar_thl = ar_thtl & ATMARP_LEN_MASK;
870 ar_tstl = tvb_get_guint8(tvb, ATM_AR_TSTL);
871 ar_tsl = ar_tstl & ATMARP_LEN_MASK;
872 ar_tpln = tvb_get_guint8(tvb, ATM_AR_TPLN);
874 tot_len = MIN_ATMARP_HEADER_SIZE + ar_shl + ar_ssl + ar_spln +
875 ar_thl + ar_tsl + ar_tpln;
877 /* Adjust the length of this tvbuff to include only the ARP datagram.
878 Our caller may use that to determine how much of its packet
879 was padding. */
880 tvb_set_reported_length(tvb, tot_len);
882 /* Extract the addresses. */
883 sha_offset = MIN_ATMARP_HEADER_SIZE;
884 if (ar_shl != 0) {
885 sha_val = tvb_get_ptr(tvb, sha_offset, ar_shl);
886 sha_str = atmarpnum_to_str(sha_val, ar_shtl);
887 } else {
888 sha_val = NULL;
889 sha_str = "<No address>";
892 ssa_offset = sha_offset + ar_shl;
893 if (ar_ssl != 0) {
894 ssa_val = tvb_get_ptr(tvb, ssa_offset, ar_ssl);
895 ssa_str = atmarpsubaddr_to_str(ssa_val, ar_sstl);
896 } else {
897 ssa_val = NULL;
898 ssa_str = NULL;
901 spa_offset = ssa_offset + ar_ssl;
902 spa_val = tvb_get_ptr(tvb, spa_offset, ar_spln);
903 spa_str = arpproaddr_to_str(spa_val, ar_spln, ar_pro);
905 tha_offset = spa_offset + ar_spln;
906 if (ar_thl != 0) {
907 tha_val = tvb_get_ptr(tvb, tha_offset, ar_thl);
908 tha_str = atmarpnum_to_str(tha_val, ar_thtl);
909 } else {
910 tha_val = NULL;
911 tha_str = "<No address>";
914 tsa_offset = tha_offset + ar_thl;
915 if (ar_tsl != 0) {
916 tsa_val = tvb_get_ptr(tvb, tsa_offset, ar_tsl);
917 tsa_str = atmarpsubaddr_to_str(tsa_val, ar_tstl);
918 } else {
919 tsa_val = NULL;
920 tsa_str = NULL;
923 tpa_offset = tsa_offset + ar_tsl;
924 tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_tpln);
925 tpa_str = arpproaddr_to_str(tpa_val, ar_tpln, ar_pro);
927 switch (ar_op) {
929 case ARPOP_REQUEST:
930 case ARPOP_REPLY:
931 case ATMARPOP_NAK:
932 default:
933 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMARP");
934 break;
936 case ARPOP_RREQUEST:
937 case ARPOP_RREPLY:
938 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMRARP");
939 break;
941 case ARPOP_IREQUEST:
942 case ARPOP_IREPLY:
943 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ATMARP");
944 break;
946 case ARPOP_MARS_REQUEST:
947 case ARPOP_MARS_MULTI:
948 case ARPOP_MARS_MSERV:
949 case ARPOP_MARS_JOIN:
950 case ARPOP_MARS_LEAVE:
951 case ARPOP_MARS_NAK:
952 case ARPOP_MARS_UNSERV:
953 case ARPOP_MARS_SJOIN:
954 case ARPOP_MARS_SLEAVE:
955 case ARPOP_MARS_GROUPLIST_REQUEST:
956 case ARPOP_MARS_GROUPLIST_REPLY:
957 case ARPOP_MARS_REDIRECT_MAP:
958 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MARS");
959 break;
961 case ARPOP_MAPOS_UNARP:
962 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
963 break;
967 switch (ar_op) {
968 case ARPOP_REQUEST:
969 col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
970 tpa_str, spa_str);
971 break;
972 case ARPOP_REPLY:
973 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s%s%s", spa_str, sha_str,
974 ((ssa_str != NULL) ? "," : ""),
975 ((ssa_str != NULL) ? ssa_str : ""));
976 break;
977 case ARPOP_IREQUEST:
978 col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s%s%s? Tell %s%s%s",
979 tha_str,
980 ((tsa_str != NULL) ? "," : ""),
981 ((tsa_str != NULL) ? tsa_str : ""),
982 sha_str,
983 ((ssa_str != NULL) ? "," : ""),
984 ((ssa_str != NULL) ? ssa_str : ""));
985 break;
986 case ARPOP_IREPLY:
987 col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s is at %s",
988 sha_str,
989 ((ssa_str != NULL) ? "," : ""),
990 ((ssa_str != NULL) ? ssa_str : ""),
991 spa_str);
992 break;
993 case ATMARPOP_NAK:
994 col_add_fstr(pinfo->cinfo, COL_INFO, "I don't know where %s is", spa_str);
995 break;
996 case ARPOP_MARS_REQUEST:
997 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS request from %s%s%s at %s",
998 sha_str,
999 ((ssa_str != NULL) ? "," : ""),
1000 ((ssa_str != NULL) ? ssa_str : ""),
1001 spa_str);
1002 break;
1004 case ARPOP_MARS_MULTI:
1005 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MULTI request from %s%s%s at %s",
1006 sha_str,
1007 ((ssa_str != NULL) ? "," : ""),
1008 ((ssa_str != NULL) ? ssa_str : ""),
1009 spa_str);
1010 break;
1012 case ARPOP_MARS_MSERV:
1013 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MSERV request from %s%s%s at %s",
1014 sha_str,
1015 ((ssa_str != NULL) ? "," : ""),
1016 ((ssa_str != NULL) ? ssa_str : ""),
1017 spa_str);
1018 break;
1020 case ARPOP_MARS_JOIN:
1021 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS JOIN request from %s%s%s at %s",
1022 sha_str,
1023 ((ssa_str != NULL) ? "," : ""),
1024 ((ssa_str != NULL) ? ssa_str : ""),
1025 spa_str);
1026 break;
1028 case ARPOP_MARS_LEAVE:
1029 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS LEAVE from %s%s%s at %s",
1030 sha_str,
1031 ((ssa_str != NULL) ? "," : ""),
1032 ((ssa_str != NULL) ? ssa_str : ""),
1033 spa_str);
1034 break;
1036 case ARPOP_MARS_NAK:
1037 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS NAK from %s%s%s at %s",
1038 sha_str,
1039 ((ssa_str != NULL) ? "," : ""),
1040 ((ssa_str != NULL) ? ssa_str : ""),
1041 spa_str);
1042 break;
1044 case ARPOP_MARS_UNSERV:
1045 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS UNSERV request from %s%s%s at %s",
1046 sha_str,
1047 ((ssa_str != NULL) ? "," : ""),
1048 ((ssa_str != NULL) ? ssa_str : ""),
1049 spa_str);
1050 break;
1052 case ARPOP_MARS_SJOIN:
1053 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SJOIN request from %s%s%s at %s",
1054 sha_str,
1055 ((ssa_str != NULL) ? "," : ""),
1056 ((ssa_str != NULL) ? ssa_str : ""),
1057 spa_str);
1058 break;
1060 case ARPOP_MARS_SLEAVE:
1061 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SLEAVE from %s%s%s at %s",
1062 sha_str,
1063 ((ssa_str != NULL) ? "," : ""),
1064 ((ssa_str != NULL) ? ssa_str : ""),
1065 spa_str);
1066 break;
1068 case ARPOP_MARS_GROUPLIST_REQUEST:
1069 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist request from %s%s%s at %s",
1070 sha_str,
1071 ((ssa_str != NULL) ? "," : ""),
1072 ((ssa_str != NULL) ? ssa_str : ""),
1073 spa_str);
1074 break;
1076 case ARPOP_MARS_GROUPLIST_REPLY:
1077 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist reply from %s%s%s at %s",
1078 sha_str,
1079 ((ssa_str != NULL) ? "," : ""),
1080 ((ssa_str != NULL) ? ssa_str : ""),
1081 spa_str);
1082 break;
1084 case ARPOP_MARS_REDIRECT_MAP:
1085 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS redirect map from %s%s%s at %s",
1086 sha_str,
1087 ((ssa_str != NULL) ? "," : ""),
1088 ((ssa_str != NULL) ? ssa_str : ""),
1089 spa_str);
1090 break;
1092 case ARPOP_MAPOS_UNARP:
1093 col_add_fstr(pinfo->cinfo, COL_INFO, "MAPOS UNARP request from %s%s%s at %s",
1094 sha_str,
1095 ((ssa_str != NULL) ? "," : ""),
1096 ((ssa_str != NULL) ? ssa_str : ""),
1097 spa_str);
1098 break;
1100 case ARPOP_EXP1:
1101 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1102 break;
1104 case ARPOP_EXP2:
1105 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1106 break;
1108 case 0:
1109 case 65535:
1110 col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1111 break;
1113 default:
1114 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ATMARP opcode 0x%04x", ar_op);
1115 break;
1118 if (tree) {
1119 if ((op_str = try_val_to_str(ar_op, atmop_vals)))
1120 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1121 "ATM Address Resolution Protocol (%s)",
1122 op_str);
1123 else
1124 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1125 "ATM Address Resolution Protocol (opcode 0x%04x)", ar_op);
1126 arp_tree = proto_item_add_subtree(ti, ett_arp);
1128 proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, ATM_AR_HRD, 2, ar_hrd);
1130 proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, ATM_AR_PRO, 2,ar_pro);
1132 tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SHTL, 1,
1133 "Sender ATM number type/length: %s/%u",
1134 (ar_shtl & ATMARP_IS_E164 ?
1135 "E.164" :
1136 "ATM Forum NSAPA"),
1137 ar_shl);
1138 tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
1139 proto_tree_add_boolean(tl_tree, hf_atmarp_sht, tvb, ATM_AR_SHTL, 1, ar_shtl);
1140 proto_tree_add_uint(tl_tree, hf_atmarp_shl, tvb, ATM_AR_SHTL, 1, ar_shtl);
1142 tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SSTL, 1,
1143 "Sender ATM subaddress type/length: %s/%u",
1144 (ar_sstl & ATMARP_IS_E164 ?
1145 "E.164" :
1146 "ATM Forum NSAPA"),
1147 ar_ssl);
1148 tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
1149 proto_tree_add_boolean(tl_tree, hf_atmarp_sst, tvb, ATM_AR_SSTL, 1, ar_sstl);
1150 proto_tree_add_uint(tl_tree, hf_atmarp_ssl, tvb, ATM_AR_SSTL, 1, ar_sstl);
1152 proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ar_op);
1155 proto_tree_add_uint(arp_tree, hf_atmarp_spln, tvb, ATM_AR_SPLN, 1, ar_spln);
1157 tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_THTL, 1,
1158 "Target ATM number type/length: %s/%u",
1159 (ar_thtl & ATMARP_IS_E164 ?
1160 "E.164" :
1161 "ATM Forum NSAPA"),
1162 ar_thl);
1163 tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
1164 proto_tree_add_boolean(tl_tree, hf_atmarp_tht, tvb, ATM_AR_THTL, 1, ar_thtl);
1165 proto_tree_add_uint(tl_tree, hf_atmarp_thl, tvb, ATM_AR_THTL, 1, ar_thtl);
1167 tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_TSTL, 1,
1168 "Target ATM subaddress type/length: %s/%u",
1169 (ar_tstl & ATMARP_IS_E164 ?
1170 "E.164" :
1171 "ATM Forum NSAPA"),
1172 ar_tsl);
1173 tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
1174 proto_tree_add_boolean(tl_tree, hf_atmarp_tst, tvb, ATM_AR_TSTL, 1, ar_tstl);
1175 proto_tree_add_uint(tl_tree, hf_atmarp_tsl, tvb, ATM_AR_TSTL, 1, ar_tstl);
1177 proto_tree_add_uint(arp_tree, hf_atmarp_tpln, tvb, ATM_AR_TPLN, 1, ar_tpln);
1179 if (ar_shl != 0)
1180 dissect_atm_number(tvb, sha_offset, ar_shtl, hf_atmarp_src_atm_num_e164,
1181 hf_atmarp_src_atm_num_nsap, arp_tree);
1183 if (ar_ssl != 0)
1184 proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_src_atm_subaddr, tvb, ssa_offset,
1185 ar_ssl,
1186 ssa_val,
1187 "%s", ssa_str);
1189 if (ar_spln != 0) {
1190 proto_tree_add_item(arp_tree,
1191 ARP_PRO_IS_IPv4(ar_pro, ar_spln) ? hf_arp_src_proto_ipv4
1192 : hf_arp_src_proto,
1193 tvb, spa_offset, ar_spln, ENC_BIG_ENDIAN);
1196 if (ar_thl != 0)
1197 dissect_atm_number(tvb, tha_offset, ar_thtl, hf_atmarp_dst_atm_num_e164,
1198 hf_atmarp_dst_atm_num_nsap, arp_tree);
1200 if (ar_tsl != 0)
1201 proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_dst_atm_subaddr, tvb, tsa_offset,
1202 ar_tsl,
1203 tsa_val,
1204 "%s", tsa_str);
1206 if (ar_tpln != 0) {
1207 proto_tree_add_item(arp_tree,
1208 ARP_PRO_IS_IPv4(ar_pro, ar_tpln) ? hf_arp_dst_proto_ipv4
1209 : hf_arp_dst_proto,
1210 tvb, tpa_offset, ar_tpln, ENC_BIG_ENDIAN);
1216 * AX.25 ARP - it's just like ARP, except where it isn't.
1218 static void
1219 dissect_ax25arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1221 #define ARP_AX25 204
1223 guint16 ar_hrd;
1224 guint16 ar_pro;
1225 guint8 ar_hln;
1226 guint8 ar_pln;
1227 guint16 ar_op;
1228 int tot_len;
1229 proto_tree *arp_tree = NULL;
1230 proto_item *ti;
1231 const gchar *op_str;
1232 int sha_offset, spa_offset, tha_offset, tpa_offset;
1233 const guint8 /* *sha_val, */ *spa_val, /* *tha_val, */ *tpa_val;
1234 gboolean is_gratuitous;
1236 /* Hardware Address Type */
1237 ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
1238 /* Protocol Address Type */
1239 ar_pro = tvb_get_ntohs(tvb, AR_PRO);
1240 /* Hardware Address Size */
1241 ar_hln = tvb_get_guint8(tvb, AR_HLN);
1242 /* Protocol Address Size */
1243 ar_pln = tvb_get_guint8(tvb, AR_PLN);
1244 /* Operation */
1245 ar_op = tvb_get_ntohs(tvb, AR_OP);
1247 tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;
1249 /* Adjust the length of this tvbuff to include only the ARP datagram.
1250 Our caller may use that to determine how much of its packet
1251 was padding. */
1252 tvb_set_reported_length(tvb, tot_len);
1254 switch (ar_op) {
1256 case ARPOP_REQUEST:
1257 if (global_arp_detect_request_storm)
1258 request_seen(pinfo);
1259 /* fall-through */
1260 case ARPOP_REPLY:
1261 default:
1262 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1263 break;
1265 case ARPOP_RREQUEST:
1266 case ARPOP_RREPLY:
1267 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1268 break;
1270 case ARPOP_IREQUEST:
1271 case ARPOP_IREPLY:
1272 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1273 break;
1276 /* Get the offsets of the addresses. */
1277 /* Source Hardware Address */
1278 sha_offset = MIN_ARP_HEADER_SIZE;
1279 /* Source Protocol Address */
1280 spa_offset = sha_offset + ar_hln;
1281 /* Target Hardware Address */
1282 tha_offset = spa_offset + ar_pln;
1283 /* Target Protocol Address */
1284 tpa_offset = tha_offset + ar_hln;
1286 /* sha_val = tvb_get_ptr(tvb, sha_offset, ar_hln); */
1287 spa_val = tvb_get_ptr(tvb, spa_offset, ar_pln);
1288 /* tha_val = tvb_get_ptr(tvb, tha_offset, ar_hln); */
1289 tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_pln);
1291 /* ARP requests/replies with the same sender and target protocol
1292 address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
1293 in effect, an announcement that the machine has MAC address
1294 XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
1295 provoke complaints if some other machine has the same IPv4 address,
1296 replies are used to announce relocation of network address, like
1297 in failover solutions. */
1298 if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) && (memcmp(spa_val, tpa_val, ar_pln) == 0))
1299 is_gratuitous = TRUE;
1300 else
1301 is_gratuitous = FALSE;
1303 switch (ar_op) {
1304 case ARPOP_REQUEST:
1305 if (is_gratuitous)
1306 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)",
1307 arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
1308 else
1309 col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
1310 arpproaddr_to_str(tpa_val, ar_pln, ar_pro),
1311 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1312 break;
1313 case ARPOP_REPLY:
1314 if (is_gratuitous)
1315 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)",
1316 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1317 else
1318 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1319 arpproaddr_to_str(spa_val, ar_pln, ar_pro),
1320 /* arphrdaddr_to_str(sha_val, ar_hln, ar_hrd)); */
1321 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
1322 break;
1323 case ARPOP_RREQUEST:
1324 case ARPOP_IREQUEST:
1325 col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s? Tell %s",
1326 /* arphrdaddr_to_str(tha_val, ar_hln, ar_hrd), */
1327 tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
1328 /* arphrdaddr_to_str(sha_val, ar_hln, ar_hrd)); */
1329 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
1330 break;
1331 case ARPOP_RREPLY:
1332 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1333 /* arphrdaddr_to_str(tha_val, ar_hln, ar_hrd), */
1334 tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
1335 arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
1336 break;
1337 case ARPOP_IREPLY:
1338 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1339 /* arphrdaddr_to_str(sha_val, ar_hln, ar_hrd), */
1340 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1341 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1342 break;
1343 default:
1344 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1345 break;
1348 if (tree) {
1349 if ((op_str = try_val_to_str(ar_op, op_vals))) {
1350 if (is_gratuitous && (ar_op == ARPOP_REQUEST))
1351 op_str = "request/gratuitous ARP";
1352 if (is_gratuitous && (ar_op == ARPOP_REPLY))
1353 op_str = "reply/gratuitous ARP";
1354 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1355 "Address Resolution Protocol (%s)", op_str);
1356 } else
1357 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1358 "Address Resolution Protocol (opcode 0x%04x)", ar_op);
1359 arp_tree = proto_item_add_subtree(ti, ett_arp);
1360 proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
1361 proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, AR_PRO, 2, ar_pro);
1362 proto_tree_add_uint(arp_tree, hf_arp_hard_size, tvb, AR_HLN, 1, ar_hln);
1363 proto_tree_add_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ar_pln);
1364 proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ar_op);
1365 if (ar_hln != 0) {
1366 proto_tree_add_item(arp_tree,
1367 ARP_HW_IS_AX25(ar_hrd, ar_hln) ? hf_arp_src_hw_ax25 : hf_arp_src_hw,
1368 tvb, sha_offset, ar_hln, FALSE);
1370 if (ar_pln != 0) {
1371 proto_tree_add_item(arp_tree,
1372 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_src_proto_ipv4
1373 : hf_arp_src_proto,
1374 tvb, spa_offset, ar_pln, FALSE);
1376 if (ar_hln != 0) {
1377 proto_tree_add_item(arp_tree,
1378 ARP_HW_IS_AX25(ar_hrd, ar_hln) ? hf_arp_dst_hw_ax25 : hf_arp_dst_hw,
1379 tvb, tha_offset, ar_hln, FALSE);
1381 if (ar_pln != 0) {
1382 proto_tree_add_item(arp_tree,
1383 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_dst_proto_ipv4
1384 : hf_arp_dst_proto,
1385 tvb, tpa_offset, ar_pln, FALSE);
1389 if (global_arp_detect_request_storm)
1391 check_for_storm_count(tvb, pinfo, arp_tree);
1395 static const guint8 mac_allzero[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1397 static void
1398 dissect_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1400 guint16 ar_hrd;
1401 guint16 ar_pro;
1402 guint8 ar_hln;
1403 guint8 ar_pln;
1404 guint16 ar_op;
1405 int tot_len;
1406 proto_tree *arp_tree = NULL;
1407 proto_item *ti, *item;
1408 const gchar *op_str;
1409 int sha_offset, spa_offset, tha_offset, tpa_offset;
1410 const guint8 *spa_val, *tpa_val;
1411 gboolean is_gratuitous;
1412 gboolean duplicate_detected = FALSE;
1413 guint32 duplicate_ip = 0;
1415 /* Call it ARP, for now, so that if we throw an exception before
1416 we decide whether it's ARP or RARP or IARP or ATMARP, it shows
1417 up in the packet list as ARP.
1419 Clear the Info column so that, if we throw an exception, it
1420 shows up as a short or malformed ARP frame. */
1421 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1422 col_clear(pinfo->cinfo, COL_INFO);
1424 /* Hardware Address Type */
1425 ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
1426 if (ar_hrd == ARPHRD_ATM2225) {
1427 call_dissector(atmarp_handle, tvb, pinfo, tree);
1428 return;
1430 if (ar_hrd == ARPHRD_AX25) {
1431 call_dissector(ax25arp_handle, tvb, pinfo, tree);
1432 return;
1434 /* Protocol Address Type */
1435 ar_pro = tvb_get_ntohs(tvb, AR_PRO);
1436 /* Hardware Address Size */
1437 ar_hln = tvb_get_guint8(tvb, AR_HLN);
1438 /* Protocol Address Size */
1439 ar_pln = tvb_get_guint8(tvb, AR_PLN);
1440 /* Operation */
1441 ar_op = tvb_get_ntohs(tvb, AR_OP);
1443 tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;
1445 /* Adjust the length of this tvbuff to include only the ARP datagram.
1446 Our caller may use that to determine how much of its packet
1447 was padding. */
1448 tvb_set_reported_length(tvb, tot_len);
1450 switch (ar_op) {
1452 case ARPOP_REQUEST:
1453 if (global_arp_detect_request_storm)
1455 request_seen(pinfo);
1457 /* FALLTHRU */
1458 case ARPOP_REPLY:
1459 default:
1460 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1461 break;
1463 case ARPOP_RREQUEST:
1464 case ARPOP_RREPLY:
1465 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1466 break;
1468 case ARPOP_DRARPREQUEST:
1469 case ARPOP_DRARPREPLY:
1470 case ARPOP_DRARPERROR:
1471 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRARP");
1472 break;
1474 case ARPOP_IREQUEST:
1475 case ARPOP_IREPLY:
1476 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1477 break;
1479 case ARPOP_MARS_REQUEST:
1480 case ARPOP_MARS_MULTI:
1481 case ARPOP_MARS_MSERV:
1482 case ARPOP_MARS_JOIN:
1483 case ARPOP_MARS_LEAVE:
1484 case ARPOP_MARS_NAK:
1485 case ARPOP_MARS_UNSERV:
1486 case ARPOP_MARS_SJOIN:
1487 case ARPOP_MARS_SLEAVE:
1488 case ARPOP_MARS_GROUPLIST_REQUEST:
1489 case ARPOP_MARS_GROUPLIST_REPLY:
1490 case ARPOP_MARS_REDIRECT_MAP:
1491 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MARS");
1492 break;
1494 case ARPOP_MAPOS_UNARP:
1495 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
1496 break;
1499 /* Get the offsets of the addresses. */
1500 /* Source Hardware Address */
1501 sha_offset = MIN_ARP_HEADER_SIZE;
1502 /* Source Protocol Address */
1503 spa_offset = sha_offset + ar_hln;
1504 /* Target Hardware Address */
1505 tha_offset = spa_offset + ar_pln;
1506 /* Target Protocol Address */
1507 tpa_offset = tha_offset + ar_hln;
1509 if ((ar_op == ARPOP_REPLY || ar_op == ARPOP_REQUEST) &&
1510 ARP_HW_IS_ETHER(ar_hrd, ar_hln) &&
1511 ARP_PRO_IS_IPv4(ar_pro, ar_pln)) {
1513 /* inform resolv.c module of the new discovered addresses */
1515 guint32 ip;
1516 const guint8 *mac;
1518 /* Add sender address if sender MAC address is neither a broadcast/
1519 multicast address nor an all-zero address and if sender IP address
1520 isn't all zeroes. */
1521 ip = tvb_get_ipv4(tvb, spa_offset);
1522 mac = tvb_get_ptr(tvb, sha_offset, 6);
1523 if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0)
1525 add_ether_byip(ip, mac);
1526 if (global_arp_detect_duplicate_ip_addresses)
1528 duplicate_detected =
1529 check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
1530 &duplicate_ip);
1534 /* Add target address if target MAC address is neither a broadcast/
1535 multicast address nor an all-zero address and if target IP address
1536 isn't all zeroes. */
1538 /* Do not add target address if the packet is a Request. According to the RFC,
1539 target addresses in requests have no meaning */
1542 ip = tvb_get_ipv4(tvb, tpa_offset);
1543 mac = tvb_get_ptr(tvb, tha_offset, 6);
1544 if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0
1545 && ar_op != ARPOP_REQUEST)
1547 add_ether_byip(ip, mac);
1548 /* If Gratuitous, don't report duplicate for same IP address twice */
1549 if (global_arp_detect_duplicate_ip_addresses && (duplicate_ip!=ip))
1551 duplicate_detected =
1552 check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
1553 &duplicate_ip);
1560 spa_val = tvb_get_ptr(tvb, spa_offset, ar_pln);
1561 tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_pln);
1563 /* ARP requests/replies with the same sender and target protocol
1564 address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
1565 in effect, an announcement that the machine has MAC address
1566 XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
1567 provoke complaints if some other machine has the same IPv4 address,
1568 replies are used to announce relocation of network address, like
1569 in failover solutions. */
1570 if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) && (memcmp(spa_val, tpa_val, ar_pln) == 0))
1571 is_gratuitous = TRUE;
1572 else
1573 is_gratuitous = FALSE;
1575 switch (ar_op) {
1576 case ARPOP_REQUEST:
1577 if (is_gratuitous)
1578 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)",
1579 arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
1580 else
1581 col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
1582 arpproaddr_to_str(tpa_val, ar_pln, ar_pro),
1583 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1584 break;
1585 case ARPOP_REPLY:
1586 if (is_gratuitous)
1587 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)",
1588 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1589 else
1590 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1591 arpproaddr_to_str(spa_val, ar_pln, ar_pro),
1592 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
1593 break;
1594 case ARPOP_RREQUEST:
1595 case ARPOP_IREQUEST:
1596 case ARPOP_DRARPREQUEST:
1597 col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s? Tell %s",
1598 tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
1599 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
1600 break;
1601 case ARPOP_RREPLY:
1602 case ARPOP_DRARPREPLY:
1603 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1604 tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
1605 arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
1606 break;
1608 case ARPOP_DRARPERROR:
1609 col_add_fstr(pinfo->cinfo, COL_INFO, "DRARP Error");
1610 break;
1612 case ARPOP_IREPLY:
1613 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1614 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1615 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1616 break;
1618 case ATMARPOP_NAK:
1619 col_add_fstr(pinfo->cinfo, COL_INFO, "ARP NAK");
1620 break;
1622 case ARPOP_MARS_REQUEST:
1623 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS request from %s at %s",
1624 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1625 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1626 break;
1628 case ARPOP_MARS_MULTI:
1629 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MULTI request from %s at %s",
1630 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1631 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1632 break;
1634 case ARPOP_MARS_MSERV:
1635 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MSERV request from %s at %s",
1636 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1637 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1638 break;
1640 case ARPOP_MARS_JOIN:
1641 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS JOIN request from %s at %s",
1642 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1643 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1644 break;
1646 case ARPOP_MARS_LEAVE:
1647 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS LEAVE from %s at %s",
1648 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1649 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1650 break;
1652 case ARPOP_MARS_NAK:
1653 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS NAK from %s at %s",
1654 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1655 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1656 break;
1658 case ARPOP_MARS_UNSERV:
1659 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS UNSERV request from %s at %s",
1660 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1661 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1662 break;
1664 case ARPOP_MARS_SJOIN:
1665 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SJOIN request from %s at %s",
1666 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1667 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1668 break;
1670 case ARPOP_MARS_SLEAVE:
1671 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SLEAVE from %s at %s",
1672 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1673 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1674 break;
1676 case ARPOP_MARS_GROUPLIST_REQUEST:
1677 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist request from %s at %s",
1678 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1679 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1680 break;
1682 case ARPOP_MARS_GROUPLIST_REPLY:
1683 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist reply from %s at %s",
1684 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1685 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1686 break;
1688 case ARPOP_MARS_REDIRECT_MAP:
1689 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS redirect map from %s at %s",
1690 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1691 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1692 break;
1694 case ARPOP_MAPOS_UNARP:
1695 col_add_fstr(pinfo->cinfo, COL_INFO, "MAPOS UNARP request from %s at %s",
1696 tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
1697 arpproaddr_to_str(spa_val, ar_pln, ar_pro));
1698 break;
1700 case ARPOP_EXP1:
1701 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1702 break;
1704 case ARPOP_EXP2:
1705 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1706 break;
1708 case 0:
1709 case 65535:
1710 col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1711 break;
1713 default:
1714 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1715 break;
1718 if (tree) {
1719 if ((op_str = try_val_to_str(ar_op, op_vals))) {
1720 if (is_gratuitous && (ar_op == ARPOP_REQUEST))
1721 op_str = "request/gratuitous ARP";
1722 if (is_gratuitous && (ar_op == ARPOP_REPLY))
1723 op_str = "reply/gratuitous ARP";
1724 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1725 "Address Resolution Protocol (%s)", op_str);
1726 } else
1727 ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1728 "Address Resolution Protocol (opcode 0x%04x)", ar_op);
1729 arp_tree = proto_item_add_subtree(ti, ett_arp);
1730 proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
1731 proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, AR_PRO, 2, ar_pro);
1732 proto_tree_add_uint(arp_tree, hf_arp_hard_size, tvb, AR_HLN, 1, ar_hln);
1733 proto_tree_add_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ar_pln);
1734 proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ar_op);
1735 if (is_gratuitous)
1737 item = proto_tree_add_boolean(arp_tree, hf_arp_isgratuitous, tvb, 0, 0, is_gratuitous);
1738 PROTO_ITEM_SET_GENERATED(item);
1740 if (ar_hln != 0) {
1741 proto_tree_add_item(arp_tree,
1742 ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1743 hf_arp_src_hw_mac :
1744 hf_arp_src_hw,
1745 tvb, sha_offset, ar_hln, ENC_BIG_ENDIAN);
1747 if (ar_pln != 0) {
1748 proto_tree_add_item(arp_tree,
1749 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
1750 hf_arp_src_proto_ipv4 :
1751 hf_arp_src_proto,
1752 tvb, spa_offset, ar_pln, ENC_BIG_ENDIAN);
1754 if (ar_hln != 0) {
1755 proto_tree_add_item(arp_tree,
1756 ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1757 hf_arp_dst_hw_mac :
1758 hf_arp_dst_hw,
1759 tvb, tha_offset, ar_hln, ENC_BIG_ENDIAN);
1761 if (ar_pln != 0 && ar_op != ARPOP_DRARPERROR) { /*DISPLAYING ERROR NUMBER FOR DRARPERROR*/
1762 proto_tree_add_item(arp_tree,
1763 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
1764 hf_arp_dst_proto_ipv4 :
1765 hf_arp_dst_proto,
1766 tvb, tpa_offset, ar_pln, ENC_BIG_ENDIAN);
1768 else if (ar_pln != 0 && ar_op == ARPOP_DRARPERROR) {
1769 proto_tree_add_item(arp_tree, hf_drarp_error_status, tvb, tpa_offset, 1, ENC_BIG_ENDIAN); /*Adding the first byte of tpa field as drarp_error_status*/
1773 if (global_arp_detect_request_storm)
1775 check_for_storm_count(tvb, pinfo, arp_tree);
1778 if (duplicate_detected)
1780 /* Also indicate in info column */
1781 col_append_fstr(pinfo->cinfo, COL_INFO, " (duplicate use of %s detected!)",
1782 arpproaddr_to_str((guint8*)&duplicate_ip, 4, ETHERTYPE_IP));
1786 void
1787 proto_register_arp(void)
1789 static struct true_false_string tfs_type_bit = { "E.164", "ATM Forum NSAPA" };
1791 static hf_register_info hf[] = {
1792 { &hf_arp_hard_type,
1793 { "Hardware type", "arp.hw.type",
1794 FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0x0,
1795 NULL, HFILL }},
1797 { &hf_arp_proto_type,
1798 { "Protocol type", "arp.proto.type",
1799 FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
1800 NULL, HFILL }},
1802 { &hf_arp_hard_size,
1803 { "Hardware size", "arp.hw.size",
1804 FT_UINT8, BASE_DEC, NULL, 0x0,
1805 NULL, HFILL }},
1807 { &hf_atmarp_sht,
1808 { "Sender ATM number type", "arp.src.htype",
1809 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1810 NULL, HFILL }},
1812 { &hf_atmarp_shl,
1813 { "Sender ATM number length", "arp.src.hlen",
1814 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1815 NULL, HFILL }},
1817 { &hf_atmarp_sst,
1818 { "Sender ATM subaddress type", "arp.src.stype",
1819 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1820 NULL, HFILL }},
1822 { &hf_atmarp_ssl,
1823 { "Sender ATM subaddress length", "arp.src.slen",
1824 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1825 NULL, HFILL }},
1827 { &hf_arp_proto_size,
1828 { "Protocol size", "arp.proto.size",
1829 FT_UINT8, BASE_DEC, NULL, 0x0,
1830 NULL, HFILL }},
1832 { &hf_arp_opcode,
1833 { "Opcode", "arp.opcode",
1834 FT_UINT16, BASE_DEC, VALS(op_vals), 0x0,
1835 NULL, HFILL }},
1837 { &hf_arp_isgratuitous,
1838 { "Is gratuitous", "arp.isgratuitous",
1839 FT_BOOLEAN, BASE_NONE, TFS(&tfs_true_false), 0x0,
1840 NULL, HFILL }},
1842 { &hf_atmarp_spln,
1843 { "Sender protocol size", "arp.src.pln",
1844 FT_UINT8, BASE_DEC, NULL, 0x0,
1845 NULL, HFILL }},
1847 { &hf_atmarp_tht,
1848 { "Target ATM number type", "arp.dst.htype",
1849 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1850 NULL, HFILL }},
1852 { &hf_atmarp_thl,
1853 { "Target ATM number length", "arp.dst.hlen",
1854 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1855 NULL, HFILL }},
1857 { &hf_atmarp_tst,
1858 { "Target ATM subaddress type", "arp.dst.stype",
1859 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1860 NULL, HFILL }},
1862 { &hf_atmarp_tsl,
1863 { "Target ATM subaddress length", "arp.dst.slen",
1864 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1865 NULL, HFILL }},
1867 { &hf_atmarp_tpln,
1868 { "Target protocol size", "arp.dst.pln",
1869 FT_UINT8, BASE_DEC, NULL, 0x0,
1870 NULL, HFILL }},
1872 { &hf_arp_src_hw,
1873 { "Sender hardware address", "arp.src.hw",
1874 FT_BYTES, BASE_NONE, NULL, 0x0,
1875 NULL, HFILL }},
1877 { &hf_arp_src_hw_mac,
1878 { "Sender MAC address", "arp.src.hw_mac",
1879 FT_ETHER, BASE_NONE, NULL, 0x0,
1880 NULL, HFILL }},
1882 { &hf_arp_src_hw_ax25,
1883 { "Sender AX.25 address", "arp.src.hw_ax25",
1884 FT_AX25, BASE_NONE, NULL, 0x0,
1885 NULL, HFILL }},
1887 { &hf_atmarp_src_atm_num_e164,
1888 { "Sender ATM number (E.164)", "arp.src.atm_num_e164",
1889 FT_STRING, BASE_NONE, NULL, 0x0,
1890 NULL, HFILL }},
1892 { &hf_atmarp_src_atm_num_nsap,
1893 { "Sender ATM number (NSAP)", "arp.src.atm_num_nsap",
1894 FT_BYTES, BASE_NONE, NULL, 0x0,
1895 NULL, HFILL }},
1897 { &hf_atmarp_src_atm_subaddr,
1898 { "Sender ATM subaddress", "arp.src.atm_subaddr",
1899 FT_BYTES, BASE_NONE, NULL, 0x0,
1900 NULL, HFILL }},
1902 { &hf_arp_src_proto,
1903 { "Sender protocol address", "arp.src.proto",
1904 FT_BYTES, BASE_NONE, NULL, 0x0,
1905 NULL, HFILL }},
1907 { &hf_arp_src_proto_ipv4,
1908 { "Sender IP address", "arp.src.proto_ipv4",
1909 FT_IPv4, BASE_NONE, NULL, 0x0,
1910 NULL, HFILL }},
1912 { &hf_arp_dst_hw,
1913 { "Target hardware address", "arp.dst.hw",
1914 FT_BYTES, BASE_NONE, NULL, 0x0,
1915 NULL, HFILL }},
1917 { &hf_arp_dst_hw_mac,
1918 { "Target MAC address", "arp.dst.hw_mac",
1919 FT_ETHER, BASE_NONE, NULL, 0x0,
1920 NULL, HFILL }},
1922 { &hf_arp_dst_hw_ax25,
1923 { "Target AX.25 address", "arp.dst.hw_ax25",
1924 FT_AX25, BASE_NONE, NULL, 0x0,
1925 NULL, HFILL }},
1927 { &hf_atmarp_dst_atm_num_e164,
1928 { "Target ATM number (E.164)", "arp.dst.atm_num_e164",
1929 FT_STRING, BASE_NONE, NULL, 0x0,
1930 NULL, HFILL }},
1932 { &hf_atmarp_dst_atm_num_nsap,
1933 { "Target ATM number (NSAP)", "arp.dst.atm_num_nsap",
1934 FT_BYTES, BASE_NONE, NULL, 0x0,
1935 NULL, HFILL }},
1937 { &hf_atmarp_dst_atm_subaddr,
1938 { "Target ATM subaddress", "arp.dst.atm_subaddr",
1939 FT_BYTES, BASE_NONE, NULL, 0x0,
1940 NULL, HFILL }},
1942 { &hf_arp_dst_proto,
1943 { "Target protocol address", "arp.dst.proto",
1944 FT_BYTES, BASE_NONE, NULL, 0x0,
1945 NULL, HFILL }},
1947 { &hf_arp_dst_proto_ipv4,
1948 { "Target IP address", "arp.dst.proto_ipv4",
1949 FT_IPv4, BASE_NONE, NULL, 0x0,
1950 NULL, HFILL }},
1952 { &hf_drarp_error_status,
1953 { "DRARP error status", "arp.dst.drarp_error_status",
1954 FT_UINT16, BASE_DEC, VALS(drarp_status), 0x0,
1955 NULL, HFILL }},
1957 { &hf_arp_duplicate_ip_address_earlier_frame,
1958 { "Frame showing earlier use of IP address", "arp.duplicate-address-frame",
1959 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1960 NULL, HFILL }},
1962 { &hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
1963 { "Seconds since earlier frame seen", "arp.seconds-since-duplicate-address-frame",
1964 FT_UINT32, BASE_DEC, NULL, 0x0,
1965 NULL, HFILL }},
1969 static gint *ett[] = {
1970 &ett_arp,
1971 &ett_atmarp_nsap,
1972 &ett_atmarp_tl,
1973 &ett_arp_duplicate_address
1976 static ei_register_info ei[] = {
1977 { &ei_seq_arp_dup_ip, { "arp.duplicate-address-detected", PI_SEQUENCE, PI_WARN, "Duplicate IP address configured", EXPFILL }},
1978 { &ei_seq_arp_storm, { "arp.packet-storm-detected", PI_SEQUENCE, PI_NOTE, "ARP packet storm detected", EXPFILL }},
1981 module_t *arp_module;
1982 expert_module_t* expert_arp;
1984 proto_arp = proto_register_protocol("Address Resolution Protocol",
1985 "ARP/RARP", "arp");
1986 proto_register_field_array(proto_arp, hf, array_length(hf));
1987 proto_register_subtree_array(ett, array_length(ett));
1989 expert_arp = expert_register_protocol(proto_arp);
1990 expert_register_field_array(expert_arp, ei, array_length(ei));
1992 atmarp_handle = create_dissector_handle(dissect_atmarp, proto_arp);
1993 ax25arp_handle = create_dissector_handle(dissect_ax25arp, proto_arp);
1995 arp_handle = register_dissector( "arp" , dissect_arp, proto_arp );
1997 /* Preferences */
1998 arp_module = prefs_register_protocol(proto_arp, NULL);
2000 prefs_register_bool_preference(arp_module, "detect_request_storms",
2001 "Detect ARP request storms",
2002 "Attempt to detect excessive rate of ARP requests",
2003 &global_arp_detect_request_storm);
2005 prefs_register_uint_preference(arp_module, "detect_storm_number_of_packets",
2006 "Number of requests to detect during period",
2007 "Number of requests needed within period to indicate a storm",
2008 10, &global_arp_detect_request_storm_packets);
2010 prefs_register_uint_preference(arp_module, "detect_storm_period",
2011 "Detection period (in ms)",
2012 "Period in milliseconds during which a packet storm may be detected",
2013 10, &global_arp_detect_request_storm_period);
2015 prefs_register_bool_preference(arp_module, "detect_duplicate_ips",
2016 "Detect duplicate IP address configuration",
2017 "Attempt to detect duplicate use of IP addresses",
2018 &global_arp_detect_duplicate_ip_addresses);
2020 /* TODO: define a minimum time between sightings that is worth reporting? */
2022 register_init_routine(&arp_init_protocol);
2025 void
2026 proto_reg_handoff_arp(void)
2028 dissector_add_uint("ethertype", ETHERTYPE_ARP, arp_handle);
2029 dissector_add_uint("ethertype", ETHERTYPE_REVARP, arp_handle);
2030 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1051, arp_handle);
2031 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1201, arp_handle);
2032 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_RARP_1201, arp_handle);
2033 dissector_add_uint("ax25.pid", AX25_P_ARP, arp_handle);