Annotation of sys/netinet/ip_input.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ip_input.c,v 1.151 2007/05/30 04:46:45 henning Exp $ */
2: /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1982, 1986, 1988, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
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 /* IPSEC */
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) /* as per RFC 1191 */
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: /* values controllable via sysctl */
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: /* Keep track of memory used for reassembly */
116: int ip_maxqueue = 300;
117: int ip_frags = 0;
118:
119: /* from in_pcb.c */
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: /* Use splvm() due to mbuf allocation. */
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: * We need to save the IP options in case a protocol wants to respond
186: * to an incoming packet over the same route if the packet got here
187: * using IP source routing. This allows connection establishment and
188: * maintenance when the remote end is on a network that is not known
189: * to us.
190: */
191: int ip_nhops = 0;
192: static struct ip_srcrt {
193: struct in_addr dst; /* final destination */
194: char nop; /* one NOP to align */
195: char srcopt[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN and OFFSET */
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: * IP initialization: fill in IP protocol switch table.
204: * All protocols not implemented in kernel go to raw IP protocol handler.
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: /* Fill in list of ports not to allocate dynamically. */
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: * Get next datagram off input queue and get IP header
259: * in first mbuf.
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: * Ip input routine. Checksum and byte swap header. If fragmented
276: * try to reassemble. Process options. Pass to next level.
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 /* IPSEC */
294:
295: /*
296: * If no IP addresses have been set yet but the interfaces
297: * are receiving, can't do anything with incoming packets yet.
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)) { /* minimum header length */
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: /* 127/8 must not appear on wire - RFC1122 */
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: /* Retrieve the packet length. */
351: len = ntohs(ip->ip_len);
352:
353: /*
354: * Convert fields to host representation.
355: */
356: if (len < hlen) {
357: ipstat.ips_badlen++;
358: goto bad;
359: }
360:
361: /*
362: * Check that the amount of data in the buffers
363: * is at least as much as the IP header would have us expect.
364: * Trim mbufs if longer than we expect.
365: * Drop packet if shorter than we expect.
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: * Packet filter
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: * Process options and, if not destined for us,
405: * ship it on. ip_dooptions returns 1 when an
406: * error was detected (causing an icmp message
407: * to be sent and the original packet to be freed).
408: */
409: ip_nhops = 0; /* for source routed packets */
410: if (hlen > sizeof (struct ip) && ip_dooptions(m)) {
411: return;
412: }
413:
414: /*
415: * Check our list of addresses, to see if the packet is for us.
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: * If we are acting as a multicast router, all
436: * incoming multicast packets are passed to the
437: * kernel-level multicast forwarding function.
438: * The packet is returned (relatively) intact; if
439: * ip_mforward() returns a non-zero value, the packet
440: * must be discarded, else it may be accepted below.
441: *
442: * (The IP ident field is put in the same byte order
443: * as expected when ip_mforward() is called from
444: * ip_output().)
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: * The process-level routing daemon needs to receive
454: * all multicast IGMP packets, whether or not this
455: * host belongs to their destination groups.
456: */
457: if (ip->ip_p == IPPROTO_IGMP)
458: goto ours;
459: ipstat.ips_forward++;
460: }
461: #endif
462: /*
463: * See if we belong to the destination multicast group on the
464: * arrival interface.
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: * Not for us; forward if possible and desirable.
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: * IPsec policy check for forwarded packets. Look at
500: * inner-most IPsec SA used.
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: /* Error or otherwise drop-packet indication */
514: if (error) {
515: ipstat.ips_cantforward++;
516: m_freem(m);
517: return;
518: }
519:
520: /*
521: * Fall through, forward packet. Outbound IPsec policy
522: * checking will occur in ip_output().
523: */
524: }
525: #endif /* IPSEC */
526:
527: ip_forward(m, pfrdr);
528: return;
529:
530: ours:
531: /*
532: * If offset or IP_MF are set, must reassemble.
533: * Otherwise, nothing need be done.
534: * (We could look in the reassembly queue to see
535: * if the packet was previously fragmented,
536: * but it's not worth the time; just let them time out.)
537: */
538: if (ip->ip_off &~ htons(IP_DF | IP_RF)) {
539: if (m->m_flags & M_EXT) { /* XXX */
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: * Look for queue of fragments
549: * of this datagram.
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: * Adjust ip_len to not reflect header,
563: * set ipqe_mff if more fragments are expected,
564: * convert offset of this to bytes.
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: * Make sure that fragments have a data length
571: * that's a non-zero multiple of 8 bytes.
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: * If datagram marked as having more fragments
584: * or if this is not the first fragment,
585: * attempt reassembly; if it succeeds, proceed.
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: * If it's a protected packet for us, skip the policy check.
627: * That's because we really only care about the properties of
628: * the protected packet, and not the intermediate versions.
629: * While this is not the most paranoid setting, it allows
630: * some flexibility in handling nested tunnels (in setting up
631: * the policies).
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: * If the protected packet was tunneled, then we need to
639: * verify the protected packet's information, not the
640: * external headers. Thus, skip the policy lookup for the
641: * external packet, and keep the IPsec information linked on
642: * the packet header (the encapsulation routines know how
643: * to deal with that).
644: */
645: if ((ip->ip_p == IPPROTO_IPIP) || (ip->ip_p == IPPROTO_IPV6))
646: goto skipipsec;
647:
648: /*
649: * If the protected packet is TCP or UDP, we'll do the
650: * policy check in the respective input routine, so we can
651: * check for bypass sockets.
652: */
653: if ((ip->ip_p == IPPROTO_TCP) || (ip->ip_p == IPPROTO_UDP))
654: goto skipipsec;
655:
656: /*
657: * IPsec policy check for local-delivery packets. Look at the
658: * inner-most SA that protected the packet. This is in fact
659: * a bit too restrictive (it could end up causing packets to
660: * be dropped that semantically follow the policy, e.g., in
661: * certain SA-bundle configurations); but the alternative is
662: * very complicated (and requires keeping track of what
663: * kinds of tunneling headers have been seen in-between the
664: * IPsec headers), and I don't think we lose much functionality
665: * that's needed in the real world (who uses bundles anyway ?).
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: /* Error or otherwise drop-packet indication. */
679: if (error) {
680: ipstat.ips_cantforward++;
681: m_freem(m);
682: return;
683: }
684:
685: skipipsec:
686: /* Otherwise, just fall through and deliver the packet */
687: #endif /* IPSEC */
688:
689: /*
690: * Switch out to protocol's input routine.
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: * Look for all-0's host part (old broadcast addr),
719: * either for subnet or net.
720: */
721: ina.s_addr == ia->ia_subnet ||
722: ina.s_addr == ia->ia_net) {
723: /* Make sure M_BCAST is set */
724: if (m)
725: m->m_flags |= M_BCAST;
726: return ia;
727: }
728: }
729: }
730:
731: return NULL;
732: }
733:
734: /*
735: * Take incoming datagram fragment and try to
736: * reassemble it into whole datagram. If a chain for
737: * reassembly of this datagram already exists, then it
738: * is given as fp; otherwise have to make a chain.
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: * Presence of header sizes in mbufs
755: * would confuse code below.
756: */
757: m->m_data += hlen;
758: m->m_len -= hlen;
759:
760: /*
761: * If first fragment to arrive, create a reassembly queue.
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: * Handle ECN by comparing this segment with the first one;
781: * if CE is set, do not lose CE.
782: * drop if CE and not-ECT are mixed for the same packet.
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: * Find a segment which begins after this one does.
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: * If there is a preceding segment, it may provide some of
805: * our data already. If so, drop the data from the incoming
806: * segment. If it provides all of our data, drop us.
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: * While we overlap succeeding segments trim them or,
824: * if they are completely covered, dequeue them.
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: * Stick new segment in its place;
849: * check for complete reassembly.
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: * Reassembly is complete. Check for a bogus message size and
868: * concatenate fragments.
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: * Create header for new ip packet by
894: * modifying header of first packet;
895: * dequeue and discard fragment reassembly header.
896: * Make header visible.
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: /* some debugging cruft by sklower, below, will go away soon */
906: if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
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: * Free a fragment reassembly header and all
924: * associated datagrams.
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: * IP timer processing;
946: * if a timer expires on a reassembly queue, discard it.
947: * clear the forwarding cache, there might be a better route.
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: * Drain off all datagram fragments.
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: * Flush a bunch of datagram fragments, till we are down to 75%.
989: */
990: void
991: ip_flush()
992: {
993: int max = 50;
994:
995: /* ipq already locked */
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: * Do option processing on a datagram,
1004: * possibly discarding it if bad options are encountered,
1005: * or forwarding it if source-routed.
1006: * Returns 1 if packet has been forwarded/freed,
1007: * 0 if the packet should be processed further.
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: * Source routing with record.
1050: * Find interface with current destination address.
1051: * If none on this machine then drop if strictly routed,
1052: * or do nothing if loosely routed.
1053: * Record interface address and bring up next address
1054: * component. If strictly routed make sure next
1055: * address is on directly accessible net.
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: * Loose routing, and not at next destination
1078: * yet; nothing to do except forward.
1079: */
1080: break;
1081: }
1082: off--; /* 0 origin */
1083: if ((off + sizeof(struct in_addr)) > optlen) {
1084: /*
1085: * End of source route. Should be for us.
1086: */
1087: save_rte(cp, ip->ip_src);
1088: break;
1089: }
1090:
1091: /*
1092: * locate outgoing interface
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: * Let ip_intr's mcast routing check handle mcast pkts
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: * If no space remains, ignore.
1130: */
1131: off--; /* 0 origin */
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: * locate outgoing interface; if we're the destination,
1138: * use the incoming interface (should be same).
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: /* XXX can't take &ipt->ipt_flg */
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: * Given address of next destination (final or next hop),
1219: * return internet address info of interface to be used to get there.
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: * Save incoming source route for use in replies,
1247: * to be picked up later by ip_srcroute if the receiver is interested.
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 /* 0 */
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: * Check whether we do proxy ARP for this address and we point to ourselves.
1270: * Code shamelessly copied from arplookup().
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); /* XXX other tables? */
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: * Retrieve incoming source route for use in replies,
1314: * in the same form used by setsockopt.
1315: * The first hop is placed before the options, will be removed later.
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: /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */
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: * First save first hop for return route
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: * Copy option fields and padding (nop) to mbuf.
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: * Record return path as an IP source route,
1361: * reversing the path (pointers are now aligned).
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: * Last hop goes to final destination.
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: * Strip out IP options, at higher
1383: * level protocol in the kernel.
1384: * Second argument is buffer to which options
1385: * will be moved, and return value is their length.
1386: * XXX should be deleted; last arg currently ignored.
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: * Forward a packet. If some error occurs return the sender
1419: * an icmp packet. Note we can't always generate a meaningful
1420: * icmp message because icmp doesn't have a large enough repertoire
1421: * of codes and types.
1422: *
1423: * If not forwarding, just drop the packet. This could be confusing
1424: * if ipforwarding was zero but some routing protocol was advancing
1425: * us as a gateway to somewhere. However, we must let the routing
1426: * protocol deal with that.
1427: *
1428: * The srcrt parameter indicates whether the packet is being forwarded
1429: * via a source route.
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: * Save at most 68 bytes of the packet in case
1486: * we need to generate an ICMP message to the src.
1487: * Pullup to avoid sharing mbuf cluster between m and mcopy.
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: * If forwarding packet using same interface that it came in on,
1497: * perhaps should send a redirect to sender to shortcut a hop.
1498: * Only send redirect if source is sending directly to us,
1499: * and if packet was not source routed (or has any options).
1500: * Also, don't send redirect if forwarding using a default route
1501: * or a route modified by a redirect.
1502: * Don't send redirect if we advertise destination's arp address
1503: * as ours (proxy arp).
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: /* Router requirements says to only send host redirects */
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: /* forwarded, but need redirect */
1545: /* type, code set above */
1546: break;
1547:
1548: case ENETUNREACH: /* shouldn't happen, checked above */
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 /*IPSEC*/
1571: ipstat.ips_cantfrag++;
1572: break;
1573:
1574: case ENOBUFS:
1575: #if 1
1576: /*
1577: * a router should not generate ICMP_SOURCEQUENCH as
1578: * required in RFC1812 Requirements for IP Version 4 Routers.
1579: * source quench could be a big problem under DoS attacks,
1580: * or the underlying interface is rate-limited.
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: /* Almost all sysctl names at this level are terminal. */
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: * Don't allow this to change in a secure environment.
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: /* NOTREACHED */
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: /* this code is broken and will probably never be fixed. */
1700: /* options were tossed already */
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: /* ip_srcroute doesn't do what we want here, need to fix */
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:
CVSweb