Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #727 - Linux SLL v2 #820

Merged
merged 3 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,15 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "$LPCAPINC"]], [[ int foo;
],[AC_MSG_RESULT(no)
])

AC_MSG_CHECKING(for DLT_LINUX_SLL2 in libpcap)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "$LPCAPINC"]], [[ int foo;
foo = DLT_LINUX_SLL2
]])],[ AC_DEFINE([HAVE_DLT_LINUX_SLL2], [1],
[Does pcap.h include a header with DLT_LINUX_SLL2?])
AC_MSG_RESULT(yes)
],[AC_MSG_RESULT(no)
])

AC_MSG_CHECKING(for DLT_C_HDLC in libpcap)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "$LPCAPINC"]], [[ int foo;
foo = DLT_C_HDLC ]])],[ AC_DEFINE([HAVE_DLT_C_HDLC], [1],
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
09/03/2023 Version 4.5.0-beta1
- create DLT_LINUX_SLL2 plugin (#727)

06/04/2023 Version 4.4.4
- overflow check fix for parse_mpls (#795)
Expand Down
3 changes: 3 additions & 0 deletions docs/CREDIT
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,6 @@ Florian Weimer <GitHub @fweimer-rh>

David Guti <GitHub @david-guti>
- prevent L2 flooding of ipv6 unicast packets for tcpreplay-edit

Bastian Triller <GitHub @btriller>
- Linux SLL2
110 changes: 66 additions & 44 deletions lib/sll.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -42,30 +42,30 @@
* For captures on Linux cooked sockets, we construct a fake header
* that includes:
*
* a 2-byte "packet type" which is one of:
* a 2-byte "packet type" which is one of:
*
* LINUX_SLL_HOST packet was sent to us
* LINUX_SLL_BROADCAST packet was broadcast
* LINUX_SLL_MULTICAST packet was multicast
* LINUX_SLL_OTHERHOST packet was sent to somebody else
* LINUX_SLL_OUTGOING packet was sent *by* us;
* LINUX_SLL_HOST packet was sent to us
* LINUX_SLL_BROADCAST packet was broadcast
* LINUX_SLL_MULTICAST packet was multicast
* LINUX_SLL_OTHERHOST packet was sent to somebody else
* LINUX_SLL_OUTGOING packet was sent *by* us;
*
* a 2-byte Ethernet protocol field;
* a 2-byte Ethernet protocol field;
*
* a 2-byte link-layer type;
* a 2-byte link-layer type;
*
* a 2-byte link-layer address length;
* a 2-byte link-layer address length;
*
* an 8-byte source link-layer address, whose actual length is
* specified by the previous value.
* an 8-byte source link-layer address, whose actual length is
* specified by the previous value.
*
* All fields except for the link-layer address are in network byte order.
*
* DO NOT change the layout of this structure, or change any of the
* LINUX_SLL_ values below. If you must change the link-layer header
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
* "[email protected]" for one, so that you don't give it a
* value that collides with a value already being used), and use the
* "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
* a value that collides with a value already being used), and use the
* new header in captures of that type, so that programs that can
* handle DLT_LINUX_SLL captures will continue to handle them correctly
* without any change, and so that capture files with different headers
Expand All @@ -77,54 +77,76 @@
#ifndef _SLL_H_
#define _SLL_H_

#include <pcap/pcap-inttypes.h>

/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */

struct sll_header {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
u_int16_t sll_protocol; /* protocol */
};

/*
* A DLT_LINUX_SLL2 fake link-layer header.
*/
#define SLL2_HDR_LEN 20 /* total header length */

struct sll2_header {
u_int16_t sll2_protocol; /* protocol */
u_int16_t sll2_reserved_mbz; /* reserved - must be zero */
u_int32_t sll2_if_index; /* 1-based interface index */
u_int16_t sll2_hatype; /* link-layer address type */
u_int8_t sll2_pkttype; /* packet type */
u_int8_t sll2_halen; /* link-layer address length */
u_int8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
};

/*
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
* PACKET_ values on Linux, but are defined here so that they're
* available even on systems other than Linux, and so that they
* don't change even if the PACKET_ values change.
* The LINUX_SLL_ values for "sll_pkttype" and LINUX_SLL2_ values for
* "sll2_pkttype"; these correspond to the PACKET_ values on Linux,
* which are defined by a header under include/uapi in the current
* kernel source, and are thus not going to change on Linux. We
* define them here so that they're available even on systems other
* than Linux.
*/
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
#define LINUX_SLL_MULTICAST 2
#define LINUX_SLL_OTHERHOST 3
#define LINUX_SLL_OUTGOING 4
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
#define LINUX_SLL_MULTICAST 2
#define LINUX_SLL_OTHERHOST 3
#define LINUX_SLL_OUTGOING 4

/*
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
* ETH_P_ values on Linux, but are defined here so that they're
* available even on systems other than Linux. We assume, for now,
* that the ETH_P_ values won't change in Linux; if they do, then:
* The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
* "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
* are defined here so that they're available even on systems other than
* Linux. We assume, for now, that the ETH_P_ values won't change in
* Linux; if they do, then:
*
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
* defines ETH_P_ values that don't match these values;
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
* defines ETH_P_ values that don't match these values;
*
* if we do translate them in "pcap-linux.c", that makes life
* unpleasant for the BPF code generator, as the values you test
* for in the kernel aren't the values that you test for when
* reading a capture file, so the fixup code run on BPF programs
* handed to the kernel ends up having to do more work.
* if we do translate them in "pcap-linux.c", that makes life
* unpleasant for the BPF code generator, as the values you test
* for in the kernel aren't the values that you test for when
* reading a capture file, so the fixup code run on BPF programs
* handed to the kernel ends up having to do more work.
*
* Add other values here as necessary, for handling packet types that
* might show up on non-Ethernet, non-802.x networks. (Not all the ones
* in the Linux "if_ether.h" will, I suspect, actually show up in
* captures.)
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */
#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */

#endif
22 changes: 22 additions & 0 deletions src/common/dlt_names.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,28 @@ char *dlt2name[] = {
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"DLT_LINUX_SLL2",
NULL
};

4 changes: 4 additions & 0 deletions src/common/dlt_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ extern const char *dlt2name[];
#define DLT_LINUX_SLL 113
#endif

#ifndef DLT_LINUX_SLL2
#define DLT_LINUX_SLL2 276
#endif

#ifndef DLT_LTALK
#define DLT_LTALK 114
#endif
Expand Down
4 changes: 4 additions & 0 deletions src/common/fakepcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#define DLT_LINUX_SLL 113
#endif

#ifndef HAVE_DLT_LINUX_SLL2
#define DLT_LINUX_SLL2 276
#endif

#ifndef HAVE_DLT_C_HDLC
#define DLT_C_HDLC 104
#endif
Expand Down
10 changes: 9 additions & 1 deletion src/common/get.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,18 @@ get_l2len_protocol(const u_char *pktdata,
if (datalen < SLL_HDR_LEN)
return -1;

*l2len = SLL_HDR_LEN;
sll_hdr_t *sll_hdr = (sll_hdr_t *)pktdata;
*l2len = sizeof(*sll_hdr);
*protocol = ntohs(sll_hdr->sll_protocol);
break;
case DLT_LINUX_SLL2:
if (datalen < SLL2_HDR_LEN)
return -1;

*l2len = SLL2_HDR_LEN;
sll2_hdr_t *sll2_hdr = (sll2_hdr_t *)pktdata;
*protocol = ntohs(sll2_hdr->sll2_protocol);
break;
default:
errx(-1,
"Unable to process unsupported DLT type: %s (0x%x)",
Expand Down
1 change: 1 addition & 0 deletions src/defines.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ typedef struct tcpr_icmpv6_hdr icmpv6_hdr_t;
typedef struct tcpr_ethernet_hdr eth_hdr_t;
typedef struct tcpr_802_1q_hdr vlan_hdr_t;
typedef struct sll_header sll_hdr_t;
typedef struct sll2_header sll2_hdr_t;
typedef struct tcpr_arp_hdr arp_hdr_t;
typedef struct tcpr_dnsv4_hdr dnsv4_hdr_t;

Expand Down
15 changes: 9 additions & 6 deletions src/tcpedit/dlt.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "dlt.h"
#include "config.h"
#include "tcpedit.h"
#include <lib/sll.h>
#include <assert.h>

/**
Expand Down Expand Up @@ -49,13 +50,13 @@ dlt2layer2len(tcpedit_t *tcpedit, int dlt)
case DLT_EN10MB:
len = 12;
break;
/*
case DLT_VLAN:
len = 14;
break;
*/

case DLT_LINUX_SLL:
len = 16;
len = SLL_HDR_LEN;
break;

case DLT_LINUX_SLL2:
len = SLL2_HDR_LEN;
break;

case DLT_PPP_SERIAL:
Expand Down Expand Up @@ -103,6 +104,7 @@ dltrequires(tcpedit_t *tcpedit, int dlt)
break;

case DLT_LINUX_SLL:
case DLT_LINUX_SLL2:
/* we have proto & SRC address */
req = TCPEDIT_DLT_DST;
break;
Expand Down Expand Up @@ -136,6 +138,7 @@ dlt2mtu(tcpedit_t *tcpedit, int dlt)
break;

case DLT_LINUX_SLL:
case DLT_LINUX_SLL2:
mtu = 16436;
break;

Expand Down
1 change: 1 addition & 0 deletions src/tcpedit/plugins/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ include %reldir%/dlt_raw/Makefile.am
include %reldir%/dlt_null/Makefile.am
include %reldir%/dlt_loop/Makefile.am
include %reldir%/dlt_linuxsll/Makefile.am
include %reldir%/dlt_linuxsll2/Makefile.am
include %reldir%/dlt_ieee80211/Makefile.am
include %reldir%/dlt_radiotap/Makefile.am
include %reldir%/dlt_jnpr_ether/Makefile.am
Expand Down
30 changes: 30 additions & 0 deletions src/tcpedit/plugins/dlt_linuxsll2/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# $Id:$
# START OF: dlt_linuxsll2
# Note, if you add any files to your plugin, you will need to edit dlt_<plugin>/Makefile.am
# add your .c files to libtcpedit_a_SOURCES
# add your .h files to noinst_HEADERS
# add any other files (like documentation, notes, etc) to EXTRA_DIST
# add your dependency information (see comment below)

libtcpedit_a_SOURCES += %reldir%/linuxsll2.c

noinst_HEADERS += \
%reldir%/linuxsll2.h \
%reldir%/linuxsll2_types.h

EXTRA_DIST += %reldir%/linuxsll2_opts.def

# dependencies for your plugin source code. Edit as necessary
linuxsll2.c: \
$(TCPEDIT_PLUGINS_DEPS) \
%reldir%/../../tcpedit_api.h \
%reldir%/linuxsll2.h \
%reldir%/linuxsll2_types.h

# You probably don't want to touch anything below this line until the end of the plugin

DLT_STUB_DEPS += %reldir%/linuxsll2_opts.def

MOSTLYCLEANFILES += *~

# END OF: dlt_linuxsll2
Loading