Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-arp.c
Line
Count
Source
1
/* packet-arp.c
2
 * Routines for ARP packet disassembly (RFC 826)
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * By Deepti Ragha <dlragha@ncsu.edu>
9
 * Copyright 2012 Deepti Ragha
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
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/osi-utils.h>
23
#include <epan/prefs.h>
24
#include <epan/expert.h>
25
#include <epan/proto_data.h>
26
#include <epan/tfs.h>
27
#include "packet-arcnet.h"
28
#include "packet-ax25.h"
29
30
void proto_register_arp(void);
31
void proto_reg_handoff_arp(void);
32
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;
46
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;
65
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;
84
85
static int hf_arp_dst_hw_ax25;
86
static int hf_arp_src_hw_ax25;
87
88
static int ett_arp;
89
static int ett_atmarp_nsap;
90
static int ett_atmarp_tl;
91
static int ett_arp_duplicate_address;
92
93
static expert_field ei_seq_arp_dup_ip;
94
static expert_field ei_seq_arp_storm;
95
static expert_field ei_arp_dst_nonzero_probe;
96
static expert_field ei_atmarp_src_atm_unknown_afi;
97
98
static dissector_handle_t arp_handle;
99
100
static dissector_table_t arp_hw_table;
101
102
static capture_dissector_handle_t arp_cap_handle;
103
104
/* Used for determining if frequency of ARP requests constitute a storm */
105
0
#define STORM    1
106
0
#define NO_STORM 2
107
108
/* Preference settings */
109
static bool global_arp_detect_request_storm;
110
static uint32_t global_arp_detect_request_storm_packets = 30;
111
static uint32_t global_arp_detect_request_storm_period = 100;
112
113
static bool global_arp_detect_duplicate_ip_addresses = true;
114
static bool global_arp_register_network_address_binding = true;
115
116
static uint32_t arp_request_count;
117
static nstime_t time_at_start_of_count;
118
119
120
/* Map of (IP address -> MAC address) to detect duplicate IP addresses
121
   Key is unsigned32 */
122
static wmem_map_t *address_hash_table;
123
124
typedef struct address_hash_value {
125
  uint8_t   mac[6];
126
  unsigned  frame_num;
127
  time_t    time_of_entry;
128
} address_hash_value;
129
130
/* Map of ((frame Num, IP address) -> MAC address) */
131
static wmem_map_t *duplicate_result_hash_table;
132
133
typedef struct duplicate_result_key {
134
  uint32_t frame_number;
135
  uint32_t ip_address;
136
} duplicate_result_key;
137
138
139
/* Definitions taken from Linux "linux/if_arp.h" header file, and from
140
141
   http://www.iana.org/assignments/arp-parameters
142
143
*/
144
145
146
/* ARP / RARP structs and definitions */
147
#ifndef ARPOP_REQUEST
148
158
#define ARPOP_REQUEST  1       /* ARP request.  */
149
#endif
150
#ifndef ARPOP_REPLY
151
160
#define ARPOP_REPLY    2       /* ARP reply.  */
152
#endif
153
/* Some OSes have different names, or don't define these at all */
154
#ifndef ARPOP_RREQUEST
155
0
#define ARPOP_RREQUEST 3       /* RARP request.  */
156
#endif
157
#ifndef ARPOP_RREPLY
158
2
#define ARPOP_RREPLY   4       /* RARP reply.  */
159
#endif
160
161
/* Additional parameters as per https://www.iana.org/assignments/arp-parameters */
162
#ifndef ARPOP_DRARPREQUEST
163
3
#define ARPOP_DRARPREQUEST 5   /* DRARP request.  */
164
#endif
165
166
#ifndef ARPOP_DRARPREPLY
167
9
#define ARPOP_DRARPREPLY 6     /* DRARP reply.  */
168
#endif
169
170
#ifndef ARPOP_DRARPERROR
171
15
#define ARPOP_DRARPERROR 7     /* DRARP error.  */
172
#endif
173
174
#ifndef ARPOP_IREQUEST
175
6
#define ARPOP_IREQUEST 8       /* Inverse ARP (RFC 1293) request.  */
176
#endif
177
#ifndef ARPOP_IREPLY
178
3
#define ARPOP_IREPLY   9       /* Inverse ARP reply.  */
179
#endif
180
#ifndef ATMARPOP_NAK
181
0
#define ATMARPOP_NAK   10      /* ATMARP NAK.  */
182
#endif
183
184
/* Additional parameters as per https://www.iana.org/assignments/arp-parameters */
185
#ifndef ARPOP_MARS_REQUEST
186
0
#define ARPOP_MARS_REQUEST   11       /*MARS request message. */
187
#endif
188
189
#ifndef ARPOP_MARS_MULTI
190
0
#define ARPOP_MARS_MULTI   12       /*MARS-Multi message. */
191
#endif
192
193
#ifndef ARPOP_MARS_MSERV
194
2
#define ARPOP_MARS_MSERV   13       /*MARS-Mserv message. */
195
#endif
196
197
#ifndef ARPOP_MARS_JOIN
198
3
#define ARPOP_MARS_JOIN  14       /*MARS-Join request. */
199
#endif
200
201
#ifndef ARPOP_MARS_LEAVE
202
2
#define ARPOP_MARS_LEAVE   15       /*MARS Leave request. */
203
#endif
204
205
#ifndef ARPOP_MARS_NAK
206
2
#define ARPOP_MARS_NAK   16       /*MARS nak message.*/
207
#endif
208
209
#ifndef ARPOP_MARS_UNSERV
210
2
#define ARPOP_MARS_UNSERV   17       /*MARS Unserv message. */
211
#endif
212
213
#ifndef ARPOP_MARS_SJOIN
214
2
#define ARPOP_MARS_SJOIN   18       /*MARS Sjoin message. */
215
#endif
216
217
#ifndef ARPOP_MARS_SLEAVE
218
4
#define ARPOP_MARS_SLEAVE   19       /*MARS Sleave message. */
219
#endif
220
221
#ifndef ARPOP_MARS_GROUPLIST_REQUEST
222
3
#define ARPOP_MARS_GROUPLIST_REQUEST   20       /*MARS Grouplist request message. */
223
#endif
224
225
#ifndef ARPOP_MARS_GROUPLIST_REPLY
226
23
#define ARPOP_MARS_GROUPLIST_REPLY   21       /*MARS Grouplist reply message. */
227
#endif
228
229
#ifndef ARPOP_MARS_REDIRECT_MAP
230
13
#define ARPOP_MARS_REDIRECT_MAP   22       /*MARS Grouplist request message. */
231
#endif
232
233
#ifndef ARPOP_MAPOS_UNARP
234
0
#define ARPOP_MAPOS_UNARP   23 /*MAPOS UNARP*/
235
#endif
236
237
#ifndef ARPOP_EXP1
238
0
#define ARPOP_EXP1     24      /* Experimental 1 */
239
#endif
240
#ifndef ARPOP_EXP2
241
0
#define ARPOP_EXP2     25      /* Experimental 2 */
242
#endif
243
244
#ifndef ARPOP_RESERVED1
245
#define ARPOP_RESERVED1         0  /*Reserved opcode 1*/
246
#endif
247
248
#ifndef ARPOP_RESERVED2
249
#define ARPOP_RESERVED2         65535 /*Reserved opcode 2*/
250
#endif
251
252
#ifndef DRARPERR_RESTRICTED
253
#define DRARPERR_RESTRICTED      1
254
#endif
255
256
#ifndef DRARPERR_NOADDRESSES
257
#define DRARPERR_NOADDRESSES     2
258
#endif
259
260
#ifndef DRARPERR_SERVERDOWN
261
#define DRARPERR_SERVERDOWN     3
262
#endif
263
264
#ifndef DRARPERR_MOVED
265
#define DRARPERR_MOVED     4
266
#endif
267
268
#ifndef DRARPERR_FAILURE
269
#define DRARPERR_FAILURE     5
270
#endif
271
272
273
274
static const value_string op_vals[] = {
275
  {ARPOP_REQUEST,                "request"                },
276
  {ARPOP_REPLY,                  "reply"                  },
277
  {ARPOP_RREQUEST,               "reverse request"        },
278
  {ARPOP_RREPLY,                 "reverse reply"          },
279
  {ARPOP_DRARPREQUEST,           "drarp request"          },
280
  {ARPOP_DRARPREPLY,             "drarp reply"            },
281
  {ARPOP_DRARPERROR,             "drarp error"            },
282
  {ARPOP_IREQUEST,               "inverse request"        },
283
  {ARPOP_IREPLY,                 "inverse reply"          },
284
  {ATMARPOP_NAK,                 "arp nak"                },
285
  {ARPOP_MARS_REQUEST,           "mars request"           },
286
  {ARPOP_MARS_MULTI,             "mars multi"             },
287
  {ARPOP_MARS_MSERV,             "mars mserv"             },
288
  {ARPOP_MARS_JOIN,              "mars join"              },
289
  {ARPOP_MARS_LEAVE,             "mars leave"             },
290
  {ARPOP_MARS_NAK,               "mars nak"               },
291
  {ARPOP_MARS_UNSERV,            "mars unserv"            },
292
  {ARPOP_MARS_SJOIN,             "mars sjoin"             },
293
  {ARPOP_MARS_SLEAVE,            "mars sleave"            },
294
  {ARPOP_MARS_GROUPLIST_REQUEST, "mars grouplist request" },
295
  {ARPOP_MARS_GROUPLIST_REPLY,   "mars grouplist reply"   },
296
  {ARPOP_MARS_REDIRECT_MAP,      "mars redirect map"      },
297
  {ARPOP_MAPOS_UNARP,            "mapos unarp"            },
298
  {ARPOP_EXP1,                   "experimental 1"         },
299
  {ARPOP_EXP2,                   "experimental 2"         },
300
  {ARPOP_RESERVED1,              "reserved"               },
301
  {ARPOP_RESERVED2,              "reserved"               },
302
  {0, NULL}};
303
304
static const value_string drarp_status[]={
305
{DRARPERR_RESTRICTED,  "restricted" },
306
{DRARPERR_NOADDRESSES, "no address" },
307
{DRARPERR_SERVERDOWN,  "serverdown" },
308
{DRARPERR_MOVED,       "moved"      },
309
{DRARPERR_FAILURE,     "failure"    },
310
{0, NULL}};
311
312
static const value_string atmop_vals[] = {
313
  {ARPOP_REQUEST,                "request"                },
314
  {ARPOP_REPLY,                  "reply"                  },
315
  {ARPOP_IREQUEST,               "inverse request"        },
316
  {ARPOP_IREPLY,                 "inverse reply"          },
317
  {ATMARPOP_NAK,                 "nak"                    },
318
  {ARPOP_MARS_REQUEST,           "mars request"           },
319
  {ARPOP_MARS_MULTI,             "mars multi"             },
320
  {ARPOP_MARS_MSERV,             "mars mserv"             },
321
  {ARPOP_MARS_JOIN,              "mars join"              },
322
  {ARPOP_MARS_LEAVE,             "mars leave"             },
323
  {ARPOP_MARS_NAK,               "mars nak"               },
324
  {ARPOP_MARS_UNSERV,            "mars unserv"            },
325
  {ARPOP_MARS_SJOIN,             "mars sjoin"             },
326
  {ARPOP_MARS_SLEAVE,            "mars sleave"            },
327
  {ARPOP_MARS_GROUPLIST_REQUEST, "mars grouplist request" },
328
  {ARPOP_MARS_GROUPLIST_REPLY,   "mars grouplist reply"   },
329
  {ARPOP_MARS_REDIRECT_MAP,      "mars redirect map"      },
330
  {ARPOP_MAPOS_UNARP,            "mapos unarp"            },
331
  {ARPOP_EXP1,                   "experimental 1"         },
332
  {ARPOP_EXP2,                   "experimental 2"         },
333
  {ARPOP_RESERVED1,              "reserved"               },
334
  {ARPOP_RESERVED2,              "reserved"               },
335
  {0, NULL} };
336
337
64
#define ATMARP_IS_E164  0x40    /* bit in type/length for E.164 format */
338
64
#define ATMARP_LEN_MASK 0x3F    /* length of {sub}address in type/length */
339
340
/*
341
 * Given the hardware address type and length, check whether an address
342
 * is an Ethernet address - the address must be of type "Ethernet" or
343
 * "IEEE 802.x", and the length must be 6 bytes.
344
 */
345
#define ARP_HW_IS_ETHER(ar_hrd, ar_hln)                         \
346
3.78k
  (((ar_hrd) == ARPHRD_ETHER || (ar_hrd) == ARPHRD_IEEE802)     \
347
3.78k
   && (ar_hln) == 6)
348
349
/*
350
* Given the hardware address type and length, check whether an address
351
* is an AX.25 address - the address must be of type "AX.25" and the
352
* length must be 7 bytes.
353
*/
354
#define ARP_HW_IS_AX25(ar_hrd, ar_hln) \
355
9
  ((ar_hrd) == ARPHRD_AX25 && (ar_hln) == 7)
356
357
/*
358
 * Given the protocol address type and length, check whether an address
359
 * is an IPv4 address - the address must be of type "IP", and the length
360
 * must be 4 bytes.
361
 */
362
#define ARP_PRO_IS_IPv4(ar_pro, ar_pln)         \
363
82
  (((ar_pro) == ETHERTYPE_IP || (ar_pro) == AX25_P_IP) && (ar_pln) == 4)
364
365
const char *
366
tvb_arphrdaddr_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int ad_len, uint16_t type)
367
3.93k
{
368
3.93k
  if (ad_len == 0)
369
226
    return "<No address>";
370
3.70k
  if (ARP_HW_IS_ETHER(type, ad_len)) {
371
    /* Ethernet address (or IEEE 802.x address, which is the same type of
372
       address). */
373
188
    return tvb_ether_to_str(scope, tvb, offset);
374
188
  }
375
3.51k
  return tvb_bytes_to_str(scope, tvb, offset, ad_len);
376
3.70k
}
377
378
static const char *
379
arpproaddr_to_str(wmem_allocator_t *scope, const uint8_t *ad, int ad_len, uint16_t type)
380
27
{
381
27
  address addr;
382
383
27
  if (ad_len == 0)
384
20
    return "<No address>";
385
7
  if (ARP_PRO_IS_IPv4(type, ad_len)) {
386
    /* IPv4 address.  */
387
0
    set_address(&addr, AT_IPv4, 4, ad);
388
389
0
    return address_to_str(scope, &addr);
390
0
  }
391
7
  if (ARP_HW_IS_AX25(type, ad_len)) {
392
0
    {
393
    /* AX.25 address */
394
0
    set_address(&addr, AT_AX25, AX25_ADDR_LEN, ad);
395
396
0
    return address_to_str(scope, &addr);
397
0
    }
398
0
  }
399
7
  return bytes_to_str(scope, ad, ad_len);
400
7
}
401
402
static const char *
403
tvb_arpproaddr_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int ad_len, uint16_t type)
404
27
{
405
27
    const uint8_t *ad = tvb_memdup(scope, tvb, offset, ad_len);
406
27
    return arpproaddr_to_str(scope, ad, ad_len, type);
407
27
}
408
409
static const char *
410
atmarpnum_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int ad_tl)
411
0
{
412
0
  int    ad_len = ad_tl & ATMARP_LEN_MASK;
413
414
0
  if (ad_len == 0)
415
0
    return "<No address>";
416
417
0
  if (ad_tl & ATMARP_IS_E164) {
418
    /*
419
     * I'm assuming this means it's an ASCII (IA5) string.
420
     */
421
0
    return (char *) tvb_get_string_enc(scope, tvb, offset, ad_len, ENC_ASCII|ENC_NA);
422
0
  } else {
423
    /*
424
     * NSAP.
425
     *
426
     * XXX - break down into subcomponents.
427
     */
428
0
    return tvb_bytes_to_str(scope, tvb, offset, ad_len);
429
0
  }
430
0
}
431
432
static const char *
433
atmarpsubaddr_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int ad_tl)
434
0
{
435
0
  int ad_len = ad_tl & ATMARP_LEN_MASK;
436
437
0
  if (ad_len == 0)
438
0
    return "<No address>";
439
440
  /*
441
   * E.164 isn't considered legal in subaddresses (RFC 2225 says that
442
   * a null or unknown ATM address is indicated by setting the length
443
   * to 0, in which case the type must be ignored; we've seen some
444
   * captures in which the length of a subaddress is 0 and the type
445
   * is E.164).
446
   *
447
   * XXX - break down into subcomponents?
448
   */
449
0
  return tvb_bytes_to_str(scope, tvb, offset, ad_len);
450
0
}
451
452
const value_string arp_hrd_vals[] = {
453
  {ARPHRD_NETROM,             "NET/ROM pseudo"             },
454
  {ARPHRD_ETHER,              "Ethernet"                   },
455
  {ARPHRD_EETHER,             "Experimental Ethernet"      },
456
  {ARPHRD_AX25,               "AX.25"                      },
457
  {ARPHRD_PRONET,             "ProNET"                     },
458
  {ARPHRD_CHAOS,              "Chaos"                      },
459
  {ARPHRD_IEEE802,            "IEEE 802"                   },
460
  {ARPHRD_ARCNET,             "ARCNET"                     },
461
  {ARPHRD_HYPERCH,            "Hyperchannel"               },
462
  {ARPHRD_LANSTAR,            "Lanstar"                    },
463
  {ARPHRD_AUTONET,            "Autonet Short Address"      },
464
  {ARPHRD_LOCALTLK,           "Localtalk"                  },
465
  {ARPHRD_LOCALNET,           "LocalNet"                   },
466
  {ARPHRD_ULTRALNK,           "Ultra link"                 },
467
  {ARPHRD_SMDS,               "SMDS"                       },
468
  {ARPHRD_DLCI,               "Frame Relay DLCI"           },
469
  {ARPHRD_ATM,                "ATM"                        },
470
  {ARPHRD_HDLC,               "HDLC"                       },
471
  {ARPHRD_FIBREC,             "Fibre Channel"              },
472
  {ARPHRD_ATM2225,            "ATM (RFC 2225)"             },
473
  {ARPHRD_SERIAL,             "Serial Line"                },
474
  {ARPHRD_ATM2,               "ATM"                        },
475
  {ARPHRD_MS188220,           "MIL-STD-188-220"            },
476
  {ARPHRD_METRICOM,           "Metricom STRIP"             },
477
  {ARPHRD_IEEE1394,           "IEEE 1394.1995"             },
478
  {ARPHRD_MAPOS,              "MAPOS"                      },
479
  {ARPHRD_TWINAX,             "Twinaxial"                  },
480
  {ARPHRD_EUI_64,             "EUI-64"                     },
481
  {ARPHRD_HIPARP,             "HIPARP"                     },
482
  {ARPHRD_IP_ARP_ISO_7816_3,  "IP and ARP over ISO 7816-3" },
483
  {ARPHRD_ARPSEC,             "ARPSec"                     },
484
  {ARPHRD_IPSEC_TUNNEL,       "IPsec tunnel"               },
485
  {ARPHRD_INFINIBAND,         "InfiniBand"                 },
486
  {ARPHRD_TIA_102_PRJ_25_CAI, "TIA-102 Project 25 CAI"     },
487
  {ARPHRD_WIEGAND_INTERFACE,  "Wiegand Interface"          },
488
  {ARPHRD_PURE_IP,            "Pure IP"                    },
489
  {ARPHRD_HW_EXP1,            "Experimental 1"             },
490
  {ARPHRD_HFI,                "HFI"                        },
491
  {ARPHRD_UB,                 "Unified Bus"                },
492
  {ARPHRD_HW_EXP2,            "Experimental 2"             },
493
  {ARPHRD_AETHERNET,          "AEthernet"                  },
494
  /* Virtual ARP types for non ARP hardware used in Linux cooked mode. */
495
  {ARPHRD_RSRVD,              "Notional KISS type"         },
496
  {ARPHRD_ADAPT,              "ADAPT"                      },
497
  {ARPHRD_ROSE,               "ROSE"                       },
498
  {ARPHRD_X25,                "CCITT X.25"                 },
499
  {ARPHRD_HWX25,              "Boards with X.25 in firmware"},
500
  {ARPHRD_CAN,                "Controller Area Network"    },
501
  {ARPHRD_PPP,                "PPP"                        },
502
  {ARPHRD_CISCO,              "Cisco HDLC"                 },
503
  {ARPHRD_LAPB,               "LAPB"                       },
504
  {ARPHRD_DDCMP,              "Digital's DDCMP protocol"   },
505
  {ARPHRD_RAWHDLC,            "Raw HDLC"                   },
506
  {ARPHRD_RAWIP,              "Raw IP"                     },
507
508
  {ARPHRD_TUNNEL,             "IPIP tunnel"                },
509
  {ARPHRD_TUNNEL6,            "IP6IP6 tunnel"              },
510
  {ARPHRD_FRAD,               "Frame Relay Access Device"  },
511
  {ARPHRD_SKIP,               "SKIP vif"                   },
512
  {ARPHRD_LOOPBACK,           "Loopback"                   },
513
  {ARPHRD_FDDI,               "Fiber Distributed Data Interface"},
514
  {ARPHRD_BIF,                "AP1000 BIF"                 },
515
  {ARPHRD_SIT,                "sit0 device - IPv6-in-IPv4" },
516
  {ARPHRD_IPDDP,              "IP over DDP tunneller"      },
517
  {ARPHRD_IPGRE,              "GRE over IP"                },
518
  {ARPHRD_PIMREG,             "PIMSM register interface"   },
519
  {ARPHRD_HIPPI,              "High Performance Parallel Interface"},
520
  {ARPHRD_ASH,                "Nexus 64Mbps Ash"           },
521
  {ARPHRD_ECONET,             "Acorn Econet"               },
522
  {ARPHRD_IRDA,               "Linux-IrDA"                 },
523
/* ARP works differently on different FC media .. so  */
524
  {ARPHRD_FCPP,               "Point to point fibrechannel" },
525
  {ARPHRD_FCAL,               "Fibrechannel arbitrated loop" },
526
  {ARPHRD_FCPL,               "Fibrechannel public loop"   },
527
  {ARPHRD_FCFABRIC, "Fibrechannel fabric"},
528
  /* 787->799 reserved for fibrechannel media types */
529
  {ARPHRD_IEEE802_TR,         "Magic type ident for TR"    },
530
  {ARPHRD_IEEE80211,          "IEEE 802.11"                },
531
  {ARPHRD_IEEE80211_PRISM,    "IEEE 802.11 + Prism2 header" },
532
  {ARPHRD_IEEE80211_RADIOTAP, "IEEE 802.11 + radiotap header" },
533
  {ARPHRD_IEEE802154,         "IEEE 802.15.4"              },
534
  {ARPHRD_IEEE802154_MONITOR, "IEEE 802.15.4 network monitor" },
535
536
  {ARPHRD_PHONET,             "PhoNet media type"          },
537
  {ARPHRD_PHONET_PIPE,        "PhoNet pipe header"         },
538
  {ARPHRD_CAIF,               "CAIF media type"            },
539
  {ARPHRD_IP6GRE,             "GRE over IPv6"              },
540
  {ARPHRD_NETLINK,            "Netlink"                    },
541
  {ARPHRD_6LOWPAN,            "IPv6 over LoWPAN"           },
542
  {ARPHRD_VSOCKMON,           "Vsock monitor header"       },
543
544
  {ARPHRD_VOID,               "Void type, nothing is known" },
545
  {ARPHRD_NONE,               "zero header length"         },
546
  {0, NULL                                                 }
547
};
548
549
/* Offsets of fields within an ARP packet. */
550
126
#define AR_HRD          0
551
64
#define AR_PRO          2
552
64
#define AR_HLN          4
553
64
#define AR_PLN          5
554
64
#define AR_OP           6
555
115
#define MIN_ARP_HEADER_SIZE     8
556
557
/* Offsets of fields within an ATMARP packet. */
558
0
#define ATM_AR_HRD       0
559
0
#define ATM_AR_PRO       2
560
0
#define ATM_AR_SHTL      4
561
0
#define ATM_AR_SSTL      5
562
#define ATM_AR_OP        6
563
0
#define ATM_AR_SPLN      8
564
0
#define ATM_AR_THTL      9
565
0
#define ATM_AR_TSTL     10
566
0
#define ATM_AR_TPLN     11
567
0
#define MIN_ATMARP_HEADER_SIZE  12
568
569
static void
570
dissect_atm_number(tvbuff_t *tvb, packet_info* pinfo, int offset, int tl, int hf_e164,
571
                   int hf_nsap, proto_tree *tree)
572
0
{
573
0
  int         len = tl & ATMARP_LEN_MASK;
574
0
  proto_item *ti;
575
0
  proto_tree *nsap_tree;
576
577
0
  if (tl & ATMARP_IS_E164)
578
0
    proto_tree_add_item(tree, hf_e164, tvb, offset, len, ENC_BIG_ENDIAN);
579
0
  else {
580
0
    ti = proto_tree_add_item(tree, hf_nsap, tvb, offset, len, ENC_BIG_ENDIAN);
581
0
    if (len >= 20) {
582
0
      nsap_tree = proto_item_add_subtree(ti, ett_atmarp_nsap);
583
0
      dissect_atm_nsap(tvb, pinfo, offset, len, nsap_tree);
584
0
    }
585
0
  }
586
0
}
587
588
static const value_string atm_nsap_afi_vals[] = {
589
    { NSAP_IDI_ISO_DCC_BIN,            "DCC ATM format"},
590
    { NSAP_IDI_ISO_DCC_BIN_GROUP,      "DCC ATM group format"},
591
    { NSAP_IDI_ISO_6523_ICD_BIN,       "ICD ATM format"},
592
    { NSAP_IDI_ISO_6523_ICD_BIN_GROUP, "ICD ATM group format"},
593
    { NSAP_IDI_E_164_BIN_FSD_NZ,       "E.164 ATM format"},
594
    { NSAP_IDI_E_164_BIN_FSD_NZ_GROUP, "E.164 ATM group format"},
595
    { 0,                               NULL}
596
};
597
598
/*
599
 * XXX - shouldn't there be a centralized routine for dissecting NSAPs?
600
 * See also "dissect_nsap()" in epan/dissectors/packet-isup.c and
601
 * "print_nsap_net()" in epan/osi-utils.c.
602
 */
603
void
604
dissect_atm_nsap(tvbuff_t *tvb, packet_info* pinfo, int offset, int len, proto_tree *tree)
605
0
{
606
0
  uint8_t afi;
607
0
  proto_item* ti;
608
609
0
  ti = proto_tree_add_item_ret_uint8(tree, hf_atmarp_src_atm_afi, tvb, offset, 1, ENC_BIG_ENDIAN, &afi);
610
0
  switch (afi) {
611
612
0
    case NSAP_IDI_ISO_DCC_BIN:       /* DCC ATM format */
613
0
    case NSAP_IDI_ISO_DCC_BIN_GROUP: /* DCC ATM group format */
614
0
      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
0
                          tvb, offset + 1, 2, ENC_BIG_ENDIAN);
616
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_high_order_dsp, tvb, offset + 3, 10, ENC_NA);
617
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_end_system_identifier, tvb, offset + 13, 6, ENC_NA);
618
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_selector, tvb, offset + 19, 1, ENC_BIG_ENDIAN);
619
0
      break;
620
621
0
    case NSAP_IDI_ISO_6523_ICD_BIN:       /* ICD ATM format */
622
0
    case NSAP_IDI_ISO_6523_ICD_BIN_GROUP: /* ICD ATM group format */
623
0
      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
0
                          tvb, offset + 1, 2, ENC_BIG_ENDIAN);
625
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_high_order_dsp, tvb, offset + 3, 10, ENC_NA);
626
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_end_system_identifier, tvb, offset + 13, 6, ENC_NA);
627
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_selector, tvb, offset + 19, 1, ENC_BIG_ENDIAN);
628
0
      break;
629
630
0
    case NSAP_IDI_E_164_BIN_FSD_NZ:       /* E.164 ATM format */
631
0
    case NSAP_IDI_E_164_BIN_FSD_NZ_GROUP: /* E.164 ATM group format */
632
0
      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
0
                          tvb, offset + 1, 8, ENC_NA);
634
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_high_order_dsp, tvb, offset + 9, 4, ENC_NA);
635
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_end_system_identifier, tvb, offset + 13, 6, ENC_NA);
636
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_selector, tvb, offset + 19, 1, ENC_BIG_ENDIAN);
637
0
      break;
638
639
0
    default:
640
0
      expert_add_info(pinfo, ti, &ei_atmarp_src_atm_unknown_afi);
641
0
      proto_tree_add_item(tree, hf_atmarp_src_atm_rest_of_address, tvb, offset + 1, len - 1, ENC_NA);
642
0
      break;
643
0
  }
644
0
}
645
646
/* l.s. 32 bits are ipv4 address */
647
static unsigned
648
address_hash_func(const void *v)
649
0
{
650
0
  return GPOINTER_TO_UINT(v);
651
0
}
652
653
/* Compare 2 ipv4 addresses */
654
static int
655
address_equal_func(const void *v, const void *v2)
656
0
{
657
0
  return v == v2;
658
0
}
659
660
static unsigned
661
duplicate_result_hash_func(const void *v)
662
0
{
663
0
  const duplicate_result_key *key = (const duplicate_result_key*)v;
664
0
  return (key->frame_number + key->ip_address);
665
0
}
666
667
static int
668
duplicate_result_equal_func(const void *v, const void *v2)
669
0
{
670
0
  const duplicate_result_key *key1 = (const duplicate_result_key*)v;
671
0
  const duplicate_result_key *key2 = (const duplicate_result_key*)v2;
672
673
0
  return (memcmp(key1, key2, sizeof(duplicate_result_key)) == 0);
674
0
}
675
676
677
678
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)
686
0
{
687
0
  address_hash_value   *value;
688
0
  address_hash_value   *result     = NULL;
689
0
  duplicate_result_key  result_key = {pinfo->num, ip};
690
691
  /* Look up existing result */
692
0
  if (pinfo->fd->visited) {
693
0
      result = (address_hash_value *)wmem_map_lookup(duplicate_result_hash_table,
694
0
                                   &result_key);
695
0
  }
696
0
  else {
697
      /* First time around, need to work out if represents duplicate and
698
         store result */
699
700
      /* Look up current assignment of IP address */
701
0
      value = (address_hash_value *)wmem_map_lookup(address_hash_table, GUINT_TO_POINTER(ip));
702
703
      /* If MAC matches table, just update details */
704
0
      if (value != NULL)
705
0
      {
706
0
        if (pinfo->num > value->frame_num)
707
0
        {
708
0
          if ((memcmp(value->mac, mac, 6) == 0))
709
0
          {
710
            /* Same MAC as before - update existing entry */
711
0
            value->frame_num = pinfo->num;
712
0
            value->time_of_entry = pinfo->abs_ts.secs;
713
0
          }
714
0
          else
715
0
          {
716
            /* Create result and store in result table */
717
0
            duplicate_result_key *persistent_key = wmem_new(wmem_file_scope(), duplicate_result_key);
718
0
            memcpy(persistent_key, &result_key, sizeof(duplicate_result_key));
719
720
0
            result = wmem_new(wmem_file_scope(), address_hash_value);
721
0
            memcpy(result, value, sizeof(address_hash_value));
722
723
0
            wmem_map_insert(duplicate_result_hash_table, persistent_key, result);
724
0
          }
725
0
        }
726
0
      }
727
0
      else
728
0
      {
729
        /* No existing entry. Prepare one */
730
0
        value = wmem_new(wmem_file_scope(), struct address_hash_value);
731
0
        memcpy(value->mac, mac, 6);
732
0
        value->frame_num = pinfo->num;
733
0
        value->time_of_entry = pinfo->abs_ts.secs;
734
735
        /* Add it */
736
0
        wmem_map_insert(address_hash_table, GUINT_TO_POINTER(ip), value);
737
0
      }
738
0
  }
739
740
  /* Add report to tree if we found a duplicate */
741
0
  if (result != NULL) {
742
0
    proto_tree *duplicate_tree;
743
0
    proto_item *ti;
744
0
    address mac_addr, result_mac_addr;
745
746
0
    set_address(&mac_addr, AT_ETHER, 6, mac);
747
0
    set_address(&result_mac_addr, AT_ETHER, 6, result->mac);
748
749
    /* Create subtree */
750
0
    duplicate_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_arp_duplicate_address, &ti,
751
0
                                                "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
752
0
                                                arpproaddr_to_str(pinfo->pool, (uint8_t*)&ip, 4, ETHERTYPE_IP),
753
0
                                                address_to_str(pinfo->pool, &mac_addr),
754
0
                                                address_to_str(pinfo->pool, &result_mac_addr),
755
0
                                                result->frame_num);
756
0
    proto_item_set_generated(ti);
757
758
    /* Add item for navigating to earlier frame */
759
0
    ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame,
760
0
                             tvb, 0, 0, result->frame_num);
761
0
    proto_item_set_generated(ti);
762
0
    expert_add_info_format(pinfo, ti,
763
0
                           &ei_seq_arp_dup_ip,
764
0
                           "Duplicate IP address configured (%s)",
765
0
                           arpproaddr_to_str(pinfo->pool, (uint8_t*)&ip, 4, ETHERTYPE_IP));
766
767
    /* Time since that frame was seen */
768
0
    ti = proto_tree_add_uint(duplicate_tree,
769
0
                             hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
770
0
                             tvb, 0, 0,
771
0
                             (uint32_t)(pinfo->abs_ts.secs - result->time_of_entry));
772
0
    proto_item_set_generated(ti);
773
774
    /* Set out parameter */
775
0
    *duplicate_ip = ip;
776
0
  }
777
778
779
0
  return (result != NULL);
