Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-arp.c
blobfca56f9e0f5e05c3a01215e0c646e26f10cdacfb
1 /* packet-arp.c
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
14 #include "config.h"
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>
28 #include <epan/tfs.h>
30 void proto_register_arp(void);
31 void proto_reg_handoff_arp(void);
33 static int proto_arp;
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;
88 static int ett_arp;
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 */
104 #define STORM 1
105 #define NO_STORM 2
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
120 Key is unsigned32 */
121 static wmem_map_t *address_hash_table;
123 typedef struct address_hash_value {
124 uint8_t mac[6];
125 unsigned frame_num;
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;
134 uint32_t ip_address;
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. */
148 #endif
149 #ifndef ARPOP_REPLY
150 #define ARPOP_REPLY 2 /* ARP reply. */
151 #endif
152 /* Some OSes have different names, or don't define these at all */
153 #ifndef ARPOP_RREQUEST
154 #define ARPOP_RREQUEST 3 /* RARP request. */
155 #endif
156 #ifndef ARPOP_RREPLY
157 #define ARPOP_RREPLY 4 /* RARP reply. */
158 #endif
160 /* Additional parameters as per https://www.iana.org/assignments/arp-parameters */
161 #ifndef ARPOP_DRARPREQUEST
162 #define ARPOP_DRARPREQUEST 5 /* DRARP request. */
163 #endif
165 #ifndef ARPOP_DRARPREPLY
166 #define ARPOP_DRARPREPLY 6 /* DRARP reply. */
167 #endif
169 #ifndef ARPOP_DRARPERROR
170 #define ARPOP_DRARPERROR 7 /* DRARP error. */
171 #endif
173 #ifndef ARPOP_IREQUEST
174 #define ARPOP_IREQUEST 8 /* Inverse ARP (RFC 1293) request. */
175 #endif
176 #ifndef ARPOP_IREPLY
177 #define ARPOP_IREPLY 9 /* Inverse ARP reply. */
178 #endif
179 #ifndef ATMARPOP_NAK
180 #define ATMARPOP_NAK 10 /* ATMARP NAK. */
181 #endif
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. */
186 #endif
188 #ifndef ARPOP_MARS_MULTI
189 #define ARPOP_MARS_MULTI 12 /*MARS-Multi message. */
190 #endif
192 #ifndef ARPOP_MARS_MSERV
193 #define ARPOP_MARS_MSERV 13 /*MARS-Mserv message. */
194 #endif
196 #ifndef ARPOP_MARS_JOIN
197 #define ARPOP_MARS_JOIN 14 /*MARS-Join request. */
198 #endif
200 #ifndef ARPOP_MARS_LEAVE
201 #define ARPOP_MARS_LEAVE 15 /*MARS Leave request. */
202 #endif
204 #ifndef ARPOP_MARS_NAK
205 #define ARPOP_MARS_NAK 16 /*MARS nak message.*/
206 #endif
208 #ifndef ARPOP_MARS_UNSERV
209 #define ARPOP_MARS_UNSERV 17 /*MARS Unserv message. */
210 #endif
212 #ifndef ARPOP_MARS_SJOIN
213 #define ARPOP_MARS_SJOIN 18 /*MARS Sjoin message. */
214 #endif
216 #ifndef ARPOP_MARS_SLEAVE
217 #define ARPOP_MARS_SLEAVE 19 /*MARS Sleave message. */
218 #endif
220 #ifndef ARPOP_MARS_GROUPLIST_REQUEST
221 #define ARPOP_MARS_GROUPLIST_REQUEST 20 /*MARS Grouplist request message. */
222 #endif
224 #ifndef ARPOP_MARS_GROUPLIST_REPLY
225 #define ARPOP_MARS_GROUPLIST_REPLY 21 /*MARS Grouplist reply message. */
226 #endif
228 #ifndef ARPOP_MARS_REDIRECT_MAP
229 #define ARPOP_MARS_REDIRECT_MAP 22 /*MARS Grouplist request message. */
230 #endif
232 #ifndef ARPOP_MAPOS_UNARP
233 #define ARPOP_MAPOS_UNARP 23 /*MAPOS UNARP*/
234 #endif
236 #ifndef ARPOP_EXP1
237 #define ARPOP_EXP1 24 /* Experimental 1 */
238 #endif
239 #ifndef ARPOP_EXP2
240 #define ARPOP_EXP2 25 /* Experimental 2 */
241 #endif
243 #ifndef ARPOP_RESERVED1
244 #define ARPOP_RESERVED1 0 /*Reserved opcode 1*/
245 #endif
247 #ifndef ARPOP_RESERVED2
248 #define ARPOP_RESERVED2 65535 /*Reserved opcode 2*/
249 #endif
251 #ifndef DRARPERR_RESTRICTED
252 #define DRARPERR_RESTRICTED 1
253 #endif
255 #ifndef DRARPERR_NOADDRESSES
256 #define DRARPERR_NOADDRESSES 2
257 #endif
259 #ifndef DRARPERR_SERVERDOWN
260 #define DRARPERR_SERVERDOWN 3
261 #endif
263 #ifndef DRARPERR_MOVED
264 #define DRARPERR_MOVED 4
265 #endif
267 #ifndef DRARPERR_FAILURE
268 #define DRARPERR_FAILURE 5
269 #endif
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" },
301 {0, NULL}};
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" },
309 {0, NULL}};
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" },
334 {0, NULL} };
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) \
346 && (ar_hln) == 6)
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
359 * must be 4 bytes.
361 #define ARP_PRO_IS_IPv4(ar_pro, ar_pln) \
362 (((ar_pro) == ETHERTYPE_IP || (ar_pro) == AX25_P_IP) && (ar_pln) == 4)
364 const char *
365 tvb_arphrdaddr_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int ad_len, uint16_t type)
367 if (ad_len == 0)
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
371 address). */
372 return tvb_ether_to_str(scope, tvb, offset);
374 return tvb_bytes_to_str(scope, tvb, offset, ad_len);
377 static const char *
378 arpproaddr_to_str(wmem_allocator_t *scope, const uint8_t *ad, int ad_len, uint16_t type)
380 address addr;
382 if (ad_len == 0)
383 return "<No address>";
384 if (ARP_PRO_IS_IPv4(type, ad_len)) {
385 /* IPv4 address. */
386 set_address(&addr, AT_IPv4, 4, ad);
388 return address_to_str(scope, &addr);
390 if (ARP_HW_IS_AX25(type, ad_len)) {
392 /* AX.25 address */
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);
401 static const char *
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);
408 static const char *
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;
413 if (ad_len == 0)
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);
421 } else {
423 * NSAP.
425 * XXX - break down into subcomponents.
427 return tvb_bytes_to_str(scope, tvb, offset, ad_len);
431 static const char *
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;
436 if (ad_len == 0)
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
444 * is E.164).
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" },
545 {0, NULL }
548 /* Offsets of fields within an ARP packet. */
549 #define AR_HRD 0
550 #define AR_PRO 2
551 #define AR_HLN 4
552 #define AR_PLN 5
553 #define AR_OP 6
554 #define MIN_ARP_HEADER_SIZE 8
556 /* Offsets of fields within an ATMARP packet. */
557 #define ATM_AR_HRD 0
558 #define ATM_AR_PRO 2
559 #define ATM_AR_SHTL 4
560 #define ATM_AR_SSTL 5
561 #define ATM_AR_OP 6
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
568 static void
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;
573 proto_item *ti;
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);
578 else {
579 ti = proto_tree_add_item(tree, hf_nsap, tvb, offset, len, ENC_BIG_ENDIAN);
580 if (len >= 20) {
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"},
594 { 0, NULL}
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.
602 void
603 dissect_atm_nsap(tvbuff_t *tvb, packet_info* pinfo, int offset, int len, proto_tree *tree)
605 uint8_t afi;
606 proto_item* ti;
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);
610 switch (afi) {
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);
619 break;
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);
628 break;
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);
637 break;
639 default:
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);
642 break;
646 /* l.s. 32 bits are ipv4 address */
647 static unsigned
648 address_hash_func(const void *v)
650 return GPOINTER_TO_UINT(v);
653 /* Compare 2 ipv4 addresses */
654 static int
655 address_equal_func(const void *v, const void *v2)
657 return v == v2;
660 static unsigned
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);
667 static int
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) */
681 static bool
682 check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree,
683 tvbuff_t *tvb,
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,
694 &result_key);
696 else {
697 /* First time around, need to work out if represents duplicate and
698 store result */
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 */
704 if (value != NULL)
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;
714 else
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);
727 else
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;
735 /* Add it */
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;
743 proto_item *ti;
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);
749 /* Create subtree */
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),
755 result->frame_num);
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,
763 &ei_seq_arp_dup_ip,
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,
770 tvb, 0, 0,
771 (uint32_t)(pinfo->abs_ts.secs - result->time_of_entry));
772 proto_item_set_generated(ti);
774 /* Set out parameter */
775 *duplicate_ip = ip;
779 return (result != NULL);
784 /* Take note that a request has been seen */
785 static void
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)
791 arp_request_count++;
795 /* Has storm request rate been exceeded with this request? */
796 static void
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);
806 else
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) ||
815 (gap < 0))
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);
821 return;
823 else
824 if (arp_request_count > global_arp_detect_request_storm_packets)
826 /* Storm detected, record and reset start time. */
827 report_storm = true;
828 p_add_proto_data(wmem_file_scope(), pinfo, proto_arp, 0, (void*)STORM);
829 time_at_start_of_count = pinfo->abs_ts;
831 else
833 /* Threshold not exceeded yet - no storm */
834 p_add_proto_data(wmem_file_scope(), pinfo, proto_arp, 0, (void*)NO_STORM);
838 if (report_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.
853 static int
854 dissect_atmarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
856 uint16_t ar_hrd;
857 uint16_t ar_pro;
858 uint8_t ar_shtl;
859 uint8_t ar_shl;
860 uint8_t ar_sstl;
861 uint8_t ar_ssl;
862 uint16_t ar_op;
863 uint8_t ar_spln;
864 uint8_t ar_thtl;
865 uint8_t ar_thl;
866 uint8_t ar_tstl;
867 uint8_t ar_tsl;
868 uint8_t ar_tpln;
869 int tot_len;
870 proto_tree *arp_tree;
871 proto_item *ti;
872 const char *op_str;
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;
877 proto_tree *tl_tree;
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
898 was padding. */
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;
906 if (ar_ssl != 0) {
907 ssa_str = atmarpsubaddr_to_str(pinfo->pool, tvb, ssa_offset, ar_sstl);
908 } else {
909 ssa_str = NULL;
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;
919 if (ar_tsl != 0) {
920 tsa_str = atmarpsubaddr_to_str(pinfo->pool, tvb, tsa_offset, ar_tstl);
921 } else {
922 tsa_str = NULL;
925 tpa_offset = tsa_offset + ar_tsl;
926 tpa_str = tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_tpln, ar_pro);
928 switch (ar_op) {
930 case ARPOP_REQUEST:
931 case ARPOP_REPLY:
932 case ATMARPOP_NAK:
933 default:
934 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMARP");
935 break;
937 case ARPOP_RREQUEST:
938 case ARPOP_RREPLY:
939 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMRARP");
940 break;
942 case ARPOP_IREQUEST:
943 case ARPOP_IREPLY:
944 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ATMARP");
945 break;
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:
952 case ARPOP_MARS_NAK:
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");
960 break;
962 case ARPOP_MAPOS_UNARP:
963 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
964 break;
968 switch (ar_op) {
969 case ARPOP_REQUEST:
970 col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
971 tpa_str, spa_str);
972 break;
973 case ARPOP_REPLY:
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 : ""));
977 break;
978 case ARPOP_IREQUEST:
979 col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s%s%s? Tell %s%s%s",
980 tha_str,
981 ((tsa_str != NULL) ? "," : ""),
982 ((tsa_str != NULL) ? tsa_str : ""),
983 sha_str,
984 ((ssa_str != NULL) ? "," : ""),
985 ((ssa_str != NULL) ? ssa_str : ""));
986 break;
987 case ARPOP_IREPLY:
988 col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s is at %s",
989 sha_str,
990 ((ssa_str != NULL) ? "," : ""),
991 ((ssa_str != NULL) ? ssa_str : ""),
992 spa_str);
993 break;
994 case ATMARPOP_NAK:
995 col_add_fstr(pinfo->cinfo, COL_INFO, "I don't know where %s is", spa_str);
996 break;
997 case ARPOP_MARS_REQUEST:
998 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS request from %s%s%s at %s",
999 sha_str,
1000 ((ssa_str != NULL) ? "," : ""),
1001 ((ssa_str != NULL) ? ssa_str : ""),
1002 spa_str);
1003 break;
1005 case ARPOP_MARS_MULTI:
1006 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MULTI request from %s%s%s at %s",
1007 sha_str,
1008 ((ssa_str != NULL) ? "," : ""),
1009 ((ssa_str != NULL) ? ssa_str : ""),
1010 spa_str);
1011 break;
1013 case ARPOP_MARS_MSERV:
1014 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MSERV request from %s%s%s at %s",
1015 sha_str,
1016 ((ssa_str != NULL) ? "," : ""),
1017 ((ssa_str != NULL) ? ssa_str : ""),
1018 spa_str);
1019 break;
1021 case ARPOP_MARS_JOIN:
1022 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS JOIN request from %s%s%s at %s",
1023 sha_str,
1024 ((ssa_str != NULL) ? "," : ""),
1025 ((ssa_str != NULL) ? ssa_str : ""),
1026 spa_str);
1027 break;
1029 case ARPOP_MARS_LEAVE:
1030 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS LEAVE from %s%s%s at %s",
1031 sha_str,
1032 ((ssa_str != NULL) ? "," : ""),
1033 ((ssa_str != NULL) ? ssa_str : ""),
1034 spa_str);
1035 break;
1037 case ARPOP_MARS_NAK:
1038 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS NAK from %s%s%s at %s",
1039 sha_str,
1040 ((ssa_str != NULL) ? "," : ""),
1041 ((ssa_str != NULL) ? ssa_str : ""),
1042 spa_str);
1043 break;
1045 case ARPOP_MARS_UNSERV:
1046 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS UNSERV request from %s%s%s at %s",
1047 sha_str,
1048 ((ssa_str != NULL) ? "," : ""),
1049 ((ssa_str != NULL) ? ssa_str : ""),
1050 spa_str);
1051 break;
1053 case ARPOP_MARS_SJOIN:
1054 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SJOIN request from %s%s%s at %s",
1055 sha_str,
1056 ((ssa_str != NULL) ? "," : ""),
1057 ((ssa_str != NULL) ? ssa_str : ""),
1058 spa_str);
1059 break;
1061 case ARPOP_MARS_SLEAVE:
1062 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SLEAVE from %s%s%s at %s",
1063 sha_str,
1064 ((ssa_str != NULL) ? "," : ""),
1065 ((ssa_str != NULL) ? ssa_str : ""),
1066 spa_str);
1067 break;
1069 case ARPOP_MARS_GROUPLIST_REQUEST:
1070 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist request from %s%s%s at %s",
1071 sha_str,
1072 ((ssa_str != NULL) ? "," : ""),
1073 ((ssa_str != NULL) ? ssa_str : ""),
1074 spa_str);
1075 break;
1077 case ARPOP_MARS_GROUPLIST_REPLY:
1078 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist reply from %s%s%s at %s",
1079 sha_str,
1080 ((ssa_str != NULL) ? "," : ""),
1081 ((ssa_str != NULL) ? ssa_str : ""),
1082 spa_str);
1083 break;
1085 case ARPOP_MARS_REDIRECT_MAP:
1086 col_add_fstr(pinfo->cinfo, COL_INFO, "MARS redirect map from %s%s%s at %s",
1087 sha_str,
1088 ((ssa_str != NULL) ? "," : ""),
1089 ((ssa_str != NULL) ? ssa_str : ""),
1090 spa_str);
1091 break;
1093 case ARPOP_MAPOS_UNARP:
1094 col_add_fstr(pinfo->cinfo, COL_INFO, "MAPOS UNARP request from %s%s%s at %s",
1095 sha_str,
1096 ((ssa_str != NULL) ? "," : ""),
1097 ((ssa_str != NULL) ? ssa_str : ""),
1098 spa_str);
1099 break;
1101 case ARPOP_EXP1:
1102 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1103 break;
1105 case ARPOP_EXP2:
1106 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1107 break;
1109 case 0:
1110 case 65535:
1111 col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1112 break;
1114 default:
1115 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ATMARP opcode 0x%04x", ar_op);
1116 break;
1119 if (tree) {
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)",
1123 op_str);
1124 else
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) ?
1137 "E.164" :
1138 "ATM Forum NSAPA",
1139 ar_shl);
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) ?
1147 "E.164" :
1148 "ATM Forum NSAPA",
1149 ar_ssl);
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) ?
1162 "E.164" :
1163 "ATM Forum NSAPA",
1164 ar_thl);
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) ?
1172 "E.164" :
1173 "ATM Forum NSAPA",
1174 ar_tsl);
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);
1180 if (ar_shl != 0)
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);
1184 if (ar_ssl != 0)
1185 proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_src_atm_subaddr, tvb, ssa_offset,
1186 ar_ssl, NULL, "%s", ssa_str);
1188 if (ar_spln != 0) {
1189 proto_tree_add_item(arp_tree,
1190 ARP_PRO_IS_IPv4(ar_pro, ar_spln) ? hf_arp_src_proto_ipv4
1191 : hf_arp_src_proto,
1192 tvb, spa_offset, ar_spln, ENC_BIG_ENDIAN);
1195 if (ar_thl != 0)
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);
1199 if (ar_tsl != 0)
1200 proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_dst_atm_subaddr, tvb, tsa_offset,
1201 ar_tsl, NULL, "%s", tsa_str);
1203 if (ar_tpln != 0) {
1204 proto_tree_add_item(arp_tree,
1205 ARP_PRO_IS_IPv4(ar_pro, ar_tpln) ? hf_arp_dst_proto_ipv4
1206 : hf_arp_dst_proto,
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.
1216 static int
1217 dissect_ax25arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1219 #define ARP_AX25 204
1221 uint16_t ar_hrd;
1222 uint16_t ar_pro;
1223 uint8_t ar_hln;
1224 uint8_t ar_pln;
1225 uint16_t ar_op;
1226 int tot_len;
1227 proto_tree *arp_tree = NULL;
1228 proto_item *ti;
1229 const char *op_str;
1230 int sha_offset, spa_offset, tha_offset, tpa_offset;
1231 const char *spa_str, *tpa_str;
1232 bool is_gratuitous;
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);
1242 /* Operation */
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
1249 was padding. */
1250 tvb_set_reported_length(tvb, tot_len);
1252 switch (ar_op) {
1254 case ARPOP_REQUEST:
1255 if (global_arp_detect_request_storm)
1256 request_seen(pinfo);
1257 /* fall-through */
1258 case ARPOP_REPLY:
1259 default:
1260 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1261 break;
1263 case ARPOP_RREQUEST:
1264 case ARPOP_RREPLY:
1265 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1266 break;
1268 case ARPOP_IREQUEST:
1269 case ARPOP_IREPLY:
1270 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1271 break;
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;
1296 else
1297 is_gratuitous = false;
1299 switch (ar_op) {
1300 case ARPOP_REQUEST:
1301 if (is_gratuitous)
1302 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)", tpa_str);
1303 else
1304 col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s", tpa_str, spa_str);
1305 break;
1306 case ARPOP_REPLY:
1307 if (is_gratuitous)
1308 col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)", spa_str);
1309 else
1310 col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1311 spa_str,
1312 tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd));
1313 break;
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));
1319 break;
1320 case ARPOP_RREPLY:
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),
1323 tpa_str);
1324 break;
1325 case ARPOP_IREPLY:
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),
1328 spa_str);
1329 break;
1330 default:
1331 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1332 break;
1335 if (tree) {
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);
1343 } else
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);
1352 if (ar_hln != 0) {
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);
1357 if (ar_pln != 0) {
1358 proto_tree_add_item(arp_tree,
1359 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_src_proto_ipv4
1360 : hf_arp_src_proto,
1361 tvb, spa_offset, ar_pln, false);
1363 if (ar_hln != 0) {
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);
1368 if (ar_pln != 0) {
1369 proto_tree_add_item(arp_tree,
1370 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_dst_proto_ipv4
1371 : hf_arp_dst_proto,
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);
1383 static bool
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);
1387 return true;
1390 static const uint8_t mac_allzero[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1392 static int
1393 dissect_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1395 uint16_t ar_hrd;
1396 uint32_t ar_pro, ar_hln, ar_pln, ar_op;
1397 int tot_len;
1398 proto_tree *arp_tree;
1399 proto_item *arp_item, *item;
1400 const char *op_str;
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);
1438 /* Operation */
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
1446 was padding. */
1447 tvb_set_reported_length(tvb, tot_len);
1449 switch (ar_op) {
1451 case ARPOP_REQUEST:
1452 if (global_arp_detect_request_storm)
1454 request_seen(pinfo);
1456 /* FALLTHRU */
1457 case ARPOP_REPLY:
1458 default:
1459 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1460 break;
1462 case ARPOP_RREQUEST:
1463 case ARPOP_RREPLY:
1464 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1465 break;
1467 case ARPOP_DRARPREQUEST:
1468 case ARPOP_DRARPREPLY:
1469 case ARPOP_DRARPERROR:
1470 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRARP");
1471 break;
1473 case ARPOP_IREQUEST:
1474 case ARPOP_IREPLY:
1475 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1476 break;
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");
1491 break;
1493 case ARPOP_MAPOS_UNARP:
1494 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
1495 break;
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 */
1514 uint32_t ip;
1515 const uint8_t *mac;
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,
1532 &duplicate_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,
1558 &duplicate_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;
1578 else {
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))
1581 is_probe = true;
1583 switch (ar_op) {
1584 case ARPOP_REQUEST:
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));
1589 } else {
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));
1597 } else {
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));
1602 break;
1603 case ARPOP_REPLY:
1604 if (is_gratuitous)
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));
1607 else
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));
1611 break;
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));
1618 break;
1619 case ARPOP_RREPLY:
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));
1624 break;
1626 case ARPOP_DRARPERROR:
1627 col_set_str(pinfo->cinfo, COL_INFO, "DRARP Error");
1628 break;
1630 case ARPOP_IREPLY:
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));
1634 break;
1636 case ATMARPOP_NAK:
1637 col_set_str(pinfo->cinfo, COL_INFO, "ARP NAK");
1638 break;
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));
1644 break;
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));
1650 break;
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));
1656 break;
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));
1662 break;
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));
1668 break;
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));
1674 break;
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));
1680 break;
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));
1686 break;
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));
1692 break;
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));
1698 break;
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));
1704 break;
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));
1710 break;
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));
1716 break;
1718 case ARPOP_EXP1:
1719 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1720 break;
1722 case ARPOP_EXP2:
1723 col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1724 break;
1726 case 0:
1727 case 65535:
1728 col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1729 break;
1731 default:
1732 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1733 break;
1736 if (tree) {
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";
1742 if (is_probe)
1743 op_str = "ARP Probe";
1744 if (is_announcement)
1745 op_str = "ARP Announcement";
1747 proto_item_append_text(arp_item, " (%s)", op_str);
1748 } else {
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);
1756 if (is_probe) {
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);
1764 if (ar_hln != 0) {
1765 proto_tree_add_item(arp_tree,
1766 ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1767 hf_arp_src_hw_mac :
1768 hf_arp_src_hw,
1769 tvb, sha_offset, ar_hln, ENC_BIG_ENDIAN);
1771 if (ar_pln != 0) {
1772 proto_tree_add_item(arp_tree,
1773 ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
1774 hf_arp_src_proto_ipv4 :
1775 hf_arp_src_proto,
1776 tvb, spa_offset, ar_pln, ENC_BIG_ENDIAN);
1778 if (ar_hln != 0) {
1779 proto_tree_add_item(arp_tree,
1780 ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1781 hf_arp_dst_hw_mac :
1782 hf_arp_dst_hw,
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 :
1789 hf_arp_dst_proto,
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);
1811 void
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,
1820 NULL, HFILL }},
1822 { &hf_arp_proto_type,
1823 { "Protocol type", "arp.proto.type",
1824 FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
1825 NULL, HFILL }},
1827 { &hf_arp_hard_size,
1828 { "Hardware size", "arp.hw.size",
1829 FT_UINT8, BASE_DEC, NULL, 0x0,
1830 NULL, HFILL }},
1832 { &hf_atmarp_sht,
1833 { "Sender ATM number type", "arp.src.htype",
1834 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1835 NULL, HFILL }},
1837 { &hf_atmarp_shl,
1838 { "Sender ATM number length", "arp.src.hlen",
1839 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1840 NULL, HFILL }},
1842 { &hf_atmarp_sst,
1843 { "Sender ATM subaddress type", "arp.src.stype",
1844 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1845 NULL, HFILL }},
1847 { &hf_atmarp_ssl,
1848 { "Sender ATM subaddress length", "arp.src.slen",
1849 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1850 NULL, HFILL }},
1852 { &hf_arp_proto_size,
1853 { "Protocol size", "arp.proto.size",
1854 FT_UINT8, BASE_DEC, NULL, 0x0,
1855 NULL, HFILL }},
1857 { &hf_arp_opcode,
1858 { "Opcode", "arp.opcode",
1859 FT_UINT16, BASE_DEC, VALS(op_vals), 0x0,
1860 NULL, HFILL }},
1862 { &hf_arp_isgratuitous,
1863 { "Is gratuitous", "arp.isgratuitous",
1864 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1865 NULL, HFILL }},
1867 { &hf_arp_isprobe,
1868 { "Is probe", "arp.isprobe",
1869 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1870 NULL, HFILL }},
1872 { &hf_arp_isannouncement,
1873 { "Is announcement", "arp.isannouncement",
1874 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1875 NULL, HFILL }},
1877 { &hf_atmarp_spln,
1878 { "Sender protocol size", "arp.src.pln",
1879 FT_UINT8, BASE_DEC, NULL, 0x0,
1880 NULL, HFILL }},
1882 { &hf_atmarp_tht,
1883 { "Target ATM number type", "arp.dst.htype",
1884 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1885 NULL, HFILL }},
1887 { &hf_atmarp_thl,
1888 { "Target ATM number length", "arp.dst.hlen",
1889 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1890 NULL, HFILL }},
1892 { &hf_atmarp_tst,
1893 { "Target ATM subaddress type", "arp.dst.stype",
1894 FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
1895 NULL, HFILL }},
1897 { &hf_atmarp_tsl,
1898 { "Target ATM subaddress length", "arp.dst.slen",
1899 FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
1900 NULL, HFILL }},
1902 { &hf_atmarp_tpln,
1903 { "Target protocol size", "arp.dst.pln",
1904 FT_UINT8, BASE_DEC, NULL, 0x0,
1905 NULL, HFILL }},
1907 { &hf_arp_src_hw,
1908 { "Sender hardware address", "arp.src.hw",
1909 FT_BYTES, BASE_NONE, NULL, 0x0,
1910 NULL, HFILL }},
1912 { &hf_arp_src_hw_mac,
1913 { "Sender MAC address", "arp.src.hw_mac",
1914 FT_ETHER, BASE_NONE, NULL, 0x0,
1915 NULL, HFILL }},
1917 { &hf_arp_src_hw_ax25,
1918 { "Sender AX.25 address", "arp.src.hw_ax25",
1919 FT_AX25, BASE_NONE, NULL, 0x0,
1920 NULL, HFILL }},
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,
1925 NULL, HFILL }},
1927 { &hf_atmarp_src_atm_num_nsap,
1928 { "Sender ATM number (NSAP)", "arp.src.atm_num_nsap",
1929 FT_BYTES, BASE_NONE, NULL, 0x0,
1930 NULL, HFILL }},
1932 { &hf_atmarp_src_atm_subaddr,
1933 { "Sender ATM subaddress", "arp.src.atm_subaddr",
1934 FT_BYTES, BASE_NONE, NULL, 0x0,
1935 NULL, HFILL }},
1937 { &hf_arp_src_proto,
1938 { "Sender protocol address", "arp.src.proto",
1939 FT_BYTES, BASE_NONE, NULL, 0x0,
1940 NULL, HFILL }},
1942 { &hf_arp_src_proto_ipv4,
1943 { "Sender IP address", "arp.src.proto_ipv4",
1944 FT_IPv4, BASE_NONE, NULL, 0x0,
1945 NULL, HFILL }},
1947 { &hf_arp_dst_hw,
1948 { "Target hardware address", "arp.dst.hw",
1949 FT_BYTES, BASE_NONE, NULL, 0x0,
1950 NULL, HFILL }},
1952 { &hf_arp_dst_hw_mac,
1953 { "Target MAC address", "arp.dst.hw_mac",
1954 FT_ETHER, BASE_NONE, NULL, 0x0,
1955 NULL, HFILL }},
1957 { &hf_arp_dst_hw_ax25,
1958 { "Target AX.25 address", "arp.dst.hw_ax25",
1959 FT_AX25, BASE_NONE, NULL, 0x0,
1960 NULL, HFILL }},
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,
1965 NULL, HFILL }},
1967 { &hf_atmarp_dst_atm_num_nsap,
1968 { "Target ATM number (NSAP)", "arp.dst.atm_num_nsap",
1969 FT_BYTES, BASE_NONE, NULL, 0x0,
1970 NULL, HFILL }},
1972 { &hf_atmarp_dst_atm_subaddr,
1973 { "Target ATM subaddress", "arp.dst.atm_subaddr",
1974 FT_BYTES, BASE_NONE, NULL, 0x0,
1975 NULL, HFILL }},
1977 { &hf_arp_dst_proto,
1978 { "Target protocol address", "arp.dst.proto",
1979 FT_BYTES, BASE_NONE, NULL, 0x0,
1980 NULL, HFILL }},
1982 { &hf_arp_dst_proto_ipv4,
1983 { "Target IP address", "arp.dst.proto_ipv4",
1984 FT_IPv4, BASE_NONE, NULL, 0x0,
1985 NULL, HFILL }},
1987 { &hf_drarp_error_status,
1988 { "DRARP error status", "arp.dst.drarp_error_status",
1989 FT_UINT16, BASE_DEC, VALS(drarp_status), 0x0,
1990 NULL, HFILL }},
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,
1995 NULL, HFILL }},
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,
2000 NULL, HFILL }},
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[] = {
2017 &ett_arp,
2018 &ett_atmarp_nsap,
2019 &ett_atmarp_tl,
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",
2033 "ARP/RARP", "arp");
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);
2049 /* Preferences */
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);
2086 void
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
2109 * Local Variables:
2110 * c-basic-offset: 2
2111 * tab-width: 8
2112 * indent-tabs-mode: nil
2113 * End:
2115 * ex: set shiftwidth=2 tabstop=8 expandtab:
2116 * :indentSize=2:tabSize=8:noTabs=true: