2 * Routines for ARP packet disassembly (RFC 826)
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * By Deepti Ragha <dlragha@ncsu.edu>
9 * Copyright 2012 Deepti Ragha
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/capture_dissectors.h>
18 #include <epan/arptypes.h>
19 #include <epan/addr_resolv.h>
20 #include "packet-arp.h"
21 #include <epan/etypes.h>
22 #include <epan/arcnet_pids.h>
23 #include <epan/ax25_pids.h>
24 #include <epan/osi-utils.h>
25 #include <epan/prefs.h>
26 #include <epan/expert.h>
27 #include <epan/proto_data.h>
30 void proto_register_arp(void);
31 void proto_reg_handoff_arp(void);
34 static int hf_arp_hard_type
;
35 static int hf_arp_proto_type
;
36 static int hf_arp_hard_size
;
37 static int hf_atmarp_sht
;
38 static int hf_atmarp_shl
;
39 static int hf_atmarp_sst
;
40 static int hf_atmarp_ssl
;
41 static int hf_arp_proto_size
;
42 static int hf_arp_opcode
;
43 static int hf_arp_isgratuitous
;
44 static int hf_arp_isprobe
;
45 static int hf_arp_isannouncement
;
47 static int proto_atmarp
;
48 static int hf_atmarp_spln
;
49 static int hf_atmarp_tht
;
50 static int hf_atmarp_thl
;
51 static int hf_atmarp_tst
;
52 static int hf_atmarp_tsl
;
53 static int hf_atmarp_tpln
;
54 static int hf_arp_src_hw
;
55 static int hf_arp_src_hw_mac
;
56 static int hf_arp_src_proto
;
57 static int hf_arp_src_proto_ipv4
;
58 static int hf_arp_dst_hw
;
59 static int hf_arp_dst_hw_mac
;
60 static int hf_arp_dst_proto
;
61 static int hf_arp_dst_proto_ipv4
;
62 static int hf_drarp_error_status
;
63 static int hf_arp_duplicate_ip_address_earlier_frame
;
64 static int hf_arp_duplicate_ip_address_seconds_since_earlier_frame
;
66 static int hf_atmarp_src_atm_num_e164
;
67 static int hf_atmarp_src_atm_num_nsap
;
68 static int hf_atmarp_src_atm_subaddr
;
69 static int hf_atmarp_dst_atm_num_e164
;
70 static int hf_atmarp_dst_atm_num_nsap
;
71 static int hf_atmarp_dst_atm_subaddr
;
72 /* Generated from convert_proto_tree_add_text.pl */
73 static int hf_atmarp_src_atm_data_country_code
;
74 static int hf_atmarp_src_atm_data_country_code_group
;
75 static int hf_atmarp_src_atm_e_164_isdn
;
76 static int hf_atmarp_src_atm_e_164_isdn_group
;
77 static int hf_atmarp_src_atm_rest_of_address
;
78 static int hf_atmarp_src_atm_end_system_identifier
;
79 static int hf_atmarp_src_atm_high_order_dsp
;
80 static int hf_atmarp_src_atm_selector
;
81 static int hf_atmarp_src_atm_international_code_designator
;
82 static int hf_atmarp_src_atm_international_code_designator_group
;
83 static int hf_atmarp_src_atm_afi
;
85 static int hf_arp_dst_hw_ax25
;
86 static int hf_arp_src_hw_ax25
;
89 static int ett_atmarp_nsap
;
90 static int ett_atmarp_tl
;
91 static int ett_arp_duplicate_address
;
93 static expert_field ei_seq_arp_dup_ip
;
94 static expert_field ei_seq_arp_storm
;
95 static expert_field ei_atmarp_src_atm_unknown_afi
;
97 static dissector_handle_t arp_handle
;
99 static dissector_table_t arp_hw_table
;
101 static capture_dissector_handle_t arp_cap_handle
;
103 /* Used for determining if frequency of ARP requests constitute a storm */
107 /* Preference settings */
108 static bool global_arp_detect_request_storm
;
109 static uint32_t global_arp_detect_request_storm_packets
= 30;
110 static uint32_t global_arp_detect_request_storm_period
= 100;
112 static bool global_arp_detect_duplicate_ip_addresses
= true;
113 static bool global_arp_register_network_address_binding
= true;
115 static uint32_t arp_request_count
;
116 static nstime_t time_at_start_of_count
;
119 /* Map of (IP address -> MAC address) to detect duplicate IP addresses
121 static wmem_map_t
*address_hash_table
;
123 typedef struct address_hash_value
{
126 time_t time_of_entry
;
127 } address_hash_value
;
129 /* Map of ((frame Num, IP address) -> MAC address) */
130 static wmem_map_t
*duplicate_result_hash_table
;
132 typedef struct duplicate_result_key
{
133 uint32_t frame_number
;
135 } duplicate_result_key
;
138 /* Definitions taken from Linux "linux/if_arp.h" header file, and from
140 http://www.iana.org/assignments/arp-parameters
145 /* ARP / RARP structs and definitions */
146 #ifndef ARPOP_REQUEST
147 #define ARPOP_REQUEST 1 /* ARP request. */
150 #define ARPOP_REPLY 2 /* ARP reply. */
152 /* Some OSes have different names, or don't define these at all */
153 #ifndef ARPOP_RREQUEST
154 #define ARPOP_RREQUEST 3 /* RARP request. */
157 #define ARPOP_RREPLY 4 /* RARP reply. */
160 /* Additional parameters as per https://www.iana.org/assignments/arp-parameters */
161 #ifndef ARPOP_DRARPREQUEST
162 #define ARPOP_DRARPREQUEST 5 /* DRARP request. */
165 #ifndef ARPOP_DRARPREPLY
166 #define ARPOP_DRARPREPLY 6 /* DRARP reply. */
169 #ifndef ARPOP_DRARPERROR
170 #define ARPOP_DRARPERROR 7 /* DRARP error. */
173 #ifndef ARPOP_IREQUEST
174 #define ARPOP_IREQUEST 8 /* Inverse ARP (RFC 1293) request. */
177 #define ARPOP_IREPLY 9 /* Inverse ARP reply. */
180 #define ATMARPOP_NAK 10 /* ATMARP NAK. */
183 /* Additional parameters as per https://www.iana.org/assignments/arp-parameters */
184 #ifndef ARPOP_MARS_REQUEST
185 #define ARPOP_MARS_REQUEST 11 /*MARS request message. */
188 #ifndef ARPOP_MARS_MULTI
189 #define ARPOP_MARS_MULTI 12 /*MARS-Multi message. */
192 #ifndef ARPOP_MARS_MSERV
193 #define ARPOP_MARS_MSERV 13 /*MARS-Mserv message. */
196 #ifndef ARPOP_MARS_JOIN
197 #define ARPOP_MARS_JOIN 14 /*MARS-Join request. */
200 #ifndef ARPOP_MARS_LEAVE
201 #define ARPOP_MARS_LEAVE 15 /*MARS Leave request. */
204 #ifndef ARPOP_MARS_NAK
205 #define ARPOP_MARS_NAK 16 /*MARS nak message.*/
208 #ifndef ARPOP_MARS_UNSERV
209 #define ARPOP_MARS_UNSERV 17 /*MARS Unserv message. */
212 #ifndef ARPOP_MARS_SJOIN
213 #define ARPOP_MARS_SJOIN 18 /*MARS Sjoin message. */
216 #ifndef ARPOP_MARS_SLEAVE
217 #define ARPOP_MARS_SLEAVE 19 /*MARS Sleave message. */
220 #ifndef ARPOP_MARS_GROUPLIST_REQUEST
221 #define ARPOP_MARS_GROUPLIST_REQUEST 20 /*MARS Grouplist request message. */
224 #ifndef ARPOP_MARS_GROUPLIST_REPLY
225 #define ARPOP_MARS_GROUPLIST_REPLY 21 /*MARS Grouplist reply message. */
228 #ifndef ARPOP_MARS_REDIRECT_MAP
229 #define ARPOP_MARS_REDIRECT_MAP 22 /*MARS Grouplist request message. */
232 #ifndef ARPOP_MAPOS_UNARP
233 #define ARPOP_MAPOS_UNARP 23 /*MAPOS UNARP*/
237 #define ARPOP_EXP1 24 /* Experimental 1 */
240 #define ARPOP_EXP2 25 /* Experimental 2 */
243 #ifndef ARPOP_RESERVED1
244 #define ARPOP_RESERVED1 0 /*Reserved opcode 1*/
247 #ifndef ARPOP_RESERVED2
248 #define ARPOP_RESERVED2 65535 /*Reserved opcode 2*/
251 #ifndef DRARPERR_RESTRICTED
252 #define DRARPERR_RESTRICTED 1
255 #ifndef DRARPERR_NOADDRESSES
256 #define DRARPERR_NOADDRESSES 2
259 #ifndef DRARPERR_SERVERDOWN
260 #define DRARPERR_SERVERDOWN 3
263 #ifndef DRARPERR_MOVED
264 #define DRARPERR_MOVED 4
267 #ifndef DRARPERR_FAILURE
268 #define DRARPERR_FAILURE 5
273 static const value_string op_vals
[] = {
274 {ARPOP_REQUEST
, "request" },
275 {ARPOP_REPLY
, "reply" },
276 {ARPOP_RREQUEST
, "reverse request" },
277 {ARPOP_RREPLY
, "reverse reply" },
278 {ARPOP_DRARPREQUEST
, "drarp request" },
279 {ARPOP_DRARPREPLY
, "drarp reply" },
280 {ARPOP_DRARPERROR
, "drarp error" },
281 {ARPOP_IREQUEST
, "inverse request" },
282 {ARPOP_IREPLY
, "inverse reply" },
283 {ATMARPOP_NAK
, "arp nak" },
284 {ARPOP_MARS_REQUEST
, "mars request" },
285 {ARPOP_MARS_MULTI
, "mars multi" },
286 {ARPOP_MARS_MSERV
, "mars mserv" },
287 {ARPOP_MARS_JOIN
, "mars join" },
288 {ARPOP_MARS_LEAVE
, "mars leave" },
289 {ARPOP_MARS_NAK
, "mars nak" },
290 {ARPOP_MARS_UNSERV
, "mars unserv" },
291 {ARPOP_MARS_SJOIN
, "mars sjoin" },
292 {ARPOP_MARS_SLEAVE
, "mars sleave" },
293 {ARPOP_MARS_GROUPLIST_REQUEST
, "mars grouplist request" },
294 {ARPOP_MARS_GROUPLIST_REPLY
, "mars grouplist reply" },
295 {ARPOP_MARS_REDIRECT_MAP
, "mars redirect map" },
296 {ARPOP_MAPOS_UNARP
, "mapos unarp" },
297 {ARPOP_EXP1
, "experimental 1" },
298 {ARPOP_EXP2
, "experimental 2" },
299 {ARPOP_RESERVED1
, "reserved" },
300 {ARPOP_RESERVED2
, "reserved" },
303 static const value_string drarp_status
[]={
304 {DRARPERR_RESTRICTED
, "restricted" },
305 {DRARPERR_NOADDRESSES
, "no address" },
306 {DRARPERR_SERVERDOWN
, "serverdown" },
307 {DRARPERR_MOVED
, "moved" },
308 {DRARPERR_FAILURE
, "failure" },
311 static const value_string atmop_vals
[] = {
312 {ARPOP_REQUEST
, "request" },
313 {ARPOP_REPLY
, "reply" },
314 {ARPOP_IREQUEST
, "inverse request" },
315 {ARPOP_IREPLY
, "inverse reply" },
316 {ATMARPOP_NAK
, "nak" },
317 {ARPOP_MARS_REQUEST
, "mars request" },
318 {ARPOP_MARS_MULTI
, "mars multi" },
319 {ARPOP_MARS_MSERV
, "mars mserv" },
320 {ARPOP_MARS_JOIN
, "mars join" },
321 {ARPOP_MARS_LEAVE
, "mars leave" },
322 {ARPOP_MARS_NAK
, "mars nak" },
323 {ARPOP_MARS_UNSERV
, "mars unserv" },
324 {ARPOP_MARS_SJOIN
, "mars sjoin" },
325 {ARPOP_MARS_SLEAVE
, "mars sleave" },
326 {ARPOP_MARS_GROUPLIST_REQUEST
, "mars grouplist request" },
327 {ARPOP_MARS_GROUPLIST_REPLY
, "mars grouplist reply" },
328 {ARPOP_MARS_REDIRECT_MAP
, "mars redirect map" },
329 {ARPOP_MAPOS_UNARP
, "mapos unarp" },
330 {ARPOP_EXP1
, "experimental 1" },
331 {ARPOP_EXP2
, "experimental 2" },
332 {ARPOP_RESERVED1
, "reserved" },
333 {ARPOP_RESERVED2
, "reserved" },
336 #define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */
337 #define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */
340 * Given the hardware address type and length, check whether an address
341 * is an Ethernet address - the address must be of type "Ethernet" or
342 * "IEEE 802.x", and the length must be 6 bytes.
344 #define ARP_HW_IS_ETHER(ar_hrd, ar_hln) \
345 (((ar_hrd) == ARPHRD_ETHER || (ar_hrd) == ARPHRD_IEEE802) \
349 * Given the hardware address type and length, check whether an address
350 * is an AX.25 address - the address must be of type "AX.25" and the
351 * length must be 7 bytes.
353 #define ARP_HW_IS_AX25(ar_hrd, ar_hln) \
354 ((ar_hrd) == ARPHRD_AX25 && (ar_hln) == 7)
357 * Given the protocol address type and length, check whether an address
358 * is an IPv4 address - the address must be of type "IP", and the length
361 #define ARP_PRO_IS_IPv4(ar_pro, ar_pln) \
362 (((ar_pro) == ETHERTYPE_IP || (ar_pro) == AX25_P_IP) && (ar_pln) == 4)
365 tvb_arphrdaddr_to_str(wmem_allocator_t
*scope
, tvbuff_t
*tvb
, int offset
, int ad_len
, uint16_t type
)
368 return "<No address>";
369 if (ARP_HW_IS_ETHER(type
, ad_len
)) {
370 /* Ethernet address (or IEEE 802.x address, which is the same type of
372 return tvb_ether_to_str(scope
, tvb
, offset
);
374 return tvb_bytes_to_str(scope
, tvb
, offset
, ad_len
);
378 arpproaddr_to_str(wmem_allocator_t
*scope
, const uint8_t *ad
, int ad_len
, uint16_t type
)
383 return "<No address>";
384 if (ARP_PRO_IS_IPv4(type
, ad_len
)) {
386 set_address(&addr
, AT_IPv4
, 4, ad
);
388 return address_to_str(scope
, &addr
);
390 if (ARP_HW_IS_AX25(type
, ad_len
)) {
393 set_address(&addr
, AT_AX25
, AX25_ADDR_LEN
, ad
);
395 return address_to_str(scope
, &addr
);
398 return bytes_to_str(scope
, ad
, ad_len
);
402 tvb_arpproaddr_to_str(wmem_allocator_t
*scope
, tvbuff_t
*tvb
, int offset
, int ad_len
, uint16_t type
)
404 const uint8_t *ad
= tvb_memdup(scope
, tvb
, offset
, ad_len
);
405 return arpproaddr_to_str(scope
, ad
, ad_len
, type
);
409 atmarpnum_to_str(wmem_allocator_t
*scope
, tvbuff_t
*tvb
, int offset
, int ad_tl
)
411 int ad_len
= ad_tl
& ATMARP_LEN_MASK
;
414 return "<No address>";
416 if (ad_tl
& ATMARP_IS_E164
) {
418 * I'm assuming this means it's an ASCII (IA5) string.
420 return (char *) tvb_get_string_enc(scope
, tvb
, offset
, ad_len
, ENC_ASCII
|ENC_NA
);
425 * XXX - break down into subcomponents.
427 return tvb_bytes_to_str(scope
, tvb
, offset
, ad_len
);
432 atmarpsubaddr_to_str(wmem_allocator_t
*scope
, tvbuff_t
*tvb
, int offset
, int ad_tl
)
434 int ad_len
= ad_tl
& ATMARP_LEN_MASK
;
437 return "<No address>";
440 * E.164 isn't considered legal in subaddresses (RFC 2225 says that
441 * a null or unknown ATM address is indicated by setting the length
442 * to 0, in which case the type must be ignored; we've seen some
443 * captures in which the length of a subaddress is 0 and the type
446 * XXX - break down into subcomponents?
448 return tvb_bytes_to_str(scope
, tvb
, offset
, ad_len
);
451 const value_string arp_hrd_vals
[] = {
452 {ARPHRD_NETROM
, "NET/ROM pseudo" },
453 {ARPHRD_ETHER
, "Ethernet" },
454 {ARPHRD_EETHER
, "Experimental Ethernet" },
455 {ARPHRD_AX25
, "AX.25" },
456 {ARPHRD_PRONET
, "ProNET" },
457 {ARPHRD_CHAOS
, "Chaos" },
458 {ARPHRD_IEEE802
, "IEEE 802" },
459 {ARPHRD_ARCNET
, "ARCNET" },
460 {ARPHRD_HYPERCH
, "Hyperchannel" },
461 {ARPHRD_LANSTAR
, "Lanstar" },
462 {ARPHRD_AUTONET
, "Autonet Short Address" },
463 {ARPHRD_LOCALTLK
, "Localtalk" },
464 {ARPHRD_LOCALNET
, "LocalNet" },
465 {ARPHRD_ULTRALNK
, "Ultra link" },
466 {ARPHRD_SMDS
, "SMDS" },
467 {ARPHRD_DLCI
, "Frame Relay DLCI" },
468 {ARPHRD_ATM
, "ATM" },
469 {ARPHRD_HDLC
, "HDLC" },
470 {ARPHRD_FIBREC
, "Fibre Channel" },
471 {ARPHRD_ATM2225
, "ATM (RFC 2225)" },
472 {ARPHRD_SERIAL
, "Serial Line" },
473 {ARPHRD_ATM2
, "ATM" },
474 {ARPHRD_MS188220
, "MIL-STD-188-220" },
475 {ARPHRD_METRICOM
, "Metricom STRIP" },
476 {ARPHRD_IEEE1394
, "IEEE 1394.1995" },
477 {ARPHRD_MAPOS
, "MAPOS" },
478 {ARPHRD_TWINAX
, "Twinaxial" },
479 {ARPHRD_EUI_64
, "EUI-64" },
480 {ARPHRD_HIPARP
, "HIPARP" },
481 {ARPHRD_IP_ARP_ISO_7816_3
, "IP and ARP over ISO 7816-3" },
482 {ARPHRD_ARPSEC
, "ARPSec" },
483 {ARPHRD_IPSEC_TUNNEL
, "IPsec tunnel" },
484 {ARPHRD_INFINIBAND
, "InfiniBand" },
485 {ARPHRD_TIA_102_PRJ_25_CAI
, "TIA-102 Project 25 CAI" },
486 {ARPHRD_WIEGAND_INTERFACE
, "Wiegand Interface" },
487 {ARPHRD_PURE_IP
, "Pure IP" },
488 {ARPHRD_HW_EXP1
, "Experimental 1" },
489 {ARPHRD_HFI
, "HFI" },
490 {ARPHRD_UB
, "Unified Bus" },
491 {ARPHRD_HW_EXP2
, "Experimental 2" },
492 {ARPHRD_AETHERNET
, "AEthernet" },
493 /* Virtual ARP types for non ARP hardware used in Linux cooked mode. */
494 {ARPHRD_RSRVD
, "Notional KISS type" },
495 {ARPHRD_ADAPT
, "ADAPT" },
496 {ARPHRD_ROSE
, "ROSE" },
497 {ARPHRD_X25
, "CCITT X.25" },
498 {ARPHRD_HWX25
, "Boards with X.25 in firmware"},
499 {ARPHRD_CAN
, "Controller Area Network" },
500 {ARPHRD_PPP
, "PPP" },
501 {ARPHRD_CISCO
, "Cisco HDLC" },
502 {ARPHRD_LAPB
, "LAPB" },
503 {ARPHRD_DDCMP
, "Digital's DDCMP protocol" },
504 {ARPHRD_RAWHDLC
, "Raw HDLC" },
505 {ARPHRD_RAWIP
, "Raw IP" },
507 {ARPHRD_TUNNEL
, "IPIP tunnel" },
508 {ARPHRD_TUNNEL6
, "IP6IP6 tunnel" },
509 {ARPHRD_FRAD
, "Frame Relay Access Device" },
510 {ARPHRD_SKIP
, "SKIP vif" },
511 {ARPHRD_LOOPBACK
, "Loopback" },
512 {ARPHRD_FDDI
, "Fiber Distributed Data Interface"},
513 {ARPHRD_BIF
, "AP1000 BIF" },
514 {ARPHRD_SIT
, "sit0 device - IPv6-in-IPv4" },
515 {ARPHRD_IPDDP
, "IP over DDP tunneller" },
516 {ARPHRD_IPGRE
, "GRE over IP" },
517 {ARPHRD_PIMREG
, "PIMSM register interface" },
518 {ARPHRD_HIPPI
, "High Performance Parallel Interface"},
519 {ARPHRD_ASH
, "Nexus 64Mbps Ash" },
520 {ARPHRD_ECONET
, "Acorn Econet" },
521 {ARPHRD_IRDA
, "Linux-IrDA" },
522 /* ARP works differently on different FC media .. so */
523 {ARPHRD_FCPP
, "Point to point fibrechannel" },
524 {ARPHRD_FCAL
, "Fibrechannel arbitrated loop" },
525 {ARPHRD_FCPL
, "Fibrechannel public loop" },
526 {ARPHRD_FCFABRIC
, "Fibrechannel fabric"},
527 /* 787->799 reserved for fibrechannel media types */
528 {ARPHRD_IEEE802_TR
, "Magic type ident for TR" },
529 {ARPHRD_IEEE80211
, "IEEE 802.11" },
530 {ARPHRD_IEEE80211_PRISM
, "IEEE 802.11 + Prism2 header" },
531 {ARPHRD_IEEE80211_RADIOTAP
, "IEEE 802.11 + radiotap header" },
532 {ARPHRD_IEEE802154
, "IEEE 802.15.4" },
533 {ARPHRD_IEEE802154_MONITOR
, "IEEE 802.15.4 network monitor" },
535 {ARPHRD_PHONET
, "PhoNet media type" },
536 {ARPHRD_PHONET_PIPE
, "PhoNet pipe header" },
537 {ARPHRD_CAIF
, "CAIF media type" },
538 {ARPHRD_IP6GRE
, "GRE over IPv6" },
539 {ARPHRD_NETLINK
, "Netlink" },
540 {ARPHRD_6LOWPAN
, "IPv6 over LoWPAN" },
541 {ARPHRD_VSOCKMON
, "Vsock monitor header" },
543 {ARPHRD_VOID
, "Void type, nothing is known" },
544 {ARPHRD_NONE
, "zero header length" },
548 /* Offsets of fields within an ARP packet. */
554 #define MIN_ARP_HEADER_SIZE 8
556 /* Offsets of fields within an ATMARP packet. */
559 #define ATM_AR_SHTL 4
560 #define ATM_AR_SSTL 5
562 #define ATM_AR_SPLN 8
563 #define ATM_AR_THTL 9
564 #define ATM_AR_TSTL 10
565 #define ATM_AR_TPLN 11
566 #define MIN_ATMARP_HEADER_SIZE 12
569 dissect_atm_number(tvbuff_t
*tvb
, packet_info
* pinfo
, int offset
, int tl
, int hf_e164
,
570 int hf_nsap
, proto_tree
*tree
)
572 int len
= tl
& ATMARP_LEN_MASK
;
574 proto_tree
*nsap_tree
;
576 if (tl
& ATMARP_IS_E164
)
577 proto_tree_add_item(tree
, hf_e164
, tvb
, offset
, len
, ENC_BIG_ENDIAN
);
579 ti
= proto_tree_add_item(tree
, hf_nsap
, tvb
, offset
, len
, ENC_BIG_ENDIAN
);
581 nsap_tree
= proto_item_add_subtree(ti
, ett_atmarp_nsap
);
582 dissect_atm_nsap(tvb
, pinfo
, offset
, len
, nsap_tree
);
587 static const value_string atm_nsap_afi_vals
[] = {
588 { NSAP_IDI_ISO_DCC_BIN
, "DCC ATM format"},
589 { NSAP_IDI_ISO_DCC_BIN_GROUP
, "DCC ATM group format"},
590 { NSAP_IDI_ISO_6523_ICD_BIN
, "ICD ATM format"},
591 { NSAP_IDI_ISO_6523_ICD_BIN_GROUP
, "ICD ATM group format"},
592 { NSAP_IDI_E_164_BIN_FSD_NZ
, "E.164 ATM format"},
593 { NSAP_IDI_E_164_BIN_FSD_NZ_GROUP
, "E.164 ATM group format"},
598 * XXX - shouldn't there be a centralized routine for dissecting NSAPs?
599 * See also "dissect_nsap()" in epan/dissectors/packet-isup.c and
600 * "print_nsap_net()" in epan/osi-utils.c.
603 dissect_atm_nsap(tvbuff_t
*tvb
, packet_info
* pinfo
, int offset
, int len
, proto_tree
*tree
)
608 afi
= tvb_get_uint8(tvb
, offset
);
609 ti
= proto_tree_add_item(tree
, hf_atmarp_src_atm_afi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
612 case NSAP_IDI_ISO_DCC_BIN
: /* DCC ATM format */
613 case NSAP_IDI_ISO_DCC_BIN_GROUP
: /* DCC ATM group format */
614 proto_tree_add_item(tree
, (afi
== NSAP_IDI_ISO_DCC_BIN_GROUP
) ? hf_atmarp_src_atm_data_country_code_group
: hf_atmarp_src_atm_data_country_code
,
615 tvb
, offset
+ 1, 2, ENC_BIG_ENDIAN
);
616 proto_tree_add_item(tree
, hf_atmarp_src_atm_high_order_dsp
, tvb
, offset
+ 3, 10, ENC_NA
);
617 proto_tree_add_item(tree
, hf_atmarp_src_atm_end_system_identifier
, tvb
, offset
+ 13, 6, ENC_NA
);
618 proto_tree_add_item(tree
, hf_atmarp_src_atm_selector
, tvb
, offset
+ 19, 1, ENC_BIG_ENDIAN
);
621 case NSAP_IDI_ISO_6523_ICD_BIN
: /* ICD ATM format */
622 case NSAP_IDI_ISO_6523_ICD_BIN_GROUP
: /* ICD ATM group format */
623 proto_tree_add_item(tree
, (afi
== NSAP_IDI_ISO_6523_ICD_BIN_GROUP
) ? hf_atmarp_src_atm_international_code_designator_group
: hf_atmarp_src_atm_international_code_designator
,
624 tvb
, offset
+ 1, 2, ENC_BIG_ENDIAN
);
625 proto_tree_add_item(tree
, hf_atmarp_src_atm_high_order_dsp
, tvb
, offset
+ 3, 10, ENC_NA
);
626 proto_tree_add_item(tree
, hf_atmarp_src_atm_end_system_identifier
, tvb
, offset
+ 13, 6, ENC_NA
);
627 proto_tree_add_item(tree
, hf_atmarp_src_atm_selector
, tvb
, offset
+ 19, 1, ENC_BIG_ENDIAN
);
630 case NSAP_IDI_E_164_BIN_FSD_NZ
: /* E.164 ATM format */
631 case NSAP_IDI_E_164_BIN_FSD_NZ_GROUP
: /* E.164 ATM group format */
632 proto_tree_add_item(tree
, (afi
== NSAP_IDI_E_164_BIN_FSD_NZ_GROUP
) ? hf_atmarp_src_atm_e_164_isdn_group
: hf_atmarp_src_atm_e_164_isdn
,
633 tvb
, offset
+ 1, 8, ENC_NA
);
634 proto_tree_add_item(tree
, hf_atmarp_src_atm_high_order_dsp
, tvb
, offset
+ 9, 4, ENC_NA
);
635 proto_tree_add_item(tree
, hf_atmarp_src_atm_end_system_identifier
, tvb
, offset
+ 13, 6, ENC_NA
);
636 proto_tree_add_item(tree
, hf_atmarp_src_atm_selector
, tvb
, offset
+ 19, 1, ENC_BIG_ENDIAN
);
640 expert_add_info(pinfo
, ti
, &ei_atmarp_src_atm_unknown_afi
);
641 proto_tree_add_item(tree
, hf_atmarp_src_atm_rest_of_address
, tvb
, offset
+ 1, len
- 1, ENC_NA
);
646 /* l.s. 32 bits are ipv4 address */
648 address_hash_func(const void *v
)
650 return GPOINTER_TO_UINT(v
);
653 /* Compare 2 ipv4 addresses */
655 address_equal_func(const void *v
, const void *v2
)
661 duplicate_result_hash_func(const void *v
)
663 const duplicate_result_key
*key
= (const duplicate_result_key
*)v
;
664 return (key
->frame_number
+ key
->ip_address
);
668 duplicate_result_equal_func(const void *v
, const void *v2
)
670 const duplicate_result_key
*key1
= (const duplicate_result_key
*)v
;
671 const duplicate_result_key
*key2
= (const duplicate_result_key
*)v2
;
673 return (memcmp(key1
, key2
, sizeof(duplicate_result_key
)) == 0);
679 /* Check to see if this mac & ip pair represent 2 devices trying to share
680 the same IP address - report if found (+ return true and set out param) */
682 check_for_duplicate_addresses(packet_info
*pinfo
, proto_tree
*tree
,
684 const uint8_t *mac
, uint32_t ip
,
685 uint32_t *duplicate_ip
)
687 address_hash_value
*value
;
688 address_hash_value
*result
= NULL
;
689 duplicate_result_key result_key
= {pinfo
->num
, ip
};
691 /* Look up existing result */
692 if (pinfo
->fd
->visited
) {
693 result
= (address_hash_value
*)wmem_map_lookup(duplicate_result_hash_table
,
697 /* First time around, need to work out if represents duplicate and
700 /* Look up current assignment of IP address */
701 value
= (address_hash_value
*)wmem_map_lookup(address_hash_table
, GUINT_TO_POINTER(ip
));
703 /* If MAC matches table, just update details */
706 if (pinfo
->num
> value
->frame_num
)
708 if ((memcmp(value
->mac
, mac
, 6) == 0))
710 /* Same MAC as before - update existing entry */
711 value
->frame_num
= pinfo
->num
;
712 value
->time_of_entry
= pinfo
->abs_ts
.secs
;
716 /* Create result and store in result table */
717 duplicate_result_key
*persistent_key
= wmem_new(wmem_file_scope(), duplicate_result_key
);
718 memcpy(persistent_key
, &result_key
, sizeof(duplicate_result_key
));
720 result
= wmem_new(wmem_file_scope(), address_hash_value
);
721 memcpy(result
, value
, sizeof(address_hash_value
));
723 wmem_map_insert(duplicate_result_hash_table
, persistent_key
, result
);
729 /* No existing entry. Prepare one */
730 value
= wmem_new(wmem_file_scope(), struct address_hash_value
);
731 memcpy(value
->mac
, mac
, 6);
732 value
->frame_num
= pinfo
->num
;
733 value
->time_of_entry
= pinfo
->abs_ts
.secs
;
736 wmem_map_insert(address_hash_table
, GUINT_TO_POINTER(ip
), value
);
740 /* Add report to tree if we found a duplicate */
741 if (result
!= NULL
) {
742 proto_tree
*duplicate_tree
;
744 address mac_addr
, result_mac_addr
;
746 set_address(&mac_addr
, AT_ETHER
, 6, mac
);
747 set_address(&result_mac_addr
, AT_ETHER
, 6, result
->mac
);
750 duplicate_tree
= proto_tree_add_subtree_format(tree
, tvb
, 0, 0, ett_arp_duplicate_address
, &ti
,
751 "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
752 arpproaddr_to_str(pinfo
->pool
, (uint8_t*)&ip
, 4, ETHERTYPE_IP
),
753 address_to_str(pinfo
->pool
, &mac_addr
),
754 address_to_str(pinfo
->pool
, &result_mac_addr
),
756 proto_item_set_generated(ti
);
758 /* Add item for navigating to earlier frame */
759 ti
= proto_tree_add_uint(duplicate_tree
, hf_arp_duplicate_ip_address_earlier_frame
,
760 tvb
, 0, 0, result
->frame_num
);
761 proto_item_set_generated(ti
);
762 expert_add_info_format(pinfo
, ti
,
764 "Duplicate IP address configured (%s)",
765 arpproaddr_to_str(pinfo
->pool
, (uint8_t*)&ip
, 4, ETHERTYPE_IP
));
767 /* Time since that frame was seen */
768 ti
= proto_tree_add_uint(duplicate_tree
,
769 hf_arp_duplicate_ip_address_seconds_since_earlier_frame
,
771 (uint32_t)(pinfo
->abs_ts
.secs
- result
->time_of_entry
));
772 proto_item_set_generated(ti
);
774 /* Set out parameter */
779 return (result
!= NULL
);
784 /* Take note that a request has been seen */
786 request_seen(packet_info
*pinfo
)
788 /* Don't count frame again after already recording first time around. */
789 if (p_get_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0) == 0)
795 /* Has storm request rate been exceeded with this request? */
797 check_for_storm_count(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
799 bool report_storm
= false;
801 if (p_get_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0) != 0)
803 /* Read any previous stored packet setting */
804 report_storm
= (p_get_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0) == (void*)STORM
);
808 /* Seeing packet for first time - check against preference settings */
809 int seconds_delta
= (int) (pinfo
->abs_ts
.secs
- time_at_start_of_count
.secs
);
810 int nseconds_delta
= pinfo
->abs_ts
.nsecs
- time_at_start_of_count
.nsecs
;
811 int gap
= (seconds_delta
*1000) + (nseconds_delta
/ 1000000);
813 /* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */
814 if ((gap
> (int)global_arp_detect_request_storm_period
) ||
817 /* Time period elapsed without threshold being exceeded */
818 arp_request_count
= 1;
819 time_at_start_of_count
= pinfo
->abs_ts
;
820 p_add_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0, (void*)NO_STORM
);
824 if (arp_request_count
> global_arp_detect_request_storm_packets
)
826 /* Storm detected, record and reset start time. */
828 p_add_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0, (void*)STORM
);
829 time_at_start_of_count
= pinfo
->abs_ts
;
833 /* Threshold not exceeded yet - no storm */
834 p_add_proto_data(wmem_file_scope(), pinfo
, proto_arp
, 0, (void*)NO_STORM
);
840 /* Report storm and reset counter */
841 proto_tree_add_expert_format(tree
, pinfo
, &ei_seq_arp_storm
, tvb
, 0, 0,
842 "ARP packet storm detected (%u packets in < %u ms)",
843 global_arp_detect_request_storm_packets
,
844 global_arp_detect_request_storm_period
);
845 arp_request_count
= 0;
851 * RFC 2225 ATMARP - it's just like ARP, except where it isn't.
854 dissect_atmarp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
870 proto_tree
*arp_tree
;
873 int sha_offset
, ssa_offset
, spa_offset
;
874 int tha_offset
, tsa_offset
, tpa_offset
;
875 const char *sha_str
, *ssa_str
, *spa_str
;
876 const char *tha_str
, *tsa_str
, *tpa_str
;
879 ar_hrd
= tvb_get_ntohs(tvb
, ATM_AR_HRD
);
880 ar_pro
= tvb_get_ntohs(tvb
, ATM_AR_PRO
);
881 ar_shtl
= tvb_get_uint8(tvb
, ATM_AR_SHTL
);
882 ar_shl
= ar_shtl
& ATMARP_LEN_MASK
;
883 ar_sstl
= tvb_get_uint8(tvb
, ATM_AR_SSTL
);
884 ar_ssl
= ar_sstl
& ATMARP_LEN_MASK
;
885 ar_op
= tvb_get_ntohs(tvb
, AR_OP
);
886 ar_spln
= tvb_get_uint8(tvb
, ATM_AR_SPLN
);
887 ar_thtl
= tvb_get_uint8(tvb
, ATM_AR_THTL
);
888 ar_thl
= ar_thtl
& ATMARP_LEN_MASK
;
889 ar_tstl
= tvb_get_uint8(tvb
, ATM_AR_TSTL
);
890 ar_tsl
= ar_tstl
& ATMARP_LEN_MASK
;
891 ar_tpln
= tvb_get_uint8(tvb
, ATM_AR_TPLN
);
893 tot_len
= MIN_ATMARP_HEADER_SIZE
+ ar_shl
+ ar_ssl
+ ar_spln
+
894 ar_thl
+ ar_tsl
+ ar_tpln
;
896 /* Adjust the length of this tvbuff to include only the ARP datagram.
897 Our caller may use that to determine how much of its packet
899 tvb_set_reported_length(tvb
, tot_len
);
901 /* Extract the addresses. */
902 sha_offset
= MIN_ATMARP_HEADER_SIZE
;
903 sha_str
= atmarpnum_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_shtl
);
905 ssa_offset
= sha_offset
+ ar_shl
;
907 ssa_str
= atmarpsubaddr_to_str(pinfo
->pool
, tvb
, ssa_offset
, ar_sstl
);
912 spa_offset
= ssa_offset
+ ar_ssl
;
913 spa_str
= tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_spln
, ar_pro
);
915 tha_offset
= spa_offset
+ ar_spln
;
916 tha_str
= atmarpnum_to_str(pinfo
->pool
, tvb
, tha_offset
, ar_thtl
);
918 tsa_offset
= tha_offset
+ ar_thl
;
920 tsa_str
= atmarpsubaddr_to_str(pinfo
->pool
, tvb
, tsa_offset
, ar_tstl
);
925 tpa_offset
= tsa_offset
+ ar_tsl
;
926 tpa_str
= tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_tpln
, ar_pro
);
934 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATMARP");
939 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ATMRARP");
944 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ATMARP");
947 case ARPOP_MARS_REQUEST
:
948 case ARPOP_MARS_MULTI
:
949 case ARPOP_MARS_MSERV
:
950 case ARPOP_MARS_JOIN
:
951 case ARPOP_MARS_LEAVE
:
953 case ARPOP_MARS_UNSERV
:
954 case ARPOP_MARS_SJOIN
:
955 case ARPOP_MARS_SLEAVE
:
956 case ARPOP_MARS_GROUPLIST_REQUEST
:
957 case ARPOP_MARS_GROUPLIST_REPLY
:
958 case ARPOP_MARS_REDIRECT_MAP
:
959 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MARS");
962 case ARPOP_MAPOS_UNARP
:
963 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MAPOS");
970 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who has %s? Tell %s",
974 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s%s%s", spa_str
, sha_str
,
975 ((ssa_str
!= NULL
) ? "," : ""),
976 ((ssa_str
!= NULL
) ? ssa_str
: ""));
979 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who is %s%s%s? Tell %s%s%s",
981 ((tsa_str
!= NULL
) ? "," : ""),
982 ((tsa_str
!= NULL
) ? tsa_str
: ""),
984 ((ssa_str
!= NULL
) ? "," : ""),
985 ((ssa_str
!= NULL
) ? ssa_str
: ""));
988 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s%s%s is at %s",
990 ((ssa_str
!= NULL
) ? "," : ""),
991 ((ssa_str
!= NULL
) ? ssa_str
: ""),
995 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "I don't know where %s is", spa_str
);
997 case ARPOP_MARS_REQUEST
:
998 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS request from %s%s%s at %s",
1000 ((ssa_str
!= NULL
) ? "," : ""),
1001 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1005 case ARPOP_MARS_MULTI
:
1006 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MULTI request from %s%s%s at %s",
1008 ((ssa_str
!= NULL
) ? "," : ""),
1009 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1013 case ARPOP_MARS_MSERV
:
1014 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MSERV request from %s%s%s at %s",
1016 ((ssa_str
!= NULL
) ? "," : ""),
1017 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1021 case ARPOP_MARS_JOIN
:
1022 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS JOIN request from %s%s%s at %s",
1024 ((ssa_str
!= NULL
) ? "," : ""),
1025 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1029 case ARPOP_MARS_LEAVE
:
1030 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS LEAVE from %s%s%s at %s",
1032 ((ssa_str
!= NULL
) ? "," : ""),
1033 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1037 case ARPOP_MARS_NAK
:
1038 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS NAK from %s%s%s at %s",
1040 ((ssa_str
!= NULL
) ? "," : ""),
1041 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1045 case ARPOP_MARS_UNSERV
:
1046 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS UNSERV request from %s%s%s at %s",
1048 ((ssa_str
!= NULL
) ? "," : ""),
1049 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1053 case ARPOP_MARS_SJOIN
:
1054 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SJOIN request from %s%s%s at %s",
1056 ((ssa_str
!= NULL
) ? "," : ""),
1057 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1061 case ARPOP_MARS_SLEAVE
:
1062 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SLEAVE from %s%s%s at %s",
1064 ((ssa_str
!= NULL
) ? "," : ""),
1065 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1069 case ARPOP_MARS_GROUPLIST_REQUEST
:
1070 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist request from %s%s%s at %s",
1072 ((ssa_str
!= NULL
) ? "," : ""),
1073 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1077 case ARPOP_MARS_GROUPLIST_REPLY
:
1078 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist reply from %s%s%s at %s",
1080 ((ssa_str
!= NULL
) ? "," : ""),
1081 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1085 case ARPOP_MARS_REDIRECT_MAP
:
1086 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS redirect map from %s%s%s at %s",
1088 ((ssa_str
!= NULL
) ? "," : ""),
1089 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1093 case ARPOP_MAPOS_UNARP
:
1094 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MAPOS UNARP request from %s%s%s at %s",
1096 ((ssa_str
!= NULL
) ? "," : ""),
1097 ((ssa_str
!= NULL
) ? ssa_str
: ""),
1102 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 1 ( opcode %d )", ar_op
);
1106 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 2 ( opcode %d )", ar_op
);
1111 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reserved opcode %d", ar_op
);
1115 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ATMARP opcode 0x%04x", ar_op
);
1120 if ((op_str
= try_val_to_str(ar_op
, atmop_vals
)))
1121 ti
= proto_tree_add_protocol_format(tree
, proto_arp
, tvb
, 0, tot_len
,
1122 "ATM Address Resolution Protocol (%s)",
1125 ti
= proto_tree_add_protocol_format(tree
, proto_arp
, tvb
, 0, tot_len
,
1126 "ATM Address Resolution Protocol (opcode 0x%04x)", ar_op
);
1127 arp_tree
= proto_item_add_subtree(ti
, ett_arp
);
1129 proto_tree_add_uint(arp_tree
, hf_arp_hard_type
, tvb
, ATM_AR_HRD
, 2, ar_hrd
);
1131 proto_tree_add_uint(arp_tree
, hf_arp_proto_type
, tvb
, ATM_AR_PRO
, 2,ar_pro
);
1133 tl_tree
= proto_tree_add_subtree_format(arp_tree
, tvb
, ATM_AR_SHTL
, 1,
1134 ett_atmarp_tl
, NULL
,
1135 "Sender ATM number type/length: %s/%u",
1136 (ar_shtl
& ATMARP_IS_E164
) ?
1140 proto_tree_add_boolean(tl_tree
, hf_atmarp_sht
, tvb
, ATM_AR_SHTL
, 1, ar_shtl
);
1141 proto_tree_add_uint(tl_tree
, hf_atmarp_shl
, tvb
, ATM_AR_SHTL
, 1, ar_shtl
);
1143 tl_tree
= proto_tree_add_subtree_format(arp_tree
, tvb
, ATM_AR_SSTL
, 1,
1144 ett_atmarp_tl
, NULL
,
1145 "Sender ATM subaddress type/length: %s/%u",
1146 (ar_sstl
& ATMARP_IS_E164
) ?
1150 proto_tree_add_boolean(tl_tree
, hf_atmarp_sst
, tvb
, ATM_AR_SSTL
, 1, ar_sstl
);
1151 proto_tree_add_uint(tl_tree
, hf_atmarp_ssl
, tvb
, ATM_AR_SSTL
, 1, ar_sstl
);
1153 proto_tree_add_uint(arp_tree
, hf_arp_opcode
, tvb
, AR_OP
, 2, ar_op
);
1156 proto_tree_add_uint(arp_tree
, hf_atmarp_spln
, tvb
, ATM_AR_SPLN
, 1, ar_spln
);
1158 tl_tree
= proto_tree_add_subtree_format(arp_tree
, tvb
, ATM_AR_THTL
, 1,
1159 ett_atmarp_tl
, NULL
,
1160 "Target ATM number type/length: %s/%u",
1161 (ar_thtl
& ATMARP_IS_E164
) ?
1165 proto_tree_add_boolean(tl_tree
, hf_atmarp_tht
, tvb
, ATM_AR_THTL
, 1, ar_thtl
);
1166 proto_tree_add_uint(tl_tree
, hf_atmarp_thl
, tvb
, ATM_AR_THTL
, 1, ar_thtl
);
1168 tl_tree
= proto_tree_add_subtree_format(arp_tree
, tvb
, ATM_AR_TSTL
, 1,
1169 ett_atmarp_tl
, NULL
,
1170 "Target ATM subaddress type/length: %s/%u",
1171 (ar_tstl
& ATMARP_IS_E164
) ?
1175 proto_tree_add_boolean(tl_tree
, hf_atmarp_tst
, tvb
, ATM_AR_TSTL
, 1, ar_tstl
);
1176 proto_tree_add_uint(tl_tree
, hf_atmarp_tsl
, tvb
, ATM_AR_TSTL
, 1, ar_tstl
);
1178 proto_tree_add_uint(arp_tree
, hf_atmarp_tpln
, tvb
, ATM_AR_TPLN
, 1, ar_tpln
);
1181 dissect_atm_number(tvb
, pinfo
, sha_offset
, ar_shtl
, hf_atmarp_src_atm_num_e164
,
1182 hf_atmarp_src_atm_num_nsap
, arp_tree
);
1185 proto_tree_add_bytes_format_value(arp_tree
, hf_atmarp_src_atm_subaddr
, tvb
, ssa_offset
,
1186 ar_ssl
, NULL
, "%s", ssa_str
);
1189 proto_tree_add_item(arp_tree
,
1190 ARP_PRO_IS_IPv4(ar_pro
, ar_spln
) ? hf_arp_src_proto_ipv4
1192 tvb
, spa_offset
, ar_spln
, ENC_BIG_ENDIAN
);
1196 dissect_atm_number(tvb
, pinfo
, tha_offset
, ar_thtl
, hf_atmarp_dst_atm_num_e164
,
1197 hf_atmarp_dst_atm_num_nsap
, arp_tree
);
1200 proto_tree_add_bytes_format_value(arp_tree
, hf_atmarp_dst_atm_subaddr
, tvb
, tsa_offset
,
1201 ar_tsl
, NULL
, "%s", tsa_str
);
1204 proto_tree_add_item(arp_tree
,
1205 ARP_PRO_IS_IPv4(ar_pro
, ar_tpln
) ? hf_arp_dst_proto_ipv4
1207 tvb
, tpa_offset
, ar_tpln
, ENC_BIG_ENDIAN
);
1210 return tvb_captured_length(tvb
);
1214 * AX.25 ARP - it's just like ARP, except where it isn't.
1217 dissect_ax25arp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1219 #define ARP_AX25 204
1227 proto_tree
*arp_tree
= NULL
;
1230 int sha_offset
, spa_offset
, tha_offset
, tpa_offset
;
1231 const char *spa_str
, *tpa_str
;
1234 /* Hardware Address Type */
1235 ar_hrd
= tvb_get_ntohs(tvb
, AR_HRD
);
1236 /* Protocol Address Type */
1237 ar_pro
= tvb_get_ntohs(tvb
, AR_PRO
);
1238 /* Hardware Address Size */
1239 ar_hln
= tvb_get_uint8(tvb
, AR_HLN
);
1240 /* Protocol Address Size */
1241 ar_pln
= tvb_get_uint8(tvb
, AR_PLN
);
1243 ar_op
= tvb_get_ntohs(tvb
, AR_OP
);
1245 tot_len
= MIN_ARP_HEADER_SIZE
+ ar_hln
*2 + ar_pln
*2;
1247 /* Adjust the length of this tvbuff to include only the ARP datagram.
1248 Our caller may use that to determine how much of its packet
1250 tvb_set_reported_length(tvb
, tot_len
);
1255 if (global_arp_detect_request_storm
)
1256 request_seen(pinfo
);
1260 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ARP");
1263 case ARPOP_RREQUEST
:
1265 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RARP");
1268 case ARPOP_IREQUEST
:
1270 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ARP");
1274 /* Get the offsets of the addresses. */
1275 /* Source Hardware Address */
1276 sha_offset
= MIN_ARP_HEADER_SIZE
;
1277 /* Source Protocol Address */
1278 spa_offset
= sha_offset
+ ar_hln
;
1279 /* Target Hardware Address */
1280 tha_offset
= spa_offset
+ ar_pln
;
1281 /* Target Protocol Address */
1282 tpa_offset
= tha_offset
+ ar_hln
;
1284 spa_str
= tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
);
1285 tpa_str
= tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
);
1287 /* ARP requests/replies with the same sender and target protocol
1288 address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
1289 in effect, an announcement that the machine has MAC address
1290 XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
1291 provoke complaints if some other machine has the same IPv4 address,
1292 replies are used to announce relocation of network address, like
1293 in failover solutions. */
1294 if (((ar_op
== ARPOP_REQUEST
) || (ar_op
== ARPOP_REPLY
)) && (strcmp(spa_str
, tpa_str
) == 0))
1295 is_gratuitous
= true;
1297 is_gratuitous
= false;
1302 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Request)", tpa_str
);
1304 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who has %s? Tell %s", tpa_str
, spa_str
);
1308 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Reply)", spa_str
);
1310 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1312 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
));
1314 case ARPOP_RREQUEST
:
1315 case ARPOP_IREQUEST
:
1316 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who is %s? Tell %s",
1317 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, tha_offset
, ar_hln
, ar_hrd
),
1318 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
));
1321 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1322 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, tha_offset
, ar_hln
, ar_hrd
),
1326 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1327 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1331 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ARP opcode 0x%04x", ar_op
);
1336 if ((op_str
= try_val_to_str(ar_op
, op_vals
))) {
1337 if (is_gratuitous
&& (ar_op
== ARPOP_REQUEST
))
1338 op_str
= "request/gratuitous ARP";
1339 if (is_gratuitous
&& (ar_op
== ARPOP_REPLY
))
1340 op_str
= "reply/gratuitous ARP";
1341 ti
= proto_tree_add_protocol_format(tree
, proto_arp
, tvb
, 0, tot_len
,
1342 "Address Resolution Protocol (%s)", op_str
);
1344 ti
= proto_tree_add_protocol_format(tree
, proto_arp
, tvb
, 0, tot_len
,
1345 "Address Resolution Protocol (opcode 0x%04x)", ar_op
);
1346 arp_tree
= proto_item_add_subtree(ti
, ett_arp
);
1347 proto_tree_add_uint(arp_tree
, hf_arp_hard_type
, tvb
, AR_HRD
, 2, ar_hrd
);
1348 proto_tree_add_uint(arp_tree
, hf_arp_proto_type
, tvb
, AR_PRO
, 2, ar_pro
);
1349 proto_tree_add_uint(arp_tree
, hf_arp_hard_size
, tvb
, AR_HLN
, 1, ar_hln
);
1350 proto_tree_add_uint(arp_tree
, hf_arp_proto_size
, tvb
, AR_PLN
, 1, ar_pln
);
1351 proto_tree_add_uint(arp_tree
, hf_arp_opcode
, tvb
, AR_OP
, 2, ar_op
);
1353 proto_tree_add_item(arp_tree
,
1354 ARP_HW_IS_AX25(ar_hrd
, ar_hln
) ? hf_arp_src_hw_ax25
: hf_arp_src_hw
,
1355 tvb
, sha_offset
, ar_hln
, false);
1358 proto_tree_add_item(arp_tree
,
1359 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ? hf_arp_src_proto_ipv4
1361 tvb
, spa_offset
, ar_pln
, false);
1364 proto_tree_add_item(arp_tree
,
1365 ARP_HW_IS_AX25(ar_hrd
, ar_hln
) ? hf_arp_dst_hw_ax25
: hf_arp_dst_hw
,
1366 tvb
, tha_offset
, ar_hln
, false);
1369 proto_tree_add_item(arp_tree
,
1370 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ? hf_arp_dst_proto_ipv4
1372 tvb
, tpa_offset
, ar_pln
, false);
1376 if (global_arp_detect_request_storm
)
1378 check_for_storm_count(tvb
, pinfo
, arp_tree
);
1380 return tvb_captured_length(tvb
);
1384 capture_arp(const unsigned char *pd _U_
, int offset _U_
, int len _U_
, capture_packet_info_t
*cpinfo
, const union wtap_pseudo_header
*pseudo_header _U_
)
1386 capture_dissector_increment_count(cpinfo
, proto_arp
);
1390 static const uint8_t mac_allzero
[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1393 dissect_arp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1396 uint32_t ar_pro
, ar_hln
, ar_pln
, ar_op
;
1398 proto_tree
*arp_tree
;
1399 proto_item
*arp_item
, *item
;
1401 int sha_offset
, spa_offset
, tha_offset
, tpa_offset
;
1402 bool is_gratuitous
, is_probe
= false, is_announcement
= false;
1403 bool duplicate_detected
= false;
1404 uint32_t duplicate_ip
= 0;
1405 dissector_handle_t hw_handle
;
1407 /* Call it ARP, for now, so that if we throw an exception before
1408 we decide whether it's ARP or RARP or IARP or ATMARP, it shows
1409 up in the packet list as ARP.
1411 Clear the Info column so that, if we throw an exception, it
1412 shows up as a short or malformed ARP frame. */
1413 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ARP");
1414 col_clear(pinfo
->cinfo
, COL_INFO
);
1416 /* Hardware Address Type */
1417 ar_hrd
= tvb_get_ntohs(tvb
, AR_HRD
);
1419 /* See if there is a hardware type already registered */
1420 hw_handle
= dissector_get_uint_handle(arp_hw_table
, ar_hrd
);
1421 if (hw_handle
!= NULL
) {
1422 call_dissector(hw_handle
, tvb
, pinfo
, tree
);
1423 return tvb_captured_length(tvb
);
1426 /* Otherwise dissect as Ethernet hardware */
1428 arp_item
= proto_tree_add_item(tree
, proto_arp
, tvb
, 0, -1, ENC_NA
);
1429 arp_tree
= proto_item_add_subtree(arp_item
, ett_arp
);
1431 proto_tree_add_uint(arp_tree
, hf_arp_hard_type
, tvb
, AR_HRD
, 2, ar_hrd
);
1432 /* Protocol Address Type */
1433 proto_tree_add_item_ret_uint(arp_tree
, hf_arp_proto_type
, tvb
, AR_PRO
, 2, ENC_BIG_ENDIAN
, &ar_pro
);
1434 /* Hardware Address Size */
1435 proto_tree_add_item_ret_uint(arp_tree
, hf_arp_hard_size
, tvb
, AR_HLN
, 1, ENC_NA
, &ar_hln
);
1436 /* Protocol Address Size */
1437 proto_tree_add_item_ret_uint(arp_tree
, hf_arp_proto_size
, tvb
, AR_PLN
, 1, ENC_NA
, &ar_pln
);
1439 proto_tree_add_item_ret_uint(arp_tree
, hf_arp_opcode
, tvb
, AR_OP
, 2, ENC_BIG_ENDIAN
, &ar_op
);
1441 tot_len
= MIN_ARP_HEADER_SIZE
+ ar_hln
*2 + ar_pln
*2;
1442 proto_item_set_len(arp_item
, tot_len
);
1444 /* Adjust the length of this tvbuff to include only the ARP datagram.
1445 Our caller may use that to determine how much of its packet
1447 tvb_set_reported_length(tvb
, tot_len
);
1452 if (global_arp_detect_request_storm
)
1454 request_seen(pinfo
);
1459 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ARP");
1462 case ARPOP_RREQUEST
:
1464 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RARP");
1467 case ARPOP_DRARPREQUEST
:
1468 case ARPOP_DRARPREPLY
:
1469 case ARPOP_DRARPERROR
:
1470 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DRARP");
1473 case ARPOP_IREQUEST
:
1475 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Inverse ARP");
1478 case ARPOP_MARS_REQUEST
:
1479 case ARPOP_MARS_MULTI
:
1480 case ARPOP_MARS_MSERV
:
1481 case ARPOP_MARS_JOIN
:
1482 case ARPOP_MARS_LEAVE
:
1483 case ARPOP_MARS_NAK
:
1484 case ARPOP_MARS_UNSERV
:
1485 case ARPOP_MARS_SJOIN
:
1486 case ARPOP_MARS_SLEAVE
:
1487 case ARPOP_MARS_GROUPLIST_REQUEST
:
1488 case ARPOP_MARS_GROUPLIST_REPLY
:
1489 case ARPOP_MARS_REDIRECT_MAP
:
1490 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MARS");
1493 case ARPOP_MAPOS_UNARP
:
1494 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MAPOS");
1498 /* Get the offsets of the addresses. */
1499 /* Source Hardware Address */
1500 sha_offset
= MIN_ARP_HEADER_SIZE
;
1501 /* Source Protocol Address */
1502 spa_offset
= sha_offset
+ ar_hln
;
1503 /* Target Hardware Address */
1504 tha_offset
= spa_offset
+ ar_pln
;
1505 /* Target Protocol Address */
1506 tpa_offset
= tha_offset
+ ar_hln
;
1508 if ((ar_op
== ARPOP_REPLY
|| ar_op
== ARPOP_REQUEST
) &&
1509 ARP_HW_IS_ETHER(ar_hrd
, ar_hln
) &&
1510 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
)) {
1512 /* inform resolv.c module of the new discovered addresses */
1517 /* Add sender address if sender MAC address is neither a broadcast/
1518 multicast address nor an all-zero address and if sender IP address
1519 isn't all zeroes. */
1520 ip
= tvb_get_ipv4(tvb
, spa_offset
);
1521 mac
= (const uint8_t*)tvb_memdup(pinfo
->pool
, tvb
, sha_offset
, 6);
1522 if ((mac
[0] & 0x01) == 0 && memcmp(mac
, mac_allzero
, 6) != 0 && ip
!= 0)
1524 if (global_arp_register_network_address_binding
)
1526 add_ether_byip(ip
, mac
);
1528 if (global_arp_detect_duplicate_ip_addresses
)
1530 duplicate_detected
=
1531 check_for_duplicate_addresses(pinfo
, tree
, tvb
, mac
, ip
,
1536 /* Add target address if target MAC address is neither a broadcast/
1537 multicast address nor an all-zero address and if target IP address
1538 isn't all zeroes. */
1540 /* Do not add target address if the packet is a Request. According to the RFC,
1541 target addresses in requests have no meaning */
1544 ip
= tvb_get_ipv4(tvb
, tpa_offset
);
1545 mac
= (const uint8_t*)tvb_memdup(pinfo
->pool
, tvb
, tha_offset
, 6);
1546 if ((mac
[0] & 0x01) == 0 && memcmp(mac
, mac_allzero
, 6) != 0 && ip
!= 0
1547 && ar_op
!= ARPOP_REQUEST
)
1549 if (global_arp_register_network_address_binding
)
1551 add_ether_byip(ip
, mac
);
1553 /* If Gratuitous, don't report duplicate for same IP address twice */
1554 if (global_arp_detect_duplicate_ip_addresses
&& (duplicate_ip
!=ip
))
1556 duplicate_detected
=
1557 check_for_duplicate_addresses(pinfo
, tree
, tvb
, mac
, ip
,
1565 /* ARP requests/replies with the same sender and target protocol
1566 address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
1567 in effect, an announcement that the machine has MAC address
1568 XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
1569 provoke complaints if some other machine has the same IPv4 address,
1570 replies are used to announce relocation of network address, like
1571 in failover solutions. */
1572 if (((ar_op
== ARPOP_REQUEST
) || (ar_op
== ARPOP_REPLY
)) &&
1573 (tvb_memeql(tvb
, spa_offset
, tvb_get_ptr(tvb
, tpa_offset
, ar_pln
), ar_pln
) == 0)) {
1574 is_gratuitous
= true;
1575 if ((ar_op
== ARPOP_REQUEST
) && (tvb_memeql(tvb
, tha_offset
, mac_allzero
, 6) == 0))
1576 is_announcement
= true;
1579 is_gratuitous
= false;
1580 if ((ar_op
== ARPOP_REQUEST
) && (tvb_memeql(tvb
, tha_offset
, mac_allzero
, 6) == 0) && (tvb_get_ipv4(tvb
, spa_offset
) == 0))
1585 if (is_gratuitous
) {
1586 if (is_announcement
) {
1587 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "ARP Announcement for %s",
1588 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
));
1590 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Request)",
1591 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
));
1594 else if (is_probe
) {
1595 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who has %s? (ARP Probe)",
1596 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
));
1598 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who has %s? Tell %s",
1599 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
),
1600 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1605 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Gratuitous ARP for %s (Reply)",
1606 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1608 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1609 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
),
1610 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
));
1612 case ARPOP_RREQUEST
:
1613 case ARPOP_IREQUEST
:
1614 case ARPOP_DRARPREQUEST
:
1615 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Who is %s? Tell %s",
1616 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, tha_offset
, ar_hln
, ar_hrd
),
1617 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
));
1620 case ARPOP_DRARPREPLY
:
1621 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1622 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, tha_offset
, ar_hln
, ar_hrd
),
1623 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, tpa_offset
, ar_pln
, ar_pro
));
1626 case ARPOP_DRARPERROR
:
1627 col_set_str(pinfo
->cinfo
, COL_INFO
, "DRARP Error");
1631 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s is at %s",
1632 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1633 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1637 col_set_str(pinfo
->cinfo
, COL_INFO
, "ARP NAK");
1640 case ARPOP_MARS_REQUEST
:
1641 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS request from %s at %s",
1642 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1643 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1646 case ARPOP_MARS_MULTI
:
1647 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MULTI request from %s at %s",
1648 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1649 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1652 case ARPOP_MARS_MSERV
:
1653 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS MSERV request from %s at %s",
1654 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1655 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1658 case ARPOP_MARS_JOIN
:
1659 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS JOIN request from %s at %s",
1660 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1661 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1664 case ARPOP_MARS_LEAVE
:
1665 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS LEAVE from %s at %s",
1666 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1667 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1670 case ARPOP_MARS_NAK
:
1671 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS NAK from %s at %s",
1672 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1673 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1676 case ARPOP_MARS_UNSERV
:
1677 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS UNSERV request from %s at %s",
1678 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1679 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1682 case ARPOP_MARS_SJOIN
:
1683 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SJOIN request from %s at %s",
1684 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1685 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1688 case ARPOP_MARS_SLEAVE
:
1689 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS SLEAVE from %s at %s",
1690 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1691 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1694 case ARPOP_MARS_GROUPLIST_REQUEST
:
1695 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist request from %s at %s",
1696 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1697 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1700 case ARPOP_MARS_GROUPLIST_REPLY
:
1701 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS grouplist reply from %s at %s",
1702 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1703 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1706 case ARPOP_MARS_REDIRECT_MAP
:
1707 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MARS redirect map from %s at %s",
1708 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1709 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1712 case ARPOP_MAPOS_UNARP
:
1713 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MAPOS UNARP request from %s at %s",
1714 tvb_arphrdaddr_to_str(pinfo
->pool
, tvb
, sha_offset
, ar_hln
, ar_hrd
),
1715 tvb_arpproaddr_to_str(pinfo
->pool
, tvb
, spa_offset
, ar_pln
, ar_pro
));
1719 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 1 ( opcode %d )", ar_op
);
1723 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Experimental 2 ( opcode %d )", ar_op
);
1728 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reserved opcode %d", ar_op
);
1732 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown ARP opcode 0x%04x", ar_op
);
1737 if ((op_str
= try_val_to_str(ar_op
, op_vals
))) {
1738 if (is_gratuitous
&& (ar_op
== ARPOP_REQUEST
))
1739 op_str
= "request/gratuitous ARP";
1740 if (is_gratuitous
&& (ar_op
== ARPOP_REPLY
))
1741 op_str
= "reply/gratuitous ARP";
1743 op_str
= "ARP Probe";
1744 if (is_announcement
)
1745 op_str
= "ARP Announcement";
1747 proto_item_append_text(arp_item
, " (%s)", op_str
);
1749 proto_item_append_text(arp_item
, " (opcode 0x%04x)", ar_op
);
1752 if (is_gratuitous
) {
1753 item
= proto_tree_add_boolean(arp_tree
, hf_arp_isgratuitous
, tvb
, 0, 0, is_gratuitous
);
1754 proto_item_set_generated(item
);
1757 item
= proto_tree_add_boolean(arp_tree
, hf_arp_isprobe
, tvb
, 0, 0, is_probe
);
1758 proto_item_set_generated(item
);
1760 if (is_announcement
) {
1761 item
= proto_tree_add_boolean(arp_tree
, hf_arp_isannouncement
, tvb
, 0, 0, is_announcement
);
1762 proto_item_set_generated(item
);
1765 proto_tree_add_item(arp_tree
,
1766 ARP_HW_IS_ETHER(ar_hrd
, ar_hln
) ?
1769 tvb
, sha_offset
, ar_hln
, ENC_BIG_ENDIAN
);
1772 proto_tree_add_item(arp_tree
,
1773 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ?
1774 hf_arp_src_proto_ipv4
:
1776 tvb
, spa_offset
, ar_pln
, ENC_BIG_ENDIAN
);
1779 proto_tree_add_item(arp_tree
,
1780 ARP_HW_IS_ETHER(ar_hrd
, ar_hln
) ?
1783 tvb
, tha_offset
, ar_hln
, ENC_BIG_ENDIAN
);
1785 if (ar_pln
!= 0 && ar_op
!= ARPOP_DRARPERROR
) { /*DISPLAYING ERROR NUMBER FOR DRARPERROR*/
1786 proto_tree_add_item(arp_tree
,
1787 ARP_PRO_IS_IPv4(ar_pro
, ar_pln
) ?
1788 hf_arp_dst_proto_ipv4
:
1790 tvb
, tpa_offset
, ar_pln
, ENC_BIG_ENDIAN
);
1792 else if (ar_pln
!= 0 && ar_op
== ARPOP_DRARPERROR
) {
1793 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*/
1797 if (global_arp_detect_request_storm
)
1799 check_for_storm_count(tvb
, pinfo
, arp_tree
);
1802 if (duplicate_detected
)
1804 /* Also indicate in info column */
1805 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (duplicate use of %s detected!)",
1806 arpproaddr_to_str(pinfo
->pool
, (uint8_t*)&duplicate_ip
, 4, ETHERTYPE_IP
));
1808 return tvb_captured_length(tvb
);
1812 proto_register_arp(void)
1814 static struct true_false_string tfs_type_bit
= { "E.164", "ATM Forum NSAPA" };
1816 static hf_register_info hf
[] = {
1817 { &hf_arp_hard_type
,
1818 { "Hardware type", "arp.hw.type",
1819 FT_UINT16
, BASE_DEC
, VALS(arp_hrd_vals
), 0x0,
1822 { &hf_arp_proto_type
,
1823 { "Protocol type", "arp.proto.type",
1824 FT_UINT16
, BASE_HEX
, VALS(etype_vals
), 0x0,
1827 { &hf_arp_hard_size
,
1828 { "Hardware size", "arp.hw.size",
1829 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1833 { "Sender ATM number type", "arp.src.htype",
1834 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1838 { "Sender ATM number length", "arp.src.hlen",
1839 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1843 { "Sender ATM subaddress type", "arp.src.stype",
1844 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1848 { "Sender ATM subaddress length", "arp.src.slen",
1849 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1852 { &hf_arp_proto_size
,
1853 { "Protocol size", "arp.proto.size",
1854 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1858 { "Opcode", "arp.opcode",
1859 FT_UINT16
, BASE_DEC
, VALS(op_vals
), 0x0,
1862 { &hf_arp_isgratuitous
,
1863 { "Is gratuitous", "arp.isgratuitous",
1864 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1868 { "Is probe", "arp.isprobe",
1869 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1872 { &hf_arp_isannouncement
,
1873 { "Is announcement", "arp.isannouncement",
1874 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1878 { "Sender protocol size", "arp.src.pln",
1879 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1883 { "Target ATM number type", "arp.dst.htype",
1884 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1888 { "Target ATM number length", "arp.dst.hlen",
1889 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1893 { "Target ATM subaddress type", "arp.dst.stype",
1894 FT_BOOLEAN
, 8, TFS(&tfs_type_bit
), ATMARP_IS_E164
,
1898 { "Target ATM subaddress length", "arp.dst.slen",
1899 FT_UINT8
, BASE_DEC
, NULL
, ATMARP_LEN_MASK
,
1903 { "Target protocol size", "arp.dst.pln",
1904 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1908 { "Sender hardware address", "arp.src.hw",
1909 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1912 { &hf_arp_src_hw_mac
,
1913 { "Sender MAC address", "arp.src.hw_mac",
1914 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1917 { &hf_arp_src_hw_ax25
,
1918 { "Sender AX.25 address", "arp.src.hw_ax25",
1919 FT_AX25
, BASE_NONE
, NULL
, 0x0,
1922 { &hf_atmarp_src_atm_num_e164
,
1923 { "Sender ATM number (E.164)", "arp.src.atm_num_e164",
1924 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1927 { &hf_atmarp_src_atm_num_nsap
,
1928 { "Sender ATM number (NSAP)", "arp.src.atm_num_nsap",
1929 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1932 { &hf_atmarp_src_atm_subaddr
,
1933 { "Sender ATM subaddress", "arp.src.atm_subaddr",
1934 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1937 { &hf_arp_src_proto
,
1938 { "Sender protocol address", "arp.src.proto",
1939 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1942 { &hf_arp_src_proto_ipv4
,
1943 { "Sender IP address", "arp.src.proto_ipv4",
1944 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1948 { "Target hardware address", "arp.dst.hw",
1949 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1952 { &hf_arp_dst_hw_mac
,
1953 { "Target MAC address", "arp.dst.hw_mac",
1954 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1957 { &hf_arp_dst_hw_ax25
,
1958 { "Target AX.25 address", "arp.dst.hw_ax25",
1959 FT_AX25
, BASE_NONE
, NULL
, 0x0,
1962 { &hf_atmarp_dst_atm_num_e164
,
1963 { "Target ATM number (E.164)", "arp.dst.atm_num_e164",
1964 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1967 { &hf_atmarp_dst_atm_num_nsap
,
1968 { "Target ATM number (NSAP)", "arp.dst.atm_num_nsap",
1969 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1972 { &hf_atmarp_dst_atm_subaddr
,
1973 { "Target ATM subaddress", "arp.dst.atm_subaddr",
1974 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1977 { &hf_arp_dst_proto
,
1978 { "Target protocol address", "arp.dst.proto",
1979 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1982 { &hf_arp_dst_proto_ipv4
,
1983 { "Target IP address", "arp.dst.proto_ipv4",
1984 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1987 { &hf_drarp_error_status
,
1988 { "DRARP error status", "arp.dst.drarp_error_status",
1989 FT_UINT16
, BASE_DEC
, VALS(drarp_status
), 0x0,
1992 { &hf_arp_duplicate_ip_address_earlier_frame
,
1993 { "Frame showing earlier use of IP address", "arp.duplicate-address-frame",
1994 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
1997 { &hf_arp_duplicate_ip_address_seconds_since_earlier_frame
,
1998 { "Seconds since earlier frame seen", "arp.seconds-since-duplicate-address-frame",
1999 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2002 /* Generated from convert_proto_tree_add_text.pl */
2003 { &hf_atmarp_src_atm_data_country_code
, { "Data Country Code", "arp.src.atm_data_country_code", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2004 { &hf_atmarp_src_atm_data_country_code_group
, { "Data Country Code (group)", "arp.src.atm_data_country_code_group", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2005 { &hf_atmarp_src_atm_high_order_dsp
, { "High Order DSP", "arp.src.atm_high_order_dsp", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2006 { &hf_atmarp_src_atm_end_system_identifier
, { "End System Identifier", "arp.src.atm_end_system_identifier", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2007 { &hf_atmarp_src_atm_selector
, { "Selector", "arp.src.atm_selector", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2008 { &hf_atmarp_src_atm_international_code_designator
, { "International Code Designator", "arp.src.atm_international_code_designator", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2009 { &hf_atmarp_src_atm_international_code_designator_group
, { "International Code Designator (group)", "arp.src.atm_international_code_designator_group", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2010 { &hf_atmarp_src_atm_e_164_isdn
, { "E.164 ISDN", "arp.src.atm_e.164_isdn", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2011 { &hf_atmarp_src_atm_e_164_isdn_group
, { "E.164 ISDN", "arp.src.atm_e.164_isdn_group", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2012 { &hf_atmarp_src_atm_rest_of_address
, { "Rest of address", "arp.src.atm_rest_of_address", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2013 { &hf_atmarp_src_atm_afi
, { "AFI", "arp.src.atm_afi", FT_UINT8
, BASE_HEX
, VALS(atm_nsap_afi_vals
), 0x0, NULL
, HFILL
}},
2016 static int *ett
[] = {
2020 &ett_arp_duplicate_address
2023 static ei_register_info ei
[] = {
2024 { &ei_seq_arp_dup_ip
, { "arp.duplicate-address-detected", PI_SEQUENCE
, PI_WARN
, "Duplicate IP address configured", EXPFILL
}},
2025 { &ei_seq_arp_storm
, { "arp.packet-storm-detected", PI_SEQUENCE
, PI_NOTE
, "ARP packet storm detected", EXPFILL
}},
2026 { &ei_atmarp_src_atm_unknown_afi
, { "arp.src.atm_afi.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown AFI", EXPFILL
}},
2029 module_t
*arp_module
;
2030 expert_module_t
* expert_arp
;
2032 proto_arp
= proto_register_protocol("Address Resolution Protocol",
2034 proto_atmarp
= proto_register_protocol("ATM Address Resolution Protocol",
2035 "ATMARP", "atmarp");
2037 proto_register_field_array(proto_arp
, hf
, array_length(hf
));
2038 proto_register_subtree_array(ett
, array_length(ett
));
2040 expert_arp
= expert_register_protocol(proto_arp
);
2041 expert_register_field_array(expert_arp
, ei
, array_length(ei
));
2043 arp_handle
= register_dissector( "arp" , dissect_arp
, proto_arp
);
2044 register_dissector("atm_arp", dissect_atmarp
, proto_atmarp
);
2045 register_dissector("ax25_arp", dissect_ax25arp
, proto_arp
);
2047 arp_hw_table
= register_dissector_table("arp.hw.type", "ARP Hardware Type", proto_arp
, FT_UINT16
, BASE_DEC
);
2050 arp_module
= prefs_register_protocol(proto_arp
, NULL
);
2052 prefs_register_bool_preference(arp_module
, "detect_request_storms",
2053 "Detect ARP request storms",
2054 "Attempt to detect excessive rate of ARP requests",
2055 &global_arp_detect_request_storm
);
2057 prefs_register_uint_preference(arp_module
, "detect_storm_number_of_packets",
2058 "Number of requests to detect during period",
2059 "Number of requests needed within period to indicate a storm",
2060 10, &global_arp_detect_request_storm_packets
);
2062 prefs_register_uint_preference(arp_module
, "detect_storm_period",
2063 "Detection period (in ms)",
2064 "Period in milliseconds during which a packet storm may be detected",
2065 10, &global_arp_detect_request_storm_period
);
2067 prefs_register_bool_preference(arp_module
, "detect_duplicate_ips",
2068 "Detect duplicate IP address configuration",
2069 "Attempt to detect duplicate use of IP addresses",
2070 &global_arp_detect_duplicate_ip_addresses
);
2072 prefs_register_bool_preference(arp_module
, "register_network_address_binding",
2073 "Register network address mappings",
2074 "Try to resolve physical addresses to host names from ARP requests/responses",
2075 &global_arp_register_network_address_binding
);
2077 /* TODO: define a minimum time between sightings that is worth reporting? */
2079 address_hash_table
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), address_hash_func
, address_equal_func
);
2080 duplicate_result_hash_table
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), duplicate_result_hash_func
,
2081 duplicate_result_equal_func
);
2083 arp_cap_handle
= register_capture_dissector("arp", capture_arp
, proto_arp
);
2087 proto_reg_handoff_arp(void)
2089 dissector_handle_t atmarp_handle
= find_dissector("atm_arp");
2090 dissector_handle_t ax25arp_handle
= find_dissector("ax25_arp");
2092 dissector_add_uint("ethertype", ETHERTYPE_ARP
, arp_handle
);
2093 dissector_add_uint("ethertype", ETHERTYPE_REVARP
, arp_handle
);
2094 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1051
, arp_handle
);
2095 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1201
, arp_handle
);
2096 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_RARP_1201
, arp_handle
);
2097 dissector_add_uint("ax25.pid", AX25_P_ARP
, arp_handle
);
2098 dissector_add_uint("gre.proto", ETHERTYPE_ARP
, arp_handle
);
2099 capture_dissector_add_uint("ethertype", ETHERTYPE_ARP
, arp_cap_handle
);
2100 capture_dissector_add_uint("ax25.pid", AX25_P_ARP
, arp_cap_handle
);
2102 dissector_add_uint("arp.hw.type", ARPHRD_ATM2225
, atmarp_handle
);
2103 dissector_add_uint("arp.hw.type", ARPHRD_AX25
, ax25arp_handle
);
2107 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2112 * indent-tabs-mode: nil
2115 * ex: set shiftwidth=2 tabstop=8 expandtab:
2116 * :indentSize=2:tabSize=8:noTabs=true: