3333
3434#include "netdissect-stdinc.h"
3535
36+ #define ND_LONGJMP_FROM_TCHECK
3637#include "netdissect.h"
3738#include "addrtoname.h"
3839#include "extract.h"
3940
4041#include "ip6.h"
4142
4243static int
43- ip6_sopt_print (netdissect_options * ndo , const u_char * bp , int len )
44+ ip6_sopt_print (netdissect_options * ndo , const u_char * bp , const u_int len )
4445{
45- int i ;
46- int optlen ;
46+ unsigned int i , opttype , optlen ;
4747
4848 for (i = 0 ; i < len ; i += optlen ) {
49- if (GET_U_1 (bp + i ) == IP6OPT_PAD1 )
49+ opttype = GET_U_1 (bp + i );
50+ if (opttype == IP6OPT_PAD1 )
5051 optlen = 1 ;
5152 else {
52- if (i + 1 < len )
53- optlen = GET_U_1 (bp + i + 1 ) + 2 ;
54- else
55- goto trunc ;
53+ ND_ICHECKMSG_U ("remaining length" , (u_int )(len - i ), < ,
54+ IP6OPT_MINLEN );
55+ optlen = GET_U_1 (bp + i + 1 ) + 2 ;
5656 }
57- if ( i + optlen > len )
58- goto trunc ;
57+ ND_ICHECKMSG_U ( "remaining length" , ( u_int )( len - i ), < , optlen );
58+ ND_TCHECK_LEN ( bp + i , optlen ) ;
5959
60- switch (GET_U_1 ( bp + i ) ) {
60+ switch (opttype ) {
6161 case IP6OPT_PAD1 :
6262 ND_PRINT (", pad1" );
6363 break ;
6464 case IP6OPT_PADN :
65- if (len - i < IP6OPT_MINLEN ) {
66- ND_PRINT (", padn: trunc" );
67- goto trunc ;
68- }
6965 ND_PRINT (", padn" );
7066 break ;
7167 default :
72- if (len - i < IP6OPT_MINLEN ) {
73- ND_PRINT (", sopt_type %u: trunc)" , GET_U_1 (bp + i ));
74- goto trunc ;
75- }
76- ND_PRINT (", sopt_type 0x%02x: len=%u" , GET_U_1 (bp + i ),
77- GET_U_1 (bp + i + 1 ));
68+ ND_PRINT (", unknown subopt-type 0x%02x len=%u" , opttype , optlen - 2 );
7869 break ;
7970 }
8071 }
8172 return 0 ;
8273
83- trunc :
74+ invalid :
8475 return -1 ;
8576}
8677
8778static int
88- ip6_opt_process (netdissect_options * ndo , const u_char * bp , int len ,
79+ ip6_opt_process (netdissect_options * ndo , const u_char * bp , const u_int len ,
8980 int * found_jumbop , uint32_t * payload_len )
9081{
91- int i ;
92- int optlen = 0 ;
82+ unsigned int i , opttype , optlen ;
9383 int found_jumbo = 0 ;
9484 uint32_t jumbolen = 0 ;
9585
9686 if (len == 0 )
9787 return 0 ;
9888 for (i = 0 ; i < len ; i += optlen ) {
99- if (GET_U_1 (bp + i ) == IP6OPT_PAD1 )
89+ opttype = GET_U_1 (bp + i );
90+ if (opttype == IP6OPT_PAD1 )
10091 optlen = 1 ;
10192 else {
102- if (i + 1 < len )
103- optlen = GET_U_1 (bp + i + 1 ) + 2 ;
104- else
105- goto trunc ;
93+ ND_ICHECKMSG_U ("remaining length" , (u_int )(len - i ), < ,
94+ IP6OPT_MINLEN );
95+ optlen = GET_U_1 (bp + i + 1 ) + 2 ;
10696 }
107- if ( i + optlen > len )
108- goto trunc ;
97+ ND_ICHECKMSG_U ( "remaining length" , ( u_int )( len - i ), < , optlen );
98+ ND_TCHECK_LEN ( bp + i , optlen ) ;
10999
110- switch (GET_U_1 ( bp + i ) ) {
100+ switch (opttype ) {
111101 case IP6OPT_PAD1 :
112102 if (ndo -> ndo_vflag )
113103 ND_PRINT ("(pad1)" );
114104 break ;
115105 case IP6OPT_PADN :
116- if (len - i < IP6OPT_MINLEN ) {
117- ND_PRINT ("(padn: trunc)" );
118- goto trunc ;
119- }
120106 if (ndo -> ndo_vflag )
121107 ND_PRINT ("(padn)" );
122108 break ;
123109 case IP6OPT_ROUTER_ALERT :
124- if (len - i < IP6OPT_RTALERT_LEN ) {
125- ND_PRINT ("(rtalert: trunc)" );
126- goto trunc ;
127- }
128- if (GET_U_1 (bp + i + 1 ) != IP6OPT_RTALERT_LEN - 2 ) {
129- ND_PRINT ("(rtalert: invalid len %u)" , GET_U_1 (bp + i + 1 ));
130- goto trunc ;
131- }
110+ ND_ICHECKMSG_U ("(rtalert) remaining length" , (u_int )(len - i ), < ,
111+ IP6OPT_RTALERT_LEN );
112+ ND_ICHECKMSG_U ("(rtalert) length" , optlen - 2 , != ,
113+ IP6OPT_RTALERT_LEN - 2 );
132114 if (ndo -> ndo_vflag )
133115 ND_PRINT ("(rtalert: 0x%04x) " , GET_BE_U_2 (bp + i + 2 ));
134116 break ;
135117 case IP6OPT_JUMBO :
136- if (len - i < IP6OPT_JUMBO_LEN ) {
137- ND_PRINT ("(jumbo: trunc)" );
138- goto trunc ;
139- }
140- if (GET_U_1 (bp + i + 1 ) != IP6OPT_JUMBO_LEN - 2 ) {
141- ND_PRINT ("(jumbo: invalid len %u)" , GET_U_1 (bp + i + 1 ));
142- goto trunc ;
143- }
118+ ND_ICHECKMSG_U ("(jumbo) remaining length" , (u_int )(len - i ), < ,
119+ IP6OPT_JUMBO_LEN );
120+ ND_ICHECKMSG_U ("(jumbo) length" , optlen - 2 , != ,
121+ IP6OPT_JUMBO_LEN - 2 );
144122 jumbolen = GET_BE_U_4 (bp + i + 2 );
145123 if (found_jumbo ) {
146124 /* More than one Jumbo Payload option */
@@ -176,40 +154,31 @@ ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
176154 }
177155 break ;
178156 case IP6OPT_HOME_ADDRESS :
179- if (len - i < IP6OPT_HOMEADDR_MINLEN ) {
180- ND_PRINT ("(homeaddr: trunc)" );
181- goto trunc ;
182- }
183- if (GET_U_1 (bp + i + 1 ) < IP6OPT_HOMEADDR_MINLEN - 2 ) {
184- ND_PRINT ("(homeaddr: invalid len %u)" , GET_U_1 (bp + i + 1 ));
185- goto trunc ;
186- }
157+ ND_ICHECKMSG_U ("(homeaddr) remaining length" , (u_int )(len - i ), < ,
158+ IP6OPT_HOMEADDR_MINLEN );
159+ ND_ICHECKMSG_U ("(homeaddr) length" , optlen - 2 , < ,
160+ IP6OPT_HOMEADDR_MINLEN - 2 );
187161 if (ndo -> ndo_vflag ) {
188162 ND_PRINT ("(homeaddr: %s" , GET_IP6ADDR_STRING (bp + i + 2 ));
189- if (GET_U_1 ( bp + i + 1 ) > IP6OPT_HOMEADDR_MINLEN - 2 ) {
163+ if (optlen > IP6OPT_HOMEADDR_MINLEN ) {
190164 if (ip6_sopt_print (ndo , bp + i + IP6OPT_HOMEADDR_MINLEN ,
191165 (optlen - IP6OPT_HOMEADDR_MINLEN )) == -1 )
192- goto trunc ;
166+ goto invalid ;
193167 }
194168 ND_PRINT (")" );
195169 }
196170 break ;
197171 default :
198- if (len - i < IP6OPT_MINLEN ) {
199- ND_PRINT ("(type %u: trunc)" , GET_U_1 (bp + i ));
200- goto trunc ;
201- }
202172 if (ndo -> ndo_vflag )
203- ND_PRINT ("(opt_type 0x%02x: len=%u)" , GET_U_1 (bp + i ),
204- GET_U_1 (bp + i + 1 ));
173+ ND_PRINT ("(unknown opt-type 0x%02x len=%u)" , opttype , optlen - 2 );
205174 break ;
206175 }
207176 }
208177 if (ndo -> ndo_vflag )
209178 ND_PRINT (" " );
210179 return 0 ;
211180
212- trunc :
181+ invalid :
213182 return -1 ;
214183}
215184
@@ -227,11 +196,11 @@ hbhopt_process(netdissect_options *ndo, const u_char *bp, int *found_jumbo,
227196 ND_PRINT (" " );
228197 if (ip6_opt_process (ndo , (const u_char * )dp + sizeof (* dp ),
229198 hbhlen - sizeof (* dp ), found_jumbo , jumbolen ) == -1 )
230- goto trunc ;
199+ goto invalid ;
231200 return hbhlen ;
232201
233- trunc :
234- nd_print_trunc (ndo );
202+ invalid :
203+ nd_print_invalid (ndo );
235204 return -1 ;
236205}
237206
@@ -254,12 +223,12 @@ dstopt_process(netdissect_options *ndo, const u_char *bp)
254223 */
255224 if (ip6_opt_process (ndo , (const u_char * )dp + sizeof (* dp ),
256225 dstoptlen - sizeof (* dp ), NULL , NULL ) == -1 )
257- goto trunc ;
226+ goto invalid ;
258227 }
259228
260229 return dstoptlen ;
261230
262- trunc :
263- nd_print_trunc (ndo );
231+ invalid :
232+ nd_print_invalid (ndo );
264233 return -1 ;
265234}
0 commit comments