@@ -101,15 +101,56 @@ static const struct tok lsa_opaque_values[] = {
101
101
{ LS_OPAQUE_TYPE_TE , "Traffic Engineering" },
102
102
{ LS_OPAQUE_TYPE_GRACE , "Graceful restart" },
103
103
{ LS_OPAQUE_TYPE_RI , "Router Information" },
104
+ { LS_OPAQUE_TYPE_EP , "Extended Prefix" },
104
105
{ 0 , NULL }
105
106
};
106
107
108
+ static const struct tok lsa_opaque_ri_sid_subtlv_values [] = {
109
+ { LS_OPAQUE_RI_SUBTLV_SID_LABEL , "SID/Label" },
110
+ { 0 , NULL }
111
+ };
112
+
107
113
static const struct tok lsa_opaque_te_tlv_values [] = {
108
114
{ LS_OPAQUE_TE_TLV_ROUTER , "Router Address" },
109
115
{ LS_OPAQUE_TE_TLV_LINK , "Link" },
110
116
{ 0 , NULL }
111
117
};
112
118
119
+ static const struct tok lsa_opaque_ep_extd_prefix_subtlv_values [] = {
120
+ { LS_OPAQUE_EP_SUBTLV_PREFIX_SID , "Prefix-SID" },
121
+ { 0 , NULL }
122
+ };
123
+
124
+ static const struct tok ep_range_tlv_prefix_sid_subtlv_flag_values [] = {
125
+ { 0x40 , "No-PHP" },
126
+ { 0x20 , "Mapping-Server" },
127
+ { 0x10 , "Explicit-NULL" },
128
+ { 0x08 , "Value" },
129
+ { 0x04 , "Local" },
130
+ { 0 , NULL }
131
+ };
132
+
133
+
134
+ static const struct tok lsa_opaque_ep_route_type_values [] = {
135
+ { 0 , "Unspecified" },
136
+ { 1 , "Intra-Area" },
137
+ { 3 , "Inter-Area" },
138
+ { 5 , "AS External" },
139
+ { 7 , "NSSA External" },
140
+ { 0 , NULL }
141
+ };
142
+
143
+ static const struct tok lsa_opaque_ep_tlv_values [] = {
144
+ { LS_OPAQUE_EP_EXTD_PREFIX_TLV , "Extended Prefix" },
145
+ { LS_OPAQUE_EP_EXTD_PREFIX_RANGE_TLV , "Extended Prefix Range" },
146
+ { 0 , NULL }
147
+ };
148
+
149
+ static const struct tok ep_tlv_flag_values [] = {
150
+ { 0x80 , "Inter-Area" },
151
+ { 0 , NULL }
152
+ };
153
+
113
154
static const struct tok lsa_opaque_te_link_tlv_subtlv_values [] = {
114
155
{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE , "Link Type" },
115
156
{ LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID , "Link ID" },
@@ -151,6 +192,8 @@ static const struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
151
192
152
193
static const struct tok lsa_opaque_ri_tlv_values [] = {
153
194
{ LS_OPAQUE_RI_TLV_CAP , "Router Capabilities" },
195
+ { LS_OPAQUE_RI_TLV_HOSTNAME , "Hostname" },
196
+ { LS_OPAQUE_RI_TLV_SID_LABEL_RANGE , "SID/Label Range" },
154
197
{ 0 , NULL }
155
198
};
156
199
@@ -211,6 +254,7 @@ ospf_grace_lsa_print(netdissect_options *ndo,
211
254
212
255
/* Infinite loop protection. */
213
256
if (tlv_type == 0 || tlv_length == 0 ) {
257
+ nd_print_invalid (ndo );
214
258
return -1 ;
215
259
}
216
260
@@ -298,6 +342,7 @@ ospf_te_lsa_print(netdissect_options *ndo,
298
342
299
343
/* Infinite loop protection. */
300
344
if (tlv_type == 0 || tlv_length == 0 ) {
345
+ nd_print_invalid (ndo );
301
346
return -1 ;
302
347
}
303
348
@@ -611,6 +656,218 @@ ospf_print_tos_metrics(netdissect_options *ndo,
611
656
}
612
657
}
613
658
659
+ static int
660
+ ospf_print_ri_lsa_sid_label_range_tlv (netdissect_options * ndo , const uint8_t * tptr ,
661
+ u_int tlv_length )
662
+ {
663
+ u_int subtlv_type , subtlv_length ;
664
+
665
+ while (tlv_length >= 4 ) {
666
+
667
+ subtlv_type = GET_BE_U_2 (tptr );
668
+ subtlv_length = GET_BE_U_2 (tptr + 2 );
669
+ tptr += 4 ;
670
+ tlv_length -= 4 ;
671
+
672
+ /* Infinite loop protection. */
673
+ if (subtlv_type == 0 || subtlv_length == 0 ) {
674
+ nd_print_invalid (ndo );
675
+ return -1 ;
676
+ }
677
+
678
+ ND_PRINT ("\n\t %s subTLV (%u), length: %u, value: " ,
679
+ tok2str (lsa_opaque_ri_sid_subtlv_values ,"unknown" ,subtlv_type ),
680
+ subtlv_type ,
681
+ subtlv_length );
682
+
683
+ switch (subtlv_type ) {
684
+ case LS_OPAQUE_RI_SUBTLV_SID_LABEL :
685
+ if (subtlv_length == 3 ) {
686
+ ND_PRINT ("\n\t\tLabel: %u" , GET_BE_U_3 (tptr ));
687
+ } else if (subtlv_length == 4 ) {
688
+ ND_PRINT ("\n\t\tSID: %u" , GET_BE_U_4 (tptr ));
689
+ } else {
690
+ ND_PRINT ("\n\t\tBogus subTLV length %u" , subtlv_length );
691
+ }
692
+ break ;
693
+
694
+ default :
695
+ if (ndo -> ndo_vflag <= 1 ) {
696
+ if (!print_unknown_data (ndo , tptr , "\n\t\t" , subtlv_length ))
697
+ return -1 ;
698
+ }
699
+ }
700
+
701
+ /* in OSPF everything has to be 32-bit aligned, including subTLVs */
702
+ if (subtlv_length % 4 ) {
703
+ subtlv_length += (4 - (subtlv_length % 4 ));
704
+ }
705
+ tptr += subtlv_length ;
706
+ tlv_length -= subtlv_length ;
707
+ }
708
+ return 0 ;
709
+ }
710
+
711
+ static int
712
+ ospf_print_ep_lsa_extd_prefix_tlv (netdissect_options * ndo , const uint8_t * tptr ,
713
+ u_int tlv_length )
714
+ {
715
+ u_int subtlv_type , subtlv_length ;
716
+ uint8_t flags , mt_id , algo ;
717
+
718
+ while (tlv_length >= 4 ) {
719
+ subtlv_type = GET_BE_U_2 (tptr );
720
+ subtlv_length = GET_BE_U_2 (tptr + 2 );
721
+ tptr += 4 ;
722
+ tlv_length -= 4 ;
723
+
724
+ /* Infinite loop protection. */
725
+ if (subtlv_type == 0 || subtlv_length == 0 ) {
726
+ nd_print_invalid (ndo );
727
+ return -1 ;
728
+ }
729
+
730
+ ND_PRINT ("\n\t\t%s subTLV (%u), length: %u, value: " ,
731
+ tok2str (lsa_opaque_ep_extd_prefix_subtlv_values ,"unknown" ,subtlv_type ),
732
+ subtlv_type ,
733
+ subtlv_length );
734
+
735
+ switch (subtlv_type ) {
736
+ case LS_OPAQUE_EP_SUBTLV_PREFIX_SID :
737
+ flags = GET_U_1 (tptr );
738
+ mt_id = GET_U_1 (tptr + 2 );
739
+ algo = GET_U_1 (tptr + 3 );
740
+
741
+ if (subtlv_length == 7 ) {
742
+ ND_PRINT ("\n\t\t Label: %u, MT-ID: %u, Algorithm: %u" ,
743
+ GET_BE_U_3 (tptr + 4 ), mt_id , algo );
744
+ } else if (subtlv_length == 8 ) {
745
+ ND_PRINT ("\n\t\t Index: %u, MT-ID: %u, Algorithm: %u, Flags [%s]" ,
746
+ GET_BE_U_4 (tptr + 4 ), mt_id , algo ,
747
+ bittok2str (ep_range_tlv_prefix_sid_subtlv_flag_values , "none" , flags ));
748
+ } else {
749
+ ND_PRINT ("\n\t\tBogus subTLV length %u" , subtlv_length );
750
+ }
751
+ break ;
752
+
753
+ default :
754
+ if (ndo -> ndo_vflag <= 1 ) {
755
+ if (!print_unknown_data (ndo , tptr , "\n\t\t" , subtlv_length ))
756
+ return -1 ;
757
+ }
758
+ }
759
+
760
+ /* in OSPF everything has to be 32-bit aligned, including subTLVs */
761
+ if (subtlv_length % 4 ) {
762
+ subtlv_length += (4 - (subtlv_length % 4 ));
763
+ }
764
+ tptr += subtlv_length ;
765
+ tlv_length -= subtlv_length ;
766
+ }
767
+ return 0 ;
768
+ }
769
+
770
+ static int
771
+ ospf_ep_lsa_print (netdissect_options * ndo , const uint8_t * tptr , u_int lsa_length )
772
+ {
773
+ u_int tlv_type , tlv_length ;
774
+ uint16_t range_size ;
775
+ uint8_t af , prefix_length , route_type , flags ;
776
+
777
+ while (lsa_length >= 4 ) {
778
+
779
+ tlv_type = GET_BE_U_2 (tptr );
780
+ tlv_length = GET_BE_U_2 (tptr + 2 );
781
+ tptr += 4 ;
782
+ lsa_length -= 4 ;
783
+
784
+ /* Infinite loop protection. */
785
+ if (tlv_type == 0 || tlv_length == 0 ) {
786
+ nd_print_invalid (ndo );
787
+ return -1 ;
788
+ }
789
+
790
+ ND_PRINT ("\n\t %s TLV (%u), length: %u, value: " ,
791
+ tok2str (lsa_opaque_ep_tlv_values ,"unknown" ,tlv_type ),
792
+ tlv_type ,
793
+ tlv_length );
794
+
795
+ switch (tlv_type ) {
796
+ case LS_OPAQUE_EP_EXTD_PREFIX_TLV :
797
+ prefix_length = GET_U_1 (tptr + 1 );
798
+ af = GET_U_1 (tptr + 2 );
799
+ route_type = GET_U_1 (tptr );
800
+ flags = GET_U_1 (tptr + 3 );
801
+
802
+ if (af != 0 ) {
803
+ ND_PRINT ("\n\t Bogus AF %u" , af );
804
+ return -1 ;
805
+ }
806
+
807
+ if (prefix_length > 32 ) {
808
+ ND_PRINT ("\n\t IPv4 prefix: bad bit length %u" , prefix_length );
809
+ return -1 ;
810
+ }
811
+
812
+ ND_PRINT ("\n\t IPv4 prefix: %15s/%u, Route Type: %s, Flags [%s]" ,
813
+ GET_IPADDR_STRING (tptr + 4 ), prefix_length ,
814
+ tok2str (lsa_opaque_ep_route_type_values , "Unknown" , route_type ),
815
+ bittok2str (ep_tlv_flag_values , "none" , flags ));
816
+
817
+ /* subTLVs present ? */
818
+ if (tlv_length > 12 ) {
819
+ if (ospf_print_ep_lsa_extd_prefix_tlv (ndo , tptr + 8 , tlv_length - 8 ) == -1 ) {
820
+ return -1 ;
821
+ }
822
+ }
823
+ break ;
824
+
825
+ case LS_OPAQUE_EP_EXTD_PREFIX_RANGE_TLV :
826
+ prefix_length = GET_U_1 (tptr );
827
+ af = GET_U_1 (tptr + 1 );
828
+ range_size = GET_BE_U_2 (tptr + 2 );
829
+ flags = GET_U_1 (tptr + 4 );
830
+
831
+ if (af != 0 ) {
832
+ ND_PRINT ("\n\t Bogus AF %u" , af );
833
+ return -1 ;
834
+ }
835
+
836
+ if (prefix_length > 32 ) {
837
+ ND_PRINT ("\n\t IPv4 prefix: bad bit length %u" , prefix_length );
838
+ return -1 ;
839
+ }
840
+
841
+ ND_PRINT ("\n\t IPv4 prefix: %15s/%u, Range size: %u, Flags [%s]" ,
842
+ GET_IPADDR_STRING (tptr + 8 ), prefix_length ,
843
+ range_size ,
844
+ bittok2str (ep_tlv_flag_values , "none" , flags ));
845
+
846
+ /* subTLVs present ? */
847
+ if (tlv_length > 12 ) {
848
+ if (ospf_print_ep_lsa_extd_prefix_tlv (ndo , tptr + 12 , tlv_length - 12 ) == -1 ) {
849
+ return -1 ;
850
+ }
851
+ }
852
+ break ;
853
+
854
+ default :
855
+ if (ndo -> ndo_vflag <= 1 ) {
856
+ if (!print_unknown_data (ndo , tptr , "\n\t\t" , tlv_length ))
857
+ return -1 ;
858
+ }
859
+ }
860
+
861
+ /* in OSPF everything has to be 32-bit aligned, including TLVs */
862
+ if (tlv_length % 4 ) {
863
+ tlv_length += (4 - (tlv_length % 4 ));
864
+ }
865
+ tptr += tlv_length ;
866
+ lsa_length -= tlv_length ;
867
+ }
868
+ return 0 ;
869
+ }
870
+
614
871
/*
615
872
* Print a single link state advertisement. If truncated or if LSA length
616
873
* field is less than the length of the LSA header, return NULl, else
@@ -836,6 +1093,20 @@ ospf_print_lsa(netdissect_options *ndo,
836
1093
ND_PRINT ("Capabilities: %s" ,
837
1094
bittok2str (lsa_opaque_ri_tlv_cap_values , "Unknown" , GET_BE_U_4 (tptr )));
838
1095
break ;
1096
+
1097
+ case LS_OPAQUE_RI_TLV_HOSTNAME :
1098
+ ND_PRINT ("\n\t Hostname: " );
1099
+ nd_printjnp (ndo , tptr , tlv_length );
1100
+ break ;
1101
+
1102
+ case LS_OPAQUE_RI_TLV_SID_LABEL_RANGE :
1103
+ ND_TCHECK_4 (tptr );
1104
+ ND_PRINT ("\n\t Range size: %u" , GET_BE_U_3 (tptr ));
1105
+ if (ospf_print_ri_lsa_sid_label_range_tlv (ndo , tptr + 4 , tlv_length - 4 ) == -1 ) {
1106
+ return (ls_end );
1107
+ }
1108
+ break ;
1109
+
839
1110
default :
840
1111
if (ndo -> ndo_vflag <= 1 ) {
841
1112
if (!print_unknown_data (ndo , tptr , "\n\t " , tlv_length ))
@@ -844,6 +1115,11 @@ ospf_print_lsa(netdissect_options *ndo,
844
1115
break ;
845
1116
846
1117
}
1118
+
1119
+ /* in OSPF everything has to be 32-bit aligned, including TLVs */
1120
+ if (tlv_length % 4 ) {
1121
+ tlv_length += (4 - (tlv_length % 4 ));
1122
+ }
847
1123
tptr += tlv_length ;
848
1124
ls_length_remaining -= tlv_length ;
849
1125
}
@@ -863,6 +1139,13 @@ ospf_print_lsa(netdissect_options *ndo,
863
1139
}
864
1140
break ;
865
1141
1142
+ case LS_OPAQUE_TYPE_EP :
1143
+ if (ospf_ep_lsa_print (ndo , (const u_char * )(lsap -> lsa_un .un_ep_tlv ),
1144
+ ls_length ) == -1 ) {
1145
+ return (ls_end );
1146
+ }
1147
+ break ;
1148
+
866
1149
default :
867
1150
if (ndo -> ndo_vflag <= 1 ) {
868
1151
if (!print_unknown_data (ndo , (const uint8_t * )lsap -> lsa_un .un_unknown ,
0 commit comments