Skip to content

Commit d6195af

Browse files
committed
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 <[email protected]>
1 parent 8482d8c commit d6195af

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,7 @@ set(NETDISSECT_SOURCE_LIST_C
11241124
print-geonet.c
11251125
print-gre.c
11261126
print-hncp.c
1127+
print-hsr-prp.c
11271128
print-hsrp.c
11281129
print-http.c
11291130
print-icmp.c

Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ LIBNETDISSECT_SRC=\
142142
print-geonet.c \
143143
print-gre.c \
144144
print-hncp.c \
145+
print-hsr-prp.c \
145146
print-hsrp.c \
146147
print-http.c \
147148
print-icmp.c \

ethertype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@
185185
#ifndef ETHERTYPE_PTP
186186
#define ETHERTYPE_PTP 0x88f7
187187
#endif
188+
#ifndef ETHERTYPE_HSR
189+
#define ETHERTYPE_HSR 0x892f
190+
#endif
188191
#ifndef ETHERTYPE_LOOPBACK
189192
#define ETHERTYPE_LOOPBACK 0x9000
190193
#endif

netdissect.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char
654654
extern void hex_print(netdissect_options *, const char *indent, const u_char *cp, u_int);
655655
extern void hex_print_with_offset(netdissect_options *, const char *indent, const u_char *cp, u_int, u_int);
656656
extern void hncp_print(netdissect_options *, const u_char *, u_int);
657+
extern void hsr_print(netdissect_options *, const u_char *, u_int);
657658
extern void hsrp_print(netdissect_options *, const u_char *, u_int);
658659
extern void http_print(netdissect_options *, const u_char *, u_int);
659660
extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int);

print-ether.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const struct tok ethertype_values[] = {
103103
{ ETHERTYPE_CALM_FAST, "CALM FAST"},
104104
{ ETHERTYPE_AOE, "AoE" },
105105
{ ETHERTYPE_PTP, "PTP" },
106+
{ ETHERTYPE_HSR, "HSR" },
106107
{ ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" },
107108
{ 0, NULL}
108109
};
@@ -287,6 +288,24 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length,
287288
hdrlen += 4;
288289
}
289290

291+
if (length_type == ETHERTYPE_HSR) {
292+
if (ndo->ndo_eflag) {
293+
ether_type_print(ndo, length_type);
294+
if (!printed_length) {
295+
ND_PRINT(", length %u: ", orig_length);
296+
printed_length = 1;
297+
} else
298+
ND_PRINT(", ");
299+
hsr_print(ndo, p, length);
300+
}
301+
302+
length_type = GET_BE_U_2(p + 4);
303+
p += 6;
304+
length -= 6;
305+
caplen -= 6;
306+
hdrlen += 6;
307+
}
308+
290309
/*
291310
* We now have the final length/type field.
292311
*/

print-hsr-prp.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Redistribution and use in source and binary forms, with or without
3+
* modification, are permitted provided that: (1) source code
4+
* distributions retain the above copyright notice and this paragraph
5+
* in its entirety, and (2) distributions including binary code include
6+
* the above copyright notice and this paragraph in its entirety in
7+
* the documentation or other materials provided with the distribution.
8+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9+
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10+
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11+
* FOR A PARTICULAR PURPOSE.
12+
*/
13+
14+
/* \summary: High-availability Seamless Redundancy (HSR) and
15+
* Parallel Redundancy Protocol (PRP) printer */
16+
17+
/* specification: https://webstore.iec.ch/publication/64423 */
18+
19+
#ifdef HAVE_CONFIG_H
20+
#include <config.h>
21+
#endif
22+
23+
#include "netdissect-stdinc.h"
24+
#include "netdissect.h"
25+
#include "extract.h"
26+
#include "addrtoname.h"
27+
28+
/*
29+
* HSR header
30+
* 0 1 2 3
31+
* 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
32+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33+
* |NetID|L| LSDUsize | Sequence number |
34+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35+
* 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
36+
* 0 1 2 3
37+
*
38+
* L = LanID
39+
* LSDUsize = Link Service Data Unit size = size of the packet excluding MAC
40+
* header, tags before the HSR tag (e.g. VLAN), and the HSR ethertype field.
41+
* For PRP it includes the PRP suffix.
42+
*/
43+
44+
#define HSR_HDR_LEN 6
45+
46+
void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length)
47+
{
48+
int lanid, netid;
49+
uint16_t lsdu_size;
50+
uint16_t hdr;
51+
uint32_t seq_nr;
52+
53+
ND_ICHECK_U(length, <, HSR_HDR_LEN);
54+
55+
hdr = GET_BE_U_2(bp);
56+
lsdu_size = hdr & 0xFFF;
57+
lanid = (hdr >> 12) & 0x1;
58+
netid = hdr >> 13;
59+
60+
length -= 2;
61+
bp += 2;
62+
seq_nr = GET_BE_U_2(bp);
63+
64+
ND_PRINT("LSDUsize %u, SeqNr %u, LanId %s, NetId %u, ",
65+
lsdu_size, seq_nr, lanid ? "A" : "B", netid);
66+
67+
return;
68+
69+
invalid:
70+
nd_print_invalid(ndo);
71+
}
72+

0 commit comments

Comments
 (0)