@@ -217,6 +217,33 @@ static const struct tok lsa_opaque_ri_tlv_sr_algos[] = {
217
217
{ 0 , NULL }
218
218
};
219
219
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
+
220
247
static const struct tok ospf_lls_tlv_values [] = {
221
248
{ OSPF_LLS_EO , "Extended Options" },
222
249
{ OSPF_LLS_MD5 , "MD5 Authentication" },
@@ -930,6 +957,113 @@ ospf_ep_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length
930
957
return 0 ;
931
958
}
932
959
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
+
933
1067
/*
934
1068
* Print a single link state advertisement. If truncated or if LSA length
935
1069
* field is less than the length of the LSA header, return NULl, else
@@ -1231,6 +1365,13 @@ ospf_print_lsa(netdissect_options *ndo,
1231
1365
}
1232
1366
break ;
1233
1367
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
+
1234
1375
default :
1235
1376
if (ndo -> ndo_vflag <= 1 ) {
1236
1377
if (!print_unknown_data (ndo , (const uint8_t * )lsap -> lsa_un .un_unknown ,
0 commit comments