This source file includes following definitions.
- ip4_input6
- ip4_input
- ipip_input
- ipip_output
- ipe4_attach
- ipe4_init
- ipe4_zeroize
- ipe4_input
- ipip_sysctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/mbuf.h>
45 #include <sys/socket.h>
46 #include <sys/sysctl.h>
47
48 #include <net/if.h>
49 #include <net/route.h>
50 #include <net/netisr.h>
51 #include <net/bpf.h>
52
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/ip.h>
56 #include <netinet/in_pcb.h>
57 #include <netinet/in_var.h>
58 #include <netinet/ip_var.h>
59 #include <netinet/ip_ecn.h>
60
61 #ifdef MROUTING
62 #include <netinet/ip_mroute.h>
63 #endif
64
65 #include <netinet/ip_ipsp.h>
66 #include <netinet/ip_ipip.h>
67
68 #include "bpfilter.h"
69
70 #ifdef ENCDEBUG
71 #define DPRINTF(x) if (encdebug) printf x
72 #else
73 #define DPRINTF(x)
74 #endif
75
76
77
78
79
80 int ipip_allow = 0;
81
82 struct ipipstat ipipstat;
83
84 #ifdef INET6
85
86
87
88 int
89 ip4_input6(struct mbuf **m, int *offp, int proto)
90 {
91
92 if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0) {
93 DPRINTF(("ip4_input6(): dropped due to policy\n"));
94 ipipstat.ipips_pdrops++;
95 m_freem(*m);
96 return IPPROTO_DONE;
97 }
98
99 ipip_input(*m, *offp, NULL);
100 return IPPROTO_DONE;
101 }
102 #endif
103
104 #ifdef INET
105
106
107
108 void
109 ip4_input(struct mbuf *m, ...)
110 {
111 va_list ap;
112 int iphlen;
113
114
115 if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
116 DPRINTF(("ip4_input(): dropped due to policy\n"));
117 ipipstat.ipips_pdrops++;
118 m_freem(m);
119 return;
120 }
121
122 va_start(ap, m);
123 iphlen = va_arg(ap, int);
124 va_end(ap);
125
126 ipip_input(m, iphlen, NULL);
127 }
128 #endif
129
130
131
132
133
134
135
136
137 void
138 ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
139 {
140 struct sockaddr_in *sin;
141 struct ifnet *ifp;
142 struct ifaddr *ifa;
143 struct ifqueue *ifq = NULL;
144 struct ip *ipo;
145 #ifdef INET6
146 struct sockaddr_in6 *sin6;
147 struct ip6_hdr *ip6 = NULL;
148 u_int8_t itos;
149 #endif
150 u_int8_t nxt;
151 int isr;
152 u_int8_t otos;
153 u_int8_t v;
154 int hlen, s;
155
156 ipipstat.ipips_ipackets++;
157
158 m_copydata(m, 0, 1, &v);
159
160 switch (v >> 4) {
161 #ifdef INET
162 case 4:
163 hlen = sizeof(struct ip);
164 break;
165 #endif
166 #ifdef INET6
167 case 6:
168 hlen = sizeof(struct ip6_hdr);
169 break;
170 #endif
171 default:
172 ipipstat.ipips_family++;
173 m_freem(m);
174 return ;
175 }
176
177
178 if (m->m_len < hlen) {
179 if ((m = m_pullup(m, hlen)) == NULL) {
180 DPRINTF(("ipip_input(): m_pullup() failed\n"));
181 ipipstat.ipips_hdrops++;
182 return;
183 }
184 }
185
186 ipo = mtod(m, struct ip *);
187
188
189 switch (v >> 4) {
190 #ifdef INET
191 case 4:
192 otos = ipo->ip_tos;
193 break;
194 #endif
195 #ifdef INET6
196 case 6:
197 otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
198 break;
199 #endif
200 default:
201 panic("ipip_input: should never reach here");
202 }
203
204
205 m_adj(m, iphlen);
206
207
208 if (m->m_pkthdr.len < sizeof(struct ip)) {
209 ipipstat.ipips_hdrops++;
210 m_freem(m);
211 return;
212 }
213
214 m_copydata(m, 0, 1, &v);
215
216 switch (v >> 4) {
217 #ifdef INET
218 case 4:
219 hlen = sizeof(struct ip);
220 break;
221 #endif
222
223 #ifdef INET6
224 case 6:
225 hlen = sizeof(struct ip6_hdr);
226 break;
227 #endif
228 default:
229 ipipstat.ipips_family++;
230 m_freem(m);
231 return;
232 }
233
234
235
236
237 if (m->m_len < hlen) {
238 if ((m = m_pullup(m, hlen)) == NULL) {
239 DPRINTF(("ipip_input(): m_pullup() failed\n"));
240 ipipstat.ipips_hdrops++;
241 return;
242 }
243 }
244
245
246
247
248
249
250
251
252 switch (v >> 4) {
253 #ifdef INET
254 case 4:
255 ipo = mtod(m, struct ip *);
256 nxt = ipo->ip_p;
257 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &ipo->ip_tos)) {
258 m_freem(m);
259 return;
260 }
261 break;
262 #endif
263 #ifdef INET6
264 case 6:
265 ip6 = (struct ip6_hdr *) ipo;
266 nxt = ip6->ip6_nxt;
267 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
268 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
269 m_freem(m);
270 return;
271 }
272 ip6->ip6_flow &= ~htonl(0xff << 20);
273 ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
274 break;
275 #endif
276 default:
277 panic("ipip_input: should never reach here");
278 }
279
280
281 if ((m->m_pkthdr.rcvif == NULL ||
282 !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
283 ipip_allow != 2) {
284 TAILQ_FOREACH(ifp, &ifnet, if_list) {
285 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
286 #ifdef INET
287 if (ipo) {
288 if (ifa->ifa_addr->sa_family !=
289 AF_INET)
290 continue;
291
292 sin = (struct sockaddr_in *) ifa->ifa_addr;
293
294 if (sin->sin_addr.s_addr ==
295 ipo->ip_src.s_addr) {
296 ipipstat.ipips_spoof++;
297 m_freem(m);
298 return;
299 }
300 }
301 #endif
302
303 #ifdef INET6
304 if (ip6) {
305 if (ifa->ifa_addr->sa_family !=
306 AF_INET6)
307 continue;
308
309 sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
310
311 if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) {
312 ipipstat.ipips_spoof++;
313 m_freem(m);
314 return;
315 }
316
317 }
318 #endif
319 }
320 }
321 }
322
323
324 ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
325
326
327
328
329
330
331
332
333
334 switch (v >> 4) {
335 #ifdef INET
336 case 4:
337 ifq = &ipintrq;
338 isr = NETISR_IP;
339 break;
340 #endif
341 #ifdef INET6
342 case 6:
343 ifq = &ip6intrq;
344 isr = NETISR_IPV6;
345 break;
346 #endif
347 default:
348 panic("ipip_input: should never reach here");
349 }
350
351 #if NBPFILTER > 0
352 if (gifp && gifp->if_bpf)
353 bpf_mtap_af(gifp->if_bpf, ifq == &ipintrq ? AF_INET : AF_INET6,
354 m, BPF_DIRECTION_IN);
355 #endif
356
357 s = splnet();
358 if (IF_QFULL(ifq)) {
359 IF_DROP(ifq);
360 m_freem(m);
361 ipipstat.ipips_qfull++;
362
363 splx(s);
364
365 DPRINTF(("ipip_input(): packet dropped because of full "
366 "queue\n"));
367 return;
368 }
369
370 IF_ENQUEUE(ifq, m);
371 schednetisr(isr);
372 splx(s);
373 return;
374 }
375
376 int
377 ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int dummy,
378 int dummy2)
379 {
380 u_int8_t tp, otos;
381
382 #ifdef INET
383 u_int8_t itos;
384 struct ip *ipo;
385 #endif
386
387 #ifdef INET6
388 struct ip6_hdr *ip6, *ip6o;
389 #endif
390
391
392
393 m_copydata(m, 0, 1, &tp);
394 tp = (tp >> 4) & 0xff;
395
396 switch (tdb->tdb_dst.sa.sa_family) {
397 #ifdef INET
398 case AF_INET:
399 if (tdb->tdb_src.sa.sa_family != AF_INET ||
400 tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY ||
401 tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) {
402
403 DPRINTF(("ipip_output(): unspecified tunnel endpoind "
404 "address in SA %s/%08x\n",
405 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
406
407 ipipstat.ipips_unspec++;
408 m_freem(m);
409 *mp = NULL;
410 return EINVAL;
411 }
412
413 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
414 if (m == 0) {
415 DPRINTF(("ipip_output(): M_PREPEND failed\n"));
416 ipipstat.ipips_hdrops++;
417 *mp = NULL;
418 return ENOBUFS;
419 }
420
421 ipo = mtod(m, struct ip *);
422
423 ipo->ip_v = IPVERSION;
424 ipo->ip_hl = 5;
425 ipo->ip_len = htons(m->m_pkthdr.len);
426 ipo->ip_ttl = ip_defttl;
427 ipo->ip_sum = 0;
428 ipo->ip_src = tdb->tdb_src.sin.sin_addr;
429 ipo->ip_dst = tdb->tdb_dst.sin.sin_addr;
430
431
432
433
434
435 ipo->ip_id = htons(ip_randomid());
436
437
438 if (tp == IPVERSION) {
439
440 m_copydata(m, sizeof(struct ip) +
441 offsetof(struct ip, ip_tos),
442 sizeof(u_int8_t), (caddr_t) &itos);
443
444 ipo->ip_p = IPPROTO_IPIP;
445
446
447
448
449
450 m_copydata(m, sizeof(struct ip) +
451 offsetof(struct ip, ip_off),
452 sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
453 NTOHS(ipo->ip_off);
454 ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
455 HTONS(ipo->ip_off);
456 }
457 #ifdef INET6
458 else if (tp == (IPV6_VERSION >> 4)) {
459 u_int32_t itos32;
460
461
462 m_copydata(m, sizeof(struct ip) +
463 offsetof(struct ip6_hdr, ip6_flow),
464 sizeof(u_int32_t), (caddr_t) &itos32);
465 itos = ntohl(itos32) >> 20;
466 ipo->ip_p = IPPROTO_IPV6;
467 ipo->ip_off = 0;
468 }
469 #endif
470 else {
471 m_freem(m);
472 *mp = NULL;
473 ipipstat.ipips_family++;
474 return EAFNOSUPPORT;
475 }
476
477 otos = 0;
478 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
479 ipo->ip_tos = otos;
480 break;
481 #endif
482
483 #ifdef INET6
484 case AF_INET6:
485 if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) ||
486 tdb->tdb_src.sa.sa_family != AF_INET6 ||
487 IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) {
488
489 DPRINTF(("ipip_output(): unspecified tunnel endpoind "
490 "address in SA %s/%08x\n",
491 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
492
493 ipipstat.ipips_unspec++;
494 m_freem(m);
495 *mp = NULL;
496 return ENOBUFS;
497 }
498
499
500 ip6 = mtod(m, struct ip6_hdr *);
501 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
502 ip6->ip6_src.s6_addr16[1] = 0;
503 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
504 ip6->ip6_dst.s6_addr16[1] = 0;
505
506 M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
507 if (m == 0) {
508 DPRINTF(("ipip_output(): M_PREPEND failed\n"));
509 ipipstat.ipips_hdrops++;
510 *mp = NULL;
511 return ENOBUFS;
512 }
513
514
515 ip6o = mtod(m, struct ip6_hdr *);
516 ip6o->ip6_flow = 0;
517 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
518 ip6o->ip6_vfc |= IPV6_VERSION;
519 ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o));
520 ip6o->ip6_hlim = ip_defttl;
521 in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL);
522 in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL);
523
524 #ifdef INET
525 if (tp == IPVERSION) {
526
527 m_copydata(m, sizeof(struct ip6_hdr) +
528 offsetof(struct ip, ip_tos), sizeof(u_int8_t),
529 (caddr_t) &itos);
530
531
532 ip6o->ip6_nxt = IPPROTO_IPIP;
533 }
534 else
535 #endif
536 if (tp == (IPV6_VERSION >> 4)) {
537 u_int32_t itos32;
538
539
540 m_copydata(m, sizeof(struct ip6_hdr) +
541 offsetof(struct ip6_hdr, ip6_flow),
542 sizeof(u_int32_t), (caddr_t) &itos32);
543 itos = ntohl(itos32) >> 20;
544
545 ip6o->ip6_nxt = IPPROTO_IPV6;
546 } else {
547 m_freem(m);
548 *mp = NULL;
549 ipipstat.ipips_family++;
550 return EAFNOSUPPORT;
551 }
552
553 otos = 0;
554 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
555 ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
556 break;
557 #endif
558
559 default:
560 DPRINTF(("ipip_output(): unsupported protocol family %d\n",
561 tdb->tdb_dst.sa.sa_family));
562 m_freem(m);
563 *mp = NULL;
564 ipipstat.ipips_family++;
565 return EAFNOSUPPORT;
566 }
567
568 ipipstat.ipips_opackets++;
569 *mp = m;
570
571 #ifdef INET
572 if (tdb->tdb_dst.sa.sa_family == AF_INET) {
573 if (tdb->tdb_xform->xf_type == XF_IP4)
574 tdb->tdb_cur_bytes +=
575 m->m_pkthdr.len - sizeof(struct ip);
576
577 ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip);
578 }
579 #endif
580
581 #ifdef INET6
582 if (tdb->tdb_dst.sa.sa_family == AF_INET6) {
583 if (tdb->tdb_xform->xf_type == XF_IP4)
584 tdb->tdb_cur_bytes +=
585 m->m_pkthdr.len - sizeof(struct ip6_hdr);
586
587 ipipstat.ipips_obytes +=
588 m->m_pkthdr.len - sizeof(struct ip6_hdr);
589 }
590 #endif
591
592 return 0;
593 }
594
595 #ifdef IPSEC
596 int
597 ipe4_attach()
598 {
599 return 0;
600 }
601
602 int
603 ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
604 {
605 tdbp->tdb_xform = xsp;
606 return 0;
607 }
608
609 int
610 ipe4_zeroize(struct tdb *tdbp)
611 {
612 return 0;
613 }
614
615 void
616 ipe4_input(struct mbuf *m, ...)
617 {
618
619 printf("ipe4_input(): should never be called\n");
620 if (m)
621 m_freem(m);
622 }
623 #endif
624
625 int
626 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
627 size_t newlen)
628 {
629
630 if (namelen != 1)
631 return (ENOTDIR);
632
633 switch (name[0]) {
634 case IPIPCTL_ALLOW:
635 return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow));
636 default:
637 return (ENOPROTOOPT);
638 }
639
640 }