2 * Routines for ARP packet disassembly (RFC 826)
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.
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 */
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
116 static GHashTable
*address_hash_table
= NULL
;
118 typedef struct address_hash_value
{
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
;
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. */
145 #define ARPOP_REPLY 2 /* ARP reply. */
147 /* Some OSes have different names, or don't define these at all */
148 #ifndef ARPOP_RREQUEST
149 #define ARPOP_RREQUEST 3 /* RARP request. */
152 #define ARPOP_RREPLY 4 /* RARP reply. */
155 /*Additional parameters as per http://www.iana.org/assignments/arp-parameters*/
156 #ifndef ARPOP_DRARPREQUEST
157 #define ARPOP_DRARPREQUEST 5 /* DRARP request. */
160 #ifndef ARPOP_DRARPREPLY
161 #define ARPOP_DRARPREPLY 6 /* DRARP reply. */
164 #ifndef ARPOP_DRARPERROR
165 #define ARPOP_DRARPERROR 7 /* DRARP error. */
168 #ifndef ARPOP_IREQUEST
169 #define ARPOP_IREQUEST 8 /* Inverse ARP (RFC 1293) request. */
172 #define ARPOP_IREPLY 9 /* Inverse ARP reply. */
175 #define ATMARPOP_NAK 10 /* ATMARP NAK. */
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. */
183 #ifndef ARPOP_MARS_MULTI
184 #define ARPOP_MARS_MULTI 12 /*MARS-Multi message. */
187 #ifndef ARPOP_MARS_MSERV
188 #define ARPOP_MARS_MSERV 13 /*MARS-Mserv message. */
191 #ifndef ARPOP_MARS_JOIN
192 #define ARPOP_MARS_JOIN 14 /*MARS-Join request. */
195 #ifndef ARPOP_MARS_LEAVE
196 #define ARPOP_MARS_LEAVE 15 /*MARS Leave request. */
199 #ifndef ARPOP_MARS_NAK
200 #define ARPOP_MARS_NAK 16 /*MARS nak message.*/
203 #ifndef ARPOP_MARS_UNSERV
204 #define ARPOP_MARS_UNSERV 17 /*MARS Unserv message. */
207 #ifndef ARPOP_MARS_SJOIN
208 #define ARPOP_MARS_SJOIN 18 /*MARS Sjoin message. */
211 #ifndef ARPOP_MARS_SLEAVE
212 #define ARPOP_MARS_SLEAVE 19 /*MARS Sleave message. */
215 #ifndef ARPOP_MARS_GROUPLIST_REQUEST
216 #define ARPOP_MARS_GROUPLIST_REQUEST 20 /*MARS Grouplist request message. */
219 #ifndef ARPOP_MARS_GROUPLIST_REPLY
220 #define ARPOP_MARS_GROUPLIST_REPLY 21 /*MARS Grouplist reply message. */
223 #ifndef ARPOP_MARS_REDIRECT_MAP
224 #define ARPOP_MARS_REDIRECT_MAP 22 /*MARS Grouplist request message. */
227 #ifndef ARPOP_MAPOS_UNARP
228 #define ARPOP_MAPOS_UNARP 23 /*MAPOS UNARP*/
232 #define ARPOP_EXP1 24 /* Experimental 1 */
235 #define ARPOP_EXP2 25 /* Experimental 2 */
238 #ifndef ARPOP_RESERVED1
239 #define ARPOP_RESERVED1 0 /*Reserved opcode 1*/
242 #ifndef ARPOP_RESERVED2
243 #define ARPOP_RESERVED2 65535 /*Reserved opcode 2*/
246 #ifndef DRARPERR_RESTRICTED
247 #define DRARPERR_RESTRICTED 1
250 #ifndef DRARPERR_NOADDRESSES
251 #define DRARPERR_NOADDRESSES 2
254 #ifndef DRARPERR_SERVERDOWN
255 #define DRARPERR_SERVERDOWN 3
258 #ifndef DRARPERR_MOVED
259 #define DRARPERR_MOVED 4
262 #ifndef DRARPERR_FAILURE
263 #define DRARPERR_FAILURE 5
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" },
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" },
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" },
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) \
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
356 #define ARP_PRO_IS_IPv4(ar_pro, ar_pln) \
357 (((ar_pro) == ETHERTYPE_IP || (ar_pro) == AX25_P_IP) && (ar_pln) == 4)
360 tvb_arphrdaddr_to_str(tvbuff_t
*tvb
, gint offset
, int ad_len
, guint16 type
)
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
367 return tvb_ether_to_str(tvb
, offset
);
369 return tvb_bytes_to_str(tvb
, offset
, ad_len
);
373 arpproaddr_to_str(const guint8
*ad
, int ad_len
, guint16 type
)
376 return "<No address>";
377 if (ARP_PRO_IS_IPv4(type
, ad_len
)) {
379 return ip_to_str(ad
);
381 if (ARP_HW_IS_AX25(type
, ad_len
)) {
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
392 atmarpnum_to_str(const guint8
*ad
, int ad_tl
)
394 int ad_len
= ad_tl
& ATMARP_LEN_MASK
;
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, "...");
410 memcpy(cur
, ad
, ad_len
);
411 cur
[ad_len
+ 1] = '\0';
418 * XXX - break down into subcomponents.
420 return bytes_to_str(ad
, ad_len
);
425 atmarpsubaddr_to_str(const guint8
*ad
, int ad_tl
)
427 int ad_len
= ad_tl
& ATMARP_LEN_MASK
;
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
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" },
486 /* Offsets of fields within an ARP packet. */
492 #define MIN_ARP_HEADER_SIZE 8
494 /* Offsets of fields within an ATMARP packet. */
497 #define ATM_AR_SHTL 4
498 #define ATM_AR_SSTL 5
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
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
;
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
);
517 ti
= proto_tree_add_item(tree
, hf_nsap
, tvb
, offset
, len
, ENC_BIG_ENDIAN
);
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.
531 dissect_atm_nsap(tvbuff_t
*tvb
, int offset
, int len
, proto_tree
*tree
)
535 afi
= tvb_get_guint8(tvb
, offset
);
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));
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));
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,
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));
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));
596 /* l.s. 32 bits are ipv4 address */
598 address_hash_func(gconstpointer v
)
600 return GPOINTER_TO_UINT(v
);
603 /* Compare 2 ipv4 addresses */
605 address_equal_func(gconstpointer v
, gconstpointer v2
)
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
);
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) */
632 check_for_duplicate_addresses(packet_info
*pinfo
, proto_tree
*tree
,
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
,
647 /* First time around, need to work out if represents duplicate and
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 */
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
;
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
);
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
;
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
;
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
),
699 ether_to_str(result
->mac
),
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
,
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
,
717 (guint32
)(pinfo
->fd
->abs_ts
.secs
- result
->time_of_entry
));
718 PROTO_ITEM_SET_GENERATED(ti
);
720 /* Set out parameter */
725 return (result
!= NULL
);
730 /* Initializes the hash table each time a new
731 * file is loaded or re-loaded in wireshark */
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 */
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)
764 /* Has storm request rate been exceeded with this request? */
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
);
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
) ||
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
);
793 if (arp_request_count
> global_arp_detect_request_storm_packets
)
795 /* Storm detected, record and reset start time. */
797 p_add_proto_data(pinfo
->fd
, proto_arp
, 0, (void*)STORM
);
798 time_at_start_of_count
= pinfo
->fd
->abs_ts
;
802 /* Threshold not exceeded yet - no storm */
803 p_add_proto_data(pinfo
->fd
, proto_arp
, 0, (void*)NO_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
,
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.
829 dissect_atmarp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
845 proto_tree
*arp_tree
;
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
;
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
880 tvb_set_reported_length(tvb
, tot_len
);
882 /* Extract the addresses. */
883 sha_offset
= MIN_ATMARP_HEADER_SIZE
;
885 sha_val
= tvb_get_ptr(tvb
, sha_offset
, ar_shl
);
886 sha_str
= atmarpnum_to_str(sha_val
, ar_shtl
);
889 sha_str
= "<No address>";
892 ssa_offset
= sha_offset
+ ar_shl
;
894 ssa_val
= tvb_get_ptr(tvb
, ssa_offset
, ar_ssl
);
895 ssa_str
= atmarpsubaddr_to_str(ssa_val
, ar_sstl
);
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
;
907 tha_val
= tvb_get_ptr(tvb
, tha_offset
, ar_thl
);
908 tha_str
= atmarpnum_to_str(tha_val
, ar_thtl
);
911 tha_str
= "<No address>";
914 tsa_offset
= tha_offset
+ ar_thl
;
916 tsa_val
= tvb_get_ptr(tvb
, tsa_offset
, ar_tsl
);
917 tsa_str
= atmarpsubaddr_to_str(tsa_val
, ar_tstl
);
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
);
933 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATMARP");
938 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATMRARP");
943 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ATMARP");
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
:
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");
961 case ARPOP_MAPOS_UNARP
:
962 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MAPOS");
969 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who has %s? Tell %s",
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
: ""));
978 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who is %s%s%s? Tell %s%s%s",
980 ((tsa_str
!= NULL
) ? "," : ""),
981 ((tsa_str
!= NULL
) ? tsa_str
: ""),
983 ((ssa_str
!= NULL
) ? "," : ""),
984 ((ssa_str
!= NULL
) ? ssa_str
: ""));
987 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s%s%s is at %s",
989 ((ssa_str
!= NULL
) ? "," : ""),
990 ((ssa_str
!= NULL
) ? ssa_str
: ""),
994 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "I don't know where %s is", spa_str
);
996 case ARPOP_MARS_REQUEST
:
997 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS request from %s%s%s at %s",
999 ((ssa_str
!= NULL
) ? "," : ""),
1000 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1004 case ARPOP_MARS_MULTI
:
1005 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MULTI request from %s%s%s at %s",
1007 ((ssa_str
!= NULL
) ? "," : ""),
1008 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1012 case ARPOP_MARS_MSERV
:
1013 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MSERV request from %s%s%s at %s",
1015 ((ssa_str
!= NULL
) ? "," : ""),
1016 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1020 case ARPOP_MARS_JOIN
:
1021 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS JOIN request from %s%s%s at %s",
1023 ((ssa_str
!= NULL
) ? "," : ""),
1024 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1028 case ARPOP_MARS_LEAVE
:
1029 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS LEAVE from %s%s%s at %s",
1031 ((ssa_str
!= NULL
) ? "," : ""),
1032 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1036 case ARPOP_MARS_NAK
:
1037 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS NAK from %s%s%s at %s",
1039 ((ssa_str
!= NULL
) ? "," : ""),
1040 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1044 case ARPOP_MARS_UNSERV
:
1045 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS UNSERV request from %s%s%s at %s",
1047 ((ssa_str
!= NULL
) ? "," : ""),
1048 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1052 case ARPOP_MARS_SJOIN
:
1053 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SJOIN request from %s%s%s at %s",
1055 ((ssa_str
!= NULL
) ? "," : ""),
1056 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1060 case ARPOP_MARS_SLEAVE
:
1061 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SLEAVE from %s%s%s at %s",
1063 ((ssa_str
!= NULL
) ? "," : ""),
1064 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1068 case ARPOP_MARS_GROUPLIST_REQUEST
:
1069 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist request from %s%s%s at %s",
1071 ((ssa_str
!= NULL
) ? "," : ""),
1072 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1076 case ARPOP_MARS_GROUPLIST_REPLY
:
1077 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist reply from %s%s%s at %s",
1079 ((ssa_str
!= NULL
) ? "," : ""),
1080 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1084 case ARPOP_MARS_REDIRECT_MAP
:
1085 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS redirect map from %s%s%s at %s",
1087 ((ssa_str
!= NULL
) ? "," : ""),
1088 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1092 case ARPOP_MAPOS_UNARP
:
1093 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MAPOS UNARP request from %s%s%s at %s",
1095 ((ssa_str
!= NULL
) ? "," : ""),
1096 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1101 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 1 ( opcode %d )", ar_op
);
1105 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 2 ( opcode %d )", ar_op
);
1110 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reserved opcode %d", ar_op
);
1114 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ATMARP opcode 0x%04x", ar_op
);
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)",
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
?
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
?
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
?
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
?
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
);
1180 dissect_atm_number(tvb
, sha_offset
, ar_shtl
, hf_atmarp_src_atm_num_e164
,
1181 hf_atmarp_src_atm_num_nsap
, arp_tree
);
1184 proto_tree_add_bytes_format_value(arp_tree
, hf_atmarp_src_atm_subaddr
, tvb
, ssa_offset
,
1190 proto_tree_add_item(arp_tree
,
1191 ARP_PRO_IS_IPv4(ar_pro
, ar_spln
) ? hf_arp_src_proto_ipv4
1193 tvb
, spa_offset
, ar_spln
, ENC_BIG_ENDIAN
);
1197 dissect_atm_number(tvb
, tha_offset
, ar_thtl
, hf_atmarp_dst_atm_num_e164
,
1198 hf_atmarp_dst_atm_num_nsap
, arp_tree
);
1201 proto_tree_add_bytes_format_value(arp_tree
, hf_atmarp_dst_atm_subaddr
, tvb
, tsa_offset
,
1207 proto_tree_add_item(arp_tree
,
1208 ARP_PRO_IS_IPv4(ar_pro
, ar_tpln
) ? hf_arp_dst_proto_ipv4
1210 tvb
, tpa_offset
, ar_tpln
, ENC_BIG_ENDIAN
);
1216 * AX.25 ARP - it's just like ARP, except where it isn't.
1219 dissect_ax25arp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1221 #define ARP_AX25 204
1229 proto_tree
*arp_tree
= NULL
;
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
);
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
1252 tvb_set_reported_length(tvb
, tot_len
);
1257 if (global_arp_detect_request_storm
)
1258 request_seen(pinfo
);
1262 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ARP");
1265 case ARPOP_RREQUEST
:
1267 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RARP");
1270 case ARPOP_IREQUEST
:
1272 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ARP");
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
;
1301 is_gratuitous
= FALSE
;
1306 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Request)",
1307 arpproaddr_to_str(tpa_val
, ar_pln
, ar_pro
));
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
));
1315 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Reply)",
1316 arpproaddr_to_str(spa_val
, ar_pln
, ar_pro
));
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
));
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
));
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
));
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
));
1344 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ARP opcode 0x%04x", ar_op
);
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
);
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
);
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
);
1371 proto_tree_add_item(arp_tree
,
1372 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ? hf_arp_src_proto_ipv4
1374 tvb
, spa_offset
, ar_pln
, FALSE
);
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
);
1382 proto_tree_add_item(arp_tree
,
1383 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ? hf_arp_dst_proto_ipv4
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 };
1398 dissect_arp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
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
);
1430 if (ar_hrd
== ARPHRD_AX25
) {
1431 call_dissector(ax25arp_handle
, tvb
, pinfo
, tree
);
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
);
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
1448 tvb_set_reported_length(tvb
, tot_len
);
1453 if (global_arp_detect_request_storm
)
1455 request_seen(pinfo
);
1460 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ARP");
1463 case ARPOP_RREQUEST
:
1465 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RARP");
1468 case ARPOP_DRARPREQUEST
:
1469 case ARPOP_DRARPREPLY
:
1470 case ARPOP_DRARPERROR
:
1471 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DRARP");
1474 case ARPOP_IREQUEST
:
1476 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ARP");
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");
1494 case ARPOP_MAPOS_UNARP
:
1495 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MAPOS");
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 */
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
,
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
,
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
;
1573 is_gratuitous
= FALSE
;
1578 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Request)",
1579 arpproaddr_to_str(tpa_val
, ar_pln
, ar_pro
));
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
));
1587 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Reply)",
1588 arpproaddr_to_str(spa_val
, ar_pln
, ar_pro
));
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
));
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
));
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
));
1608 case ARPOP_DRARPERROR
:
1609 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "DRARP Error");
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
));
1619 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "ARP NAK");
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
1701 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 1 ( opcode %d )", ar_op
);
1705 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 2 ( opcode %d )", ar_op
);
1710 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reserved opcode %d", ar_op
);
1714 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ARP opcode 0x%04x", ar_op
);
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
);
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
);
1737 item
= proto_tree_add_boolean(arp_tree
, hf_arp_isgratuitous
, tvb
, 0, 0, is_gratuitous
);
1738 PROTO_ITEM_SET_GENERATED(item
);
1741 proto_tree_add_item(arp_tree
,
1742 ARP_HW_IS_ETHER(ar_hrd
, ar_hln
) ?
1745 tvb
, sha_offset
, ar_hln
, ENC_BIG_ENDIAN
);
1748 proto_tree_add_item(arp_tree
,
1749 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ?
1750 hf_arp_src_proto_ipv4
:
1752 tvb
, spa_offset
, ar_pln
, ENC_BIG_ENDIAN
);
1755 proto_tree_add_item(arp_tree
,
1756 ARP_HW_IS_ETHER(ar_hrd
, ar_hln
) ?
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
:
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
));
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,
1797 { &hf_arp_proto_type
,
1798 { "Protocol type", "arp.proto.type",
1799 FT_UINT16
, BASE_HEX
, VALS(etype_vals
), 0x0,
1802 { &hf_arp_hard_size
,
1803 { "Hardware size", "arp.hw.size",
1804 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1808 { "Sender ATM number type", "arp.src.htype",
1809 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1813 { "Sender ATM number length", "arp.src.hlen",
1814 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1818 { "Sender ATM subaddress type", "arp.src.stype",
1819 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1823 { "Sender ATM subaddress length", "arp.src.slen",
1824 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1827 { &hf_arp_proto_size
,
1828 { "Protocol size", "arp.proto.size",
1829 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1833 { "Opcode", "arp.opcode",
1834 FT_UINT16
, BASE_DEC
, VALS(op_vals
), 0x0,
1837 { &hf_arp_isgratuitous
,
1838 { "Is gratuitous", "arp.isgratuitous",
1839 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_true_false
), 0x0,
1843 { "Sender protocol size", "arp.src.pln",
1844 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1848 { "Target ATM number type", "arp.dst.htype",
1849 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1853 { "Target ATM number length", "arp.dst.hlen",
1854 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1858 { "Target ATM subaddress type", "arp.dst.stype",
1859 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1863 { "Target ATM subaddress length", "arp.dst.slen",
1864 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1868 { "Target protocol size", "arp.dst.pln",
1869 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1873 { "Sender hardware address", "arp.src.hw",
1874 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1877 { &hf_arp_src_hw_mac
,
1878 { "Sender MAC address", "arp.src.hw_mac",
1879 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1882 { &hf_arp_src_hw_ax25
,
1883 { "Sender AX.25 address", "arp.src.hw_ax25",
1884 FT_AX25
, BASE_NONE
, NULL
, 0x0,
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,
1892 { &hf_atmarp_src_atm_num_nsap
,
1893 { "Sender ATM number (NSAP)", "arp.src.atm_num_nsap",
1894 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1897 { &hf_atmarp_src_atm_subaddr
,
1898 { "Sender ATM subaddress", "arp.src.atm_subaddr",
1899 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1902 { &hf_arp_src_proto
,
1903 { "Sender protocol address", "arp.src.proto",
1904 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1907 { &hf_arp_src_proto_ipv4
,
1908 { "Sender IP address", "arp.src.proto_ipv4",
1909 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1913 { "Target hardware address", "arp.dst.hw",
1914 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1917 { &hf_arp_dst_hw_mac
,
1918 { "Target MAC address", "arp.dst.hw_mac",
1919 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1922 { &hf_arp_dst_hw_ax25
,
1923 { "Target AX.25 address", "arp.dst.hw_ax25",
1924 FT_AX25
, BASE_NONE
, NULL
, 0x0,
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,
1932 { &hf_atmarp_dst_atm_num_nsap
,
1933 { "Target ATM number (NSAP)", "arp.dst.atm_num_nsap",
1934 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1937 { &hf_atmarp_dst_atm_subaddr
,
1938 { "Target ATM subaddress", "arp.dst.atm_subaddr",
1939 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1942 { &hf_arp_dst_proto
,
1943 { "Target protocol address", "arp.dst.proto",
1944 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1947 { &hf_arp_dst_proto_ipv4
,
1948 { "Target IP address", "arp.dst.proto_ipv4",
1949 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1952 { &hf_drarp_error_status
,
1953 { "DRARP error status", "arp.dst.drarp_error_status",
1954 FT_UINT16
, BASE_DEC
, VALS(drarp_status
), 0x0,
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,
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,
1969 static gint
*ett
[] = {
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",
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
);
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
);
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
);