1
- /* $OpenBSD: ip_ipip.c,v 1.79 2017/05/26 15:56:51 bluhm Exp $ */
1
+ /* $OpenBSD: ip_ipip.c,v 1.80 2017/05/26 16:27:25 bluhm Exp $ */
2
2
/*
3
3
* The authors of this code are John Ioannidis ([email protected] ),
4
4
* Angelos D. Keromytis ([email protected] ) and
@@ -120,11 +120,10 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
120
120
struct ifnet * gifp )
121
121
{
122
122
struct mbuf * m = * mp ;
123
- int iphlen = * offp ;
124
123
struct sockaddr_in * sin ;
125
124
struct ifnet * ifp ;
126
125
struct niqueue * ifq = NULL ;
127
- struct ip * ipo ;
126
+ struct ip * ip ;
128
127
#ifdef INET6
129
128
struct sockaddr_in6 * sin6 ;
130
129
struct ip6_hdr * ip6 ;
@@ -160,8 +159,8 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
160
159
/* Keep outer ecn field. */
161
160
switch (oaf ) {
162
161
case AF_INET :
163
- ipo = mtod (m , struct ip * );
164
- otos = ipo -> ip_tos ;
162
+ ip = mtod (m , struct ip * );
163
+ otos = ip -> ip_tos ;
165
164
break ;
166
165
#ifdef INET6
167
166
case AF_INET6 :
@@ -172,14 +171,13 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
172
171
}
173
172
174
173
/* Remove outer IP header */
175
- m_adj (m , iphlen );
176
-
177
- /* Sanity check */
178
- if (m -> m_pkthdr .len < sizeof (struct ip )) {
179
- ipipstat_inc (ipips_hdrops );
180
- m_freem (m );
181
- return IPPROTO_DONE ;
182
- }
174
+ KASSERT (* offp > 0 );
175
+ m_adj (m , * offp );
176
+ * offp = 0 ;
177
+ ip = NULL ;
178
+ #ifdef INET6
179
+ ip6 = NULL ;
180
+ #endif
183
181
184
182
switch (proto ) {
185
183
case IPPROTO_IPV4 :
@@ -197,6 +195,13 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
197
195
return IPPROTO_DONE ;
198
196
}
199
197
198
+ /* Sanity check */
199
+ if (m -> m_pkthdr .len < hlen ) {
200
+ ipipstat_inc (ipips_hdrops );
201
+ m_freem (m );
202
+ return IPPROTO_DONE ;
203
+ }
204
+
200
205
/*
201
206
* Bring the inner header into the first mbuf, if not there already.
202
207
*/
@@ -217,31 +222,30 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
217
222
/* Some sanity checks in the inner IP header */
218
223
switch (proto ) {
219
224
case IPPROTO_IPV4 :
220
- ipo = mtod (m , struct ip * );
221
- #ifdef INET6
222
- ip6 = NULL ;
223
- #endif
224
- itos = ipo -> ip_tos ;
225
+ ip = mtod (m , struct ip * );
226
+ hlen = ip -> ip_hl << 2 ;
227
+ if (m -> m_pkthdr .len < hlen ) {
228
+ ipipstat_inc (ipips_hdrops );
229
+ m_freem (m );
230
+ return IPPROTO_DONE ;
231
+ }
232
+ itos = ip -> ip_tos ;
225
233
mode = m -> m_flags & (M_AUTH |M_CONF ) ?
226
234
ECN_ALLOWED_IPSEC : ECN_ALLOWED ;
227
- if (!ip_ecn_egress (mode , & otos , & ipo -> ip_tos )) {
235
+ if (!ip_ecn_egress (mode , & otos , & ip -> ip_tos )) {
228
236
DPRINTF (("%s: ip_ecn_egress() failed\n" , __func__ ));
229
237
ipipstat_inc (ipips_pdrops );
230
238
m_freem (m );
231
239
return IPPROTO_DONE ;
232
240
}
233
241
/* re-calculate the checksum if ip_tos was changed */
234
- if (itos != ipo -> ip_tos ) {
235
- hlen = ipo -> ip_hl << 2 ;
236
- if (m -> m_pkthdr .len >= hlen ) {
237
- ipo -> ip_sum = 0 ;
238
- ipo -> ip_sum = in_cksum (m , hlen );
239
- }
242
+ if (itos != ip -> ip_tos ) {
243
+ ip -> ip_sum = 0 ;
244
+ ip -> ip_sum = in_cksum (m , hlen );
240
245
}
241
246
break ;
242
247
#ifdef INET6
243
248
case IPPROTO_IPV6 :
244
- ipo = NULL ;
245
249
ip6 = mtod (m , struct ip6_hdr * );
246
250
itos = (ntohl (ip6 -> ip6_flow ) >> 20 ) & 0xff ;
247
251
if (!ip_ecn_egress (ECN_ALLOWED , & otos , & itos )) {
@@ -253,11 +257,6 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
253
257
ip6 -> ip6_flow &= ~htonl (0xff << 20 );
254
258
ip6 -> ip6_flow |= htonl ((u_int32_t ) itos << 20 );
255
259
break ;
256
- #endif
257
- default :
258
- ipo = NULL ;
259
- #ifdef INET6
260
- ip6 = NULL ;
261
260
#endif
262
261
}
263
262
@@ -272,11 +271,11 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
272
271
273
272
memset (& ss , 0 , sizeof (ss ));
274
273
275
- if (ipo ) {
274
+ if (ip ) {
276
275
sin = (struct sockaddr_in * )& ss ;
277
276
sin -> sin_family = AF_INET ;
278
277
sin -> sin_len = sizeof (* sin );
279
- sin -> sin_addr = ipo -> ip_src ;
278
+ sin -> sin_addr = ip -> ip_src ;
280
279
#ifdef INET6
281
280
} else if (ip6 ) {
282
281
sin6 = (struct sockaddr_in6 * )& ss ;
@@ -298,7 +297,7 @@ ipip_input_gif(struct mbuf **mp, int *offp, int proto, int oaf,
298
297
}
299
298
300
299
/* Statistics */
301
- ipipstat_add (ipips_ibytes , m -> m_pkthdr .len - iphlen );
300
+ ipipstat_add (ipips_ibytes , m -> m_pkthdr .len - hlen );
302
301
303
302
/*
304
303
* Interface pointer stays the same; if no IPsec processing has
0 commit comments