780
0
}
781
782
783
784
/* Take note that a request has been seen */
785
static void
786
request_seen(packet_info *pinfo)
787
0
{
788
  /* Don't count frame again after already recording first time around. */
789
0
  if (p_get_proto_data(wmem_file_scope(), pinfo, proto_arp, 0) == 0)
790
0
  {
791
0
    arp_request_count++;
792
0
  }
793
0
}
794
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)
798
0
{
799
0
  bool report_storm = false;
800
801
0
  if (p_get_proto_data(wmem_file_scope(), pinfo, proto_arp, 0) != 0)
802
0
  {
803
    /* Read any previous stored packet setting */
804
0
    report_storm = (p_get_proto_data(wmem_file_scope(), pinfo, proto_arp, 0) == (void*)STORM);
805
0
  }
806
0
  else
807
0
  {
808
    /* Seeing packet for first time - check against preference settings */
809
0
    nstime_t delta;
810
0
    nstime_delta(&delta, &pinfo->abs_ts, &time_at_start_of_count);
811
0
    int64_t gap = ((int64_t)delta.secs * 1000) + (delta.nsecs / 1000000);
812
813
    /* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */
814
0
    if ((gap > (int64_t)global_arp_detect_request_storm_period) ||
815
0
        (gap < 0))
816
0
    {
817
      /* Time period elapsed without threshold being exceeded */
818
0
      arp_request_count = 1;
819
0
      time_at_start_of_count = pinfo->abs_ts;
820
0
      p_add_proto_data(wmem_file_scope(), pinfo, proto_arp, 0, (void*)NO_STORM);
821
0
      return;
822
0
    }
823
0
    else
824
0
      if (arp_request_count > global_arp_detect_request_storm_packets)
825
0
      {
826
        /* Storm detected, record and reset start time. */
827
0
        report_storm = true;
828
0
        p_add_proto_data(wmem_file_scope(), pinfo, proto_arp, 0, (void*)STORM);
829
0
        time_at_start_of_count = pinfo->abs_ts;
830
0
      }
831
0
      else
832
0
      {
833
        /* Threshold not exceeded yet - no storm */
834
0
        p_add_proto_data(wmem_file_scope(), pinfo, proto_arp, 0, (void*)NO_STORM);
835
0
      }
836
0
  }
837
838
0
  if (report_storm)
839
0
  {
840
    /* Report storm and reset counter */
841
0
    proto_tree_add_expert_format(tree, pinfo, &ei_seq_arp_storm, tvb, 0, 0,
842
0
                           "ARP packet storm detected (%u packets in < %u ms)",
843
0
                           global_arp_detect_request_storm_packets,
844
0
                           global_arp_detect_request_storm_period);
845
0
    arp_request_count = 0;
846
0
  }
847
0
}
848
849
850
/*
851
 * RFC 2225 ATMARP - it's just like ARP, except where it isn't.
852
 */
853
static int
854
dissect_atmarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
855
0
{
856
0
  uint16_t      ar_hrd;
857
0
  uint16_t      ar_pro;
858
0
  uint8_t       ar_shtl;
859
0
  uint8_t       ar_shl;
860
0
  uint8_t       ar_sstl;
861
0
  uint8_t       ar_ssl;
862
0
  uint16_t      ar_op;
863
0
  uint8_t       ar_spln;
864
0
  uint8_t       ar_thtl;
865
0
  uint8_t       ar_thl;
866
0
  uint8_t       ar_tstl;
867
0
  uint8_t       ar_tsl;
868
0
  uint8_t       ar_tpln;
869
0
  int           tot_len;
870
0
  proto_tree   *arp_tree;
871
0
  proto_item   *ti;
872
0
  const char   *op_str;
873
0
  int           sha_offset, ssa_offset, spa_offset;
874
0
  int           tha_offset, tsa_offset, tpa_offset;
875
0
  const char   *sha_str, *ssa_str, *spa_str;
876
0
  const char   *tha_str, *tsa_str, *tpa_str;
877
0
  proto_tree   *tl_tree;
878
879
0
  ar_hrd = tvb_get_ntohs(tvb, ATM_AR_HRD);
880
0
  ar_pro = tvb_get_ntohs(tvb, ATM_AR_PRO);
881
0
  ar_shtl = tvb_get_uint8(tvb, ATM_AR_SHTL);
882
0
  ar_shl = ar_shtl & ATMARP_LEN_MASK;
883
0
  ar_sstl = tvb_get_uint8(tvb, ATM_AR_SSTL);
884
0
  ar_ssl = ar_sstl & ATMARP_LEN_MASK;
885
0
  ar_op  = tvb_get_ntohs(tvb, AR_OP);
886
0
  ar_spln = tvb_get_uint8(tvb, ATM_AR_SPLN);
887
0
  ar_thtl = tvb_get_uint8(tvb, ATM_AR_THTL);
888
0
  ar_thl = ar_thtl & ATMARP_LEN_MASK;
889
0
  ar_tstl = tvb_get_uint8(tvb, ATM_AR_TSTL);
890
0
  ar_tsl = ar_tstl & ATMARP_LEN_MASK;
891
0
  ar_tpln = tvb_get_uint8(tvb, ATM_AR_TPLN);
892
893
0
  tot_len = MIN_ATMARP_HEADER_SIZE + ar_shl + ar_ssl + ar_spln +
894
0
    ar_thl + ar_tsl + ar_tpln;
895
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
0
  tvb_set_reported_length(tvb, tot_len);
900
901
  /* Extract the addresses.  */
902
0
  sha_offset = MIN_ATMARP_HEADER_SIZE;
903
0
  sha_str = atmarpnum_to_str(pinfo->pool, tvb, sha_offset, ar_shtl);
904
905
0
  ssa_offset = sha_offset + ar_shl;
906
0
  if (ar_ssl != 0) {
907
0
    ssa_str = atmarpsubaddr_to_str(pinfo->pool, tvb, ssa_offset, ar_sstl);
908
0
  } else {
909
0
    ssa_str = NULL;
910
0
  }
911
912
0
  spa_offset = ssa_offset + ar_ssl;
913
0
  spa_str = tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_spln, ar_pro);
914
915
0
  tha_offset = spa_offset + ar_spln;
916
0
  tha_str = atmarpnum_to_str(pinfo->pool, tvb, tha_offset, ar_thtl);
917
918
0
  tsa_offset = tha_offset + ar_thl;
919
0
  if (ar_tsl != 0) {
920
0
    tsa_str = atmarpsubaddr_to_str(pinfo->pool, tvb, tsa_offset, ar_tstl);
921
0
  } else {
922
0
    tsa_str = NULL;
923
0
  }
924
925
0
  tpa_offset = tsa_offset + ar_tsl;
926
0
  tpa_str = tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_tpln, ar_pro);
927
928
0
  switch (ar_op) {
929
930
0
  case ARPOP_REQUEST:
931
0
  case ARPOP_REPLY:
932
0
  case ATMARPOP_NAK:
933
0
  default:
934
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMARP");
935
0
    break;
936
937
0
  case ARPOP_RREQUEST:
938
0
  case ARPOP_RREPLY:
939
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMRARP");
940
0
    break;
941
942
0
  case ARPOP_IREQUEST:
943
0
  case ARPOP_IREPLY:
944
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ATMARP");
945
0
    break;
946
947
0
  case ARPOP_MARS_REQUEST:
948
0
  case ARPOP_MARS_MULTI:
949
0
  case ARPOP_MARS_MSERV:
950
0
  case ARPOP_MARS_JOIN:
951
0
  case ARPOP_MARS_LEAVE:
952
0
  case ARPOP_MARS_NAK:
953
0
  case ARPOP_MARS_UNSERV:
954
0
  case ARPOP_MARS_SJOIN:
955
0
  case ARPOP_MARS_SLEAVE:
956
0
  case ARPOP_MARS_GROUPLIST_REQUEST:
957
0
  case ARPOP_MARS_GROUPLIST_REPLY:
958
0
  case ARPOP_MARS_REDIRECT_MAP:
959
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MARS");
960
0
    break;
961
962
0
  case ARPOP_MAPOS_UNARP:
963
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
964
0
    break;
965
966
0
  }
967
968
0
  switch (ar_op) {
969
0
  case ARPOP_REQUEST:
970
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
971
0
                 tpa_str, spa_str);
972
0
    break;
973
0
  case ARPOP_REPLY:
974
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s%s%s", spa_str, sha_str,
975
0
                 ((ssa_str != NULL) ? "," : ""),
976
0
                 ((ssa_str != NULL) ? ssa_str : ""));
977
0
    break;
978
0
  case ARPOP_IREQUEST:
979
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s%s%s? Tell %s%s%s",
980
0
                 tha_str,
981
0
                 ((tsa_str != NULL) ? "," : ""),
982
0
                 ((tsa_str != NULL) ? tsa_str : ""),
983
0
                 sha_str,
984
0
                 ((ssa_str != NULL) ? "," : ""),
985
0
                 ((ssa_str != NULL) ? ssa_str : ""));
986
0
    break;
987
0
  case ARPOP_IREPLY:
988
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s is at %s",
989
0
                 sha_str,
990
0
                 ((ssa_str != NULL) ? "," : ""),
991
0
                 ((ssa_str != NULL) ? ssa_str : ""),
992
0
                 spa_str);
993
0
    break;
994
0
  case ATMARPOP_NAK:
995
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "I don't know where %s is", spa_str);
996
0
    break;
997
0
  case ARPOP_MARS_REQUEST:
998
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS request from %s%s%s at %s",
999
0
                 sha_str,
1000
0
                 ((ssa_str != NULL) ? "," : ""),
1001
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1002
0
                 spa_str);
1003
0
    break;
1004
1005
0
  case ARPOP_MARS_MULTI:
1006
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MULTI request from %s%s%s at %s",
1007
0
                 sha_str,
1008
0
                 ((ssa_str != NULL) ? "," : ""),
1009
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1010
0
                 spa_str);
1011
0
    break;
1012
1013
0
  case ARPOP_MARS_MSERV:
1014
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MSERV request from %s%s%s at %s",
1015
0
                 sha_str,
1016
0
                 ((ssa_str != NULL) ? "," : ""),
1017
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1018
0
                 spa_str);
1019
0
    break;
1020
1021
0
  case ARPOP_MARS_JOIN:
1022
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS JOIN request from %s%s%s at %s",
1023
0
                 sha_str,
1024
0
                 ((ssa_str != NULL) ? "," : ""),
1025
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1026
0
                 spa_str);
1027
0
    break;
1028
1029
0
  case ARPOP_MARS_LEAVE:
1030
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS LEAVE from %s%s%s at %s",
1031
0
                 sha_str,
1032
0
                 ((ssa_str != NULL) ? "," : ""),
1033
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1034
0
                 spa_str);
1035
0
    break;
1036
1037
0
  case ARPOP_MARS_NAK:
1038
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS NAK from %s%s%s at %s",
1039
0
                 sha_str,
1040
0
                 ((ssa_str != NULL) ? "," : ""),
1041
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1042
0
                 spa_str);
1043
0
    break;
1044
1045
0
  case ARPOP_MARS_UNSERV:
1046
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS UNSERV request from %s%s%s at %s",
1047
0
                 sha_str,
1048
0
                 ((ssa_str != NULL) ? "," : ""),
1049
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1050
0
                 spa_str);
1051
0
    break;
1052
1053
0
  case ARPOP_MARS_SJOIN:
1054
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SJOIN request from %s%s%s at %s",
1055
0
                 sha_str,
1056
0
                 ((ssa_str != NULL) ? "," : ""),
1057
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1058
0
                 spa_str);
1059
0
    break;
1060
1061
0
  case ARPOP_MARS_SLEAVE:
1062
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SLEAVE from %s%s%s at %s",
1063
0
                 sha_str,
1064
0
                 ((ssa_str != NULL) ? "," : ""),
1065
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1066
0
                 spa_str);
1067
0
    break;
1068
1069
0
  case ARPOP_MARS_GROUPLIST_REQUEST:
1070
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist request from %s%s%s at %s",
1071
0
                 sha_str,
1072
0
                 ((ssa_str != NULL) ? "," : ""),
1073
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1074
0
                 spa_str);
1075
0
    break;
1076
1077
0
  case ARPOP_MARS_GROUPLIST_REPLY:
1078
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist reply from %s%s%s at %s",
1079
0
                 sha_str,
1080
0
                 ((ssa_str != NULL) ? "," : ""),
1081
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1082
0
                 spa_str);
1083
0
    break;
1084
1085
0
  case ARPOP_MARS_REDIRECT_MAP:
1086
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MARS redirect map from %s%s%s at %s",
1087
0
                 sha_str,
1088
0
                 ((ssa_str != NULL) ? "," : ""),
