3939#define LACP_VERSION 1
4040#define MARKER_VERSION 1
4141
42- static const struct tok slow_proto_values [] = {
43- { SLOW_PROTO_LACP , "LACP" },
44- { SLOW_PROTO_MARKER , "MARKER" },
45- { SLOW_PROTO_OAM , "OAM" },
46- { SLOW_PROTO_OSSP , "OSSP" },
47- { 0 , NULL }
48- };
49-
5042static const struct tok slow_oam_flag_values [] = {
5143 { 0x0001 , "Link Fault" },
5244 { 0x0002 , "Dying Gasp" },
@@ -243,100 +235,41 @@ static void slow_marker_lacp_print(netdissect_options *, const u_char *, u_int,
243235static void slow_oam_print (netdissect_options * , const u_char * , u_int );
244236static void slow_ossp_print (netdissect_options * , const u_char * , u_int );
245237
238+ /*
239+ * Print Slow Protocol. (802.3 Annex 57A)
240+ */
246241void
247242slow_print (netdissect_options * ndo ,
248243 const u_char * pptr , u_int len )
249244{
250- int print_version ;
251245 u_int subtype ;
252246
253247 ndo -> ndo_protocol = "slow" ;
248+
254249 if (len < 1 )
255250 goto tooshort ;
256251 subtype = GET_U_1 (pptr );
252+ len -= 1 ;
253+ pptr += 1 ;
257254
258- /*
259- * Sanity checking of the header.
260- */
261255 switch (subtype ) {
262- case SLOW_PROTO_LACP :
263- if (len < 2 )
264- goto tooshort ;
265- if (GET_U_1 (pptr + 1 ) != LACP_VERSION ) {
266- ND_PRINT ("LACP version %u packet not supported" ,
267- GET_U_1 (pptr + 1 ));
268- return ;
269- }
270- print_version = 1 ;
271- break ;
272-
256+ case SLOW_PROTO_LACP : /* fall through */
273257 case SLOW_PROTO_MARKER :
274- if (len < 2 )
275- goto tooshort ;
276- if (GET_U_1 (pptr + 1 ) != MARKER_VERSION ) {
277- ND_PRINT ("MARKER version %u packet not supported" ,
278- GET_U_1 (pptr + 1 ));
279- return ;
280- }
281- print_version = 1 ;
258+ slow_marker_lacp_print (ndo , pptr , len , subtype );
282259 break ;
283260
284261 case SLOW_PROTO_OAM :
285- case SLOW_PROTO_OSSP :
286- print_version = 0 ;
287- break ;
288-
289- default :
290- /* print basic information and exit */
291- print_version = -1 ;
292- break ;
293- }
294-
295- if (print_version == 1 ) {
296- ND_PRINT ("%sv%u, length %u" ,
297- tok2str (slow_proto_values , "unknown (%u)" , subtype ),
298- GET_U_1 ((pptr + 1 )),
299- len );
300- } else {
301- /* some slow protos don't have a version number in the header */
302- ND_PRINT ("%s, length %u" ,
303- tok2str (slow_proto_values , "unknown (%u)" , subtype ),
304- len );
305- }
306-
307- /* unrecognized subtype */
308- if (print_version == -1 ) {
309- print_unknown_data (ndo , pptr , "\n\t" , len );
310- return ;
311- }
312-
313- if (!ndo -> ndo_vflag )
314- return ;
315-
316- switch (subtype ) {
317- default : /* should not happen */
262+ slow_oam_print (ndo , pptr , len );
318263 break ;
319264
320265 case SLOW_PROTO_OSSP :
321- /* skip subtype */
322- len -= 1 ;
323- pptr += 1 ;
324266 slow_ossp_print (ndo , pptr , len );
325267 break ;
326268
327- case SLOW_PROTO_OAM :
328- /* skip subtype */
329- len -= 1 ;
330- pptr += 1 ;
331- slow_oam_print (ndo , pptr , len );
332- break ;
333-
334- case SLOW_PROTO_LACP : /* LACP and MARKER share the same semantics */
335- case SLOW_PROTO_MARKER :
336- /* skip subtype and version */
337- len -= 2 ;
338- pptr += 2 ;
339- slow_marker_lacp_print (ndo , pptr , len , subtype );
269+ default :
270+ ND_PRINT ("unknown (%u), length %u" , subtype , len + 1 );
271+ if (ndo -> ndo_vflag )
272+ print_unknown_data (ndo , pptr , "\n\t" , len );
340273 break ;
341274 }
342275 return ;
@@ -348,14 +281,17 @@ slow_print(netdissect_options *ndo,
348281 ND_PRINT ("\n\t\t packet is too short" );
349282}
350283
284+ /*
285+ * Print Link Aggregation Control Protocol and Marker protocol. (802.3ad / 802.1ax)
286+ */
351287static void
352288slow_marker_lacp_print (netdissect_options * ndo ,
353289 const u_char * tptr , u_int tlen ,
354290 u_int proto_subtype )
355291{
356292 const struct tlv_header_t * tlv_header ;
357293 const u_char * tlv_tptr ;
358- u_int tlv_type , tlv_len , tlv_tlen ;
294+ u_int tlv_type , tlv_len , tlv_tlen , version ;
359295
360296 union {
361297 const struct lacp_marker_tlv_terminator_t * lacp_marker_tlv_terminator ;
@@ -364,6 +300,26 @@ slow_marker_lacp_print(netdissect_options *ndo,
364300 const struct marker_tlv_marker_info_t * marker_tlv_marker_info ;
365301 } tlv_ptr ;
366302
303+ if (tlen < 1 )
304+ goto tooshort ;
305+
306+ version = GET_U_1 (tptr );
307+ tlen -= 1 ;
308+ tptr += 1 ;
309+
310+ ND_PRINT ("%sv%u, length %u" ,
311+ proto_subtype == SLOW_PROTO_LACP ? "LACP" : "MARKER" ,
312+ version , tlen + 2 );
313+
314+ if (!ndo -> ndo_vflag )
315+ return ;
316+
317+ if ((proto_subtype == SLOW_PROTO_LACP && version != LACP_VERSION )
318+ || (proto_subtype == SLOW_PROTO_MARKER && version != MARKER_VERSION )) {
319+ print_unknown_data (ndo , tptr , "\n\t" , tlen );
320+ return ;
321+ }
322+
367323 while (tlen != 0 ) {
368324 /* is the packet big enough to include the tlv header ? */
369325 if (tlen < sizeof (struct tlv_header_t ))
@@ -485,6 +441,9 @@ slow_marker_lacp_print(netdissect_options *ndo,
485441 ND_PRINT ("\n\t\t packet is too short" );
486442}
487443
444+ /*
445+ * Print Operations, Administration, and Maintenance. (802.3)
446+ */
488447static void
489448slow_oam_print (netdissect_options * ndo ,
490449 const u_char * tptr , u_int tlen )
@@ -518,6 +477,11 @@ slow_oam_print(netdissect_options *ndo,
518477 const struct slow_oam_loopbackctrl_t * slow_oam_loopbackctrl ;
519478 } tlv ;
520479
480+ ND_PRINT ("OAM, length %u" , tlen + 1 );
481+
482+ if (!ndo -> ndo_vflag )
483+ return ;
484+
521485 ptr .slow_oam_common_header = (const struct slow_oam_common_header_t * )tptr ;
522486 if (tlen < sizeof (* ptr .slow_oam_common_header ))
523487 goto tooshort ;
@@ -754,6 +718,11 @@ slow_ossp_print(netdissect_options *ndo,
754718{
755719 uint32_t oui ;
756720
721+ ND_PRINT ("OSSP, length %u" , tlen + 1 );
722+
723+ if (!ndo -> ndo_vflag )
724+ return ;
725+
757726 ND_ICHECKMSG_U ("length" , tlen , < , 3 );
758727
759728 oui = GET_BE_U_3 (tptr );
0 commit comments