1998-09-16 02:39:15 +00:00
|
|
|
/* packet-arp.c
|
2004-06-17 20:04:53 +00:00
|
|
|
* Routines for ARP packet disassembly (RFC 826)
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
1998-09-16 02:39:15 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2006-10-29 19:14:31 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-09-16 02:39:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2000-11-17 21:00:40 +00:00
|
|
|
#include <string.h>
|
1999-03-23 03:14:46 +00:00
|
|
|
#include <glib.h>
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/strutil.h>
|
2004-12-26 22:26:02 +00:00
|
|
|
#include <epan/arptypes.h>
|
2004-08-06 19:57:49 +00:00
|
|
|
#include <epan/addr_resolv.h>
|
2005-08-17 09:25:04 +00:00
|
|
|
#include <epan/emem.h>
|
1999-11-27 04:48:14 +00:00
|
|
|
#include "packet-arp.h"
|
2005-09-17 00:02:31 +00:00
|
|
|
#include <epan/etypes.h>
|
|
|
|
#include <epan/arcnet_pids.h>
|
2006-10-20 14:20:22 +00:00
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <epan/expert.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
static int proto_arp = -1;
|
1999-10-03 17:12:15 +00:00
|
|
|
static int hf_arp_hard_type = -1;
|
|
|
|
static int hf_arp_proto_type = -1;
|
|
|
|
static int hf_arp_hard_size = -1;
|
2000-11-30 10:42:50 +00:00
|
|
|
static int hf_atmarp_sht = -1;
|
|
|
|
static int hf_atmarp_shl = -1;
|
|
|
|
static int hf_atmarp_sst = -1;
|
1999-11-27 04:01:43 +00:00
|
|
|
static int hf_atmarp_ssl = -1;
|
1999-10-03 17:12:15 +00:00
|
|
|
static int hf_arp_proto_size = -1;
|
|
|
|
static int hf_arp_opcode = -1;
|
2009-05-21 05:15:03 +00:00
|
|
|
static int hf_arp_isgratuitous = -1;
|
1999-11-27 04:01:43 +00:00
|
|
|
static int hf_atmarp_spln = -1;
|
2000-11-30 10:42:50 +00:00
|
|
|
static int hf_atmarp_tht = -1;
|
|
|
|
static int hf_atmarp_thl = -1;
|
|
|
|
static int hf_atmarp_tst = -1;
|
1999-11-27 04:01:43 +00:00
|
|
|
static int hf_atmarp_tsl = -1;
|
|
|
|
static int hf_atmarp_tpln = -1;
|
2002-02-10 22:41:48 +00:00
|
|
|
static int hf_arp_src_hw = -1;
|
|
|
|
static int hf_arp_src_hw_mac = -1;
|
1999-10-03 17:12:15 +00:00
|
|
|
static int hf_arp_src_proto = -1;
|
2002-02-10 22:41:48 +00:00
|
|
|
static int hf_arp_src_proto_ipv4 = -1;
|
|
|
|
static int hf_arp_dst_hw = -1;
|
|
|
|
static int hf_arp_dst_hw_mac = -1;
|
1999-10-03 17:12:15 +00:00
|
|
|
static int hf_arp_dst_proto = -1;
|
2002-02-10 22:41:48 +00:00
|
|
|
static int hf_arp_dst_proto_ipv4 = -1;
|
2006-10-20 14:20:22 +00:00
|
|
|
static int hf_arp_packet_storm = -1;
|
2007-12-19 10:49:22 +00:00
|
|
|
static int hf_arp_duplicate_ip_address = -1;
|
|
|
|
static int hf_arp_duplicate_ip_address_earlier_frame = -1;
|
|
|
|
static int hf_arp_duplicate_ip_address_seconds_since_earlier_frame = -1;
|
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
static int hf_atmarp_src_atm_num_e164 = -1;
|
|
|
|
static int hf_atmarp_src_atm_num_nsap = -1;
|
1999-11-27 04:01:43 +00:00
|
|
|
static int hf_atmarp_src_atm_subaddr = -1;
|
1999-11-27 04:48:14 +00:00
|
|
|
static int hf_atmarp_dst_atm_num_e164 = -1;
|
|
|
|
static int hf_atmarp_dst_atm_num_nsap = -1;
|
1999-11-27 04:01:43 +00:00
|
|
|
static int hf_atmarp_dst_atm_subaddr = -1;
|
1999-07-29 05:47:07 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint ett_arp = -1;
|
1999-11-27 04:48:14 +00:00
|
|
|
static gint ett_atmarp_nsap = -1;
|
2000-11-30 10:42:50 +00:00
|
|
|
static gint ett_atmarp_tl = -1;
|
2007-12-19 10:49:22 +00:00
|
|
|
static gint ett_arp_duplicate_address = -1;
|
1999-11-16 11:44:20 +00:00
|
|
|
|
2001-11-27 07:13:32 +00:00
|
|
|
static dissector_handle_t atmarp_handle;
|
2001-11-26 05:13:14 +00:00
|
|
|
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
/* Used for determining if frequency of ARP requests constitute a storm */
|
|
|
|
#define STORM 1
|
|
|
|
#define NO_STORM 2
|
|
|
|
|
|
|
|
/* Preference settings */
|
|
|
|
static gboolean global_arp_detect_request_storm = FALSE;
|
|
|
|
static guint32 global_arp_detect_request_storm_packets = 30;
|
|
|
|
static guint32 global_arp_detect_request_storm_period = 100;
|
|
|
|
|
2007-12-19 10:49:22 +00:00
|
|
|
static gboolean global_arp_detect_duplicate_ip_addresses = TRUE;
|
|
|
|
|
2006-10-20 14:20:22 +00:00
|
|
|
static guint32 arp_request_count = 0;
|
|
|
|
static nstime_t time_at_start_of_count;
|
|
|
|
|
|
|
|
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Map of (IP address -> MAC address) to detect duplicate IP addresses
|
|
|
|
Key is unsigned32 */
|
|
|
|
static GHashTable *address_hash_table = NULL;
|
|
|
|
|
|
|
|
struct address_hash_value {
|
2009-03-29 22:16:26 +00:00
|
|
|
guint8 mac[6];
|
|
|
|
guint frame_num;
|
|
|
|
time_t time_of_entry;
|
2007-12-19 10:49:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
1998-11-03 07:45:10 +00:00
|
|
|
/* Definitions taken from Linux "linux/if_arp.h" header file, and from
|
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
http://www.iana.org/assignments/arp-parameters
|
1998-11-03 07:45:10 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
*/
|
1998-11-03 07:45:10 +00:00
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
/* ARP / RARP structs and definitions */
|
|
|
|
#ifndef ARPOP_REQUEST
|
|
|
|
#define ARPOP_REQUEST 1 /* ARP request. */
|
|
|
|
#endif
|
|
|
|
#ifndef ARPOP_REPLY
|
|
|
|
#define ARPOP_REPLY 2 /* ARP reply. */
|
|
|
|
#endif
|
|
|
|
/* Some OSes have different names, or don't define these at all */
|
|
|
|
#ifndef ARPOP_RREQUEST
|
|
|
|
#define ARPOP_RREQUEST 3 /* RARP request. */
|
|
|
|
#endif
|
|
|
|
#ifndef ARPOP_RREPLY
|
|
|
|
#define ARPOP_RREPLY 4 /* RARP reply. */
|
|
|
|
#endif
|
1999-11-27 04:01:43 +00:00
|
|
|
#ifndef ARPOP_IREQUEST
|
|
|
|
#define ARPOP_IREQUEST 8 /* Inverse ARP (RFC 1293) request. */
|
|
|
|
#endif
|
|
|
|
#ifndef ARPOP_IREPLY
|
|
|
|
#define ARPOP_IREPLY 9 /* Inverse ARP reply. */
|
|
|
|
#endif
|
|
|
|
#ifndef ATMARPOP_NAK
|
|
|
|
#define ATMARPOP_NAK 10 /* ATMARP NAK. */
|
|
|
|
#endif
|
2010-07-18 16:01:11 +00:00
|
|
|
#ifndef ARPOP_EXP1
|
|
|
|
#define ARPOP_EXP1 24 /* Experimental 1 */
|
|
|
|
#endif
|
|
|
|
#ifndef ARPOP_EXP2
|
|
|
|
#define ARPOP_EXP2 25 /* Experimental 2 */
|
|
|
|
#endif
|
1999-03-23 03:14:46 +00:00
|
|
|
|
1999-11-04 08:15:38 +00:00
|
|
|
static const value_string op_vals[] = {
|
1999-12-07 15:38:20 +00:00
|
|
|
{ARPOP_REQUEST, "request" },
|
|
|
|
{ARPOP_REPLY, "reply" },
|
|
|
|
{ARPOP_RREQUEST, "reverse request"},
|
|
|
|
{ARPOP_RREPLY, "reverse reply" },
|
|
|
|
{ARPOP_IREQUEST, "inverse request"},
|
|
|
|
{ARPOP_IREPLY, "inverse reply" },
|
2010-07-18 16:01:11 +00:00
|
|
|
{ARPOP_EXP1, "experimental 1" },
|
|
|
|
{ARPOP_EXP2, "experimental 2" },
|
1999-11-27 04:01:43 +00:00
|
|
|
{0, NULL } };
|
|
|
|
|
|
|
|
static const value_string atmop_vals[] = {
|
1999-12-07 15:38:20 +00:00
|
|
|
{ARPOP_REQUEST, "request" },
|
|
|
|
{ARPOP_REPLY, "reply" },
|
|
|
|
{ARPOP_IREQUEST, "inverse request"},
|
|
|
|
{ARPOP_IREPLY, "inverse reply" },
|
|
|
|
{ATMARPOP_NAK, "nak" },
|
1999-11-04 08:15:38 +00:00
|
|
|
{0, NULL } };
|
|
|
|
|
2000-11-30 10:42:50 +00:00
|
|
|
#define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */
|
|
|
|
#define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
/*
|
|
|
|
* Given the hardware address type and length, check whether an address
|
|
|
|
* is an Ethernet address - the address must be of type "Ethernet" or
|
|
|
|
* "IEEE 802.x", and the length must be 6 bytes.
|
|
|
|
*/
|
2009-03-29 22:16:26 +00:00
|
|
|
#define ARP_HW_IS_ETHER(ar_hrd, ar_hln) \
|
|
|
|
(((ar_hrd) == ARPHRD_ETHER || (ar_hrd) == ARPHRD_IEEE802) \
|
|
|
|
&& (ar_hln) == 6)
|
2002-02-10 22:41:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Given the protocol address type and length, check whether an address
|
|
|
|
* is an IPv4 address - the address must be of type "IP", and the length
|
|
|
|
* must be 4 bytes.
|
|
|
|
*/
|
2009-03-29 22:16:26 +00:00
|
|
|
#define ARP_PRO_IS_IPv4(ar_pro, ar_pln) \
|
|
|
|
((ar_pro) == ETHERTYPE_IP && (ar_pln) == 4)
|
2002-02-10 22:41:48 +00:00
|
|
|
|
2005-07-27 07:57:01 +00:00
|
|
|
const gchar *
|
2011-02-11 03:33:11 +00:00
|
|
|
tvb_arphrdaddr_to_str(tvbuff_t *tvb, gint offset, int ad_len, guint16 type)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
|
|
|
if (ad_len == 0)
|
|
|
|
return "<No address>";
|
2002-02-10 22:41:48 +00:00
|
|
|
if (ARP_HW_IS_ETHER(type, ad_len)) {
|
|
|
|
/* Ethernet address (or IEEE 802.x address, which is the same type of
|
|
|
|
address). */
|
2011-02-11 03:33:11 +00:00
|
|
|
return tvb_ether_to_str(tvb, offset);
|
1998-11-03 07:45:10 +00:00
|
|
|
}
|
2011-02-11 03:33:11 +00:00
|
|
|
return tvb_bytes_to_str(tvb, offset, ad_len);
|
1998-11-03 07:45:10 +00:00
|
|
|
}
|
|
|
|
|
2005-07-27 07:57:01 +00:00
|
|
|
static const gchar *
|
2001-03-13 21:34:28 +00:00
|
|
|
arpproaddr_to_str(const guint8 *ad, int ad_len, guint16 type)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
|
|
|
if (ad_len == 0)
|
|
|
|
return "<No address>";
|
2002-02-10 22:41:48 +00:00
|
|
|
if (ARP_PRO_IS_IPv4(type, ad_len)) {
|
1999-11-27 04:01:43 +00:00
|
|
|
/* IPv4 address. */
|
1998-11-03 07:45:10 +00:00
|
|
|
return ip_to_str(ad);
|
|
|
|
}
|
1999-05-11 08:21:39 +00:00
|
|
|
return bytes_to_str(ad, ad_len);
|
1998-11-03 07:45:10 +00:00
|
|
|
}
|
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
#define MAX_E164_STR_LEN 20
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2005-07-27 07:57:01 +00:00
|
|
|
static const gchar *
|
2001-03-13 21:34:28 +00:00
|
|
|
atmarpnum_to_str(const guint8 *ad, int ad_tl)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
1999-11-27 04:48:14 +00:00
|
|
|
int ad_len = ad_tl & ATMARP_LEN_MASK;
|
|
|
|
gchar *cur;
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
if (ad_len == 0)
|
|
|
|
return "<No address>";
|
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
if (ad_tl & ATMARP_IS_E164) {
|
|
|
|
/*
|
|
|
|
* I'm assuming this means it's an ASCII (IA5) string.
|
|
|
|
*/
|
2005-08-17 09:25:04 +00:00
|
|
|
cur = ep_alloc(MAX_E164_STR_LEN+3+1);
|
1999-11-27 04:48:14 +00:00
|
|
|
if (ad_len > MAX_E164_STR_LEN) {
|
|
|
|
/* Can't show it all. */
|
|
|
|
memcpy(cur, ad, MAX_E164_STR_LEN);
|
2005-10-16 00:33:00 +00:00
|
|
|
g_snprintf(&cur[MAX_E164_STR_LEN], 3+1, "...");
|
1999-11-27 04:48:14 +00:00
|
|
|
} else {
|
|
|
|
memcpy(cur, ad, ad_len);
|
|
|
|
cur[ad_len + 1] = '\0';
|
|
|
|
}
|
|
|
|
return cur;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* NSAP.
|
|
|
|
*
|
|
|
|
* XXX - break down into subcomponents.
|
|
|
|
*/
|
|
|
|
return bytes_to_str(ad, ad_len);
|
|
|
|
}
|
1999-11-27 04:01:43 +00:00
|
|
|
}
|
|
|
|
|
2005-07-27 07:57:01 +00:00
|
|
|
static const gchar *
|
2001-03-13 21:34:28 +00:00
|
|
|
atmarpsubaddr_to_str(const guint8 *ad, int ad_tl)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
2000-11-30 10:42:50 +00:00
|
|
|
int ad_len = ad_tl & ATMARP_LEN_MASK;
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ad_len == 0)
|
|
|
|
return "<No address>";
|
|
|
|
|
|
|
|
/*
|
2000-11-30 10:42:50 +00:00
|
|
|
* E.164 isn't considered legal in subaddresses (RFC 2225 says that
|
|
|
|
* a null or unknown ATM address is indicated by setting the length
|
|
|
|
* to 0, in which case the type must be ignored; we've seen some
|
|
|
|
* captures in which the length of a subaddress is 0 and the type
|
|
|
|
* is E.164).
|
|
|
|
*
|
1999-11-27 04:01:43 +00:00
|
|
|
* XXX - break down into subcomponents?
|
|
|
|
*/
|
|
|
|
return bytes_to_str(ad, ad_len);
|
|
|
|
}
|
|
|
|
|
1999-11-04 08:15:38 +00:00
|
|
|
static const value_string hrd_vals[] = {
|
|
|
|
{ARPHRD_NETROM, "NET/ROM pseudo" },
|
|
|
|
{ARPHRD_ETHER, "Ethernet" },
|
|
|
|
{ARPHRD_EETHER, "Experimental Ethernet"},
|
|
|
|
{ARPHRD_AX25, "AX.25" },
|
|
|
|
{ARPHRD_PRONET, "ProNET" },
|
|
|
|
{ARPHRD_CHAOS, "Chaos" },
|
|
|
|
{ARPHRD_IEEE802, "IEEE 802" },
|
|
|
|
{ARPHRD_ARCNET, "ARCNET" },
|
|
|
|
{ARPHRD_HYPERCH, "Hyperchannel" },
|
|
|
|
{ARPHRD_LANSTAR, "Lanstar" },
|
|
|
|
{ARPHRD_AUTONET, "Autonet Short Address"},
|
|
|
|
{ARPHRD_LOCALTLK, "Localtalk" },
|
|
|
|
{ARPHRD_LOCALNET, "LocalNet" },
|
|
|
|
{ARPHRD_ULTRALNK, "Ultra link" },
|
|
|
|
{ARPHRD_SMDS, "SMDS" },
|
|
|
|
{ARPHRD_DLCI, "Frame Relay DLCI" },
|
|
|
|
{ARPHRD_ATM, "ATM" },
|
|
|
|
{ARPHRD_HDLC, "HDLC" },
|
|
|
|
{ARPHRD_FIBREC, "Fibre Channel" },
|
|
|
|
{ARPHRD_ATM2225, "ATM (RFC 2225)" },
|
|
|
|
{ARPHRD_SERIAL, "Serial Line" },
|
|
|
|
{ARPHRD_ATM2, "ATM" },
|
|
|
|
{ARPHRD_MS188220, "MIL-STD-188-220" },
|
|
|
|
{ARPHRD_METRICOM, "Metricom STRIP" },
|
|
|
|
{ARPHRD_IEEE1394, "IEEE 1394.1995" },
|
|
|
|
{ARPHRD_MAPOS, "MAPOS" },
|
|
|
|
{ARPHRD_TWINAX, "Twinaxial" },
|
|
|
|
{ARPHRD_EUI_64, "EUI-64" },
|
2008-12-27 14:30:46 +00:00
|
|
|
{ARPHRD_HIPARP, "HIPARP" },
|
|
|
|
{ARPHRD_IP_ARP_ISO_7816_3, "IP and ARP over ISO 7816-3"},
|
|
|
|
{ARPHRD_ARPSEC, "ARPSec" },
|
|
|
|
{ARPHRD_IPSEC_TUNNEL, "IPsec tunnel"},
|
|
|
|
{ARPHRD_INFINIBAND, "InfiniBand" },
|
|
|
|
{ARPHRD_TIA_102_PRJ_25_CAI, "TIA-102 Project 25 CAI"},
|
|
|
|
{ARPHRD_WIEGAND_INTERFACE, "Wiegand Interface"},
|
|
|
|
{ARPHRD_PURE_IP, "Pure IP" },
|
2010-07-18 16:01:11 +00:00
|
|
|
{ARPHDR_HW_EXP1, "Experimental 1"},
|
|
|
|
{ARPHDR_HFI, "HFI" },
|
|
|
|
{ARPHDR_HW_EXP2, "Experimental 2"},
|
1999-11-04 08:15:38 +00:00
|
|
|
{0, NULL } };
|
|
|
|
|
2005-06-26 19:56:52 +00:00
|
|
|
const gchar *
|
1999-01-28 21:29:36 +00:00
|
|
|
arphrdtype_to_str(guint16 hwtype, const char *fmt) {
|
2009-03-29 22:16:26 +00:00
|
|
|
return val_to_str(hwtype, hrd_vals, fmt);
|
1999-01-28 21:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Offsets of fields within an ARP packet. */
|
|
|
|
#define AR_HRD 0
|
|
|
|
#define AR_PRO 2
|
|
|
|
#define AR_HLN 4
|
|
|
|
#define AR_PLN 5
|
|
|
|
#define AR_OP 6
|
1999-10-03 17:12:15 +00:00
|
|
|
#define MIN_ARP_HEADER_SIZE 8
|
1999-01-28 21:29:36 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
/* Offsets of fields within an ATMARP packet. */
|
|
|
|
#define ATM_AR_HRD 0
|
|
|
|
#define ATM_AR_PRO 2
|
|
|
|
#define ATM_AR_SHTL 4
|
2000-11-30 10:42:50 +00:00
|
|
|
#define ATM_AR_SSTL 5
|
1999-11-27 04:01:43 +00:00
|
|
|
#define ATM_AR_OP 6
|
|
|
|
#define ATM_AR_SPLN 8
|
|
|
|
#define ATM_AR_THTL 9
|
2000-11-30 10:42:50 +00:00
|
|
|
#define ATM_AR_TSTL 10
|
1999-11-27 04:01:43 +00:00
|
|
|
#define ATM_AR_TPLN 11
|
|
|
|
#define MIN_ATMARP_HEADER_SIZE 12
|
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
static void
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_atm_number(tvbuff_t *tvb, int offset, int tl, int hf_e164,
|
2009-03-29 22:16:26 +00:00
|
|
|
int hf_nsap, proto_tree *tree)
|
1999-11-27 04:48:14 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
int len = tl & ATMARP_LEN_MASK;
|
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *nsap_tree;
|
|
|
|
|
|
|
|
if (tl & ATMARP_IS_E164)
|
2011-09-26 08:25:18 +00:00
|
|
|
proto_tree_add_item(tree, hf_e164, tvb, offset, len, ENC_BIG_ENDIAN);
|
2009-03-29 22:16:26 +00:00
|
|
|
else {
|
2011-09-26 08:25:18 +00:00
|
|
|
ti = proto_tree_add_item(tree, hf_nsap, tvb, offset, len, ENC_BIG_ENDIAN);
|
2009-03-29 22:16:26 +00:00
|
|
|
if (len >= 20) {
|
|
|
|
nsap_tree = proto_item_add_subtree(ti, ett_atmarp_nsap);
|
|
|
|
dissect_atm_nsap(tvb, offset, len, nsap_tree);
|
|
|
|
}
|
|
|
|
}
|
1999-11-27 04:48:14 +00:00
|
|
|
}
|
|
|
|
|
2005-09-12 07:44:11 +00:00
|
|
|
/*
|
|
|
|
* XXX - shouldn't there be a centralized routine for dissecting NSAPs?
|
|
|
|
* See also "dissect_nsap()" in epan/dissectors/packet-isup.c and
|
|
|
|
* "print_nsap_net_buf()" and "print_nsap_net()" in epan/osi=utils.c.
|
|
|
|
*/
|
1999-11-27 04:48:14 +00:00
|
|
|
void
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_atm_nsap(tvbuff_t *tvb, int offset, int len, proto_tree *tree)
|
1999-11-27 04:48:14 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
guint8 afi;
|
|
|
|
|
|
|
|
afi = tvb_get_guint8(tvb, offset);
|
|
|
|
switch (afi) {
|
|
|
|
|
|
|
|
case 0x39: /* DCC ATM format */
|
|
|
|
case 0xBD: /* DCC ATM group format */
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 0, 3,
|
|
|
|
"Data Country Code%s: 0x%04X",
|
|
|
|
(afi == 0xBD) ? " (group)" : "",
|
|
|
|
tvb_get_ntohs(tvb, offset + 1));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 3, 10,
|
|
|
|
"High Order DSP: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 3, 10));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 13, 6,
|
|
|
|
"End System Identifier: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 13, 6));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 19, 1,
|
|
|
|
"Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x47: /* ICD ATM format */
|
|
|
|
case 0xC5: /* ICD ATM group format */
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 0, 3,
|
|
|
|
"International Code Designator%s: 0x%04X",
|
|
|
|
(afi == 0xC5) ? " (group)" : "",
|
|
|
|
tvb_get_ntohs(tvb, offset + 1));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 3, 10,
|
|
|
|
"High Order DSP: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 3, 10));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 13, 6,
|
|
|
|
"End System Identifier: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 13, 6));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 19, 1,
|
|
|
|
"Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x45: /* E.164 ATM format */
|
|
|
|
case 0xC3: /* E.164 ATM group format */
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 0, 9,
|
|
|
|
"E.164 ISDN%s: %s",
|
|
|
|
(afi == 0xC3) ? " (group)" : "",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 1, 8));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 9, 4,
|
|
|
|
"High Order DSP: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 3, 10));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 13, 6,
|
|
|
|
"End System Identifier: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 13, 6));
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 19, 1,
|
|
|
|
"Selector: 0x%02X", tvb_get_guint8(tvb, offset + 19));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
proto_tree_add_text(tree, tvb, offset, 1,
|
|
|
|
"Unknown AFI: 0x%02X", afi);
|
|
|
|
proto_tree_add_text(tree, tvb, offset + 1, len - 1,
|
|
|
|
"Rest of address: %s",
|
|
|
|
tvb_bytes_to_str(tvb, offset + 1, len - 1));
|
|
|
|
break;
|
|
|
|
}
|
1999-11-27 04:48:14 +00:00
|
|
|
}
|
|
|
|
|
2007-12-19 10:49:22 +00:00
|
|
|
/* l.s. 32 bits are ipv4 address */
|
|
|
|
static guint address_hash_func(gconstpointer v)
|
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
return GPOINTER_TO_UINT(v);
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Compare 2 ipv4 addresses */
|
|
|
|
static gint address_equal_func(gconstpointer v, gconstpointer v2)
|
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
return v == v2;
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check to see if this mac & ip pair represent 2 devices trying to share
|
2008-01-02 10:35:20 +00:00
|
|
|
the same IP address - report if found (+ return TRUE and set out param) */
|
|
|
|
static gboolean check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree,
|
|
|
|
tvbuff_t *tvb,
|
2008-05-30 00:01:24 +00:00
|
|
|
const guint8 *mac, guint32 ip,
|
2008-01-02 10:35:20 +00:00
|
|
|
guint32 *duplicate_ip)
|
2007-12-19 10:49:22 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
struct address_hash_value *value;
|
|
|
|
gboolean return_value = FALSE;
|
2007-12-19 10:49:22 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
/* Look up any existing entries */
|
|
|
|
value = g_hash_table_lookup(address_hash_table, GUINT_TO_POINTER(ip));
|
2007-12-19 10:49:22 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
/* If MAC matches table, just update details */
|
|
|
|
if (value != NULL)
|
|
|
|
{
|
|
|
|
if (pinfo->fd->num > value->frame_num)
|
2007-12-19 10:49:22 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
if ((memcmp(value->mac, mac, 6) == 0))
|
|
|
|
{
|
|
|
|
/* Same MAC as before - update existing entry */
|
2007-12-19 10:49:22 +00:00
|
|
|
value->frame_num = pinfo->fd->num;
|
|
|
|
value->time_of_entry = pinfo->fd->abs_ts.secs;
|
2009-03-29 22:16:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Doesn't match earlier MAC - report! */
|
|
|
|
proto_tree *duplicate_tree;
|
|
|
|
|
|
|
|
/* Create subtree */
|
|
|
|
proto_item *ti = proto_tree_add_none_format(tree, hf_arp_duplicate_ip_address,
|
|
|
|
tvb, 0, 0,
|
|
|
|
"Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
|
|
|
|
arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP),
|
|
|
|
ether_to_str(mac),
|
|
|
|
ether_to_str(value->mac),
|
|
|
|
value->frame_num);
|
|
|
|
PROTO_ITEM_SET_GENERATED(ti);
|
|
|
|
duplicate_tree = proto_item_add_subtree(ti, ett_arp_duplicate_address);
|
|
|
|
|
|
|
|
/* Add item for navigating to earlier frame */
|
|
|
|
ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame,
|
|
|
|
tvb, 0, 0, value->frame_num);
|
|
|
|
PROTO_ITEM_SET_GENERATED(ti);
|
|
|
|
expert_add_info_format(pinfo, ti,
|
|
|
|
PI_SEQUENCE, PI_WARN,
|
|
|
|
"Duplicate IP address configured (%s)",
|
|
|
|
arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP));
|
|
|
|
|
|
|
|
/* Time since that frame was seen */
|
|
|
|
ti = proto_tree_add_uint(duplicate_tree,
|
|
|
|
hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
|
|
|
|
tvb, 0, 0,
|
|
|
|
(guint32)(pinfo->fd->abs_ts.secs - value->time_of_entry));
|
|
|
|
PROTO_ITEM_SET_GENERATED(ti);
|
|
|
|
|
|
|
|
*duplicate_ip = ip;
|
|
|
|
return_value = TRUE;
|
|
|
|
}
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
2009-03-29 22:16:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No existing entry. Prepare one */
|
|
|
|
value = se_alloc(sizeof(struct address_hash_value));
|
|
|
|
memcpy(value->mac, mac, 6);
|
|
|
|
value->frame_num = pinfo->fd->num;
|
|
|
|
value->time_of_entry = pinfo->fd->abs_ts.secs;
|
|
|
|
|
|
|
|
/* Add it */
|
|
|
|
g_hash_table_insert(address_hash_table, GUINT_TO_POINTER(ip), value);
|
|
|
|
}
|
2008-01-02 10:35:20 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
return return_value;
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initializes the hash table each time a new
|
|
|
|
* file is loaded or re-loaded in wireshark */
|
|
|
|
static void
|
|
|
|
arp_init_protocol(void)
|
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
/* Destroy any existing hashes. */
|
|
|
|
if (address_hash_table)
|
|
|
|
g_hash_table_destroy(address_hash_table);
|
2007-12-19 10:49:22 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
/* Now create it over */
|
|
|
|
address_hash_table = g_hash_table_new(address_hash_func, address_equal_func);
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-10-20 14:20:22 +00:00
|
|
|
/* Take note that a request has been seen */
|
2009-03-29 22:16:26 +00:00
|
|
|
static void request_seen(packet_info *pinfo)
|
2006-10-20 14:20:22 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
/* Don't count frame again after already recording first time around. */
|
|
|
|
if (p_get_proto_data(pinfo->fd, proto_arp) == 0)
|
|
|
|
{
|
|
|
|
arp_request_count++;
|
|
|
|
}
|
2006-10-20 14:20:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Has storm request rate been exceeded with this request? */
|
2009-03-29 22:16:26 +00:00
|
|
|
static void check_for_storm_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2006-10-20 14:20:22 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
gboolean report_storm = FALSE;
|
2006-10-20 14:20:22 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
if (p_get_proto_data(pinfo->fd, proto_arp) != 0)
|
|
|
|
{
|
|
|
|
/* Read any previous stored packet setting */
|
|
|
|
report_storm = (p_get_proto_data(pinfo->fd, proto_arp) == (void*)STORM);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Seeing packet for first time - check against preference settings */
|
|
|
|
gint seconds_delta = (gint) (pinfo->fd->abs_ts.secs - time_at_start_of_count.secs);
|
|
|
|
gint nseconds_delta = pinfo->fd->abs_ts.nsecs - time_at_start_of_count.nsecs;
|
|
|
|
gint gap = (seconds_delta*1000) + (nseconds_delta / 1000000);
|
|
|
|
|
|
|
|
/* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */
|
|
|
|
if ((gap > (gint)global_arp_detect_request_storm_period) ||
|
|
|
|
(gap < 0))
|
2006-10-20 14:20:22 +00:00
|
|
|
{
|
2009-03-29 22:16:26 +00:00
|
|
|
/* Time period elapsed without threshold being exceeded */
|
|
|
|
arp_request_count = 1;
|
|
|
|
time_at_start_of_count = pinfo->fd->abs_ts;
|
|
|
|
p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM);
|
|
|
|
return;
|
2006-10-20 14:20:22 +00:00
|
|
|
}
|
|
|
|
else
|
2009-03-29 22:16:26 +00:00
|
|
|
if (arp_request_count > global_arp_detect_request_storm_packets)
|
|
|
|
{
|
|
|
|
/* Storm detected, record and reset start time. */
|
|
|
|
report_storm = TRUE;
|
|
|
|
p_add_proto_data(pinfo->fd, proto_arp, (void*)STORM);
|
|
|
|
time_at_start_of_count = pinfo->fd->abs_ts;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Threshold not exceeded yet - no storm */
|
|
|
|
p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM);
|
|
|
|
}
|
|
|
|
}
|
2007-03-11 06:16:00 +00:00
|
|
|
|
2009-03-29 22:16:26 +00:00
|
|
|
if (report_storm)
|
|
|
|
{
|
|
|
|
/* Report storm and reset counter */
|
|
|
|
proto_item *ti = proto_tree_add_none_format(tree, hf_arp_packet_storm, tvb, 0, 0,
|
|
|
|
"Packet storm detected (%u packets in < %u ms)",
|
|
|
|
global_arp_detect_request_storm_packets,
|
|
|
|
global_arp_detect_request_storm_period);
|
|
|
|
PROTO_ITEM_SET_GENERATED(ti);
|
|
|
|
|
|
|
|
expert_add_info_format(pinfo, ti,
|
|
|
|
PI_SEQUENCE, PI_NOTE,
|
|
|
|
"ARP packet storm detected (%u packets in < %u ms)",
|
|
|
|
global_arp_detect_request_storm_packets,
|
|
|
|
global_arp_detect_request_storm_period);
|
|
|
|
arp_request_count = 0;
|
|
|
|
}
|
2006-10-20 14:20:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
/*
|
|
|
|
* RFC 2225 ATMARP - it's just like ARP, except where it isn't.
|
|
|
|
*/
|
|
|
|
static void
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_atmarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
|
|
|
guint16 ar_hrd;
|
|
|
|
guint16 ar_pro;
|
|
|
|
guint8 ar_shtl;
|
|
|
|
guint8 ar_shl;
|
2000-11-30 10:42:50 +00:00
|
|
|
guint8 ar_sstl;
|
1999-11-27 04:01:43 +00:00
|
|
|
guint8 ar_ssl;
|
|
|
|
guint16 ar_op;
|
|
|
|
guint8 ar_spln;
|
|
|
|
guint8 ar_thtl;
|
|
|
|
guint8 ar_thl;
|
2000-11-30 10:42:50 +00:00
|
|
|
guint8 ar_tstl;
|
1999-11-27 04:01:43 +00:00
|
|
|
guint8 ar_tsl;
|
|
|
|
guint8 ar_tpln;
|
|
|
|
int tot_len;
|
|
|
|
proto_tree *arp_tree;
|
|
|
|
proto_item *ti;
|
2005-06-26 19:56:52 +00:00
|
|
|
const gchar *op_str;
|
1999-11-27 04:01:43 +00:00
|
|
|
int sha_offset, ssa_offset, spa_offset;
|
|
|
|
int tha_offset, tsa_offset, tpa_offset;
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *sha_val, *ssa_val, *spa_val;
|
|
|
|
const guint8 *tha_val, *tsa_val, *tpa_val;
|
2005-07-27 07:57:01 +00:00
|
|
|
const gchar *sha_str, *ssa_str, *spa_str;
|
|
|
|
const gchar *tha_str, *tsa_str, *tpa_str;
|
2000-11-30 10:42:50 +00:00
|
|
|
proto_tree *tl_tree;
|
|
|
|
proto_item *tl;
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
/* Override the setting to "ARP/RARP". */
|
2000-11-13 07:19:37 +00:00
|
|
|
pinfo->current_proto = "ATMARP";
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_hrd = tvb_get_ntohs(tvb, ATM_AR_HRD);
|
|
|
|
ar_pro = tvb_get_ntohs(tvb, ATM_AR_PRO);
|
|
|
|
ar_shtl = tvb_get_guint8(tvb, ATM_AR_SHTL);
|
1999-11-27 04:01:43 +00:00
|
|
|
ar_shl = ar_shtl & ATMARP_LEN_MASK;
|
2000-11-30 10:42:50 +00:00
|
|
|
ar_sstl = tvb_get_guint8(tvb, ATM_AR_SSTL);
|
|
|
|
ar_ssl = ar_sstl & ATMARP_LEN_MASK;
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_op = tvb_get_ntohs(tvb, AR_OP);
|
|
|
|
ar_spln = tvb_get_guint8(tvb, ATM_AR_SPLN);
|
|
|
|
ar_thtl = tvb_get_guint8(tvb, ATM_AR_THTL);
|
1999-11-27 04:01:43 +00:00
|
|
|
ar_thl = ar_thtl & ATMARP_LEN_MASK;
|
2000-11-30 10:42:50 +00:00
|
|
|
ar_tstl = tvb_get_guint8(tvb, ATM_AR_TSTL);
|
|
|
|
ar_tsl = ar_tstl & ATMARP_LEN_MASK;
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_tpln = tvb_get_guint8(tvb, ATM_AR_TPLN);
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2000-11-30 10:42:50 +00:00
|
|
|
tot_len = MIN_ATMARP_HEADER_SIZE + ar_shl + ar_ssl + ar_spln +
|
2009-03-29 22:16:26 +00:00
|
|
|
ar_thl + ar_tsl + ar_tpln;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2000-11-19 01:00:20 +00:00
|
|
|
/* Adjust the length of this tvbuff to include only the ARP datagram.
|
|
|
|
Our caller may use that to determine how much of its packet
|
|
|
|
was padding. */
|
|
|
|
tvb_set_reported_length(tvb, tot_len);
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
/* Extract the addresses. */
|
2000-11-13 07:19:37 +00:00
|
|
|
sha_offset = MIN_ATMARP_HEADER_SIZE;
|
|
|
|
if (ar_shl != 0) {
|
|
|
|
sha_val = tvb_get_ptr(tvb, sha_offset, ar_shl);
|
|
|
|
sha_str = atmarpnum_to_str(sha_val, ar_shtl);
|
|
|
|
} else {
|
|
|
|
sha_val = NULL;
|
1999-11-27 04:01:43 +00:00
|
|
|
sha_str = "<No address>";
|
2000-11-13 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
ssa_offset = sha_offset + ar_shl;
|
2000-11-13 07:19:37 +00:00
|
|
|
if (ar_ssl != 0) {
|
|
|
|
ssa_val = tvb_get_ptr(tvb, ssa_offset, ar_ssl);
|
2000-11-30 10:42:50 +00:00
|
|
|
ssa_str = atmarpsubaddr_to_str(ssa_val, ar_sstl);
|
2000-11-13 07:19:37 +00:00
|
|
|
} else {
|
|
|
|
ssa_val = NULL;
|
1999-11-27 04:01:43 +00:00
|
|
|
ssa_str = NULL;
|
2000-11-13 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
spa_offset = ssa_offset + ar_ssl;
|
2000-11-13 07:19:37 +00:00
|
|
|
spa_val = tvb_get_ptr(tvb, spa_offset, ar_spln);
|
|
|
|
spa_str = arpproaddr_to_str(spa_val, ar_spln, ar_pro);
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
tha_offset = spa_offset + ar_spln;
|
2000-11-13 07:19:37 +00:00
|
|
|
if (ar_thl != 0) {
|
|
|
|
tha_val = tvb_get_ptr(tvb, tha_offset, ar_thl);
|
|
|
|
tha_str = atmarpnum_to_str(tha_val, ar_thtl);
|
|
|
|
} else {
|
|
|
|
tha_val = NULL;
|
1999-11-27 04:01:43 +00:00
|
|
|
tha_str = "<No address>";
|
2000-11-13 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
tsa_offset = tha_offset + ar_thl;
|
2000-11-13 07:19:37 +00:00
|
|
|
if (ar_tsl != 0) {
|
|
|
|
tsa_val = tvb_get_ptr(tvb, tsa_offset, ar_tsl);
|
2000-11-30 10:42:50 +00:00
|
|
|
tsa_str = atmarpsubaddr_to_str(tsa_val, ar_tstl);
|
2000-11-13 07:19:37 +00:00
|
|
|
} else {
|
|
|
|
tsa_val = NULL;
|
1999-11-27 04:01:43 +00:00
|
|
|
tsa_str = NULL;
|
2000-11-13 07:19:37 +00:00
|
|
|
}
|
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
tpa_offset = tsa_offset + ar_tsl;
|
2000-11-13 07:19:37 +00:00
|
|
|
tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_tpln);
|
|
|
|
tpa_str = arpproaddr_to_str(tpa_val, ar_tpln, ar_pro);
|
2000-11-19 01:00:20 +00:00
|
|
|
|
2011-09-26 08:25:18 +00:00
|
|
|
switch (ar_op) {
|
|
|
|
|
|
|
|
case ARPOP_REQUEST:
|
|
|
|
case ARPOP_REPLY:
|
|
|
|
case ATMARPOP_NAK:
|
|
|
|
default:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMARP");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ARPOP_RREQUEST:
|
|
|
|
case ARPOP_RREPLY:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMRARP");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ARPOP_IREQUEST:
|
|
|
|
case ARPOP_IREPLY:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ATMARP");
|
|
|
|
break;
|
1999-11-27 04:01:43 +00:00
|
|
|
}
|
|
|
|
|
2011-09-26 08:25:18 +00:00
|
|
|
switch (ar_op) {
|
|
|
|
case ARPOP_REQUEST:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
|
|
|
|
tpa_str, spa_str);
|
|
|
|
break;
|
|
|
|
case ARPOP_REPLY:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s%s%s", spa_str, sha_str,
|
|
|
|
((ssa_str != NULL) ? "," : ""),
|
|
|
|
((ssa_str != NULL) ? ssa_str : ""));
|
|
|
|
break;
|
|
|
|
case ARPOP_IREQUEST:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s%s%s? Tell %s%s%s",
|
|
|
|
tha_str,
|
|
|
|
((tsa_str != NULL) ? "," : ""),
|
|
|
|
((tsa_str != NULL) ? tsa_str : ""),
|
|
|
|
sha_str,
|
|
|
|
((ssa_str != NULL) ? "," : ""),
|
|
|
|
((ssa_str != NULL) ? ssa_str : ""));
|
|
|
|
break;
|
|
|
|
case ARPOP_IREPLY:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s is at %s",
|
|
|
|
sha_str,
|
|
|
|
((ssa_str != NULL) ? "," : ""),
|
|
|
|
((ssa_str != NULL) ? ssa_str : ""),
|
|
|
|
spa_str);
|
|
|
|
break;
|
|
|
|
case ATMARPOP_NAK:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "I don't know where %s is", spa_str);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ATMARP opcode 0x%04x", ar_op);
|
|
|
|
break;
|
1999-11-27 04:01:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tree) {
|
|
|
|
if ((op_str = match_strval(ar_op, atmop_vals)))
|
2000-11-13 07:19:37 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
|
2009-03-29 22:16:26 +00:00
|
|
|
"ATM Address Resolution Protocol (%s)",
|
|
|
|
op_str);
|
1999-11-27 04:01:43 +00:00
|
|
|
else
|
2000-11-13 07:19:37 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
|
2009-03-29 22:16:26 +00:00
|
|
|
"ATM Address Resolution Protocol (opcode 0x%04x)", ar_op);
|
1999-11-27 04:01:43 +00:00
|
|
|
arp_tree = proto_item_add_subtree(ti, ett_arp);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, ATM_AR_HRD, 2, ar_hrd);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, ATM_AR_PRO, 2,ar_pro);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SHTL, 1,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Sender ATM number type/length: %s/%u",
|
|
|
|
(ar_shtl & ATMARP_IS_E164 ?
|
|
|
|
"E.164" :
|
|
|
|
"ATM Forum NSAPA"),
|
|
|
|
ar_shl);
|
2000-11-30 10:42:50 +00:00
|
|
|
tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
|
|
|
|
proto_tree_add_boolean(tl_tree, hf_atmarp_sht, tvb, ATM_AR_SHTL, 1, ar_shtl);
|
|
|
|
proto_tree_add_uint(tl_tree, hf_atmarp_shl, tvb, ATM_AR_SHTL, 1, ar_shtl);
|
|
|
|
|
|
|
|
tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SSTL, 1,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Sender ATM subaddress type/length: %s/%u",
|
|
|
|
(ar_sstl & ATMARP_IS_E164 ?
|
|
|
|
"E.164" :
|
|
|
|
"ATM Forum NSAPA"),
|
|
|
|
ar_ssl);
|
2000-11-30 10:42:50 +00:00
|
|
|
tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
|
|
|
|
proto_tree_add_boolean(tl_tree, hf_atmarp_sst, tvb, ATM_AR_SSTL, 1, ar_sstl);
|
|
|
|
proto_tree_add_uint(tl_tree, hf_atmarp_ssl, tvb, ATM_AR_SSTL, 1, ar_sstl);
|
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ar_op);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2009-05-21 05:15:03 +00:00
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_atmarp_spln, tvb, ATM_AR_SPLN, 1, ar_spln);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_THTL, 1,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Target ATM number type/length: %s/%u",
|
|
|
|
(ar_thtl & ATMARP_IS_E164 ?
|
|
|
|
"E.164" :
|
|
|
|
"ATM Forum NSAPA"),
|
|
|
|
ar_thl);
|
2000-11-30 10:42:50 +00:00
|
|
|
tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
|
|
|
|
proto_tree_add_boolean(tl_tree, hf_atmarp_tht, tvb, ATM_AR_THTL, 1, ar_thtl);
|
|
|
|
proto_tree_add_uint(tl_tree, hf_atmarp_thl, tvb, ATM_AR_THTL, 1, ar_thtl);
|
|
|
|
|
|
|
|
tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_TSTL, 1,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Target ATM subaddress type/length: %s/%u",
|
|
|
|
(ar_tstl & ATMARP_IS_E164 ?
|
|
|
|
"E.164" :
|
|
|
|
"ATM Forum NSAPA"),
|
|
|
|
ar_tsl);
|
2000-11-30 10:42:50 +00:00
|
|
|
tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
|
|
|
|
proto_tree_add_boolean(tl_tree, hf_atmarp_tst, tvb, ATM_AR_TSTL, 1, ar_tstl);
|
|
|
|
proto_tree_add_uint(tl_tree, hf_atmarp_tsl, tvb, ATM_AR_TSTL, 1, ar_tstl);
|
|
|
|
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_atmarp_tpln, tvb, ATM_AR_TPLN, 1, ar_tpln);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ar_shl != 0)
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_atm_number(tvb, sha_offset, ar_shtl, hf_atmarp_src_atm_num_e164,
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_atmarp_src_atm_num_nsap, arp_tree);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ar_ssl != 0)
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_bytes_format(arp_tree, hf_atmarp_src_atm_subaddr, tvb, ssa_offset,
|
2009-03-29 22:16:26 +00:00
|
|
|
ar_ssl,
|
|
|
|
ssa_val,
|
|
|
|
"Sender ATM subaddress: %s", ssa_str);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
if (ar_spln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2009-03-29 22:16:26 +00:00
|
|
|
ARP_PRO_IS_IPv4(ar_pro, ar_spln) ? hf_arp_src_proto_ipv4
|
|
|
|
: hf_arp_src_proto,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, spa_offset, ar_spln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
2000-11-30 10:42:50 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ar_thl != 0)
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_atm_number(tvb, tha_offset, ar_thtl, hf_atmarp_dst_atm_num_e164,
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_atmarp_dst_atm_num_nsap, arp_tree);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ar_tsl != 0)
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_bytes_format(arp_tree, hf_atmarp_dst_atm_subaddr, tvb, tsa_offset,
|
2009-03-29 22:16:26 +00:00
|
|
|
ar_tsl,
|
|
|
|
tsa_val,
|
|
|
|
"Target ATM subaddress: %s", tsa_str);
|
2000-11-30 10:42:50 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
if (ar_tpln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2009-03-29 22:16:26 +00:00
|
|
|
ARP_PRO_IS_IPv4(ar_pro, ar_tpln) ? hf_arp_dst_proto_ipv4
|
|
|
|
: hf_arp_dst_proto,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, tpa_offset, ar_tpln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
1999-11-27 04:01:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-10 21:13:13 +00:00
|
|
|
static const guint8 mac_allzero[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
2001-01-09 01:02:34 +00:00
|
|
|
|
2000-04-16 22:59:37 +00:00
|
|
|
static void
|
2000-11-13 07:19:37 +00:00
|
|
|
dissect_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
1999-11-27 04:01:43 +00:00
|
|
|
{
|
1999-01-28 21:29:36 +00:00
|
|
|
guint16 ar_hrd;
|
|
|
|
guint16 ar_pro;
|
|
|
|
guint8 ar_hln;
|
|
|
|
guint8 ar_pln;
|
|
|
|
guint16 ar_op;
|
1999-11-27 04:01:43 +00:00
|
|
|
int tot_len;
|
2006-10-20 14:20:22 +00:00
|
|
|
proto_tree *arp_tree = NULL;
|
2009-05-21 05:15:03 +00:00
|
|
|
proto_item *ti, *item;
|
2005-06-26 19:56:52 +00:00
|
|
|
const gchar *op_str;
|
1999-01-28 21:29:36 +00:00
|
|
|
int sha_offset, spa_offset, tha_offset, tpa_offset;
|
2011-02-11 03:33:11 +00:00
|
|
|
const guint8 *spa_val, *tpa_val;
|
2004-06-17 08:32:59 +00:00
|
|
|
gboolean is_gratuitous;
|
2008-01-02 10:35:20 +00:00
|
|
|
gboolean duplicate_detected = FALSE;
|
|
|
|
guint32 duplicate_ip = 0;
|
1999-01-28 21:29:36 +00:00
|
|
|
|
2000-12-29 04:16:57 +00:00
|
|
|
/* Call it ARP, for now, so that if we throw an exception before
|
|
|
|
we decide whether it's ARP or RARP or IARP or ATMARP, it shows
|
|
|
|
up in the packet list as ARP.
|
|
|
|
|
|
|
|
Clear the Info column so that, if we throw an exception, it
|
|
|
|
shows up as a short or malformed ARP frame. */
|
2009-08-09 06:26:46 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
|
2009-08-09 07:36:13 +00:00
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
2000-12-29 04:16:57 +00:00
|
|
|
|
2004-06-17 08:32:59 +00:00
|
|
|
/* Hardware Address Type */
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
|
1999-11-27 04:01:43 +00:00
|
|
|
if (ar_hrd == ARPHRD_ATM2225) {
|
2001-11-27 07:13:32 +00:00
|
|
|
call_dissector(atmarp_handle, tvb, pinfo, tree);
|
1999-11-27 04:01:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-06-17 08:32:59 +00:00
|
|
|
/* Protocol Address Type */
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_pro = tvb_get_ntohs(tvb, AR_PRO);
|
2004-06-17 08:32:59 +00:00
|
|
|
/* Hardware Address Size */
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_hln = tvb_get_guint8(tvb, AR_HLN);
|
2004-06-17 08:32:59 +00:00
|
|
|
/* Protocol Address Size */
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_pln = tvb_get_guint8(tvb, AR_PLN);
|
2004-06-17 08:32:59 +00:00
|
|
|
/* Operation */
|
2000-11-13 07:19:37 +00:00
|
|
|
ar_op = tvb_get_ntohs(tvb, AR_OP);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2000-11-19 01:00:20 +00:00
|
|
|
/* Adjust the length of this tvbuff to include only the ARP datagram.
|
|
|
|
Our caller may use that to determine how much of its packet
|
|
|
|
was padding. */
|
|
|
|
tvb_set_reported_length(tvb, tot_len);
|
1999-10-03 17:12:15 +00:00
|
|
|
|
2011-09-26 08:25:18 +00:00
|
|
|
switch (ar_op) {
|
|
|
|
|
|
|
|
case ARPOP_REQUEST:
|
|
|
|
if (global_arp_detect_request_storm)
|
|
|
|
{
|
|
|
|
request_seen(pinfo);
|
|
|
|
}
|
|
|
|
/* FALLTHRU */
|
|
|
|
case ARPOP_REPLY:
|
|
|
|
default:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ARPOP_RREQUEST:
|
|
|
|
case ARPOP_RREPLY:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ARPOP_IREQUEST:
|
|
|
|
case ARPOP_IREPLY:
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
|
|
|
|
break;
|
1998-11-17 04:29:13 +00:00
|
|
|
}
|
|
|
|
|
2004-06-17 20:04:53 +00:00
|
|
|
/* Get the offsets of the addresses. */
|
|
|
|
/* Source Hardware Address */
|
|
|
|
sha_offset = MIN_ARP_HEADER_SIZE;
|
|
|
|
/* Source Protocol Address */
|
|
|
|
spa_offset = sha_offset + ar_hln;
|
|
|
|
/* Target Hardware Address */
|
|
|
|
tha_offset = spa_offset + ar_pln;
|
|
|
|
/* Target Protocol Address */
|
|
|
|
tpa_offset = tha_offset + ar_hln;
|
1998-11-03 07:45:10 +00:00
|
|
|
|
2000-08-10 20:09:29 +00:00
|
|
|
if ((ar_op == ARPOP_REPLY || ar_op == ARPOP_REQUEST) &&
|
2002-02-10 22:41:48 +00:00
|
|
|
ARP_HW_IS_ETHER(ar_hrd, ar_hln) &&
|
|
|
|
ARP_PRO_IS_IPv4(ar_pro, ar_pln)) {
|
2000-08-10 20:09:29 +00:00
|
|
|
|
|
|
|
/* inform resolv.c module of the new discovered addresses */
|
|
|
|
|
2008-01-02 10:35:20 +00:00
|
|
|
guint32 ip;
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *mac;
|
2000-08-10 20:09:29 +00:00
|
|
|
|
2003-02-10 21:13:13 +00:00
|
|
|
/* Add sender address if sender MAC address is neither a broadcast/
|
|
|
|
multicast address nor an all-zero address and if sender IP address
|
|
|
|
isn't all zeroes. */
|
2005-09-11 21:25:37 +00:00
|
|
|
ip = tvb_get_ipv4(tvb, spa_offset);
|
2003-02-10 21:13:13 +00:00
|
|
|
mac = tvb_get_ptr(tvb, sha_offset, 6);
|
|
|
|
if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0)
|
2007-12-19 10:49:22 +00:00
|
|
|
{
|
2003-02-10 21:13:13 +00:00
|
|
|
add_ether_byip(ip, mac);
|
2007-12-19 10:49:22 +00:00
|
|
|
if (global_arp_detect_duplicate_ip_addresses)
|
|
|
|
{
|
2008-01-02 10:35:20 +00:00
|
|
|
duplicate_detected =
|
2009-03-29 22:16:26 +00:00
|
|
|
check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
|
|
|
|
&duplicate_ip);
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
}
|
2003-02-10 21:13:13 +00:00
|
|
|
|
|
|
|
/* Add target address if target MAC address is neither a broadcast/
|
|
|
|
multicast address nor an all-zero address and if target IP address
|
|
|
|
isn't all zeroes. */
|
2007-03-11 06:16:00 +00:00
|
|
|
|
2005-02-03 22:52:20 +00:00
|
|
|
/* Do not add target address if the packet is a Request. According to the RFC,
|
|
|
|
target addresses in requests have no meaning */
|
2007-03-11 06:16:00 +00:00
|
|
|
|
2005-09-11 21:25:37 +00:00
|
|
|
ip = tvb_get_ipv4(tvb, tpa_offset);
|
2003-02-10 21:13:13 +00:00
|
|
|
mac = tvb_get_ptr(tvb, tha_offset, 6);
|
2007-03-11 06:16:00 +00:00
|
|
|
if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0
|
2007-12-19 10:49:22 +00:00
|
|
|
&& ar_op != ARPOP_REQUEST)
|
|
|
|
{
|
2003-02-10 21:13:13 +00:00
|
|
|
add_ether_byip(ip, mac);
|
2007-12-19 10:49:22 +00:00
|
|
|
if (global_arp_detect_duplicate_ip_addresses)
|
|
|
|
{
|
2008-01-02 10:35:20 +00:00
|
|
|
duplicate_detected =
|
2009-03-29 22:16:26 +00:00
|
|
|
check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
|
|
|
|
&duplicate_ip);
|
2007-12-19 10:49:22 +00:00
|
|
|
}
|
|
|
|
}
|
2000-08-10 20:09:29 +00:00
|
|
|
}
|
|
|
|
|
2004-06-17 20:04:53 +00:00
|
|
|
spa_val = tvb_get_ptr(tvb, spa_offset, ar_pln);
|
|
|
|
tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_pln);
|
|
|
|
|
2006-10-29 19:14:31 +00:00
|
|
|
/* ARP requests/replies with the same sender and target protocol
|
|
|
|
address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
|
|
|
|
in effect, an announcement that the machine has MAC address
|
2007-03-11 06:16:00 +00:00
|
|
|
XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
|
2006-10-29 19:14:31 +00:00
|
|
|
provoke complaints if some other machine has the same IPv4 address,
|
2007-03-11 06:16:00 +00:00
|
|
|
replies are used to announce relocation of network address, like
|
2006-10-29 19:14:31 +00:00
|
|
|
in failover solutions. */
|
|
|
|
if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) && (memcmp(spa_val, tpa_val, ar_pln) == 0))
|
2004-06-17 20:04:53 +00:00
|
|
|
is_gratuitous = TRUE;
|
|
|
|
else
|
|
|
|
is_gratuitous = FALSE;
|
|
|
|
|
2011-09-26 08:25:18 +00:00
|
|
|
switch (ar_op) {
|
|
|
|
case ARPOP_REQUEST:
|
2011-11-13 22:44:51 +00:00
|
|
|
if (is_gratuitous)
|
2011-09-26 08:25:18 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)",
|
2004-06-17 20:04:53 +00:00
|
|
|
arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
|
2011-11-13 22:44:51 +00:00
|
|
|
else
|
2011-09-26 08:25:18 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s",
|
|
|
|
arpproaddr_to_str(tpa_val, ar_pln, ar_pro),
|
2004-06-17 20:04:53 +00:00
|
|
|
arpproaddr_to_str(spa_val, ar_pln, ar_pro));
|
2011-09-26 08:25:18 +00:00
|
|
|
break;
|
|
|
|
case ARPOP_REPLY:
|
|
|
|
if (is_gratuitous)
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)",
|
|
|
|
arpproaddr_to_str(spa_val, ar_pln, ar_pro));
|
|
|
|
else
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
|
|
|
|
arpproaddr_to_str(spa_val, ar_pln, ar_pro),
|
|
|
|
tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
|
|
|
|
break;
|
|
|
|
case ARPOP_RREQUEST:
|
|
|
|
case ARPOP_IREQUEST:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s? Tell %s",
|
|
|
|
tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
|
|
|
|
tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
|
|
|
|
break;
|
|
|
|
case ARPOP_RREPLY:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
|
|
|
|
tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
|
|
|
|
arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
|
|
|
|
break;
|
|
|
|
case ARPOP_IREPLY:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
|
|
|
|
tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
|
|
|
|
arpproaddr_to_str(spa_val, ar_pln, ar_pro));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
|
|
|
|
break;
|
2004-06-17 20:04:53 +00:00
|
|
|
}
|
|
|
|
|
1998-11-03 07:45:10 +00:00
|
|
|
if (tree) {
|
2004-06-17 08:32:59 +00:00
|
|
|
if ((op_str = match_strval(ar_op, op_vals))) {
|
2006-10-29 19:14:31 +00:00
|
|
|
if (is_gratuitous && (ar_op == ARPOP_REQUEST))
|
2004-06-17 20:04:53 +00:00
|
|
|
op_str = "request/gratuitous ARP";
|
2006-10-29 19:14:31 +00:00
|
|
|
if (is_gratuitous && (ar_op == ARPOP_REPLY))
|
|
|
|
op_str = "reply/gratuitous ARP";
|
2000-11-13 07:19:37 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Address Resolution Protocol (%s)", op_str);
|
2004-06-17 08:32:59 +00:00
|
|
|
} else
|
2000-11-13 07:19:37 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
|
2009-03-29 22:16:26 +00:00
|
|
|
"Address Resolution Protocol (opcode 0x%04x)", ar_op);
|
1999-11-16 11:44:20 +00:00
|
|
|
arp_tree = proto_item_add_subtree(ti, ett_arp);
|
2000-11-13 07:19:37 +00:00
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
|
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, AR_PRO, 2, ar_pro);
|
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_hard_size, tvb, AR_HLN, 1, ar_hln);
|
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ar_pln);
|
|
|
|
proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP, 2, ar_op);
|
2009-12-10 22:35:09 +00:00
|
|
|
item = proto_tree_add_boolean(arp_tree, hf_arp_isgratuitous, tvb, 0, 0, is_gratuitous);
|
2009-05-21 05:15:03 +00:00
|
|
|
PROTO_ITEM_SET_GENERATED(item);
|
2002-02-10 22:41:48 +00:00
|
|
|
if (ar_hln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2007-12-19 10:49:22 +00:00
|
|
|
ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_arp_src_hw_mac :
|
|
|
|
hf_arp_src_hw,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, sha_offset, ar_hln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
|
|
|
if (ar_pln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2007-12-19 10:49:22 +00:00
|
|
|
ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_arp_src_proto_ipv4 :
|
|
|
|
hf_arp_src_proto,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, spa_offset, ar_pln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
|
|
|
if (ar_hln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2007-12-19 10:49:22 +00:00
|
|
|
ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_arp_dst_hw_mac :
|
|
|
|
hf_arp_dst_hw,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, tha_offset, ar_hln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
|
|
|
if (ar_pln != 0) {
|
|
|
|
proto_tree_add_item(arp_tree,
|
2007-12-19 10:49:22 +00:00
|
|
|
ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
|
2009-03-29 22:16:26 +00:00
|
|
|
hf_arp_dst_proto_ipv4 :
|
|
|
|
hf_arp_dst_proto,
|
2011-09-26 08:25:18 +00:00
|
|
|
tvb, tpa_offset, ar_pln, ENC_BIG_ENDIAN);
|
2002-02-10 22:41:48 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
if (global_arp_detect_request_storm)
|
|
|
|
{
|
|
|
|
check_for_storm_count(tvb, pinfo, arp_tree);
|
|
|
|
}
|
2008-01-02 10:35:20 +00:00
|
|
|
|
|
|
|
if (duplicate_detected)
|
|
|
|
{
|
|
|
|
/* Also indicate in info column */
|
2011-09-26 08:25:18 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " (duplicate use of %s detected!)",
|
|
|
|
arpproaddr_to_str((guint8*)&duplicate_ip, 4, ETHERTYPE_IP));
|
2008-01-02 10:35:20 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
1999-07-29 05:47:07 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_register_arp(void)
|
|
|
|
{
|
2009-05-08 22:18:14 +00:00
|
|
|
static struct true_false_string tfs_type_bit = { "E.164", "ATM Forum NSAPA" };
|
2000-11-30 10:42:50 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_arp_hard_type,
|
2002-08-28 21:04:11 +00:00
|
|
|
{ "Hardware type", "arp.hw.type",
|
2010-08-23 23:09:32 +00:00
|
|
|
FT_UINT16, BASE_DEC, VALS(hrd_vals), 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_proto_type,
|
1999-10-16 08:37:30 +00:00
|
|
|
{ "Protocol type", "arp.proto.type",
|
1999-11-04 08:15:38 +00:00
|
|
|
FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_hard_size,
|
1999-11-27 04:01:43 +00:00
|
|
|
{ "Hardware size", "arp.hw.size",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2000-11-30 10:42:50 +00:00
|
|
|
{ &hf_atmarp_sht,
|
|
|
|
{ "Sender ATM number type", "arp.src.htype",
|
2009-05-08 22:18:14 +00:00
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_shl,
|
|
|
|
{ "Sender ATM number length", "arp.src.hlen",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_sst,
|
|
|
|
{ "Sender ATM subaddress type", "arp.src.stype",
|
2009-05-08 22:18:14 +00:00
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_ssl,
|
|
|
|
{ "Sender ATM subaddress length", "arp.src.slen",
|
2000-11-30 10:42:50 +00:00
|
|
|
FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_proto_size,
|
1999-10-16 08:37:30 +00:00
|
|
|
{ "Protocol size", "arp.proto.size",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_opcode,
|
1999-10-16 08:37:30 +00:00
|
|
|
{ "Opcode", "arp.opcode",
|
2010-08-23 23:09:32 +00:00
|
|
|
FT_UINT16, BASE_DEC, VALS(op_vals), 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
|
|
|
|
|
|
|
{ &hf_arp_isgratuitous,
|
|
|
|
{ "Is gratuitous", "arp.isgratuitous",
|
|
|
|
FT_BOOLEAN, BASE_NONE, TFS(&tfs_true_false), 0x0,
|
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-11-27 04:01:43 +00:00
|
|
|
{ &hf_atmarp_spln,
|
|
|
|
{ "Sender protocol size", "arp.src.pln",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2000-11-30 10:42:50 +00:00
|
|
|
{ &hf_atmarp_tht,
|
|
|
|
{ "Target ATM number type", "arp.dst.htype",
|
2009-05-08 22:18:14 +00:00
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_thl,
|
|
|
|
{ "Target ATM number length", "arp.dst.hlen",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2000-11-30 10:42:50 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_tst,
|
|
|
|
{ "Target ATM subaddress type", "arp.dst.stype",
|
2009-05-08 22:18:14 +00:00
|
|
|
FT_BOOLEAN, 8, TFS(&tfs_type_bit), ATMARP_IS_E164,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_tsl,
|
|
|
|
{ "Target ATM subaddress length", "arp.dst.slen",
|
2000-11-30 10:42:50 +00:00
|
|
|
FT_UINT8, BASE_DEC, NULL, ATMARP_LEN_MASK,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_tpln,
|
|
|
|
{ "Target protocol size", "arp.dst.pln",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
{ &hf_arp_src_hw,
|
1999-10-16 08:37:30 +00:00
|
|
|
{ "Sender hardware address", "arp.src.hw",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
{ &hf_arp_src_hw_mac,
|
|
|
|
{ "Sender MAC address", "arp.src.hw_mac",
|
|
|
|
FT_ETHER, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2002-02-10 22:41:48 +00:00
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
{ &hf_atmarp_src_atm_num_e164,
|
|
|
|
{ "Sender ATM number (E.164)", "arp.src.atm_num_e164",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:48:14 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_src_atm_num_nsap,
|
|
|
|
{ "Sender ATM number (NSAP)", "arp.src.atm_num_nsap",
|
1999-11-27 04:01:43 +00:00
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_src_atm_subaddr,
|
|
|
|
{ "Sender ATM subaddress", "arp.src.atm_subaddr",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_src_proto,
|
2002-02-10 22:41:48 +00:00
|
|
|
{ "Sender protocol address", "arp.src.proto",
|
1999-10-16 08:37:30 +00:00
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
{ &hf_arp_src_proto_ipv4,
|
|
|
|
{ "Sender IP address", "arp.src.proto_ipv4",
|
|
|
|
FT_IPv4, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2002-02-10 22:41:48 +00:00
|
|
|
|
|
|
|
{ &hf_arp_dst_hw,
|
1999-10-16 08:37:30 +00:00
|
|
|
{ "Target hardware address", "arp.dst.hw",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2002-02-10 22:41:48 +00:00
|
|
|
{ &hf_arp_dst_hw_mac,
|
|
|
|
{ "Target MAC address", "arp.dst.hw_mac",
|
|
|
|
FT_ETHER, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2002-02-10 22:41:48 +00:00
|
|
|
|
1999-11-27 04:48:14 +00:00
|
|
|
{ &hf_atmarp_dst_atm_num_e164,
|
|
|
|
{ "Target ATM number (E.164)", "arp.dst.atm_num_e164",
|
|
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:48:14 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_dst_atm_num_nsap,
|
|
|
|
{ "Target ATM number (NSAP)", "arp.dst.atm_num_nsap",
|
1999-11-27 04:01:43 +00:00
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
|
|
|
{ &hf_atmarp_dst_atm_subaddr,
|
|
|
|
{ "Target ATM subaddress", "arp.dst.atm_subaddr",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
1999-11-27 04:01:43 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
{ &hf_arp_dst_proto,
|
2002-02-10 22:41:48 +00:00
|
|
|
{ "Target protocol address", "arp.dst.proto",
|
1999-10-16 08:37:30 +00:00
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2002-02-10 22:41:48 +00:00
|
|
|
|
|
|
|
{ &hf_arp_dst_proto_ipv4,
|
|
|
|
{ "Target IP address", "arp.dst.proto_ipv4",
|
|
|
|
FT_IPv4, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
{ &hf_arp_packet_storm,
|
2007-03-11 06:16:00 +00:00
|
|
|
{ "Packet storm detected", "arp.packet-storm-detected",
|
2006-10-20 14:20:22 +00:00
|
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
{ &hf_arp_duplicate_ip_address,
|
|
|
|
{ "Duplicate IP address detected", "arp.duplicate-address-detected",
|
|
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
{ &hf_arp_duplicate_ip_address_earlier_frame,
|
|
|
|
{ "Frame showing earlier use of IP address", "arp.duplicate-address-frame",
|
|
|
|
FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
{ &hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
|
|
|
|
{ "Seconds since earlier frame seen", "arp.seconds-since-duplicate-address-frame",
|
|
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
2009-05-21 05:15:03 +00:00
|
|
|
NULL, HFILL }},
|
2007-12-19 10:49:22 +00:00
|
|
|
|
1999-10-03 17:12:15 +00:00
|
|
|
};
|
2006-10-20 14:20:22 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_arp,
|
1999-11-27 04:48:14 +00:00
|
|
|
&ett_atmarp_nsap,
|
2007-12-19 10:49:22 +00:00
|
|
|
&ett_atmarp_tl,
|
|
|
|
&ett_arp_duplicate_address
|
1999-11-16 11:44:20 +00:00
|
|
|
};
|
1999-07-29 05:47:07 +00:00
|
|
|
|
2006-10-20 14:20:22 +00:00
|
|
|
module_t *arp_module;
|
2007-03-11 06:16:00 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_arp = proto_register_protocol("Address Resolution Protocol",
|
|
|
|
"ARP/RARP", "arp");
|
1999-10-03 17:12:15 +00:00
|
|
|
proto_register_field_array(proto_arp, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2001-11-27 07:13:32 +00:00
|
|
|
|
|
|
|
atmarp_handle = create_dissector_handle(dissect_atmarp, proto_arp);
|
2003-08-17 01:05:21 +00:00
|
|
|
|
|
|
|
register_dissector( "arp" , dissect_arp, proto_arp );
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
/* Preferences */
|
|
|
|
arp_module = prefs_register_protocol(proto_arp, NULL);
|
|
|
|
|
|
|
|
prefs_register_bool_preference(arp_module, "detect_request_storms",
|
2009-03-29 22:16:26 +00:00
|
|
|
"Detect ARP request storms",
|
|
|
|
"Attempt to detect excessive rate of ARP requests",
|
|
|
|
&global_arp_detect_request_storm);
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
prefs_register_uint_preference(arp_module, "detect_storm_number_of_packets",
|
2009-03-29 22:16:26 +00:00
|
|
|
"Number of requests to detect during period",
|
|
|
|
"Number of requests needed within period to indicate a storm",
|
|
|
|
10, &global_arp_detect_request_storm_packets);
|
2006-10-20 14:20:22 +00:00
|
|
|
|
|
|
|
prefs_register_uint_preference(arp_module, "detect_storm_period",
|
2009-03-29 22:16:26 +00:00
|
|
|
"Detection period (in ms)",
|
|
|
|
"Period in milliseconds during which a packet storm may be detected",
|
|
|
|
10, &global_arp_detect_request_storm_period);
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
prefs_register_bool_preference(arp_module, "detect_duplicate_ips",
|
2009-03-29 22:16:26 +00:00
|
|
|
"Detect duplicate IP address configuration",
|
|
|
|
"Attempt to detect duplicate use of IP addresses",
|
|
|
|
&global_arp_detect_duplicate_ip_addresses);
|
2007-12-19 10:49:22 +00:00
|
|
|
|
|
|
|
/* TODO: define a minimum time between sightings that is worth reporting? */
|
|
|
|
|
|
|
|
register_init_routine(&arp_init_protocol);
|
1999-07-29 05:47:07 +00:00
|
|
|
}
|
Change the sub-dissector handoff registration routines so that the
sub-dissector table is not stored in the header_field_info struct, but
in a separate namespace. Dissector tables are now registered by name
and not by field ID. For example:
udp_dissector_table = register_dissector_table("udp.port");
Because of this different namespace, dissector tables can have names
that are not field names. This is useful for ethertype, since multiple
fields are "ethertypes".
packet-ethertype.c replaces ethertype.c (the name was changed so that it
would be named in the same fashion as all the filenames passed to make-reg-dotc)
Although it registers no protocol or field, it registers one dissector table:
ethertype_dissector_table = register_dissector_table("ethertype");
All protocols that can be called because of an ethertype field now register
that fact with dissector_add() calls.
In this way, one dissector_table services all ethertype fields
(hf_eth_type, hf_llc_type, hf_null_etype, hf_vlan_etype)
Furthermore, the code allows for names of protocols to exist in the
etype_vals, yet a dissector for that protocol doesn't exist. The name
of the dissector is printed in COL_INFO. You're welcome, Richard. :-)
svn path=/trunk/; revision=1848
2000-04-13 18:18:56 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_arp(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t arp_handle;
|
|
|
|
|
2003-08-17 01:05:21 +00:00
|
|
|
arp_handle = find_dissector("arp");
|
|
|
|
|
2010-12-20 05:35:29 +00:00
|
|
|
dissector_add_uint("ethertype", ETHERTYPE_ARP, arp_handle);
|
|
|
|
dissector_add_uint("ethertype", ETHERTYPE_REVARP, arp_handle);
|
|
|
|
dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1051, arp_handle);
|
|
|
|
dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_ARP_1201, arp_handle);
|
|
|
|
dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_RARP_1201, arp_handle);
|
Change the sub-dissector handoff registration routines so that the
sub-dissector table is not stored in the header_field_info struct, but
in a separate namespace. Dissector tables are now registered by name
and not by field ID. For example:
udp_dissector_table = register_dissector_table("udp.port");
Because of this different namespace, dissector tables can have names
that are not field names. This is useful for ethertype, since multiple
fields are "ethertypes".
packet-ethertype.c replaces ethertype.c (the name was changed so that it
would be named in the same fashion as all the filenames passed to make-reg-dotc)
Although it registers no protocol or field, it registers one dissector table:
ethertype_dissector_table = register_dissector_table("ethertype");
All protocols that can be called because of an ethertype field now register
that fact with dissector_add() calls.
In this way, one dissector_table services all ethertype fields
(hf_eth_type, hf_llc_type, hf_null_etype, hf_vlan_etype)
Furthermore, the code allows for names of protocols to exist in the
etype_vals, yet a dissector for that protocol doesn't exist. The name
of the dissector is printed in COL_INFO. You're welcome, Richard. :-)
svn path=/trunk/; revision=1848
2000-04-13 18:18:56 +00:00
|
|
|
}
|