1089
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1090
0
                 spa_str);
1091
0
    break;
1092
1093
0
  case ARPOP_MAPOS_UNARP:
1094
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "MAPOS UNARP request from %s%s%s at %s",
1095
0
                 sha_str,
1096
0
                 ((ssa_str != NULL) ? "," : ""),
1097
0
                 ((ssa_str != NULL) ? ssa_str : ""),
1098
0
                 spa_str);
1099
0
    break;
1100
1101
0
  case ARPOP_EXP1:
1102
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1103
0
    break;
1104
1105
0
  case ARPOP_EXP2:
1106
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1107
0
    break;
1108
1109
0
  case 0:
1110
0
  case 65535:
1111
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1112
0
    break;
1113
1114
0
  default:
1115
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ATMARP opcode 0x%04x", ar_op);
1116
0
    break;
1117
0
  }
1118
1119
0
  if (tree) {
1120
0
    if ((op_str = try_val_to_str(ar_op, atmop_vals)))
1121
0
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1122
0
                                          "ATM Address Resolution Protocol (%s)",
1123
0
                                          op_str);
1124
0
    else
1125
0
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1126
0
                                          "ATM Address Resolution Protocol (opcode 0x%04x)", ar_op);
1127
0
    arp_tree = proto_item_add_subtree(ti, ett_arp);
1128
1129
0
    proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, ATM_AR_HRD, 2, ar_hrd);
1130
1131
0
    proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, ATM_AR_PRO, 2,ar_pro);
1132
1133
0
    tl_tree = proto_tree_add_subtree_format(arp_tree, tvb, ATM_AR_SHTL, 1,
1134
0
                             ett_atmarp_tl, NULL,
1135
0
                             "Sender ATM number type/length: %s/%u",
1136
0
                             (ar_shtl & ATMARP_IS_E164) ?
1137
0
                                  "E.164" :
1138
0
                                  "ATM Forum NSAPA",
1139
0
                             ar_shl);
1140
0
    proto_tree_add_boolean(tl_tree, hf_atmarp_sht, tvb, ATM_AR_SHTL, 1, ar_shtl);
1141
0
    proto_tree_add_uint(tl_tree, hf_atmarp_shl, tvb, ATM_AR_SHTL, 1, ar_shtl);
1142
1143
0
    tl_tree = proto_tree_add_subtree_format(arp_tree, tvb, ATM_AR_SSTL, 1,
1144
0
                             ett_atmarp_tl, NULL,
1145
0
                             "Sender ATM subaddress type/length: %s/%u",
1146
0
                             (ar_sstl & ATMARP_IS_E164) ?
1147
0
                                  "E.164" :
1148
0
                                  "ATM Forum NSAPA",
1149
0
                             ar_ssl);
1150
0
    proto_tree_add_boolean(tl_tree, hf_atmarp_sst, tvb, ATM_AR_SSTL, 1, ar_sstl);
1151
0
    proto_tree_add_uint(tl_tree, hf_atmarp_ssl, tvb, ATM_AR_SSTL, 1, ar_sstl);
1152
1153
0
    proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP,  2, ar_op);
1154
1155
1156
0
    proto_tree_add_uint(arp_tree, hf_atmarp_spln, tvb, ATM_AR_SPLN, 1, ar_spln);
1157
1158
0
    tl_tree = proto_tree_add_subtree_format(arp_tree, tvb, ATM_AR_THTL, 1,
1159
0
                             ett_atmarp_tl, NULL,
1160
0
                             "Target ATM number type/length: %s/%u",
1161
0
                             (ar_thtl & ATMARP_IS_E164) ?
1162
0
                                  "E.164" :
1163
0
                                  "ATM Forum NSAPA",
1164
0
                             ar_thl);
1165
0
    proto_tree_add_boolean(tl_tree, hf_atmarp_tht, tvb, ATM_AR_THTL, 1, ar_thtl);
1166
0
    proto_tree_add_uint(tl_tree, hf_atmarp_thl, tvb, ATM_AR_THTL, 1, ar_thtl);
1167
1168
0
    tl_tree = proto_tree_add_subtree_format(arp_tree, tvb, ATM_AR_TSTL, 1,
1169
0
                             ett_atmarp_tl, NULL,
1170
0
                             "Target ATM subaddress type/length: %s/%u",
1171
0
                             (ar_tstl & ATMARP_IS_E164) ?
1172
0
                                  "E.164" :
1173
0
                                  "ATM Forum NSAPA",
1174
0
                             ar_tsl);
1175
0
    proto_tree_add_boolean(tl_tree, hf_atmarp_tst, tvb, ATM_AR_TSTL, 1, ar_tstl);
1176
0
    proto_tree_add_uint(tl_tree, hf_atmarp_tsl, tvb, ATM_AR_TSTL, 1, ar_tstl);
1177
1178
0
    proto_tree_add_uint(arp_tree, hf_atmarp_tpln, tvb, ATM_AR_TPLN, 1, ar_tpln);
1179
1180
0
    if (ar_shl != 0)
1181
0
      dissect_atm_number(tvb, pinfo, sha_offset, ar_shtl, hf_atmarp_src_atm_num_e164,
1182
0
                         hf_atmarp_src_atm_num_nsap, arp_tree);
1183
1184
0
    if (ar_ssl != 0)
1185
0
      proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_src_atm_subaddr, tvb, ssa_offset,
1186
0
                                  ar_ssl, NULL, "%s", ssa_str);
1187
1188
0
    if (ar_spln != 0) {
1189
0
      proto_tree_add_item(arp_tree,
1190
0
                          ARP_PRO_IS_IPv4(ar_pro, ar_spln) ? hf_arp_src_proto_ipv4
1191
0
                          : hf_arp_src_proto,
1192
0
                          tvb, spa_offset, ar_spln, ENC_BIG_ENDIAN);
1193
0
    }
1194
1195
0
    if (ar_thl != 0)
1196
0
      dissect_atm_number(tvb, pinfo, tha_offset, ar_thtl, hf_atmarp_dst_atm_num_e164,
1197
0
                         hf_atmarp_dst_atm_num_nsap, arp_tree);
1198
1199
0
    if (ar_tsl != 0)
1200
0
      proto_tree_add_bytes_format_value(arp_tree, hf_atmarp_dst_atm_subaddr, tvb, tsa_offset,
1201
0
                                  ar_tsl, NULL, "%s", tsa_str);
1202
1203
0
    if (ar_tpln != 0) {
1204
0
      proto_tree_add_item(arp_tree,
1205
0
                          ARP_PRO_IS_IPv4(ar_pro, ar_tpln) ? hf_arp_dst_proto_ipv4
1206
0
                          : hf_arp_dst_proto,
1207
0
                          tvb, tpa_offset, ar_tpln, ENC_BIG_ENDIAN);
1208
0
    }
1209
0
  }
1210
0
  return tvb_captured_length(tvb);
1211
0
}
1212
1213
/*
1214
 * AX.25 ARP - it's just like ARP, except where it isn't.
1215
 */
1216
static int
1217
dissect_ax25arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1218
5
{
1219
5
#define ARP_AX25 204
1220
1221
5
  uint16_t     ar_hrd;
1222
5
  uint16_t     ar_pro;
1223
5
  uint8_t      ar_hln;
1224
5
  uint8_t      ar_pln;
1225
5
  uint16_t     ar_op;
1226
5
  int          tot_len;
1227
5
  proto_tree  *arp_tree = NULL;
1228
5
  proto_item  *ti;
1229
5
  const char *op_str;
1230
5
  int          sha_offset, spa_offset, tha_offset, tpa_offset;
1231
5
  const char *spa_str, *tpa_str;
1232
5
  bool         is_gratuitous;
1233
1234
  /* Hardware Address Type */
1235
5
  ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
1236
  /* Protocol Address Type */
1237
5
  ar_pro = tvb_get_ntohs(tvb, AR_PRO);
1238
  /* Hardware Address Size */
1239
5
  ar_hln = tvb_get_uint8(tvb, AR_HLN);
1240
  /* Protocol Address Size */
1241
5
  ar_pln = tvb_get_uint8(tvb, AR_PLN);
1242
  /* Operation */
1243
5
  ar_op  = tvb_get_ntohs(tvb, AR_OP);
1244
1245
5
  tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;
1246
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
5
  tvb_set_reported_length(tvb, tot_len);
1251
1252
5
  switch (ar_op) {
1253
1254
0
  case ARPOP_REQUEST:
1255
0
    if (global_arp_detect_request_storm)
1256
0
      request_seen(pinfo);
1257
      /* fall-through */
1258
0
  case ARPOP_REPLY:
1259
2
  default:
1260
2
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1261
2
    break;
1262
1263
0
  case ARPOP_RREQUEST:
1264
0
  case ARPOP_RREPLY:
1265
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1266
0
    break;
1267
1268
0
  case ARPOP_IREQUEST:
1269
0
  case ARPOP_IREPLY:
1270
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1271
0
    break;
1272
5
  }
1273
1274
  /* Get the offsets of the addresses. */
1275
  /* Source Hardware Address */
1276
2
  sha_offset = MIN_ARP_HEADER_SIZE;
1277
  /* Source Protocol Address */
1278
2
  spa_offset = sha_offset + ar_hln;
1279
  /* Target Hardware Address */
1280
2
  tha_offset = spa_offset + ar_pln;
1281
  /* Target Protocol Address */
1282
2
  tpa_offset = tha_offset + ar_hln;
1283
1284
2
  spa_str = tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro);
1285
2
  tpa_str = tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro);
1286
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
2
  if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) && (strcmp(spa_str, tpa_str) == 0))
1295
0
    is_gratuitous = true;
1296
2
  else
1297
2
    is_gratuitous = false;
1298
1299
2
  switch (ar_op) {
1300
0
    case ARPOP_REQUEST:
1301
0
      if (is_gratuitous)
1302
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)", tpa_str);
1303
0
      else
1304
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s", tpa_str, spa_str);
1305
0
      break;
1306
0
    case ARPOP_REPLY:
1307
0
      if (is_gratuitous)
1308
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)", spa_str);
1309
0
      else
1310
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1311
0
                     spa_str,
1312
0
                     tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd));
1313
0
      break;
1314
0
    case ARPOP_RREQUEST:
1315
0
    case ARPOP_IREQUEST:
1316
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s? Tell %s",
1317
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, tha_offset, ar_hln, ar_hrd),
1318
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd));
1319
0
      break;
1320
0
    case ARPOP_RREPLY:
1321
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1322
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, tha_offset, ar_hln, ar_hrd),
1323
0
                   tpa_str);
1324
0
      break;
1325
0
    case ARPOP_IREPLY:
1326
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1327
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1328
0
                   spa_str);
1329
0
      break;
1330
2
    default:
1331
2
      col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1332
2
      break;
1333
2
  }
1334
1335
2
  if (tree) {
1336
2
    if ((op_str = try_val_to_str(ar_op, op_vals))) {
1337
1
      if (is_gratuitous && (ar_op == ARPOP_REQUEST))
1338
0
        op_str = "request/gratuitous ARP";
1339
1
      if (is_gratuitous && (ar_op == ARPOP_REPLY))
1340
0
        op_str = "reply/gratuitous ARP";
1341
1
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1342
1
                                        "Address Resolution Protocol (%s)", op_str);
1343
1
    } else
1344
1
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
1345
1
                                      "Address Resolution Protocol (opcode 0x%04x)", ar_op);
1346
2
    arp_tree = proto_item_add_subtree(ti, ett_arp);
1347
2
    proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
1348
2
    proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, AR_PRO, 2, ar_pro);
1349
2
    proto_tree_add_uint(arp_tree, hf_arp_hard_size, tvb, AR_HLN, 1, ar_hln);
