Skip to content

Commit f643930

Browse files
committed
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 <[email protected]>
1 parent a1e7ba4 commit f643930

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

ethertype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@
188188
#ifndef ETHERTYPE_HSR
189189
#define ETHERTYPE_HSR 0x892f
190190
#endif
191+
#ifndef ETHERTYPE_HSR_PRP_SUP
192+
#define ETHERTYPE_HSR_PRP_SUP 0x88fb
193+
#endif
191194
#ifndef ETHERTYPE_LOOPBACK
192195
#define ETHERTYPE_LOOPBACK 0x9000
193196
#endif

netdissect.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ extern void hex_print(netdissect_options *, const char *indent, const u_char *cp
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);
657657
extern void hsr_print(netdissect_options *, const u_char *, u_int);
658+
extern void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length);
658659
extern void hsrp_print(netdissect_options *, const u_char *, u_int);
659660
extern void http_print(netdissect_options *, const u_char *, u_int);
660661
extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int);

print-ether.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ const struct tok ethertype_values[] = {
104104
{ ETHERTYPE_AOE, "AoE" },
105105
{ ETHERTYPE_PTP, "PTP" },
106106
{ ETHERTYPE_HSR, "HSR" },
107+
{ ETHERTYPE_HSR_PRP_SUP, "HSR/PRP Supervision" },
107108
{ ETHERTYPE_ARISTA, "Arista Vendor Specific Protocol" },
108109
{ 0, NULL}
109110
};
@@ -672,6 +673,10 @@ ethertype_print(netdissect_options *ndo,
672673
ptp_print(ndo, p, length);
673674
return (1);
674675

676+
case ETHERTYPE_HSR_PRP_SUP:
677+
hsr_prp_supervision_print(ndo, p, length);
678+
return (1);
679+
675680
case ETHERTYPE_LAT:
676681
case ETHERTYPE_SCA:
677682
case ETHERTYPE_MOPRC:

print-hsr-prp.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,32 @@
3939
* LSDUsize = Link Service Data Unit size = size of the packet excluding MAC
4040
* header, tags before the HSR tag (e.g. VLAN), and the HSR ethertype field.
4141
* For PRP it includes the PRP suffix.
42+
*
43+
* HSR/PRP Supervision frame
44+
* 0 1 2 3
45+
* 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
46+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47+
* |PathId | version | Sequence number |
48+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49+
* | TLV1 Type | TLV1 Length | MAC Address of DANP/DANH |
50+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
51+
* | |
52+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53+
* | TLV2 Type | TLV2 Length | RedBox MAC Address |
54+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
55+
* | |
56+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57+
* | TLV0 Type | TLV0 Length |
58+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59+
* 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
60+
* 0 1 2 3
61+
*
62+
* DANP = Doubly Attached Node PRP
63+
* DANH = Doubly Attached Node HSR
4264
*/
4365

4466
#define HSR_HDR_LEN 6
67+
#define HSR_PRP_SUPERVISION_LEN 22
4568

4669
void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length)
4770
{
@@ -70,3 +93,95 @@ void hsr_print(netdissect_options *ndo, const u_char *bp, u_int length)
7093
nd_print_invalid(ndo);
7194
}
7295

96+
void hsr_prp_supervision_print(netdissect_options *ndo, const u_char *bp, u_int length)
97+
{
98+
int tlvtype, tlvlength;
99+
uint32_t seq_nr;
100+
uint16_t hdr;
101+
int version;
102+
int pathid;
103+
104+
ndo->ndo_protocol = "hsr-prp-supervision";
105+
if (!ndo->ndo_eflag) {
106+
nd_print_protocol_caps(ndo);
107+
ND_PRINT(", ");
108+
}
109+
ND_ICHECK_U(length, <, HSR_PRP_SUPERVISION_LEN);
110+
111+
hdr = GET_BE_U_2(bp);
112+
version = hdr & 0xFFF;
113+
/* PathId is always set to 0 according to current standard */
114+
pathid = (hdr >> 12);
115+
length -= 2;
116+
bp += 2;
117+
seq_nr = GET_BE_U_2(bp);
118+
length -= 2;
119+
bp += 2;
120+
ND_PRINT("Version %d, SeqNr %d, PathId %d", version, seq_nr, pathid);
121+
122+
tlvtype = GET_BE_U_2(bp) >> 8;
123+
tlvlength = GET_BE_U_2(bp) & 0xFF;
124+
length -= 2;
125+
bp += 2;
126+
127+
if (tlvlength != 6)
128+
goto invalid;
129+
130+
/* TLV1 */
131+
if (tlvtype == 20) {
132+
/* PRP: VDAN MAC for RedBox or DANP MAC for both ports in PRP Duplicate Discard */
133+
ND_PRINT(", VDAN/DANP %s", GET_MAC48_STRING(bp));
134+
} else if (tlvtype == 21) {
135+
/* PRP: Not valid for RedBox. DANP MAC for both ports in PRP Duplicate Accept mode */
136+
ND_PRINT(", DANP %s", GET_MAC48_STRING(bp));
137+
} else if (tlvtype == 23) {
138+
/* HSR: MAC address of DANH */
139+
ND_PRINT(", DANH %s", GET_MAC48_STRING(bp));
140+
} else {
141+
goto invalid;
142+
}
143+
length -= 6;
144+
bp += 6;
145+
146+
tlvtype = GET_BE_U_2(bp) >> 8;
147+
tlvlength = GET_BE_U_2(bp) & 0xFF;
148+
length -= 2;
149+
bp += 2;
150+
151+
/* No TLV2 indicates the device is not a RedBox */
152+
if (tlvtype == 0 && tlvlength == 0)
153+
return;
154+
if (tlvlength != 6) {
155+
goto invalid;
156+
}
157+
158+
/* TLV2 */
159+
if (tlvtype == 30) {
160+
/* HSR and PRP: RedBox MAC */
161+
ND_PRINT(", RedBox %s", GET_MAC48_STRING(bp));
162+
length -= 6;
163+
bp += 6;
164+
} else {
165+
goto invalid;
166+
}
167+
168+
tlvtype = GET_BE_U_2(bp) >> 8;
169+
tlvlength = GET_BE_U_2(bp) & 0xFF;
170+
length -= 2;
171+
bp += 2;
172+
173+
/* TLV0 */
174+
if (tlvtype == 0 && tlvlength == 0) {
175+
/* HSR and PRP closing TLV, should always be type and length 0.
176+
*/
177+
return;
178+
} else {
179+
goto invalid;
180+
}
181+
182+
return;
183+
184+
invalid:
185+
nd_print_invalid(ndo);
186+
}
187+

0 commit comments

Comments
 (0)