From d6195affa919b1f24beea6b1a054ac8e9b00be4f Mon Sep 17 00:00:00 2001 From: Casper Andersson Date: Thu, 1 Feb 2024 10:16:25 +0100 Subject: [PATCH 1/5] HSR/PRP: Add printing for HSR header HSR is a redundancy protocol that duplicates traffic and sends it two ways in a ring with an HSR header that includes a sequence number. Other devices in the ring will forward the first occurrence of a packet, and discard the duplicate (based on SMAC + sequence number). This enables zero packet loss when a link goes down. Signed-off-by: Casper Andersson --- CMakeLists.txt | 1 + Makefile.in | 1 + ethertype.h | 3 +++ netdissect.h | 1 + print-ether.c | 19 +++++++++++++ print-hsr-prp.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 97 insertions(+) create mode 100644 print-hsr-prp.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ee3eb9529..d7009eade 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1124,6 +1124,7 @@ set(NETDISSECT_SOURCE_LIST_C print-geonet.c print-gre.c print-hncp.c + print-hsr-prp.c print-hsrp.c print-http.c print-icmp.c diff --git a/Makefile.in b/Makefile.in index 5896da9d2..e10ecdf2b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -142,6 +142,7 @@ LIBNETDISSECT_SRC=\ print-geonet.c \ print-gre.c \ print-hncp.c \ + print-hsr-prp.c \ print-hsrp.c \ print-http.c \ print-icmp.c \ diff --git a/ethertype.h b/ethertype.h index 8b71b3025..c61537e4e 100644 --- a/ethertype.h +++ b/ethertype.h @@ -185,6 +185,9 @@ #ifndef ETHERTYPE_PTP #define ETHERTYPE_PTP 0x88f7 #endif +#ifndef ETHERTYPE_HSR +#define ETHERTYPE_HSR 0x892f +#endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif diff --git a/netdissect.h b/netdissect.h index 2a371d872..845191746 100644 --- a/netdissect.h +++ b/netdissect.h @@ -654,6 +654,7 @@ extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char extern void hex_print(netdissect_options *, const char *indent, const u_char *cp, u_int); extern void hex_print_with_offset(netdissect_options *, const char *indent, const u_char *cp, u_int, u_int); extern void hncp_print(netdissect_options *, const u_char *, u_int); +extern void hsr_print(netdissect_options *, const u_char *, u_int); extern void hsrp_print(netdissect_options *, const u_char *, u_int); extern void http_print(netdissect_options *, const u_char *, u_int); extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int); diff --git a/print-ether.c b/print-ether.c index 3f7fb5f69..32b271d79 100644 --- a/print-ether.c +++ b/print-ether.c @@ -103,6 +103,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_CALM_FAST, "CALM FAST"}, { ETHERTYPE_AOE, "AoE" }, { ETHERTYPE_PTP, "PTP" }, + { ETHERTYPE_HSR, "HSR" }, { ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" }, { 0, NULL} }; @@ -287,6 +288,24 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, hdrlen += 4; } + if (length_type == ETHERTYPE_HSR) { + if (ndo->ndo_eflag) { + ether_type_print(ndo, length_type); + if (!printed_length) { + ND_PRINT(", length %u: ", orig_length); + printed_length = 1; + } else + ND_PRINT(", "); + hsr_print(ndo, p, length); + } + + length_type = GET_BE_U_2(p + 4); + p += 6; + length -= 6; + caplen -= 6; + hdrlen += 6; + } + /* * We now have the final length/type field. */ diff --git a/print-hsr-prp.c b/print-hsr-prp.c new file mode 100644 index 000000000..4f3165d59 --- /dev/null +++ b/print-hsr-prp.c @@ -0,0 +1,72 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + */ + +/* \summary: High-availability Seamless Redundancy (HSR) and + * Parallel Redundancy Protocol (PRP) printer */ + +/* specification: https://webstore.iec.ch/publication/64423 */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "netdissect-stdinc.h" +#include "netdissect.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * HSR header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |NetID|L| LSDUsize | Sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * + * L = LanID + * LSDUsize = Link Service Data Unit size = size of the packet excluding MAC + * header, tags before the HSR tag (e.g. VLAN), and the HSR ethertype field. + * For PRP it includes the PRP suffix. + */ + +#define HSR_HDR_LEN 6 + +void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + int lanid, netid; + uint16_t lsdu_size; + uint16_t hdr; + uint32_t seq_nr; + + ND_ICHECK_U(length, <, HSR_HDR_LEN); + + hdr = GET_BE_U_2(bp); + lsdu_size = hdr & 0xFFF; + lanid = (hdr >> 12) & 0x1; + netid = hdr >> 13; + + length -= 2; + bp += 2; + seq_nr = GET_BE_U_2(bp); + + ND_PRINT("LSDUsize %u, SeqNr %u, LanId %s, NetId %u, ", + lsdu_size, seq_nr, lanid ? "A" : "B", netid); + + return; + +invalid: + nd_print_invalid(ndo); +} + From 0a8de4dcfc0b2b882c34941fab405120857787a2 Mon Sep 17 00:00:00 2001 From: Casper Andersson Date: Thu, 1 Feb 2024 10:26:13 +0100 Subject: [PATCH 2/5] HSR/PRP: Add printing for HSR/PRP Supervision frames Supervision frames are sent out by the nodes to notify about their existence, and in the case of a RedBox it will notify about the upstream devices. Signed-off-by: Casper Andersson --- ethertype.h | 3 ++ netdissect.h | 1 + print-ether.c | 5 +++ print-hsr-prp.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) diff --git a/ethertype.h b/ethertype.h index c61537e4e..22288cec6 100644 --- a/ethertype.h +++ b/ethertype.h @@ -188,6 +188,9 @@ #ifndef ETHERTYPE_HSR #define ETHERTYPE_HSR 0x892f #endif +#ifndef ETHERTYPE_HSR_PRP_SUP +#define ETHERTYPE_HSR_PRP_SUP 0x88fb +#endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif diff --git a/netdissect.h b/netdissect.h index 845191746..ed94a7cac 100644 --- a/netdissect.h +++ b/netdissect.h @@ -655,6 +655,7 @@ extern void hex_print(netdissect_options *, const char *indent, const u_char *cp extern void hex_print_with_offset(netdissect_options *, const char *indent, const u_char *cp, u_int, u_int); extern void hncp_print(netdissect_options *, const u_char *, u_int); extern void hsr_print(netdissect_options *, const u_char *, u_int); +extern void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length); extern void hsrp_print(netdissect_options *, const u_char *, u_int); extern void http_print(netdissect_options *, const u_char *, u_int); extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int); diff --git a/print-ether.c b/print-ether.c index 32b271d79..244d86249 100644 --- a/print-ether.c +++ b/print-ether.c @@ -104,6 +104,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_AOE, "AoE" }, { ETHERTYPE_PTP, "PTP" }, { ETHERTYPE_HSR, "HSR" }, + { ETHERTYPE_HSR_PRP_SUP, "HSR/PRP Supervision" }, { ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" }, { 0, NULL} }; @@ -672,6 +673,10 @@ ethertype_print(netdissect_options *ndo, ptp_print(ndo, p, length); return (1); + case ETHERTYPE_HSR_PRP_SUP: + hsr_prp_supervision_print(ndo, p, length); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: diff --git a/print-hsr-prp.c b/print-hsr-prp.c index 4f3165d59..7be0c61e4 100644 --- a/print-hsr-prp.c +++ b/print-hsr-prp.c @@ -39,9 +39,32 @@ * LSDUsize = Link Service Data Unit size = size of the packet excluding MAC * header, tags before the HSR tag (e.g. VLAN), and the HSR ethertype field. * For PRP it includes the PRP suffix. + * + * HSR/PRP Supervision frame + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |PathId | version | Sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLV1 Type | TLV1 Length | MAC Address of DANP/DANH | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLV2 Type | TLV2 Length | RedBox MAC Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLV0 Type | TLV0 Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * + * DANP = Doubly Attached Node PRP + * DANH = Doubly Attached Node HSR */ #define HSR_HDR_LEN 6 +#define HSR_PRP_SUPERVISION_LEN 22 void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length) { @@ -70,3 +93,91 @@ void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length) nd_print_invalid(ndo); } +void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + int tlvtype, tlvlength; + uint32_t seq_nr; + uint16_t hdr; + int version; + int pathid; + + ndo->ndo_protocol = "hsr-prp-supervision"; + if (!ndo->ndo_eflag) { + nd_print_protocol_caps(ndo); + ND_PRINT(", "); + } + ND_ICHECK_U(length, <, HSR_PRP_SUPERVISION_LEN); + + hdr = GET_BE_U_2(bp); + version = hdr & 0xFFF; + /* PathId is always set to 0 according to current standard */ + pathid = (hdr >> 12); + length -= 2; + bp += 2; + seq_nr = GET_BE_U_2(bp); + length -= 2; + bp += 2; + ND_PRINT("Version %d, SeqNr %d, PathId %d", version, seq_nr, pathid); + + tlvtype = GET_BE_U_2(bp) >> 8; + tlvlength = GET_BE_U_2(bp) & 0xFF; + length -= 2; + bp += 2; + + if (tlvlength != 6) + goto invalid; + + /* TLV1 */ + if (tlvtype == 20) { + /* PRP: VDAN MAC for RedBox or DANP MAC for both ports in PRP Duplicate Discard */ + ND_PRINT(", VDAN/DANP %s", GET_MAC48_STRING(bp)); + } else if (tlvtype == 21) { + /* PRP: Not valid for RedBox. DANP MAC for both ports in PRP Duplicate Accept mode */ + ND_PRINT(", DANP %s", GET_MAC48_STRING(bp)); + } else if (tlvtype == 23) { + /* HSR: MAC address of DANH */ + ND_PRINT(", DANH %s", GET_MAC48_STRING(bp)); + } else { + goto invalid; + } + length -= 6; + bp += 6; + + tlvtype = GET_BE_U_2(bp) >> 8; + tlvlength = GET_BE_U_2(bp) & 0xFF; + length -= 2; + bp += 2; + + /* No TLV2 indicates the device is not a RedBox */ + if (tlvtype == 0 && tlvlength == 0) + return; + if (tlvlength != 6) { + goto invalid; + } + + /* TLV2 */ + if (tlvtype == 30) { + /* HSR and PRP: RedBox MAC */ + ND_PRINT(", RedBox %s", GET_MAC48_STRING(bp)); + length -= 6; + bp += 6; + } else { + goto invalid; + } + + tlvtype = GET_BE_U_2(bp) >> 8; + tlvlength = GET_BE_U_2(bp) & 0xFF; + length -= 2; + bp += 2; + + /* TLV0 */ + if (tlvtype == 0 && tlvlength == 0) { + /* HSR and PRP closing TLV, should always be type and length 0. + */ + return; + } + +invalid: + nd_print_invalid(ndo); +} + From 7f7a2a6a831585307abea4b84040fd6c7272d4f7 Mon Sep 17 00:00:00 2001 From: Casper Andersson Date: Thu, 1 Feb 2024 10:35:37 +0100 Subject: [PATCH 3/5] HSR/PRP: Add printing for PRP trailer PRP is a redundancy protocol, like HSR, that duplicates packets and includes a sequence number. However, PRP uses a trailer on the packet, making the parsing a bit tricky. The trailer includes the packet size that can be used to help ascertain it is a valid PRP trailer, however it is still possible that this can appear naturally in a packet somewhere in a network that doesn't use PRP. Signed-off-by: Casper Andersson --- netdissect.h | 1 + print-ether.c | 8 ++++++++ print-hsr-prp.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/netdissect.h b/netdissect.h index ed94a7cac..8a257cb6c 100644 --- a/netdissect.h +++ b/netdissect.h @@ -655,6 +655,7 @@ extern void hex_print(netdissect_options *, const char *indent, const u_char *cp extern void hex_print_with_offset(netdissect_options *, const char *indent, const u_char *cp, u_int, u_int); extern void hncp_print(netdissect_options *, const u_char *, u_int); extern void hsr_print(netdissect_options *, const u_char *, u_int); +extern void prp_print(netdissect_options *, const u_char *, u_int); extern void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length); extern void hsrp_print(netdissect_options *, const u_char *, u_int); extern void http_print(netdissect_options *, const u_char *, u_int); diff --git a/print-ether.c b/print-ether.c index 244d86249..a9de62995 100644 --- a/print-ether.c +++ b/print-ether.c @@ -151,6 +151,7 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, int printed_length; int llc_hdrlen; struct lladdr_info src, dst; + int prp_suffix; if (length < caplen) { ND_PRINT("[length %u < caplen %u]", length, caplen); @@ -307,6 +308,13 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, hdrlen += 6; } + if (caplen >= 6) { + prp_suffix = GET_BE_U_2(p + caplen - 2); + if (prp_suffix == 0x88fb) { + prp_print(ndo, p, caplen); + } + } + /* * We now have the final length/type field. */ diff --git a/print-hsr-prp.c b/print-hsr-prp.c index 7be0c61e4..5a4c6d4c5 100644 --- a/print-hsr-prp.c +++ b/print-hsr-prp.c @@ -40,6 +40,30 @@ * header, tags before the HSR tag (e.g. VLAN), and the HSR ethertype field. * For PRP it includes the PRP suffix. * + * + * PRP trailer + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence number | LanId | LSDUsize | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PRP Suffix (0x88fb) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * + * PRP uses a trailer on the packets, making it harder to parse. The suffix + * 0x88fb indicates that it is a PRP frame, but since this could occur + * naturally in a packet there is also the LSDUsize that indicates the size of + * the packet. If this size does not match then it is not a PRP trailer. + * Unfortunately, this could still match on other packets if coincidentally + * both the suffix and LSDUsize matches up. We could also verify that LanId is + * valid (0xA or 0xB) to further reduce likelihood of bad matches. + * + * LanId in HSR header is 0 = LAN A and 1 = LAN B. In PRP frames it is + * represented as 0xA and 0xB. + * + * * HSR/PRP Supervision frame * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -93,6 +117,24 @@ void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length) nd_print_invalid(ndo); } +void prp_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + u_int lsdu_size, lanid, seqnr; + + lsdu_size = GET_BE_U_2(bp + length - 4) & 0xfff; + lanid = GET_BE_U_2(bp + length - 4) >> 12; + + /* If length does not match LSDUsize or LanId isn't valid it isn't a + * valid PRP trailer. This length assumes VLAN tags have been stripped + * away already. + */ + if (lsdu_size == length && (lanid == 0xA || lanid == 0xB)) { + seqnr = GET_BE_U_2(bp + length - 6); + ND_PRINT("PRP trailer (0x88fb), LSDUsize %d, SeqNr %d, LanId %s, ", + lsdu_size, seqnr, lanid == 0xA ? "A" : "B"); + } +} + void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length) { int tlvtype, tlvlength; From 33b82d545fa337a26089ee3e694555770d35a621 Mon Sep 17 00:00:00 2001 From: Casper Andersson Date: Thu, 1 Feb 2024 11:38:46 +0100 Subject: [PATCH 4/5] HSR/PRP: Add tests Test setup used: ip link add link veth1 type veth peer name veth2 ip link set dev veth1 up ip link set dev veth2 up ip link add name hsr0 type hsr slave1 veth1 slave2 veth2 version 1 proto 0 ip link set dev hsr0 up And same but with PRP: ip link add name prp0 type hsr slave1 veth1 slave2 veth2 proto 1 Supervision frames are automatically sent out by the kernel on HSR/PRP interfaces. Signed-off-by: Casper Andersson --- tests/TESTLIST | 4 ++++ tests/hsr.out | 24 ++++++++++++++++++++++++ tests/hsr.pcap | Bin 0 -> 1992 bytes tests/prp.out | 14 ++++++++++++++ tests/prp.pcap | Bin 0 -> 1172 bytes 5 files changed, 42 insertions(+) create mode 100644 tests/hsr.out create mode 100644 tests/hsr.pcap create mode 100644 tests/prp.out create mode 100644 tests/prp.pcap diff --git a/tests/TESTLIST b/tests/TESTLIST index 8478ceb3c..72bbff2fc 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -959,6 +959,10 @@ nhrp-trace nhrp-trace.pcap nhrp-trace.out -v nhrp nhrp.pcapng nhrp.out -v pb_nhrp_1 pb_nhrp_1.pcap pb_nhrp_1.out -v +# HSR/PRP tests +hsr hsr.pcap hsr.out -e +prp prp.pcap prp.out -e + # Undefined behavior tests ip-snmp-leftshift-unsigned ip-snmp-leftshift-unsigned.pcap ip-snmp-leftshift-unsigned.out ip6-snmp-oid-unsigned ip6-snmp-oid-unsigned.pcap ip6-snmp-oid-unsigned.out diff --git a/tests/hsr.out b/tests/hsr.out new file mode 100644 index 000000000..a417a0799 --- /dev/null +++ b/tests/hsr.out @@ -0,0 +1,24 @@ + 1 10:27:45.556140 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6787, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 2 10:27:45.556152 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6787, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 3 10:27:46.580164 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6788, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 4 10:27:46.580176 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6788, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 5 10:27:46.900124 7a:32:3c:8c:19:05 > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6789, LanId B, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38836, PathId 0, DANH 7a:32:3c:8c:19:05 + 6 10:27:46.900137 3a:d6:01:92:63:1d > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6789, LanId A, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38836, PathId 0, DANH 7a:32:3c:8c:19:05 + 7 10:27:47.604149 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6790, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 8 10:27:47.604158 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6790, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 9 10:27:48.628147 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6791, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 10 10:27:48.628158 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6791, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 11 10:27:48.920143 7a:32:3c:8c:19:05 > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6792, LanId B, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38837, PathId 0, DANH 7a:32:3c:8c:19:05 + 12 10:27:48.920154 3a:d6:01:92:63:1d > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6792, LanId A, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38837, PathId 0, DANH 7a:32:3c:8c:19:05 + 13 10:27:49.652077 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6793, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 14 10:27:49.652086 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6793, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 15 10:27:50.676324 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6794, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 16 10:27:50.676332 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6794, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 17 10:27:50.932131 7a:32:3c:8c:19:05 > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6795, LanId B, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38838, PathId 0, DANH 7a:32:3c:8c:19:05 + 18 10:27:50.932147 3a:d6:01:92:63:1d > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6795, LanId A, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38838, PathId 0, DANH 7a:32:3c:8c:19:05 + 19 10:27:51.700163 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6796, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 20 10:27:51.700174 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6796, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 21 10:27:52.724026 7a:32:3c:8c:19:05 > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6797, LanId B, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 22 10:27:52.724036 3a:d6:01:92:63:1d > ff:ff:ff:ff:ff:ff, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6797, LanId A, NetId 0, ethertype ARP (0x0806), Request who-has 142.250.74.110 tell 192.168.0.10, length 46 + 23 10:27:52.948107 7a:32:3c:8c:19:05 > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6798, LanId B, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38839, PathId 0, DANH 7a:32:3c:8c:19:05 + 24 10:27:52.948116 3a:d6:01:92:63:1d > 01:15:4e:00:01:00, ethertype HSR (0x892f), length 66: LSDUsize 52, SeqNr 6798, LanId A, NetId 0, ethertype HSR/PRP Supervision (0x88fb), Version 1, SeqNr 38839, PathId 0, DANH 7a:32:3c:8c:19:05 diff --git a/tests/hsr.pcap b/tests/hsr.pcap new file mode 100644 index 0000000000000000000000000000000000000000..cfe182c82d6c119ca30b8e2de93949a119499cc1 GIT binary patch literal 1992 zcmca|c+)~A1{MYcU}0bcaukbpr{>gfFgO9(Ap9Q;s*G%UBw0K48BC;_IoKE&IT+Z0 z$|0f$RxofuOzHdOl?P!VlOPi-Fif<%#yBZiwo_k#3=@@rCc50h*o@F-$~qBgrNz15NyD&IxxT zMqIa%8jc_n|6!PjndpLHB9a@)GO@cHPh9tb<9a*saSd|g6buuQ+(@#C0G*|NasU7T literal 0 HcmV?d00001 diff --git a/tests/prp.out b/tests/prp.out new file mode 100644 index 000000000..e8205de67 --- /dev/null +++ b/tests/prp.out @@ -0,0 +1,14 @@ + 1 10:34:30.580215 c6:81:06:cb:35:98 > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3263, LanId A, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 2 10:34:30.580224 b2:f0:66:9b:81:1c > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3263, LanId B, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 3 10:34:31.028126 c6:81:06:cb:35:98 > 01:15:4e:00:01:00, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3264, LanId A, ethertype HSR/PRP Supervision (0x88fb), length 66: Version 1, SeqNr 36486, PathId 0, VDAN/DANP c6:81:06:cb:35:98 + 4 10:34:31.028135 b2:f0:66:9b:81:1c > 01:15:4e:00:01:00, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3264, LanId B, ethertype HSR/PRP Supervision (0x88fb), length 66: Version 1, SeqNr 36486, PathId 0, VDAN/DANP c6:81:06:cb:35:98 + 5 10:34:31.604157 c6:81:06:cb:35:98 > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3265, LanId A, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 6 10:34:31.604167 b2:f0:66:9b:81:1c > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3265, LanId B, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 7 10:34:32.628138 c6:81:06:cb:35:98 > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3266, LanId A, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 8 10:34:32.628148 b2:f0:66:9b:81:1c > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3266, LanId B, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 9 10:34:33.044029 c6:81:06:cb:35:98 > 01:15:4e:00:01:00, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3267, LanId A, ethertype HSR/PRP Supervision (0x88fb), length 66: Version 1, SeqNr 36487, PathId 0, VDAN/DANP c6:81:06:cb:35:98 + 10 10:34:33.044039 b2:f0:66:9b:81:1c > 01:15:4e:00:01:00, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3267, LanId B, ethertype HSR/PRP Supervision (0x88fb), length 66: Version 1, SeqNr 36487, PathId 0, VDAN/DANP c6:81:06:cb:35:98 + 11 10:34:33.652277 c6:81:06:cb:35:98 > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3268, LanId A, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 12 10:34:33.652284 b2:f0:66:9b:81:1c > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3268, LanId B, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 13 10:34:34.676144 c6:81:06:cb:35:98 > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3269, LanId A, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 + 14 10:34:34.676155 b2:f0:66:9b:81:1c > ff:ff:ff:ff:ff:ff, PRP trailer (0x88fb), LSDUsize 52, SeqNr 3269, LanId B, ethertype ARP (0x0806), length 66: Request who-has 142.250.74.142 tell 192.168.0.10, length 52 diff --git a/tests/prp.pcap b/tests/prp.pcap new file mode 100644 index 0000000000000000000000000000000000000000..e59dd49eff089cba424d0bc9d22baab2ab4612bd GIT binary patch literal 1172 zcmca|c+)~A1{MYcU}0bca<&!kPA$L1!QcdBgYbVaIM&E^+H?j78v`Q;0~=5wgnwWK z0~bVp-!HE|2n(6y*}uS~<2T5}1`HE7eMp<#C_}o58-ONm2by><7vesU8yQ9YfNqDl zspB^TV_%yH8-$1K8tiPI10XkoOni=EBE*fPn+S8`Uvp0CgyTV&8`&+;O(ZiM4}#pd z1L*5jQ_)Q%Gp-MT+z2vp3xk7>%$;7f=pyzgKi>HT$5xX w%#B|^Qz;yez})x;!$dN}@d(I`yMVqn2;`zpdOQkpBgjN+3=_$8<57?s0mslP-T(jq literal 0 HcmV?d00001 From 6bb3a08d60f76d58676019f02b60dabd4553c943 Mon Sep 17 00:00:00 2001 From: Casper Andersson Date: Wed, 14 Feb 2024 15:16:47 +0100 Subject: [PATCH 5/5] HSR/PRP: Add -P flag for dissecting PRP trailer To avoid dissecting PRP trailer when we aren't using PRP. --- netdissect.h | 1 + print-ether.c | 2 +- tcpdump.c | 6 +++++- tests/TESTLIST | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/netdissect.h b/netdissect.h index 8a257cb6c..2a245ea48 100644 --- a/netdissect.h +++ b/netdissect.h @@ -223,6 +223,7 @@ struct netdissect_options { int ndo_Aflag; /* print packet only in ASCII observing TAB, * LF, CR and SPACE as graphical chars */ + int ndo_Pflag; /* print PRP trailer */ int ndo_Hflag; /* dissect 802.11s draft mesh standard */ const char *ndo_protocol; /* protocol */ jmp_buf ndo_early_end; /* jmp_buf for setjmp()/longjmp() */ diff --git a/print-ether.c b/print-ether.c index a9de62995..a6d11e385 100644 --- a/print-ether.c +++ b/print-ether.c @@ -308,7 +308,7 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length, hdrlen += 6; } - if (caplen >= 6) { + if (ndo->ndo_Pflag && caplen >= 6) { prp_suffix = GET_BE_U_2(p + caplen - 2); if (prp_suffix == 0x88fb) { prp_print(ndo, p, caplen); diff --git a/tcpdump.c b/tcpdump.c index 5e2321971..e43da3fdd 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -672,7 +672,7 @@ show_remote_devices_and_exit(void) #define U_FLAG #endif -#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" +#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpPq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" /* * Long options. @@ -1829,6 +1829,10 @@ main(int argc, char **argv) ++pflag; break; + case 'P': + ++ndo->ndo_Pflag; + break; + case 'q': ++ndo->ndo_qflag; ++ndo->ndo_suppress_default_print; diff --git a/tests/TESTLIST b/tests/TESTLIST index 72bbff2fc..44e868b25 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -961,7 +961,7 @@ pb_nhrp_1 pb_nhrp_1.pcap pb_nhrp_1.out -v # HSR/PRP tests hsr hsr.pcap hsr.out -e -prp prp.pcap prp.out -e +prp prp.pcap prp.out -e -P # Undefined behavior tests ip-snmp-leftshift-unsigned ip-snmp-leftshift-unsigned.pcap ip-snmp-leftshift-unsigned.out