1350
2
    proto_tree_add_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ar_pln);
1351
2
    proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP,  2, ar_op);
1352
2
    if (ar_hln != 0) {
1353
1
      proto_tree_add_item(arp_tree,
1354
1
        ARP_HW_IS_AX25(ar_hrd, ar_hln) ? hf_arp_src_hw_ax25 : hf_arp_src_hw,
1355
1
        tvb, sha_offset, ar_hln, false);
1356
1
    }
1357
2
    if (ar_pln != 0) {
1358
1
      proto_tree_add_item(arp_tree,
1359
1
        ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_src_proto_ipv4
1360
1
                                        : hf_arp_src_proto,
1361
1
        tvb, spa_offset, ar_pln, false);
1362
1
    }
1363
2
    if (ar_hln != 0) {
1364
1
      proto_tree_add_item(arp_tree,
1365
1
        ARP_HW_IS_AX25(ar_hrd, ar_hln) ? hf_arp_dst_hw_ax25 : hf_arp_dst_hw,
1366
1
        tvb, tha_offset, ar_hln, false);
1367
1
    }
1368
2
    if (ar_pln != 0) {
1369
1
      proto_tree_add_item(arp_tree,
1370
1
        ARP_PRO_IS_IPv4(ar_pro, ar_pln) ? hf_arp_dst_proto_ipv4
1371
1
                                        : hf_arp_dst_proto,
1372
1
        tvb, tpa_offset, ar_pln, false);
1373
1
    }
1374
2
  }
1375
1376
2
  if (global_arp_detect_request_storm)
1377
0
  {
1378
0
    check_for_storm_count(tvb, pinfo, arp_tree);
1379
0
  }
1380
2
  return tvb_captured_length(tvb);
1381
2
}
1382
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_)
1385
0
{
1386
0
  capture_dissector_increment_count(cpinfo, proto_arp);
1387
0
  return true;
1388
0
}
1389
1390
static const uint8_t mac_allzero[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1391
1392
static int
1393
dissect_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1394
62
{
1395
62
  uint16_t      ar_hrd;
1396
62
  uint32_t      ar_pro, ar_hln, ar_pln, ar_op;
1397
62
  int           tot_len;
1398
62
  proto_tree   *arp_tree;
1399
62
  proto_item   *arp_item, *item;
1400
62
  const char   *op_str;
1401
62
  int           sha_offset, spa_offset, tha_offset, tpa_offset;
1402
62
  bool          is_gratuitous, is_probe = false, is_announcement = false;
1403
62
  bool          duplicate_detected = false;
1404
62
  uint32_t      duplicate_ip       = 0;
1405
62
  dissector_handle_t hw_handle;
1406
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.
1410
1411
     Clear the Info column so that, if we throw an exception, it
1412
     shows up as a short or malformed ARP frame. */
1413
62
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1414
62
  col_clear(pinfo->cinfo, COL_INFO);
1415
1416
  /* Hardware Address Type */
1417
62
  ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
1418
1419
  /* See if there is a hardware type already registered */
1420
62
  hw_handle = dissector_get_uint_handle(arp_hw_table, ar_hrd);
1421
62
  if (hw_handle != NULL) {
1422
5
    call_dissector(hw_handle, tvb, pinfo, tree);
1423
5
    return tvb_captured_length(tvb);
1424
5
  }
1425
1426
  /* Otherwise dissect as Ethernet hardware */
1427
1428
57
  arp_item = proto_tree_add_item(tree, proto_arp, tvb, 0, -1, ENC_NA);
1429
57
  arp_tree = proto_item_add_subtree(arp_item, ett_arp);
1430
1431
57
  proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
1432
  /* Protocol Address Type */
1433
57
  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
57
  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
57
  proto_tree_add_item_ret_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ENC_NA, &ar_pln);
1438
  /* Operation */
1439
57
  proto_tree_add_item_ret_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ENC_BIG_ENDIAN, &ar_op);
1440
1441
57
  tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;
1442
57
  proto_item_set_len(arp_item, tot_len);
1443
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
57
  tvb_set_reported_length(tvb, tot_len);
1448
1449
57
  switch (ar_op) {
1450
1451
2
    case ARPOP_REQUEST:
1452
2
      if (global_arp_detect_request_storm)
1453
0
      {
1454
0
        request_seen(pinfo);
1455
0
      }
1456
      /* FALLTHRU */
1457
4
    case ARPOP_REPLY:
1458
30
    default:
1459
30
      col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
1460
30
      break;
1461
1462
0
    case ARPOP_RREQUEST:
1463
1
    case ARPOP_RREPLY:
1464
1
      col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
1465
1
      break;
1466
1467
0
    case ARPOP_DRARPREQUEST:
1468
4
    case ARPOP_DRARPREPLY:
1469
4
    case ARPOP_DRARPERROR:
1470
4
      col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRARP");
1471
4
      break;
1472
1473
3
    case ARPOP_IREQUEST:
1474
3
    case ARPOP_IREPLY:
1475
3
      col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
1476
3
      break;
1477
1478
0
   case ARPOP_MARS_REQUEST:
1479
0
   case ARPOP_MARS_MULTI:
1480
1
   case ARPOP_MARS_MSERV:
1481
2
   case ARPOP_MARS_JOIN:
1482
2
   case ARPOP_MARS_LEAVE:
1483
2
   case ARPOP_MARS_NAK:
1484
2
   case ARPOP_MARS_UNSERV:
1485
2
   case ARPOP_MARS_SJOIN:
1486
3
   case ARPOP_MARS_SLEAVE:
1487
3
   case ARPOP_MARS_GROUPLIST_REQUEST:
1488
13
   case ARPOP_MARS_GROUPLIST_REPLY:
1489
13
   case ARPOP_MARS_REDIRECT_MAP:
1490
13
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MARS");
1491
13
     break;
1492
1493
0
   case ARPOP_MAPOS_UNARP:
1494
0
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAPOS");
1495
0
     break;
1496
57
  }
1497
1498
  /* Get the offsets of the addresses. */
1499
  /* Source Hardware Address */
1500
51
  sha_offset = MIN_ARP_HEADER_SIZE;
1501
  /* Source Protocol Address */
1502
51
  spa_offset = sha_offset + ar_hln;
1503
  /* Target Hardware Address */
1504
51
  tha_offset = spa_offset + ar_pln;
1505
  /* Target Protocol Address */
1506
51
  tpa_offset = tha_offset + ar_hln;
1507
1508
51
  if ((ar_op == ARPOP_REPLY || ar_op == ARPOP_REQUEST) &&
1509
4
      ARP_HW_IS_ETHER(ar_hrd, ar_hln) &&
1510
0
      ARP_PRO_IS_IPv4(ar_pro, ar_pln)) {
1511
1512
    /* inform resolv.c module of the new discovered addresses */
1513
1514
0
    uint32_t ip;
1515
0
    const uint8_t *mac;
1516
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
0
    ip = tvb_get_ipv4(tvb, spa_offset);
1521
0
    mac = (const uint8_t*)tvb_memdup(pinfo->pool, tvb, sha_offset, 6);
1522
0
    if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0)
1523
0
    {
1524
0
      if (global_arp_register_network_address_binding)
1525
0
      {
1526
0
        add_ether_byip(ip, mac);
1527
0
      }
1528
0
      if (global_arp_detect_duplicate_ip_addresses)
1529
0
      {
1530
0
        duplicate_detected =
1531
0
          check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
1532
0
                                        &duplicate_ip);
1533
0
      }
1534
0
    }
1535
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. */
1539
1540
    /* Do not add target address if the packet is a Request. According to the RFC,
1541
       target addresses in requests have no meaning */
1542
1543
1544
0
    ip = tvb_get_ipv4(tvb, tpa_offset);
1545
0
    mac = (const uint8_t*)tvb_memdup(pinfo->pool, tvb, tha_offset, 6);
1546
0
    if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0
1547
0
        && ar_op != ARPOP_REQUEST)
1548
0
    {
1549
0
      if (global_arp_register_network_address_binding)
1550
0
      {
1551
0
        add_ether_byip(ip, mac);
1552
0
      }
1553
      /* If Gratuitous, don't report duplicate for same IP address twice */
1554
0
      if (global_arp_detect_duplicate_ip_addresses && (duplicate_ip!=ip))
1555
0
      {
1556
0
        duplicate_detected =
1557
0
          check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
1558
0
                                        &duplicate_ip);
1559
0
      }
1560
0
    }
1561
1562
1563
0
  }
1564
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
51
  if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) &&
1573
4
      (tvb_memeql(tvb, spa_offset, tvb_get_ptr(tvb, tpa_offset, ar_pln), ar_pln) == 0)) {
1574
1
    is_gratuitous = true;
1575
1
    if ((ar_op == ARPOP_REQUEST) && (ar_hln == 6) && (tvb_memeql(tvb, tha_offset, mac_allzero, 6) == 0))
1576
0
      is_announcement = true;
1577
1
  }
1578
50
  else {
1579
50
    is_gratuitous = false;
1580
50
    if ((ar_op == ARPOP_REQUEST) && ARP_PRO_IS_IPv4(ar_pro, ar_pln) &&
1581
0
        (tvb_get_ipv4(tvb, spa_offset) == 0))
1582
0
      is_probe = true;
1583
50
  }
1584
51
  switch (ar_op) {
1585
2
    case ARPOP_REQUEST:
1586
2
      if (is_gratuitous) {
1587
1
        if (is_announcement) {
1588
0
          col_add_fstr(pinfo->cinfo, COL_INFO, "ARP Announcement for %s",
1589
0
                     tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro));
1590
1
        } else {
1591
1
          col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)",
1592
1
                     tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro));
1593
1
        }
1594
1
      }
1595
1
      else if (is_probe) {
1596
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? (ARP Probe)",
1597
0
                     tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro));
1598
1
      } else {
1599
1
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
1600
1
          tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro),
1601
1
          tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1602
1
      }
1603
2
      break;
1604
2
    case ARPOP_REPLY:
1605
2
      if (is_gratuitous)
1606
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)",
1607
0
                     tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1608
2
      else
1609
2
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1610
2
                     tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro),
1611
2
                     tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd));
1612
2
      break;
1613
0
    case ARPOP_RREQUEST:
1614
3
    case ARPOP_IREQUEST:
1615
3
    case ARPOP_DRARPREQUEST:
1616
3
      col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s? Tell %s",
1617
3
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, tha_offset, ar_hln, ar_hrd),
1618
3
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd));
1619
3
      break;
1620
1
    case ARPOP_RREPLY:
1621
5
    case ARPOP_DRARPREPLY:
1622
5
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1623
5
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, tha_offset, ar_hln, ar_hrd),
1624
5
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, tpa_offset, ar_pln, ar_pro));
1625
5
      break;
1626
1627
0
    case ARPOP_DRARPERROR:
1628
0
      col_set_str(pinfo->cinfo, COL_INFO, "DRARP Error");
1629
0
      break;
1630
1631
0
    case ARPOP_IREPLY:
1632
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
1633
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1634
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1635
0
      break;
1636
1637
0
    case ATMARPOP_NAK:
1638
0
      col_set_str(pinfo->cinfo, COL_INFO, "ARP NAK");
1639
0
      break;
1640
1641
0
    case ARPOP_MARS_REQUEST:
1642
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS request from %s at %s",
1643
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1644
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1645
0
      break;
1646
1647
0
    case ARPOP_MARS_MULTI:
1648
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MULTI request from %s at %s",
1649
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1650
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1651
0
      break;
1652
1653
1
    case ARPOP_MARS_MSERV:
1654
1
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS MSERV request from %s at %s",
1655
1
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1656
1
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1657
1
      break;
1658
1659
1
    case ARPOP_MARS_JOIN:
