@@ -217,6 +217,33 @@ static const struct tok lsa_opaque_ri_tlv_sr_algos[] = {
217217	{ 0 ,                    NULL  }
218218};
219219
220+ static  const  struct  tok  lsa_opaque_el_tlv_values [] =  {
221+         { LS_OPAQUE_EXTENDED_LINK_TLV , "Extended Link"  },
222+         { 0 ,                    NULL  }
223+ };
224+ 
225+ static  const  struct  tok  lsa_opaque_extended_link_link_type_values [] =  {
226+         { RLA_TYPE_ROUTER ,  "Point-to-Point Link"  },
227+         { RLA_TYPE_TRANSIT , "Link to Transit Network"  },
228+         { RLA_TYPE_STUB ,    "Link to Stub Network"  },
229+         { RLA_TYPE_VIRTUAL , "Virtual Link"  },
230+         { 0 ,                    NULL  }
231+ };
232+ 
233+ static  const  struct  tok  lsa_opaque_extended_link_subtlv_adj_sid_flag_values [] =  {
234+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_B , "Backup"  },
235+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V , "Value/Index"  },
236+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L , "Local/Global"  },
237+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_G , "Group"  },
238+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_P , "Persistent"  },
239+         { 0 ,                    NULL  }
240+ };
241+ 
242+ static  const  struct  tok  lsa_opaque_extended_link_subtlv_values [] =  {
243+         { LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID , "Adj-SID Sub-TLV"  },
244+         { 0 ,                    NULL  }
245+ };
246+ 
220247static  const  struct  tok  ospf_lls_tlv_values [] =  {
221248	{ OSPF_LLS_EO ,	"Extended Options"  },
222249	{ OSPF_LLS_MD5 ,	"MD5 Authentication"  },
@@ -930,6 +957,113 @@ ospf_ep_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length
930957    return  0 ;
931958}
932959
960+ static  int 
961+ ospf_el_lsa_print (netdissect_options  * ndo , const  uint8_t  * tptr , u_int  lsa_length )
962+ {
963+     u_int  tlv_type , tlv_length , link_type , sub_tlv_flags ;
964+     u_int  sub_tlv_type , sub_tlv_length , sub_tlv_remaining ;
965+     const  uint8_t  * sub_tlv_tptr ;
966+     u_int  vflag , lflag ;
967+ 
968+     while  (lsa_length  >= 4 ) {
969+ 	tlv_type  =  GET_BE_U_2 (tptr );
970+ 	tlv_length  =  GET_BE_U_2 (tptr + 2 );
971+ 	tptr += 4 ;
972+ 	lsa_length -= 4 ;
973+ 
974+ 	/* Infinite loop protection. */ 
975+ 	if  (tlv_type  ==  0  ||  tlv_length  ==  0 ) {
976+ 	    return  -1 ;
977+ 	}
978+ 
979+ 	ND_PRINT ("\n\t    %s TLV (%u), length: %u, value: " ,
980+ 		 tok2str (lsa_opaque_el_tlv_values ,"unknown" ,tlv_type ),
981+ 		 tlv_type ,
982+ 		 tlv_length );
983+ 
984+ 	switch  (tlv_type ) {
985+         case  LS_OPAQUE_EXTENDED_LINK_TLV :
986+             link_type  =  GET_U_1 (tptr );
987+ 
988+             ND_PRINT ("\n\t      Link Type: %s (%u)" ,
989+                 tok2str (lsa_opaque_extended_link_link_type_values ,"unknown" ,link_type ),
990+                 link_type );
991+             ND_PRINT ("\n\t      Reserved: %u" , GET_BE_U_3 (tptr + 1 ));
992+             ND_PRINT ("\n\t      Link ID: %s" , GET_IPADDR_STRING (tptr + 4 ));
993+             ND_PRINT ("\n\t      Link Data: %s" , GET_IPADDR_STRING (tptr + 8 ));
994+ 
995+             sub_tlv_tptr  =  tptr  +  12 ;
996+             sub_tlv_remaining  =  tlv_length  -  12 ;
997+ 
998+             while (sub_tlv_remaining  >  0 ) {
999+                 sub_tlv_type  =  GET_BE_U_2 (sub_tlv_tptr );
1000+                 sub_tlv_length  =  GET_BE_U_2 (sub_tlv_tptr  +  2 );
1001+                 sub_tlv_remaining -= 4 ;
1002+                 sub_tlv_tptr += 4 ;
1003+ 
1004+                 ND_PRINT ("\n\t      %s (%u), length: %u, value: " ,
1005+                     tok2str (lsa_opaque_extended_link_subtlv_values ,"unknown" ,sub_tlv_type ),
1006+                     sub_tlv_type ,
1007+                     sub_tlv_length );
1008+ 
1009+                 switch (sub_tlv_type ){
1010+ 
1011+                 case  LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID :
1012+                     sub_tlv_flags  =  GET_U_1 (sub_tlv_tptr );
1013+ 
1014+                     ND_PRINT ("\n\t        Flags: [%s]" ,
1015+                         bittok2str (lsa_opaque_extended_link_subtlv_adj_sid_flag_values , "none" , sub_tlv_flags ));
1016+                     ND_PRINT ("\n\t        Reserved: %u" , GET_U_1 (sub_tlv_tptr + 1 ));
1017+                     ND_PRINT ("\n\t        MT-ID: %u" , GET_U_1 (sub_tlv_tptr + 2 ));
1018+                     ND_PRINT ("\n\t        Weight: %u" , GET_U_1 (sub_tlv_tptr + 3 ));
1019+ 
1020+                     vflag  =  sub_tlv_flags  &  LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V ;
1021+                     lflag  =  sub_tlv_flags  &  LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L ;
1022+                     if  (vflag  &&  lflag ) {
1023+                         ND_PRINT ("\n\t        SID/Label: %u" ,GET_BE_U_3 (sub_tlv_tptr  +  4 ));
1024+                     }
1025+                     else  if  ( !vflag  &&  !lflag  ) {
1026+                         ND_PRINT ("\n\t        SID/Label: %u" ,GET_BE_U_4 (sub_tlv_tptr  +  4 ));
1027+                     }
1028+                     else  {
1029+                         ND_PRINT ("\n\t        Invalid V-Flag and L-flag combination" );
1030+                         if  (!print_unknown_data (ndo , sub_tlv_tptr , "\n\t      " , sub_tlv_length ))
1031+                             return (-1 );
1032+                     }
1033+                     break ;
1034+ 
1035+                 default :
1036+                     if  (ndo -> ndo_vflag  <= 1 ) {
1037+                         if  (!print_unknown_data (ndo , sub_tlv_tptr , "\n\t      " , sub_tlv_length ))
1038+                             return (-1 );
1039+                     }
1040+                     break ;
1041+                 }
1042+ 
1043+                 if  (sub_tlv_length  % 4 ) {
1044+                     sub_tlv_length  +=  (4  -  (sub_tlv_length  % 4 ));
1045+                 }
1046+                 sub_tlv_tptr += sub_tlv_length ;
1047+                 sub_tlv_remaining -= sub_tlv_length ;
1048+             }
1049+             break ;
1050+ 	default :
1051+ 	    if  (ndo -> ndo_vflag  <= 1 ) {
1052+ 		if  (!print_unknown_data (ndo , tptr , "\n\t      " , tlv_length ))
1053+ 		    return  -1 ;
1054+ 	    }
1055+ 	}
1056+ 
1057+ 	/* in OSPF everything has to be 32-bit aligned, including TLVs */ 
1058+ 	if  (tlv_length  % 4 ) {
1059+ 	    tlv_length  +=  (4  -  (tlv_length  % 4 ));
1060+ 	}
1061+ 	tptr += tlv_length ;
1062+ 	lsa_length -= tlv_length ;
1063+     }
1064+     return  0 ;
1065+ }
1066+ 
9331067/* 
9341068 * Print a single link state advertisement.  If truncated or if LSA length 
9351069 * field is less than the length of the LSA header, return NULl, else 
@@ -1231,6 +1365,13 @@ ospf_print_lsa(netdissect_options *ndo,
12311365                }
12321366                break ;
12331367
1368+             case  LS_OPAQUE_TYPE_EL :
1369+                 if  (ospf_el_lsa_print (ndo , (const  u_char  * )(lsap -> lsa_un .un_el_tlv ),
1370+                                       ls_length ) ==  -1 ) {
1371+                     return (ls_end );
1372+                 }
1373+                 break ;
1374+ 
12341375            default :
12351376                if  (ndo -> ndo_vflag  <= 1 ) {
12361377                    if  (!print_unknown_data (ndo , (const  uint8_t  * )lsap -> lsa_un .un_unknown ,
0 commit comments