33
33
34
34
#include "netdissect-stdinc.h"
35
35
36
+ #define ND_LONGJMP_FROM_TCHECK
36
37
#include "netdissect.h"
37
38
#include "addrtoname.h"
38
39
#include "extract.h"
39
40
40
41
#include "ip6.h"
41
42
42
43
static 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 )
44
45
{
45
- int i ;
46
- int optlen ;
46
+ unsigned int i , opttype , optlen ;
47
47
48
48
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 )
50
51
optlen = 1 ;
51
52
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 ;
56
56
}
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 ) ;
59
59
60
- switch (GET_U_1 ( bp + i ) ) {
60
+ switch (opttype ) {
61
61
case IP6OPT_PAD1 :
62
62
ND_PRINT (", pad1" );
63
63
break ;
64
64
case IP6OPT_PADN :
65
- if (len - i < IP6OPT_MINLEN ) {
66
- ND_PRINT (", padn: trunc" );
67
- goto trunc ;
68
- }
69
65
ND_PRINT (", padn" );
70
66
break ;
71
67
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 );
78
69
break ;
79
70
}
80
71
}
81
72
return 0 ;
82
73
83
- trunc :
74
+ invalid :
84
75
return -1 ;
85
76
}
86
77
87
78
static 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 ,
89
80
int * found_jumbop , uint32_t * payload_len )
90
81
{
91
- int i ;
92
- int optlen = 0 ;
82
+ unsigned int i , opttype , optlen ;
93
83
int found_jumbo = 0 ;
94
84
uint32_t jumbolen = 0 ;
95
85
96
86
if (len == 0 )
97
87
return 0 ;
98
88
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 )
100
91
optlen = 1 ;
101
92
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 ;
106
96
}
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 ) ;
109
99
110
- switch (GET_U_1 ( bp + i ) ) {
100
+ switch (opttype ) {
111
101
case IP6OPT_PAD1 :
112
102
if (ndo -> ndo_vflag )
113
103
ND_PRINT ("(pad1)" );
114
104
break ;
115
105
case IP6OPT_PADN :
116
- if (len - i < IP6OPT_MINLEN ) {
117
- ND_PRINT ("(padn: trunc)" );
118
- goto trunc ;
119
- }
120
106
if (ndo -> ndo_vflag )
121
107
ND_PRINT ("(padn)" );
122
108
break ;
123
109
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 );
132
114
if (ndo -> ndo_vflag )
133
115
ND_PRINT ("(rtalert: 0x%04x) " , GET_BE_U_2 (bp + i + 2 ));
134
116
break ;
135
117
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 );
144
122
jumbolen = GET_BE_U_4 (bp + i + 2 );
145
123
if (found_jumbo ) {
146
124
/* More than one Jumbo Payload option */
@@ -176,40 +154,31 @@ ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
176
154
}
177
155
break ;
178
156
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 );
187
161
if (ndo -> ndo_vflag ) {
188
162
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 ) {
190
164
if (ip6_sopt_print (ndo , bp + i + IP6OPT_HOMEADDR_MINLEN ,
191
165
(optlen - IP6OPT_HOMEADDR_MINLEN )) == -1 )
192
- goto trunc ;
166
+ goto invalid ;
193
167
}
194
168
ND_PRINT (")" );
195
169
}
196
170
break ;
197
171
default :
198
- if (len - i < IP6OPT_MINLEN ) {
199
- ND_PRINT ("(type %u: trunc)" , GET_U_1 (bp + i ));
200
- goto trunc ;
201
- }
202
172
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 );
205
174
break ;
206
175
}
207
176
}
208
177
if (ndo -> ndo_vflag )
209
178
ND_PRINT (" " );
210
179
return 0 ;
211
180
212
- trunc :
181
+ invalid :
213
182
return -1 ;
214
183
}
215
184
@@ -227,11 +196,11 @@ hbhopt_process(netdissect_options *ndo, const u_char *bp, int *found_jumbo,
227
196
ND_PRINT (" " );
228
197
if (ip6_opt_process (ndo , (const u_char * )dp + sizeof (* dp ),
229
198
hbhlen - sizeof (* dp ), found_jumbo , jumbolen ) == -1 )
230
- goto trunc ;
199
+ goto invalid ;
231
200
return hbhlen ;
232
201
233
- trunc :
234
- nd_print_trunc (ndo );
202
+ invalid :
203
+ nd_print_invalid (ndo );
235
204
return -1 ;
236
205
}
237
206
@@ -254,12 +223,12 @@ dstopt_process(netdissect_options *ndo, const u_char *bp)
254
223
*/
255
224
if (ip6_opt_process (ndo , (const u_char * )dp + sizeof (* dp ),
256
225
dstoptlen - sizeof (* dp ), NULL , NULL ) == -1 )
257
- goto trunc ;
226
+ goto invalid ;
258
227
}
259
228
260
229
return dstoptlen ;
261
230
262
- trunc :
263
- nd_print_trunc (ndo );
231
+ invalid :
232
+ nd_print_invalid (ndo );
264
233
return -1 ;
265
234
}
0 commit comments