1660
1
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS JOIN request from %s at %s",
1661
1
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1662
1
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1663
1
      break;
1664
1665
0
    case ARPOP_MARS_LEAVE:
1666
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS LEAVE from %s at %s",
1667
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1668
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1669
0
      break;
1670
1671
0
    case ARPOP_MARS_NAK:
1672
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS NAK from %s at %s",
1673
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1674
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1675
0
      break;
1676
1677
0
    case ARPOP_MARS_UNSERV:
1678
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS UNSERV request from %s at %s",
1679
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1680
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1681
0
      break;
1682
1683
0
    case ARPOP_MARS_SJOIN:
1684
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SJOIN request from %s at %s",
1685
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1686
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1687
0
      break;
1688
1689
1
    case ARPOP_MARS_SLEAVE:
1690
1
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS SLEAVE from %s at %s",
1691
1
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1692
1
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1693
1
      break;
1694
1695
0
    case ARPOP_MARS_GROUPLIST_REQUEST:
1696
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist request from %s at %s",
1697
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1698
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1699
0
      break;
1700
1701
10
    case ARPOP_MARS_GROUPLIST_REPLY:
1702
10
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS grouplist reply from %s at %s",
1703
10
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1704
10
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1705
10
      break;
1706
1707
0
    case ARPOP_MARS_REDIRECT_MAP:
1708
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MARS redirect map from %s at %s",
1709
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1710
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1711
0
      break;
1712
1713
0
    case ARPOP_MAPOS_UNARP:
1714
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "MAPOS UNARP request from %s at %s",
1715
0
                   tvb_arphrdaddr_to_str(pinfo->pool, tvb, sha_offset, ar_hln, ar_hrd),
1716
0
                   tvb_arpproaddr_to_str(pinfo->pool, tvb, spa_offset, ar_pln, ar_pro));
1717
0
      break;
1718
1719
0
    case ARPOP_EXP1:
1720
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 1 ( opcode %d )", ar_op);
1721
0
      break;
1722
1723
0
    case ARPOP_EXP2:
1724
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "Experimental 2 ( opcode %d )", ar_op);
1725
0
      break;
1726
1727
16
    case 0:
1728
17
    case 65535:
1729
17
      col_add_fstr(pinfo->cinfo, COL_INFO, "Reserved opcode %d", ar_op);
1730
17
      break;
1731
1732
9
    default:
1733
9
      col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
1734
9
      break;
1735
51
  }
1736
1737
51
  if (tree) {
1738
51
    if ((op_str = try_val_to_str(ar_op, op_vals)))  {
1739
42
      if (is_gratuitous && (ar_op == ARPOP_REQUEST))
1740
1
        op_str = "request/gratuitous ARP";
1741
42
      if (is_gratuitous && (ar_op == ARPOP_REPLY))
1742
0
        op_str = "reply/gratuitous ARP";
1743
42
      if (is_probe)
1744
0
        op_str = "ARP Probe";
1745
42
      if (is_announcement)
1746
0
        op_str = "ARP Announcement";
1747
1748
42
      proto_item_append_text(arp_item, " (%s)", op_str);
1749
42
    } else {
1750
9
      proto_item_append_text(arp_item, " (opcode 0x%04x)", ar_op);
1751
9
    }
1752
1753
51
    if (is_gratuitous) {
1754
1
      item = proto_tree_add_boolean(arp_tree, hf_arp_isgratuitous, tvb, 0, 0, is_gratuitous);
1755
1
      proto_item_set_generated(item);
1756
1
    }
1757
51
    if (is_probe) {
1758
0
      item = proto_tree_add_boolean(arp_tree, hf_arp_isprobe, tvb, 0, 0, is_probe);
1759
0
      proto_item_set_generated(item);
1760
0
    }
1761
51
    if (is_announcement) {
1762
0
      item = proto_tree_add_boolean(arp_tree, hf_arp_isannouncement, tvb, 0, 0, is_announcement);
1763
0
      proto_item_set_generated(item);
1764
0
    }
1765
51
    if (ar_hln != 0) {
1766
10
      proto_tree_add_item(arp_tree,
1767
10
                          ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1768
0
                          hf_arp_src_hw_mac :
1769
10
                          hf_arp_src_hw,
1770
10
                          tvb, sha_offset, ar_hln, ENC_BIG_ENDIAN);
1771
10
    }
1772
51
    if (ar_pln != 0) {
1773
11
      proto_tree_add_item(arp_tree,
1774
11
                          ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
1775
0
                          hf_arp_src_proto_ipv4 :
1776
11
                          hf_arp_src_proto,
1777
11
                          tvb, spa_offset, ar_pln, ENC_BIG_ENDIAN);
1778
11
    }
1779
51
    if (ar_hln != 0) {
1780
10
      item = proto_tree_add_item(arp_tree,
1781
10
                          ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
1782
0
                          hf_arp_dst_hw_mac :
1783
10
                          hf_arp_dst_hw,
1784
10
                          tvb, tha_offset, ar_hln, ENC_BIG_ENDIAN);
1785
10
      if (is_probe && (tvb_memeql(tvb, tha_offset, mac_allzero, MIN(6, ar_hln)) != 0)) {
1786
0
        expert_add_info(pinfo, item, &ei_arp_dst_nonzero_probe);
1787
0
      }
1788
10
    }
1789
51
    if (ar_pln != 0 && ar_op != ARPOP_DRARPERROR) {     /*DISPLAYING ERROR NUMBER FOR DRARPERROR*/
1790
11
      proto_tree_add_item(arp_tree,
1791
11
                          ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
1792
0
                          hf_arp_dst_proto_ipv4 :
1793
11
                          hf_arp_dst_proto,
1794
11
                          tvb, tpa_offset, ar_pln, ENC_BIG_ENDIAN);
1795
11
    }
1796
40
    else if (ar_pln != 0 && ar_op == ARPOP_DRARPERROR) {
1797
0
       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*/
1798
0
    }
1799
51
  }
1800
1801
51
  if (global_arp_detect_request_storm)
1802
0
  {
1803
0
    check_for_storm_count(tvb, pinfo, arp_tree);
1804
0
  }
1805
1806
51
  if (duplicate_detected)
1807
0
  {
1808
    /* Also indicate in info column */
1809
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " (duplicate use of %s detected!)",
1810
0
                    arpproaddr_to_str(pinfo->pool, (uint8_t*)&duplicate_ip, 4, ETHERTYPE_IP));
1811
0
  }
1812
51
  return tvb_captured_length(tvb);
