This source file includes following definitions.
- ipq_lock_try
- ipq_unlock
- inet_ntoa
- ip_init
- ipintr
- ipv4_input
- in_iawithaddr
- ip_reass
- ip_freef
- ip_slowtimo
- ip_drain
- ip_flush
- ip_dooptions
- ip_rtaddr
- save_rte
- ip_weadvertise
- ip_srcroute
- ip_stripoptions
- ip_forward
- ip_sysctl
- ip_savecontrol
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 #include "pf.h"
36 #include "carp.h"
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/mbuf.h>
41 #include <sys/domain.h>
42 #include <sys/protosw.h>
43 #include <sys/socket.h>
44 #include <sys/socketvar.h>
45 #include <sys/syslog.h>
46 #include <sys/sysctl.h>
47
48 #include <net/if.h>
49 #include <net/if_dl.h>
50 #include <net/route.h>
51
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/if_ether.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_icmp.h>
60
61 #if NPF > 0
62 #include <net/pfvar.h>
63 #endif
64
65 #ifdef IPSEC
66 #include <netinet/ip_ipsp.h>
67 #endif
68
69 #if NCARP > 0
70 #include <net/if_types.h>
71 #include <netinet/ip_carp.h>
72 #endif
73
74 #define IPMTUDISCTIMEOUT (10 * 60)
75
76 struct ipqhead ipq;
77
78 int encdebug = 0;
79 int ipsec_keep_invalid = IPSEC_DEFAULT_EMBRYONIC_SA_TIMEOUT;
80 int ipsec_require_pfs = IPSEC_DEFAULT_PFS;
81 int ipsec_soft_allocations = IPSEC_DEFAULT_SOFT_ALLOCATIONS;
82 int ipsec_exp_allocations = IPSEC_DEFAULT_EXP_ALLOCATIONS;
83 int ipsec_soft_bytes = IPSEC_DEFAULT_SOFT_BYTES;
84 int ipsec_exp_bytes = IPSEC_DEFAULT_EXP_BYTES;
85 int ipsec_soft_timeout = IPSEC_DEFAULT_SOFT_TIMEOUT;
86 int ipsec_exp_timeout = IPSEC_DEFAULT_EXP_TIMEOUT;
87 int ipsec_soft_first_use = IPSEC_DEFAULT_SOFT_FIRST_USE;
88 int ipsec_exp_first_use = IPSEC_DEFAULT_EXP_FIRST_USE;
89 int ipsec_expire_acquire = IPSEC_DEFAULT_EXPIRE_ACQUIRE;
90 char ipsec_def_enc[20];
91 char ipsec_def_auth[20];
92 char ipsec_def_comp[20];
93
94
95 int ipforwarding = 0;
96 int ipmforwarding = 0;
97 int ipmultipath = 0;
98 int ipsendredirects = 1;
99 int ip_dosourceroute = 0;
100 int ip_defttl = IPDEFTTL;
101 int ip_mtudisc = 1;
102 u_int ip_mtudisc_timeout = IPMTUDISCTIMEOUT;
103 int ip_directedbcast = 0;
104 #ifdef DIAGNOSTIC
105 int ipprintfs = 0;
106 #endif
107
108 struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
109
110 int ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT;
111 int ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT;
112 int ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT;
113 int ipsec_ipcomp_default_level = IPSEC_IPCOMP_LEVEL_DEFAULT;
114
115
116 int ip_maxqueue = 300;
117 int ip_frags = 0;
118
119
120 extern int ipport_firstauto;
121 extern int ipport_lastauto;
122 extern int ipport_hifirstauto;
123 extern int ipport_hilastauto;
124 extern struct baddynamicports baddynamicports;
125
126 int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS;
127
128 extern struct domain inetdomain;
129 extern struct protosw inetsw[];
130 u_char ip_protox[IPPROTO_MAX];
131 int ipqmaxlen = IFQ_MAXLEN;
132 struct in_ifaddrhead in_ifaddr;
133 struct ifqueue ipintrq;
134
135 int ipq_locked;
136 static __inline int ipq_lock_try(void);
137 static __inline void ipq_unlock(void);
138
139 struct pool ipqent_pool;
140
141 struct ipstat ipstat;
142
143 static __inline int
144 ipq_lock_try()
145 {
146 int s;
147
148
149 s = splvm();
150 if (ipq_locked) {
151 splx(s);
152 return (0);
153 }
154 ipq_locked = 1;
155 splx(s);
156 return (1);
157 }
158
159 #define ipq_lock() ipq_lock_try()
160
161 static __inline void
162 ipq_unlock()
163 {
164 int s;
165
166 s = splvm();
167 ipq_locked = 0;
168 splx(s);
169 }
170
171 char *
172 inet_ntoa(ina)
173 struct in_addr ina;
174 {
175 static char buf[4*sizeof "123"];
176 unsigned char *ucp = (unsigned char *)&ina;
177
178 snprintf(buf, sizeof buf, "%d.%d.%d.%d",
179 ucp[0] & 0xff, ucp[1] & 0xff,
180 ucp[2] & 0xff, ucp[3] & 0xff);
181 return (buf);
182 }
183
184
185
186
187
188
189
190
191 int ip_nhops = 0;
192 static struct ip_srcrt {
193 struct in_addr dst;
194 char nop;
195 char srcopt[IPOPT_OFFSET + 1];
196 struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
197 } ip_srcrt;
198
199 void save_rte(u_char *, struct in_addr);
200 int ip_weadvertise(u_int32_t);
201
202
203
204
205
206 void
207 ip_init()
208 {
209 struct protosw *pr;
210 int i;
211 const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
212 const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
213
214 pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",
215 NULL);
216
217 pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
218 if (pr == 0)
219 panic("ip_init");
220 for (i = 0; i < IPPROTO_MAX; i++)
221 ip_protox[i] = pr - inetsw;
222 for (pr = inetdomain.dom_protosw;
223 pr < inetdomain.dom_protoswNPROTOSW; pr++)
224 if (pr->pr_domain->dom_family == PF_INET &&
225 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
226 ip_protox[pr->pr_protocol] = pr - inetsw;
227 LIST_INIT(&ipq);
228 ipintrq.ifq_maxlen = ipqmaxlen;
229 TAILQ_INIT(&in_ifaddr);
230 if (ip_mtudisc != 0)
231 ip_mtudisc_timeout_q =
232 rt_timer_queue_create(ip_mtudisc_timeout);
233
234
235 bzero((void *)&baddynamicports, sizeof(baddynamicports));
236 for (i = 0; defbaddynamicports_tcp[i] != 0; i++)
237 DP_SET(baddynamicports.tcp, defbaddynamicports_tcp[i]);
238 for (i = 0; defbaddynamicports_udp[i] != 0; i++)
239 DP_SET(baddynamicports.udp, defbaddynamicports_udp[i]);
240
241 strlcpy(ipsec_def_enc, IPSEC_DEFAULT_DEF_ENC, sizeof(ipsec_def_enc));
242 strlcpy(ipsec_def_auth, IPSEC_DEFAULT_DEF_AUTH, sizeof(ipsec_def_auth));
243 strlcpy(ipsec_def_comp, IPSEC_DEFAULT_DEF_COMP, sizeof(ipsec_def_comp));
244 }
245
246 struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
247 struct route ipforward_rt;
248 int ipforward_rtableid;
249
250 void
251 ipintr()
252 {
253 struct mbuf *m;
254 int s;
255
256 while (ipintrq.ifq_head) {
257
258
259
260
261 s = splnet();
262 IF_DEQUEUE(&ipintrq, m);
263 splx(s);
264 if (m == 0)
265 return;
266 #ifdef DIAGNOSTIC
267 if ((m->m_flags & M_PKTHDR) == 0)
268 panic("ipintr no HDR");
269 #endif
270 ipv4_input(m);
271 }
272 }
273
274
275
276
277
278 void
279 ipv4_input(m)
280 struct mbuf *m;
281 {
282 struct ip *ip;
283 struct ipq *fp;
284 struct in_ifaddr *ia;
285 struct ipqent *ipqe;
286 int hlen, mff, len;
287 in_addr_t pfrdr = 0;
288 #ifdef IPSEC
289 int error, s;
290 struct tdb *tdb;
291 struct tdb_ident *tdbi;
292 struct m_tag *mtag;
293 #endif
294
295
296
297
298
299 if (TAILQ_EMPTY(&in_ifaddr))
300 goto bad;
301 ipstat.ips_total++;
302 if (m->m_len < sizeof (struct ip) &&
303 (m = m_pullup(m, sizeof (struct ip))) == NULL) {
304 ipstat.ips_toosmall++;
305 return;
306 }
307 ip = mtod(m, struct ip *);
308 if (ip->ip_v != IPVERSION) {
309 ipstat.ips_badvers++;
310 goto bad;
311 }
312 hlen = ip->ip_hl << 2;
313 if (hlen < sizeof(struct ip)) {
314 ipstat.ips_badhlen++;
315 goto bad;
316 }
317 if (hlen > m->m_len) {
318 if ((m = m_pullup(m, hlen)) == NULL) {
319 ipstat.ips_badhlen++;
320 return;
321 }
322 ip = mtod(m, struct ip *);
323 }
324
325
326 if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
327 (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
328 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
329 ipstat.ips_badaddr++;
330 goto bad;
331 }
332 }
333
334 if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) {
335 if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) {
336 ipstat.ips_inhwcsum++;
337 ipstat.ips_badsum++;
338 goto bad;
339 }
340
341 if (in_cksum(m, hlen) != 0) {
342 ipstat.ips_badsum++;
343 goto bad;
344 }
345 } else {
346 m->m_pkthdr.csum_flags &= ~M_IPV4_CSUM_IN_OK;
347 ipstat.ips_inhwcsum++;
348 }
349
350
351 len = ntohs(ip->ip_len);
352
353
354
355
356 if (len < hlen) {
357 ipstat.ips_badlen++;
358 goto bad;
359 }
360
361
362
363
364
365
366
367 if (m->m_pkthdr.len < len) {
368 ipstat.ips_tooshort++;
369 goto bad;
370 }
371 if (m->m_pkthdr.len > len) {
372 if (m->m_len == m->m_pkthdr.len) {
373 m->m_len = len;
374 m->m_pkthdr.len = len;
375 } else
376 m_adj(m, len - m->m_pkthdr.len);
377 }
378
379 #if NCARP > 0
380 if (m->m_pkthdr.rcvif->if_type == IFT_CARP &&
381 m->m_pkthdr.rcvif->if_flags & IFF_LINK0 &&
382 ip->ip_p != IPPROTO_ICMP &&
383 carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr,
384 &ip->ip_dst.s_addr))
385 goto bad;
386 #endif
387
388 #if NPF > 0
389
390
391
392 pfrdr = ip->ip_dst.s_addr;
393 if (pf_test(PF_IN, m->m_pkthdr.rcvif, &m, NULL) != PF_PASS)
394 goto bad;
395 if (m == NULL)
396 return;
397
398 ip = mtod(m, struct ip *);
399 hlen = ip->ip_hl << 2;
400 pfrdr = (pfrdr != ip->ip_dst.s_addr);
401 #endif
402
403
404
405
406
407
408
409 ip_nhops = 0;
410 if (hlen > sizeof (struct ip) && ip_dooptions(m)) {
411 return;
412 }
413
414
415
416
417 if ((ia = in_iawithaddr(ip->ip_dst, m)) != NULL &&
418 (ia->ia_ifp->if_flags & IFF_UP))
419 goto ours;
420
421 if (IN_MULTICAST(ip->ip_dst.s_addr)) {
422 struct in_multi *inm;
423 #ifdef MROUTING
424 extern struct socket *ip_mrouter;
425
426 if (m->m_flags & M_EXT) {
427 if ((m = m_pullup(m, hlen)) == NULL) {
428 ipstat.ips_toosmall++;
429 return;
430 }
431 ip = mtod(m, struct ip *);
432 }
433 if (ipmforwarding && ip_mrouter) {
434
435
436
437
438
439
440
441
442
443
444
445
446 if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
447 ipstat.ips_cantforward++;
448 m_freem(m);
449 return;
450 }
451
452
453
454
455
456
457 if (ip->ip_p == IPPROTO_IGMP)
458 goto ours;
459 ipstat.ips_forward++;
460 }
461 #endif
462
463
464
465
466 IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);
467 if (inm == NULL) {
468 ipstat.ips_notmember++;
469 if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr))
470 ipstat.ips_cantforward++;
471 m_freem(m);
472 return;
473 }
474 goto ours;
475 }
476 if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
477 ip->ip_dst.s_addr == INADDR_ANY)
478 goto ours;
479
480 #if NCARP > 0
481 if (m->m_pkthdr.rcvif->if_type == IFT_CARP &&
482 m->m_pkthdr.rcvif->if_flags & IFF_LINK0 &&
483 ip->ip_p == IPPROTO_ICMP &&
484 carp_lsdrop(m, AF_INET, &ip->ip_src.s_addr,
485 &ip->ip_dst.s_addr))
486 goto bad;
487 #endif
488
489
490
491 if (ipforwarding == 0) {
492 ipstat.ips_cantforward++;
493 m_freem(m);
494 return;
495 }
496 #ifdef IPSEC
497 if (ipsec_in_use) {
498
499
500
501
502 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
503 s = splnet();
504 if (mtag != NULL) {
505 tdbi = (struct tdb_ident *)(mtag + 1);
506 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
507 } else
508 tdb = NULL;
509 ipsp_spd_lookup(m, AF_INET, hlen, &error,
510 IPSP_DIRECTION_IN, tdb, NULL);
511 splx(s);
512
513
514 if (error) {
515 ipstat.ips_cantforward++;
516 m_freem(m);
517 return;
518 }
519
520
521
522
523
524 }
525 #endif
526
527 ip_forward(m, pfrdr);
528 return;
529
530 ours:
531
532
533
534
535
536
537
538 if (ip->ip_off &~ htons(IP_DF | IP_RF)) {
539 if (m->m_flags & M_EXT) {
540 if ((m = m_pullup(m, hlen)) == NULL) {
541 ipstat.ips_toosmall++;
542 return;
543 }
544 ip = mtod(m, struct ip *);
545 }
546
547
548
549
550
551 ipq_lock();
552 LIST_FOREACH(fp, &ipq, ipq_q)
553 if (ip->ip_id == fp->ipq_id &&
554 ip->ip_src.s_addr == fp->ipq_src.s_addr &&
555 ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
556 ip->ip_p == fp->ipq_p)
557 goto found;
558 fp = 0;
559 found:
560
561
562
563
564
565
566 ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
567 mff = (ip->ip_off & htons(IP_MF)) != 0;
568 if (mff) {
569
570
571
572
573 if (ntohs(ip->ip_len) == 0 ||
574 (ntohs(ip->ip_len) & 0x7) != 0) {
575 ipstat.ips_badfrags++;
576 ipq_unlock();
577 goto bad;
578 }
579 }
580 ip->ip_off = htons(ntohs(ip->ip_off) << 3);
581
582
583
584
585
586
587 if (mff || ip->ip_off) {
588 ipstat.ips_fragments++;
589 if (ip_frags + 1 > ip_maxqueue) {
590 ip_flush();
591 ipstat.ips_rcvmemdrop++;
592 ipq_unlock();
593 goto bad;
594 }
595
596 ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
597 if (ipqe == NULL) {
598 ipstat.ips_rcvmemdrop++;
599 ipq_unlock();
600 goto bad;
601 }
602 ip_frags++;
603 ipqe->ipqe_mff = mff;
604 ipqe->ipqe_m = m;
605 ipqe->ipqe_ip = ip;
606 m = ip_reass(ipqe, fp);
607 if (m == 0) {
608 ipq_unlock();
609 return;
610 }
611 ipstat.ips_reassembled++;
612 ip = mtod(m, struct ip *);
613 hlen = ip->ip_hl << 2;
614 ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
615 } else
616 if (fp)
617 ip_freef(fp);
618 ipq_unlock();
619 }
620
621 #ifdef IPSEC
622 if (!ipsec_in_use)
623 goto skipipsec;
624
625
626
627
628
629
630
631
632
633 if ((ip->ip_p == IPPROTO_ESP) || (ip->ip_p == IPPROTO_AH) ||
634 (ip->ip_p == IPPROTO_IPCOMP))
635 goto skipipsec;
636
637
638
639
640
641
642
643
644
645 if ((ip->ip_p == IPPROTO_IPIP) || (ip->ip_p == IPPROTO_IPV6))
646 goto skipipsec;
647
648
649
650
651
652
653 if ((ip->ip_p == IPPROTO_TCP) || (ip->ip_p == IPPROTO_UDP))
654 goto skipipsec;
655
656
657
658
659
660
661
662
663
664
665
666
667 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
668 s = splnet();
669 if (mtag) {
670 tdbi = (struct tdb_ident *)(mtag + 1);
671 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
672 } else
673 tdb = NULL;
674 ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN,
675 tdb, NULL);
676 splx(s);
677
678
679 if (error) {
680 ipstat.ips_cantforward++;
681 m_freem(m);
682 return;
683 }
684
685 skipipsec:
686
687 #endif
688
689
690
691
692 ipstat.ips_delivered++;
693 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, NULL, 0);
694 return;
695 bad:
696 m_freem(m);
697 }
698
699 struct in_ifaddr *
700 in_iawithaddr(ina, m)
701 struct in_addr ina;
702 struct mbuf *m;
703 {
704 struct in_ifaddr *ia;
705
706 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
707 if ((ina.s_addr == ia->ia_addr.sin_addr.s_addr) ||
708 ((ia->ia_ifp->if_flags & (IFF_LOOPBACK|IFF_LINK1)) ==
709 (IFF_LOOPBACK|IFF_LINK1) &&
710 ia->ia_subnet == (ina.s_addr & ia->ia_subnetmask)))
711 return ia;
712 if (((ip_directedbcast == 0) || (m && ip_directedbcast &&
713 ia->ia_ifp == m->m_pkthdr.rcvif)) &&
714 (ia->ia_ifp->if_flags & IFF_BROADCAST)) {
715 if (ina.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
716 ina.s_addr == ia->ia_netbroadcast.s_addr ||
717
718
719
720
721 ina.s_addr == ia->ia_subnet ||
722 ina.s_addr == ia->ia_net) {
723
724 if (m)
725 m->m_flags |= M_BCAST;
726 return ia;
727 }
728 }
729 }
730
731 return NULL;
732 }
733
734
735
736
737
738
739
740 struct mbuf *
741 ip_reass(ipqe, fp)
742 struct ipqent *ipqe;
743 struct ipq *fp;
744 {
745 struct mbuf *m = ipqe->ipqe_m;
746 struct ipqent *nq, *p, *q;
747 struct ip *ip;
748 struct mbuf *t;
749 int hlen = ipqe->ipqe_ip->ip_hl << 2;
750 int i, next;
751 u_int8_t ecn, ecn0;
752
753
754
755
756
757 m->m_data += hlen;
758 m->m_len -= hlen;
759
760
761
762
763 if (fp == 0) {
764 MALLOC(fp, struct ipq *, sizeof (struct ipq),
765 M_FTABLE, M_NOWAIT);
766 if (fp == NULL)
767 goto dropfrag;
768 LIST_INSERT_HEAD(&ipq, fp, ipq_q);
769 fp->ipq_ttl = IPFRAGTTL;
770 fp->ipq_p = ipqe->ipqe_ip->ip_p;
771 fp->ipq_id = ipqe->ipqe_ip->ip_id;
772 LIST_INIT(&fp->ipq_fragq);
773 fp->ipq_src = ipqe->ipqe_ip->ip_src;
774 fp->ipq_dst = ipqe->ipqe_ip->ip_dst;
775 p = NULL;
776 goto insert;
777 }
778
779
780
781
782
783
784 ecn = ipqe->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
785 ecn0 = LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos & IPTOS_ECN_MASK;
786 if (ecn == IPTOS_ECN_CE) {
787 if (ecn0 == IPTOS_ECN_NOTECT)
788 goto dropfrag;
789 if (ecn0 != IPTOS_ECN_CE)
790 LIST_FIRST(&fp->ipq_fragq)->ipqe_ip->ip_tos |= IPTOS_ECN_CE;
791 }
792 if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT)
793 goto dropfrag;
794
795
796
797
798 for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq);
799 q != LIST_END(&fp->ipq_fragq); p = q, q = LIST_NEXT(q, ipqe_q))
800 if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off))
801 break;
802
803
804
805
806
807
808 if (p != NULL) {
809 i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) -
810 ntohs(ipqe->ipqe_ip->ip_off);
811 if (i > 0) {
812 if (i >= ntohs(ipqe->ipqe_ip->ip_len))
813 goto dropfrag;
814 m_adj(ipqe->ipqe_m, i);
815 ipqe->ipqe_ip->ip_off =
816 htons(ntohs(ipqe->ipqe_ip->ip_off) + i);
817 ipqe->ipqe_ip->ip_len =
818 htons(ntohs(ipqe->ipqe_ip->ip_len) - i);
819 }
820 }
821
822
823
824
825
826 for (; q != NULL &&
827 ntohs(ipqe->ipqe_ip->ip_off) + ntohs(ipqe->ipqe_ip->ip_len) >
828 ntohs(q->ipqe_ip->ip_off); q = nq) {
829 i = (ntohs(ipqe->ipqe_ip->ip_off) +
830 ntohs(ipqe->ipqe_ip->ip_len)) - ntohs(q->ipqe_ip->ip_off);
831 if (i < ntohs(q->ipqe_ip->ip_len)) {
832 q->ipqe_ip->ip_len =
833 htons(ntohs(q->ipqe_ip->ip_len) - i);
834 q->ipqe_ip->ip_off =
835 htons(ntohs(q->ipqe_ip->ip_off) + i);
836 m_adj(q->ipqe_m, i);
837 break;
838 }
839 nq = LIST_NEXT(q, ipqe_q);
840 m_freem(q->ipqe_m);
841 LIST_REMOVE(q, ipqe_q);
842 pool_put(&ipqent_pool, q);
843 ip_frags--;
844 }
845
846 insert:
847
848
849
850
851 if (p == NULL) {
852 LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q);
853 } else {
854 LIST_INSERT_AFTER(p, ipqe, ipqe_q);
855 }
856 next = 0;
857 for (p = NULL, q = LIST_FIRST(&fp->ipq_fragq);
858 q != LIST_END(&fp->ipq_fragq); p = q, q = LIST_NEXT(q, ipqe_q)) {
859 if (ntohs(q->ipqe_ip->ip_off) != next)
860 return (0);
861 next += ntohs(q->ipqe_ip->ip_len);
862 }
863 if (p->ipqe_mff)
864 return (0);
865
866
867
868
869
870 q = LIST_FIRST(&fp->ipq_fragq);
871 ip = q->ipqe_ip;
872 if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
873 ipstat.ips_toolong++;
874 ip_freef(fp);
875 return (0);
876 }
877 m = q->ipqe_m;
878 t = m->m_next;
879 m->m_next = 0;
880 m_cat(m, t);
881 nq = LIST_NEXT(q, ipqe_q);
882 pool_put(&ipqent_pool, q);
883 ip_frags--;
884 for (q = nq; q != NULL; q = nq) {
885 t = q->ipqe_m;
886 nq = LIST_NEXT(q, ipqe_q);
887 pool_put(&ipqent_pool, q);
888 ip_frags--;
889 m_cat(m, t);
890 }
891
892
893
894
895
896
897
898 ip->ip_len = htons(next);
899 ip->ip_src = fp->ipq_src;
900 ip->ip_dst = fp->ipq_dst;
901 LIST_REMOVE(fp, ipq_q);
902 FREE(fp, M_FTABLE);
903 m->m_len += (ip->ip_hl << 2);
904 m->m_data -= (ip->ip_hl << 2);
905
906 if (m->m_flags & M_PKTHDR) {
907 int plen = 0;
908 for (t = m; t; t = t->m_next)
909 plen += t->m_len;
910 m->m_pkthdr.len = plen;
911 }
912 return (m);
913
914 dropfrag:
915 ipstat.ips_fragdropped++;
916 m_freem(m);
917 pool_put(&ipqent_pool, ipqe);
918 ip_frags--;
919 return (0);
920 }
921
922
923
924
925
926 void
927 ip_freef(fp)
928 struct ipq *fp;
929 {
930 struct ipqent *q, *p;
931
932 for (q = LIST_FIRST(&fp->ipq_fragq); q != LIST_END(&fp->ipq_fragq);
933 q = p) {
934 p = LIST_NEXT(q, ipqe_q);
935 m_freem(q->ipqe_m);
936 LIST_REMOVE(q, ipqe_q);
937 pool_put(&ipqent_pool, q);
938 ip_frags--;
939 }
940 LIST_REMOVE(fp, ipq_q);
941 FREE(fp, M_FTABLE);
942 }
943
944
945
946
947
948
949 void
950 ip_slowtimo()
951 {
952 struct ipq *fp, *nfp;
953 int s = splsoftnet();
954
955 ipq_lock();
956 for (fp = LIST_FIRST(&ipq); fp != LIST_END(&ipq); fp = nfp) {
957 nfp = LIST_NEXT(fp, ipq_q);
958 if (--fp->ipq_ttl == 0) {
959 ipstat.ips_fragtimeout++;
960 ip_freef(fp);
961 }
962 }
963 ipq_unlock();
964 if (ipforward_rt.ro_rt) {
965 RTFREE(ipforward_rt.ro_rt);
966 ipforward_rt.ro_rt = 0;
967 }
968 splx(s);
969 }
970
971
972
973
974 void
975 ip_drain()
976 {
977
978 if (ipq_lock_try() == 0)
979 return;
980 while (!LIST_EMPTY(&ipq)) {
981 ipstat.ips_fragdropped++;
982 ip_freef(LIST_FIRST(&ipq));
983 }
984 ipq_unlock();
985 }
986
987
988
989
990 void
991 ip_flush()
992 {
993 int max = 50;
994
995
996 while (!LIST_EMPTY(&ipq) && ip_frags > ip_maxqueue * 3 / 4 && --max) {
997 ipstat.ips_fragdropped++;
998 ip_freef(LIST_FIRST(&ipq));
999 }
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009 int
1010 ip_dooptions(m)
1011 struct mbuf *m;
1012 {
1013 struct ip *ip = mtod(m, struct ip *);
1014 u_char *cp;
1015 struct ip_timestamp ipt;
1016 struct in_ifaddr *ia;
1017 int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
1018 struct in_addr sin, dst;
1019 n_time ntime;
1020
1021 dst = ip->ip_dst;
1022 cp = (u_char *)(ip + 1);
1023 cnt = (ip->ip_hl << 2) - sizeof (struct ip);
1024
1025 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1026 opt = cp[IPOPT_OPTVAL];
1027 if (opt == IPOPT_EOL)
1028 break;
1029 if (opt == IPOPT_NOP)
1030 optlen = 1;
1031 else {
1032 if (cnt < IPOPT_OLEN + sizeof(*cp)) {
1033 code = &cp[IPOPT_OLEN] - (u_char *)ip;
1034 goto bad;
1035 }
1036 optlen = cp[IPOPT_OLEN];
1037 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) {
1038 code = &cp[IPOPT_OLEN] - (u_char *)ip;
1039 goto bad;
1040 }
1041 }
1042
1043 switch (opt) {
1044
1045 default:
1046 break;
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 case IPOPT_LSRR:
1058 case IPOPT_SSRR:
1059 if (!ip_dosourceroute) {
1060 type = ICMP_UNREACH;
1061 code = ICMP_UNREACH_SRCFAIL;
1062 goto bad;
1063 }
1064 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
1065 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
1066 goto bad;
1067 }
1068 ipaddr.sin_addr = ip->ip_dst;
1069 ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr)));
1070 if (ia == 0) {
1071 if (opt == IPOPT_SSRR) {
1072 type = ICMP_UNREACH;
1073 code = ICMP_UNREACH_SRCFAIL;
1074 goto bad;
1075 }
1076
1077
1078
1079
1080 break;
1081 }
1082 off--;
1083 if ((off + sizeof(struct in_addr)) > optlen) {
1084
1085
1086
1087 save_rte(cp, ip->ip_src);
1088 break;
1089 }
1090
1091
1092
1093
1094 bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
1095 sizeof(ipaddr.sin_addr));
1096 if (opt == IPOPT_SSRR) {
1097 #define INA struct in_ifaddr *
1098 #define SA struct sockaddr *
1099 if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
1100 ia = (INA)ifa_ifwithnet((SA)&ipaddr);
1101 } else
1102 ia = ip_rtaddr(ipaddr.sin_addr);
1103 if (ia == 0) {
1104 type = ICMP_UNREACH;
1105 code = ICMP_UNREACH_SRCFAIL;
1106 goto bad;
1107 }
1108 ip->ip_dst = ipaddr.sin_addr;
1109 bcopy((caddr_t)&ia->ia_addr.sin_addr,
1110 (caddr_t)(cp + off), sizeof(struct in_addr));
1111 cp[IPOPT_OFFSET] += sizeof(struct in_addr);
1112
1113
1114
1115 forward = !IN_MULTICAST(ip->ip_dst.s_addr);
1116 break;
1117
1118 case IPOPT_RR:
1119 if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
1120 code = &cp[IPOPT_OLEN] - (u_char *)ip;
1121 goto bad;
1122 }
1123 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
1124 code = &cp[IPOPT_OFFSET] - (u_char *)ip;
1125 goto bad;
1126 }
1127
1128
1129
1130
1131 off--;
1132 if ((off + sizeof(struct in_addr)) > optlen)
1133 break;
1134 bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
1135 sizeof(ipaddr.sin_addr));
1136
1137
1138
1139
1140 if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
1141 (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
1142 type = ICMP_UNREACH;
1143 code = ICMP_UNREACH_HOST;
1144 goto bad;
1145 }
1146 bcopy((caddr_t)&ia->ia_addr.sin_addr,
1147 (caddr_t)(cp + off), sizeof(struct in_addr));
1148 cp[IPOPT_OFFSET] += sizeof(struct in_addr);
1149 break;
1150
1151 case IPOPT_TS:
1152 code = cp - (u_char *)ip;
1153 if (optlen < sizeof(struct ip_timestamp))
1154 goto bad;
1155 bcopy(cp, &ipt, sizeof(struct ip_timestamp));
1156 if (ipt.ipt_ptr < 5 || ipt.ipt_len < 5)
1157 goto bad;
1158 if (ipt.ipt_ptr - 1 + sizeof(n_time) > ipt.ipt_len) {
1159 if (++ipt.ipt_oflw == 0)
1160 goto bad;
1161 break;
1162 }
1163 bcopy(cp + ipt.ipt_ptr - 1, &sin, sizeof sin);
1164 switch (ipt.ipt_flg) {
1165
1166 case IPOPT_TS_TSONLY:
1167 break;
1168
1169 case IPOPT_TS_TSANDADDR:
1170 if (ipt.ipt_ptr - 1 + sizeof(n_time) +
1171 sizeof(struct in_addr) > ipt.ipt_len)
1172 goto bad;
1173 ipaddr.sin_addr = dst;
1174 ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
1175 m->m_pkthdr.rcvif);
1176 if (ia == 0)
1177 continue;
1178 bcopy((caddr_t)&ia->ia_addr.sin_addr,
1179 (caddr_t)&sin, sizeof(struct in_addr));
1180 ipt.ipt_ptr += sizeof(struct in_addr);
1181 break;
1182
1183 case IPOPT_TS_PRESPEC:
1184 if (ipt.ipt_ptr - 1 + sizeof(n_time) +
1185 sizeof(struct in_addr) > ipt.ipt_len)
1186 goto bad;
1187 bcopy((caddr_t)&sin, (caddr_t)&ipaddr.sin_addr,
1188 sizeof(struct in_addr));
1189 if (ifa_ifwithaddr((SA)&ipaddr) == 0)
1190 continue;
1191 ipt.ipt_ptr += sizeof(struct in_addr);
1192 break;
1193
1194 default:
1195
1196 code = (u_char *)&ipt.ipt_ptr -
1197 (u_char *)ip + 1;
1198 goto bad;
1199 }
1200 ntime = iptime();
1201 bcopy((caddr_t)&ntime, (caddr_t)cp + ipt.ipt_ptr - 1,
1202 sizeof(n_time));
1203 ipt.ipt_ptr += sizeof(n_time);
1204 }
1205 }
1206 if (forward && ipforwarding) {
1207 ip_forward(m, 1);
1208 return (1);
1209 }
1210 return (0);
1211 bad:
1212 icmp_error(m, type, code, 0, 0);
1213 ipstat.ips_badoptions++;
1214 return (1);
1215 }
1216
1217
1218
1219
1220
1221 struct in_ifaddr *
1222 ip_rtaddr(dst)
1223 struct in_addr dst;
1224 {
1225 struct sockaddr_in *sin;
1226
1227 sin = satosin(&ipforward_rt.ro_dst);
1228
1229 if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) {
1230 if (ipforward_rt.ro_rt) {
1231 RTFREE(ipforward_rt.ro_rt);
1232 ipforward_rt.ro_rt = 0;
1233 }
1234 sin->sin_family = AF_INET;
1235 sin->sin_len = sizeof(*sin);
1236 sin->sin_addr = dst;
1237
1238 rtalloc(&ipforward_rt);
1239 }
1240 if (ipforward_rt.ro_rt == 0)
1241 return ((struct in_ifaddr *)0);
1242 return (ifatoia(ipforward_rt.ro_rt->rt_ifa));
1243 }
1244
1245
1246
1247
1248
1249 void
1250 save_rte(option, dst)
1251 u_char *option;
1252 struct in_addr dst;
1253 {
1254 unsigned olen;
1255
1256 olen = option[IPOPT_OLEN];
1257 #ifdef DIAGNOSTIC
1258 if (ipprintfs)
1259 printf("save_rte: olen %d\n", olen);
1260 #endif
1261 if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst)))
1262 return;
1263 bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen);
1264 ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
1265 ip_srcrt.dst = dst;
1266 }
1267
1268
1269
1270
1271
1272 int
1273 ip_weadvertise(addr)
1274 u_int32_t addr;
1275 {
1276 struct rtentry *rt;
1277 struct ifnet *ifp;
1278 struct ifaddr *ifa;
1279 struct sockaddr_inarp sin;
1280
1281 sin.sin_len = sizeof(sin);
1282 sin.sin_family = AF_INET;
1283 sin.sin_addr.s_addr = addr;
1284 sin.sin_other = SIN_PROXY;
1285 rt = rtalloc1(sintosa(&sin), 0, 0);
1286 if (rt == 0)
1287 return 0;
1288
1289 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
1290 rt->rt_gateway->sa_family != AF_LINK) {
1291 RTFREE(rt);
1292 return 0;
1293 }
1294
1295 TAILQ_FOREACH(ifp, &ifnet, if_list)
1296 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1297 if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
1298 continue;
1299
1300 if (!bcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr),
1301 LLADDR((struct sockaddr_dl *)rt->rt_gateway),
1302 ETHER_ADDR_LEN)) {
1303 RTFREE(rt);
1304 return 1;
1305 }
1306 }
1307
1308 RTFREE(rt);
1309 return 0;
1310 }
1311
1312
1313
1314
1315
1316
1317 struct mbuf *
1318 ip_srcroute()
1319 {
1320 struct in_addr *p, *q;
1321 struct mbuf *m;
1322
1323 if (ip_nhops == 0)
1324 return ((struct mbuf *)0);
1325 m = m_get(M_DONTWAIT, MT_SOOPTS);
1326 if (m == 0)
1327 return ((struct mbuf *)0);
1328
1329 #define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt))
1330
1331
1332 m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) +
1333 OPTSIZ;
1334 #ifdef DIAGNOSTIC
1335 if (ipprintfs)
1336 printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len);
1337 #endif
1338
1339
1340
1341
1342 p = &ip_srcrt.route[ip_nhops - 1];
1343 *(mtod(m, struct in_addr *)) = *p--;
1344 #ifdef DIAGNOSTIC
1345 if (ipprintfs)
1346 printf(" hops %x", ntohl(mtod(m, struct in_addr *)->s_addr));
1347 #endif
1348
1349
1350
1351
1352 ip_srcrt.nop = IPOPT_NOP;
1353 ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF;
1354 bcopy((caddr_t)&ip_srcrt.nop,
1355 mtod(m, caddr_t) + sizeof(struct in_addr), OPTSIZ);
1356 q = (struct in_addr *)(mtod(m, caddr_t) +
1357 sizeof(struct in_addr) + OPTSIZ);
1358 #undef OPTSIZ
1359
1360
1361
1362
1363 while (p >= ip_srcrt.route) {
1364 #ifdef DIAGNOSTIC
1365 if (ipprintfs)
1366 printf(" %x", ntohl(q->s_addr));
1367 #endif
1368 *q++ = *p--;
1369 }
1370
1371
1372
1373 *q = ip_srcrt.dst;
1374 #ifdef DIAGNOSTIC
1375 if (ipprintfs)
1376 printf(" %x\n", ntohl(q->s_addr));
1377 #endif
1378 return (m);
1379 }
1380
1381
1382
1383
1384
1385
1386
1387
1388 void
1389 ip_stripoptions(m, mopt)
1390 struct mbuf *m;
1391 struct mbuf *mopt;
1392 {
1393 int i;
1394 struct ip *ip = mtod(m, struct ip *);
1395 caddr_t opts;
1396 int olen;
1397
1398 olen = (ip->ip_hl<<2) - sizeof (struct ip);
1399 opts = (caddr_t)(ip + 1);
1400 i = m->m_len - (sizeof (struct ip) + olen);
1401 bcopy(opts + olen, opts, (unsigned)i);
1402 m->m_len -= olen;
1403 if (m->m_flags & M_PKTHDR)
1404 m->m_pkthdr.len -= olen;
1405 ip->ip_hl = sizeof(struct ip) >> 2;
1406 }
1407
1408 int inetctlerrmap[PRC_NCMDS] = {
1409 0, 0, 0, 0,
1410 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
1411 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
1412 EMSGSIZE, EHOSTUNREACH, 0, 0,
1413 0, 0, 0, 0,
1414 ENOPROTOOPT
1415 };
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431 void
1432 ip_forward(m, srcrt)
1433 struct mbuf *m;
1434 int srcrt;
1435 {
1436 struct ip *ip = mtod(m, struct ip *);
1437 struct sockaddr_in *sin;
1438 struct rtentry *rt;
1439 int error, type = 0, code = 0, destmtu = 0, rtableid = 0;
1440 struct mbuf *mcopy;
1441 n_long dest;
1442
1443 dest = 0;
1444 #ifdef DIAGNOSTIC
1445 if (ipprintfs)
1446 printf("forward: src %x dst %x ttl %x\n", ip->ip_src.s_addr,
1447 ip->ip_dst.s_addr, ip->ip_ttl);
1448 #endif
1449 if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
1450 ipstat.ips_cantforward++;
1451 m_freem(m);
1452 return;
1453 }
1454 if (ip->ip_ttl <= IPTTLDEC) {
1455 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
1456 return;
1457 }
1458
1459 #if NPF > 0
1460 rtableid = m->m_pkthdr.pf.rtableid;
1461 #endif
1462
1463 sin = satosin(&ipforward_rt.ro_dst);
1464 if ((rt = ipforward_rt.ro_rt) == 0 ||
1465 ip->ip_dst.s_addr != sin->sin_addr.s_addr ||
1466 rtableid != ipforward_rtableid) {
1467 if (ipforward_rt.ro_rt) {
1468 RTFREE(ipforward_rt.ro_rt);
1469 ipforward_rt.ro_rt = 0;
1470 }
1471 sin->sin_family = AF_INET;
1472 sin->sin_len = sizeof(*sin);
1473 sin->sin_addr = ip->ip_dst;
1474
1475 rtalloc_mpath(&ipforward_rt, &ip->ip_src.s_addr, rtableid);
1476 if (ipforward_rt.ro_rt == 0) {
1477 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
1478 return;
1479 }
1480 ipforward_rtableid = rtableid;
1481 rt = ipforward_rt.ro_rt;
1482 }
1483
1484
1485
1486
1487
1488
1489 mcopy = m_copym(m, 0, min(ntohs(ip->ip_len), 68), M_DONTWAIT);
1490 if (mcopy)
1491 mcopy = m_pullup(mcopy, min(ntohs(ip->ip_len), 68));
1492
1493 ip->ip_ttl -= IPTTLDEC;
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 if (rt->rt_ifp == m->m_pkthdr.rcvif &&
1506 (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
1507 satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
1508 ipsendredirects && !srcrt &&
1509 !ip_weadvertise(satosin(rt_key(rt))->sin_addr.s_addr)) {
1510 if (rt->rt_ifa &&
1511 (ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==
1512 ifatoia(rt->rt_ifa)->ia_subnet) {
1513 if (rt->rt_flags & RTF_GATEWAY)
1514 dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
1515 else
1516 dest = ip->ip_dst.s_addr;
1517
1518 type = ICMP_REDIRECT;
1519 code = ICMP_REDIRECT_HOST;
1520 #ifdef DIAGNOSTIC
1521 if (ipprintfs)
1522 printf("redirect (%d) to %x\n", code, (u_int32_t)dest);
1523 #endif
1524 }
1525 }
1526
1527 error = ip_output(m, (struct mbuf *)NULL, &ipforward_rt,
1528 (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
1529 (void *)NULL, (void *)NULL);
1530 if (error)
1531 ipstat.ips_cantforward++;
1532 else {
1533 ipstat.ips_forward++;
1534 if (type)
1535 ipstat.ips_redirectsent++;
1536 else
1537 goto freecopy;
1538 }
1539 if (mcopy == NULL)
1540 goto freert;
1541
1542 switch (error) {
1543
1544 case 0:
1545
1546 break;
1547
1548 case ENETUNREACH:
1549 case EHOSTUNREACH:
1550 case ENETDOWN:
1551 case EHOSTDOWN:
1552 default:
1553 type = ICMP_UNREACH;
1554 code = ICMP_UNREACH_HOST;
1555 break;
1556
1557 case EMSGSIZE:
1558 type = ICMP_UNREACH;
1559 code = ICMP_UNREACH_NEEDFRAG;
1560
1561 #ifdef IPSEC
1562 if (ipforward_rt.ro_rt) {
1563 struct rtentry *rt = ipforward_rt.ro_rt;
1564
1565 if (rt->rt_rmx.rmx_mtu)
1566 destmtu = rt->rt_rmx.rmx_mtu;
1567 else
1568 destmtu = ipforward_rt.ro_rt->rt_ifp->if_mtu;
1569 }
1570 #endif
1571 ipstat.ips_cantfrag++;
1572 break;
1573
1574 case ENOBUFS:
1575 #if 1
1576
1577
1578
1579
1580
1581
1582 goto freecopy;
1583 #else
1584 type = ICMP_SOURCEQUENCH;
1585 code = 0;
1586 break;
1587 #endif
1588 }
1589
1590 icmp_error(mcopy, type, code, dest, destmtu);
1591 goto freert;
1592
1593 freecopy:
1594 if (mcopy)
1595 m_free(mcopy);
1596 freert:
1597 #ifndef SMALL_KERNEL
1598 if (ipmultipath && ipforward_rt.ro_rt &&
1599 (ipforward_rt.ro_rt->rt_flags & RTF_MPATH)) {
1600 RTFREE(ipforward_rt.ro_rt);
1601 ipforward_rt.ro_rt = 0;
1602 }
1603 #endif
1604 return;
1605 }
1606
1607 int
1608 ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
1609 int *name;
1610 u_int namelen;
1611 void *oldp;
1612 size_t *oldlenp;
1613 void *newp;
1614 size_t newlen;
1615 {
1616 int error;
1617
1618
1619 if (namelen != 1 && name[0] != IPCTL_IFQUEUE)
1620 return (ENOTDIR);
1621
1622 switch (name[0]) {
1623 #ifdef notyet
1624 case IPCTL_DEFMTU:
1625 return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu));
1626 #endif
1627 case IPCTL_SOURCEROUTE:
1628
1629
1630
1631 if (newp && securelevel > 0)
1632 return (EPERM);
1633 return (sysctl_int(oldp, oldlenp, newp, newlen,
1634 &ip_dosourceroute));
1635 case IPCTL_MTUDISC:
1636 error = sysctl_int(oldp, oldlenp, newp, newlen,
1637 &ip_mtudisc);
1638 if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) {
1639 ip_mtudisc_timeout_q =
1640 rt_timer_queue_create(ip_mtudisc_timeout);
1641 } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) {
1642 rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE);
1643 Free(ip_mtudisc_timeout_q);
1644 ip_mtudisc_timeout_q = NULL;
1645 }
1646 return error;
1647 case IPCTL_MTUDISCTIMEOUT:
1648 error = sysctl_int(oldp, oldlenp, newp, newlen,
1649 &ip_mtudisc_timeout);
1650 if (ip_mtudisc_timeout_q != NULL)
1651 rt_timer_queue_change(ip_mtudisc_timeout_q,
1652 ip_mtudisc_timeout);
1653 return (error);
1654 case IPCTL_IPSEC_ENC_ALGORITHM:
1655 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
1656 ipsec_def_enc, sizeof(ipsec_def_enc)));
1657 case IPCTL_IPSEC_AUTH_ALGORITHM:
1658 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
1659 ipsec_def_auth,
1660 sizeof(ipsec_def_auth)));
1661 case IPCTL_IPSEC_IPCOMP_ALGORITHM:
1662 return (sysctl_tstring(oldp, oldlenp, newp, newlen,
1663 ipsec_def_comp,
1664 sizeof(ipsec_def_comp)));
1665 case IPCTL_IFQUEUE:
1666 return (sysctl_ifq(name + 1, namelen - 1,
1667 oldp, oldlenp, newp, newlen, &ipintrq));
1668 default:
1669 if (name[0] < IPCTL_MAXID)
1670 return (sysctl_int_arr(ipctl_vars, name, namelen,
1671 oldp, oldlenp, newp, newlen));
1672 return (EOPNOTSUPP);
1673 }
1674
1675 }
1676
1677 void
1678 ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
1679 struct mbuf *m)
1680 {
1681 #ifdef SO_TIMESTAMP
1682 if (inp->inp_socket->so_options & SO_TIMESTAMP) {
1683 struct timeval tv;
1684
1685 microtime(&tv);
1686 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
1687 SCM_TIMESTAMP, SOL_SOCKET);
1688 if (*mp)
1689 mp = &(*mp)->m_next;
1690 }
1691 #endif
1692 if (inp->inp_flags & INP_RECVDSTADDR) {
1693 *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
1694 sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
1695 if (*mp)
1696 mp = &(*mp)->m_next;
1697 }
1698 #ifdef notyet
1699
1700
1701 if (inp->inp_flags & INP_RECVOPTS) {
1702 *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
1703 sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP);
1704 if (*mp)
1705 mp = &(*mp)->m_next;
1706 }
1707
1708 if (inp->inp_flags & INP_RECVRETOPTS) {
1709 *mp = sbcreatecontrol((caddr_t) ip_srcroute(),
1710 sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP);
1711 if (*mp)
1712 mp = &(*mp)->m_next;
1713 }
1714 #endif
1715 if (inp->inp_flags & INP_RECVIF) {
1716 struct sockaddr_dl sdl;
1717 struct ifnet *ifp;
1718
1719 if ((ifp = m->m_pkthdr.rcvif) == NULL ||
1720 ifp->if_sadl == NULL) {
1721 bzero(&sdl, sizeof(sdl));
1722 sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]);
1723 sdl.sdl_family = AF_LINK;
1724 sdl.sdl_index = ifp != NULL ? ifp->if_index : 0;
1725 sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
1726 *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
1727 IP_RECVIF, IPPROTO_IP);
1728 } else {
1729 *mp = sbcreatecontrol((caddr_t) ifp->if_sadl,
1730 ifp->if_sadl->sdl_len, IP_RECVIF, IPPROTO_IP);
1731 }
1732 if (*mp)
1733 mp = &(*mp)->m_next;
1734 }
1735 if (inp->inp_flags & INP_RECVTTL) {
1736 *mp = sbcreatecontrol((caddr_t) &ip->ip_ttl,
1737 sizeof(u_char), IP_RECVTTL, IPPROTO_IP);
1738 if (*mp)
1739 mp = &(*mp)->m_next;
1740 }
1741 }
1742