From 41c0aefde73e76bd41671ba4bb19959ec9be773a 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 | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+) create mode 100644 print-hsr-prp.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 73acc7501..7b33687c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -999,6 +999,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 4ffca817b..17bf06d88 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 a757a39c2..acc79f687 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 0e6557fed..528de26c3 100644 --- a/netdissect.h +++ b/netdissect.h @@ -598,6 +598,7 @@ extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char extern void hex_print(netdissect_options *, const char *ident, const u_char *cp, u_int); extern void hex_print_with_offset(netdissect_options *, const char *ident, 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 da95862b3..bd7600e62 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} }; @@ -285,6 +286,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..1117b114c --- /dev/null +++ b/print-hsr-prp.c @@ -0,0 +1,74 @@ +/* + * 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; + + if (length < HSR_HDR_LEN) { + goto invalid; + } + + 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 be2c4953d3d43ad8d4094ff1a4c4ea46a20d9491 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 | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/ethertype.h b/ethertype.h index acc79f687..299110327 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 528de26c3..398bf6b79 100644 --- a/netdissect.h +++ b/netdissect.h @@ -599,6 +599,7 @@ extern void hex_print(netdissect_options *, const char *ident, const u_char *cp, extern void hex_print_with_offset(netdissect_options *, const char *ident, 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 bd7600e62..d385ed04e 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} }; @@ -666,6 +667,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 1117b114c..fe242662f 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) { @@ -72,3 +95,93 @@ 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(", "); + } + if (length < HSR_PRP_SUPERVISION_LEN) { + goto invalid; + } + + 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_ETHERADDR_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_ETHERADDR_STRING(bp)); + } else if (tlvtype == 23) { + /* HSR: MAC address of DANH */ + ND_PRINT(", DANH %s", GET_ETHERADDR_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_ETHERADDR_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 ac967022c6761e92e711b84b8dd75b486527fa14 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 398bf6b79..d322c250a 100644 --- a/netdissect.h +++ b/netdissect.h @@ -599,6 +599,7 @@ extern void hex_print(netdissect_options *, const char *ident, const u_char *cp, extern void hex_print_with_offset(netdissect_options *, const char *ident, 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 d385ed04e..bf3f0e270 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 (caplen < ETHER_HDRLEN + switch_tag_len) { nd_print_trunc(ndo); @@ -305,6 +306,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 fe242662f..dba9a8e24 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 @@ -95,6 +119,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 44e658dd3eb106c9e038a370c6cd88a1b241bd61 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 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 31e1a99ce..8dcf3f91f 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -836,3 +836,7 @@ unsupported-link-type-dbus unsupported-link-type-dbus.pcap unsupported-link-type # LSP Ping lsp-ping-timestamp lsp-ping-timestamp.pcap lsp-ping-timestamp.out -vv + +# HSR/PRP tests +hsr hsr.pcap hsr.out -e +prp prp.pcap prp.out -e 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 a56ce98fc5e9f531d30045bfe27c2f9e0dbbde36 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 d322c250a..81a0c0a60 100644 --- a/netdissect.h +++ b/netdissect.h @@ -214,6 +214,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 packet in hex/ASCII */ 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 bf3f0e270..411d94b39 100644 --- a/print-ether.c +++ b/print-ether.c @@ -306,7 +306,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 6476a3d48..c429f3e04 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. @@ -1738,6 +1738,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 8dcf3f91f..7fe4f74ff 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -839,4 +839,4 @@ lsp-ping-timestamp lsp-ping-timestamp.pcap lsp-ping-timestamp.out -vv # HSR/PRP tests hsr hsr.pcap hsr.out -e -prp prp.pcap prp.out -e +prp prp.pcap prp.out -e -P