1813
51
}
1814
1815
void
1816
proto_register_arp(void)
1817
16
{
1818
16
  static struct true_false_string tfs_type_bit = { "E.164", "ATM Forum NSAPA" };
1819
1820
16
  static hf_register_info hf[] = {
1821
16
    { &hf_arp_hard_type,
1822
16
      { "Hardware type",                "arp.hw.type",
1823
16
        FT_UINT16,      BASE_DEC,       VALS(arp_hrd_vals), 0x0,
1824
16
        NULL, HFILL }},
1825
1826
16
    { &hf_arp_proto_type,
1827
16
      { "Protocol type",                "arp.proto.type",
1828
16
        FT_UINT16,      BASE_HEX,       VALS(etype_vals),       0x0,
1829
16
        NULL, HFILL }},
1830
1831
16
    { &hf_arp_hard_size,
1832
16
      { "Hardware size",                "arp.hw.size",
1833
16
        FT_UINT8,       BASE_DEC,       NULL,   0x0,
1834
16
        NULL, HFILL }},
1835
1836
16
    { &hf_atmarp_sht,
1837
16
      { "Sender ATM number type",       "arp.src.htype",
1838
16
        FT_BOOLEAN,     8,              TFS(&tfs_type_bit),     ATMARP_IS_E164,
1839
16
        NULL, HFILL }},
1840
1841
16
    { &hf_atmarp_shl,
1842
16
      { "Sender ATM number length",     "arp.src.hlen",
1843
16
        FT_UINT8,       BASE_DEC,       NULL,           ATMARP_LEN_MASK,
1844
16
        NULL, HFILL }},
1845
1846
16
    { &hf_atmarp_sst,
1847
16
      { "Sender ATM subaddress type",   "arp.src.stype",
1848
16
        FT_BOOLEAN,     8,              TFS(&tfs_type_bit),     ATMARP_IS_E164,
1849
16
        NULL, HFILL }},
1850
1851
16
    { &hf_atmarp_ssl,
1852
16
      { "Sender ATM subaddress length", "arp.src.slen",
1853
16
        FT_UINT8,       BASE_DEC,       NULL,           ATMARP_LEN_MASK,
1854
16
        NULL, HFILL }},
1855
1856
16
    { &hf_arp_proto_size,
1857
16
      { "Protocol size",                "arp.proto.size",
1858
16
        FT_UINT8,       BASE_DEC,       NULL,   0x0,
1859
16
        NULL, HFILL }},
1860
1861
16
    { &hf_arp_opcode,
1862
16
      { "Opcode",                       "arp.opcode",
1863
16
        FT_UINT16,      BASE_DEC,       VALS(op_vals),  0x0,
1864
16
        NULL, HFILL }},
1865
1866
16
    { &hf_arp_isgratuitous,
1867
16
      { "Is gratuitous",                "arp.isgratuitous",
1868
16
        FT_BOOLEAN,     BASE_NONE,      NULL,   0x0,
1869
16
        NULL, HFILL }},
1870
1871
16
    { &hf_arp_isprobe,
1872
16
      { "Is probe",                "arp.isprobe",
1873
16
        FT_BOOLEAN,     BASE_NONE,      NULL,   0x0,
1874
16
        NULL, HFILL }},
1875
1876
16
    { &hf_arp_isannouncement,
1877
16
      { "Is announcement",                "arp.isannouncement",
1878
16
        FT_BOOLEAN,     BASE_NONE,      NULL,   0x0,
1879
16
        NULL, HFILL }},
1880
1881
16
    { &hf_atmarp_spln,
1882
16
      { "Sender protocol size",         "arp.src.pln",
1883
16
        FT_UINT8,       BASE_DEC,       NULL,   0x0,
1884
16
        NULL, HFILL }},
1885
1886
16
    { &hf_atmarp_tht,
1887
16
      { "Target ATM number type",       "arp.dst.htype",
1888
16
        FT_BOOLEAN,     8,              TFS(&tfs_type_bit),     ATMARP_IS_E164,
1889
16
        NULL, HFILL }},
1890
1891
16
    { &hf_atmarp_thl,
1892
16
      { "Target ATM number length",     "arp.dst.hlen",
1893
16
        FT_UINT8,       BASE_DEC,       NULL,           ATMARP_LEN_MASK,
1894
16
        NULL, HFILL }},
1895
1896
16
    { &hf_atmarp_tst,
1897
16
      { "Target ATM subaddress type",   "arp.dst.stype",
1898
16
        FT_BOOLEAN,     8,              TFS(&tfs_type_bit),     ATMARP_IS_E164,
1899
16
        NULL, HFILL }},
1900
1901
16
    { &hf_atmarp_tsl,
1902
16
      { "Target ATM subaddress length", "arp.dst.slen",
1903
16
        FT_UINT8,       BASE_DEC,       NULL,           ATMARP_LEN_MASK,
1904
16
        NULL, HFILL }},
1905
1906
16
    { &hf_atmarp_tpln,
1907
16
      { "Target protocol size",         "arp.dst.pln",
1908
16
        FT_UINT8,       BASE_DEC,       NULL,   0x0,
1909
16
        NULL, HFILL }},
1910
1911
16
    { &hf_arp_src_hw,
1912
16
      { "Sender hardware address",      "arp.src.hw",
1913
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1914
16
        NULL, HFILL }},
1915
1916
16
    { &hf_arp_src_hw_mac,
1917
16
      { "Sender MAC address",           "arp.src.hw_mac",
1918
16
        FT_ETHER,       BASE_NONE,      NULL,   0x0,
1919
16
        NULL, HFILL }},
1920
1921
16
    { &hf_arp_src_hw_ax25,
1922
16
      { "Sender AX.25 address",         "arp.src.hw_ax25",
1923
16
        FT_AX25,        BASE_NONE,      NULL,   0x0,
1924
16
        NULL, HFILL }},
1925
1926
16
    { &hf_atmarp_src_atm_num_e164,
1927
16
      { "Sender ATM number (E.164)",    "arp.src.atm_num_e164",
1928
16
        FT_STRING,      BASE_NONE,      NULL,   0x0,
1929
16
        NULL, HFILL }},
1930
1931
16
    { &hf_atmarp_src_atm_num_nsap,
1932
16
      { "Sender ATM number (NSAP)",     "arp.src.atm_num_nsap",
1933
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1934
16
        NULL, HFILL }},
1935
1936
16
    { &hf_atmarp_src_atm_subaddr,
1937
16
      { "Sender ATM subaddress",        "arp.src.atm_subaddr",
1938
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1939
16
        NULL, HFILL }},
1940
1941
16
    { &hf_arp_src_proto,
1942
16
      { "Sender protocol address",      "arp.src.proto",
1943
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1944
16
        NULL, HFILL }},
1945
1946
16
    { &hf_arp_src_proto_ipv4,
1947
16
      { "Sender IP address",            "arp.src.proto_ipv4",
1948
16
        FT_IPv4,        BASE_NONE,      NULL,   0x0,
1949
16
        NULL, HFILL }},
1950
1951
16
    { &hf_arp_dst_hw,
1952
16
      { "Target hardware address",      "arp.dst.hw",
1953
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1954
16
        NULL, HFILL }},
1955
1956
16
    { &hf_arp_dst_hw_mac,
1957
16
      { "Target MAC address",           "arp.dst.hw_mac",
1958
16
        FT_ETHER,       BASE_NONE,      NULL,   0x0,
1959
16
        NULL, HFILL }},
1960
1961
16
    { &hf_arp_dst_hw_ax25,
1962
16
      { "Target AX.25 address",         "arp.dst.hw_ax25",
1963
16
        FT_AX25,        BASE_NONE,      NULL,   0x0,
1964
16
        NULL, HFILL }},
1965
1966
16
    { &hf_atmarp_dst_atm_num_e164,
1967
16
      { "Target ATM number (E.164)",    "arp.dst.atm_num_e164",
1968
16
        FT_STRING,      BASE_NONE,      NULL,   0x0,
1969
16
        NULL, HFILL }},
1970
1971
16
    { &hf_atmarp_dst_atm_num_nsap,
1972
16
      { "Target ATM number (NSAP)",     "arp.dst.atm_num_nsap",
1973
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1974
16
        NULL, HFILL }},
1975
1976
16
    { &hf_atmarp_dst_atm_subaddr,
1977
16
      { "Target ATM subaddress",        "arp.dst.atm_subaddr",
1978
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1979
16
        NULL, HFILL }},
1980
1981
16
    { &hf_arp_dst_proto,
1982
16
      { "Target protocol address",      "arp.dst.proto",
1983
16
        FT_BYTES,       BASE_NONE,      NULL,   0x0,
1984
16
        NULL, HFILL }},
1985
1986
16
    { &hf_arp_dst_proto_ipv4,
1987
16
      { "Target IP address",            "arp.dst.proto_ipv4",
1988
16
        FT_IPv4,        BASE_NONE,      NULL,   0x0,
1989
16
        NULL, HFILL }},
1990
1991
16
    { &hf_drarp_error_status,
1992
16
      { "DRARP error status",    "arp.dst.drarp_error_status",
1993
16
        FT_UINT16,      BASE_DEC,      VALS(drarp_status),   0x0,
1994
16
        NULL, HFILL }},
1995
1996
16
    { &hf_arp_duplicate_ip_address_earlier_frame,
1997
16
      { "Frame showing earlier use of IP address",      "arp.duplicate-address-frame",
1998
16
        FT_FRAMENUM,    BASE_NONE,      NULL,   0x0,
1999
16
        NULL, HFILL }},
2000
2001
16
    { &hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
2002
16
      { "Seconds since earlier frame seen",     "arp.seconds-since-duplicate-address-frame",
2003
16
        FT_UINT32,      BASE_DEC,       NULL,   0x0,
2004
16
        NULL, HFILL }},
2005
2006
      /* Generated from convert_proto_tree_add_text.pl */
2007
16
      { &hf_atmarp_src_atm_data_country_code, { "Data Country Code", "arp.src.atm_data_country_code", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2008
16
      { &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 }},
2009
16
      { &hf_atmarp_src_atm_high_order_dsp, { "High Order DSP", "arp.src.atm_high_order_dsp", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2010
16
      { &hf_atmarp_src_atm_end_system_identifier, { "End System Identifier", "arp.src.atm_end_system_identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2011
16
      { &hf_atmarp_src_atm_selector, { "Selector", "arp.src.atm_selector", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2012
16
      { &hf_atmarp_src_atm_international_code_designator, { "International Code Designator", "arp.src.atm_international_code_designator", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2013
16
      { &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 }},
2014
16
      { &hf_atmarp_src_atm_e_164_isdn, { "E.164 ISDN", "arp.src.atm_e.164_isdn", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2015
16
      { &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 }},
2016
16
      { &hf_atmarp_src_atm_rest_of_address, { "Rest of address", "arp.src.atm_rest_of_address", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2017
16
      { &hf_atmarp_src_atm_afi, { "AFI", "arp.src.atm_afi", FT_UINT8, BASE_HEX, VALS(atm_nsap_afi_vals), 0x0, NULL, HFILL }},
2018
16
  };
2019
2020
16
  static int *ett[] = {
2021
16
    &ett_arp,
2022
16
    &ett_atmarp_nsap,
2023
16
    &ett_atmarp_tl,
2024
16
    &ett_arp_duplicate_address
2025
16
  };
2026
2027
16
  static ei_register_info ei[] = {
2028
16
     { &ei_seq_arp_dup_ip, { "arp.duplicate-address-detected", PI_SEQUENCE, PI_WARN, "Duplicate IP address configured", EXPFILL }},
2029
16
     { &ei_seq_arp_storm, { "arp.packet-storm-detected", PI_SEQUENCE, PI_NOTE, "ARP packet storm detected", EXPFILL }},
2030
16
     { &ei_arp_dst_nonzero_probe, { "arp.dst.nonzero.probe", PI_PROTOCOL, PI_WARN, "Target Hardware Address field SHOULD be set to all zeroes in an ARP Probe (RFC 5227)", EXPFILL }},
2031
16
     { &ei_atmarp_src_atm_unknown_afi, { "arp.src.atm_afi.unknown", PI_PROTOCOL, PI_WARN, "Unknown AFI", EXPFILL }},
2032
16
  };
2033
2034
16
  module_t *arp_module;
2035
16
  expert_module_t* expert_arp;
2036
2037
16
  proto_arp = proto_register_protocol("Address Resolution Protocol",
2038
16
                                      "ARP/RARP", "arp");
2039
16
  proto_atmarp = proto_register_protocol("ATM Address Resolution Protocol",
2040
16
                                      "ATMARP", "atmarp");
2041
2042
16
  proto_register_field_array(proto_arp, hf, array_length(hf));
2043
16
  proto_register_subtree_array(ett, array_length(ett));
2044
2045
16
  expert_arp = expert_register_protocol(proto_arp);
2046
16
  expert_register_field_array(expert_arp, ei, array_length(ei));
2047
2048
16
  arp_handle = register_dissector( "arp" , dissect_arp, proto_arp );
2049
16
  register_dissector("atm_arp", dissect_atmarp, proto_atmarp);
2050
16
  register_dissector("ax25_arp", dissect_ax25arp, proto_arp);
2051
2052
16
  arp_hw_table = register_dissector_table("arp.hw.type", "ARP Hardware Type", proto_arp, FT_UINT16, BASE_DEC);
2053
2054
  /* Preferences */
2055
16
  arp_module = prefs_register_protocol(proto_arp, NULL);
2056
2057
16
  prefs_register_bool_preference(arp_module, "detect_request_storms",
2058
16
                                 "Detect ARP request storms",
2059
16
                                 "Attempt to detect excessive rate of ARP requests",
2060
16
                                 &global_arp_detect_request_storm);
2061
2062
16
  prefs_register_uint_preference(arp_module, "detect_storm_number_of_packets",
2063
16
                                 "Number of requests to detect during period",
2064
16
                                 "Number of requests needed within period to indicate a storm",
2065
16
                                 10, &global_arp_detect_request_storm_packets);
2066
2067
16
  prefs_register_uint_preference(arp_module, "detect_storm_period",
2068
16
                                 "Detection period (in ms)",
2069
16
                                 "Period in milliseconds during which a packet storm may be detected",
2070
16
                                 10, &global_arp_detect_request_storm_period);
2071
2072
16
  prefs_register_bool_preference(arp_module, "detect_duplicate_ips",
2073
16
                                 "Detect duplicate IP address configuration",
2074
16
                                 "Attempt to detect duplicate use of IP addresses",
2075
16
                                 &global_arp_detect_duplicate_ip_addresses);
2076
2077
16
  prefs_register_bool_preference(arp_module, "register_network_address_binding",
2078
16
                                 "Register network address mappings",
2079
16
                                 "Try to resolve physical addresses to host names from ARP requests/responses",
2080
16
                                 &global_arp_register_network_address_binding);
2081
2082
  /* TODO: define a minimum time between sightings that is worth reporting? */
2083
2084
16
  address_hash_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), address_hash_func, address_equal_func);
2085
16
  duplicate_result_hash_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), duplicate_result_hash_func,
2086
16
                                                 duplicate_result_equal_func);
2087
2088
16
  arp_cap_handle = register_capture_dissector("arp", capture_arp, proto_arp);
2089
16
}
2090
2091
void
2092
proto_reg_handoff_arp(void)
2093
16
{
2094
16
  dissector_handle_t atmarp_handle = find_dissector("atm_arp");
2095
16
  dissector_handle_t ax25arp_handle = find_dissector("ax25_arp");
2096
2097
16
  dissector_add_uint("ethertype", ETHERTYPE_ARP, arp_handle);
2098
16
  dissector_add_uint("ethertype", ETHERTYPE_REVARP, arp_handle);
2099
16
  dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1051, arp_handle);
2100
16
  dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1201, arp_handle);
2101
16
  dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_RARP_1201, arp_handle);
2102
16
  dissector_add_uint("ax25.pid", AX25_P_ARP, arp_handle);
2103
16
  dissector_add_uint("gre.proto", ETHERTYPE_ARP, arp_handle);
2104
16
  capture_dissector_add_uint("ethertype", ETHERTYPE_ARP, arp_cap_handle);
2105
16
  capture_dissector_add_uint("ax25.pid", AX25_P_ARP, arp_cap_handle);
2106
2107
16
  dissector_add_uint("arp.hw.type", ARPHRD_ATM2225, atmarp_handle);
2108
16
  dissector_add_uint("arp.hw.type", ARPHRD_AX25, ax25arp_handle);
2109
16
}
2110
2111
/*
2112
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2113
 *
2114
 * Local Variables:
2115
 * c-basic-offset: 2
2116
 * tab-width: 8
2117
 * indent-tabs-mode: nil
2118
 * End:
2119
 *
2120
 * ex: set shiftwidth=2 tabstop=8 expandtab:
2121
 * :indentSize=2:tabSize=8:noTabs=true:
2122
 */