1 /* 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 34 * $Id: ip_input.c,v 1.109 1998/12/14 18:09:13 luigi Exp $ 35 * $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $ 36 */ 37 38 #define _IP_VHL 39 40 #include "opt_bootp.h" 41 #include "opt_ipfw.h" 42 #include "opt_ipdn.h" 43 #include "opt_ipdivert.h" 44 #include "opt_ipfilter.h" 45 46 #include <stddef.h> 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/mbuf.h> 51 #include <sys/malloc.h> 52 #include <sys/domain.h> 53 #include <sys/protosw.h> 54 #include <sys/socket.h> 55 #include <sys/time.h> 56 #include <sys/kernel.h> 57 #include <sys/syslog.h> 58 #include <sys/sysctl.h> 59 60 #include <net/if.h> 61 #include <net/if_var.h> 62 #include <net/if_dl.h> 63 #include <net/route.h> 64 #include <net/netisr.h> 65 66 #include <netinet/in.h> 67 #include <netinet/in_systm.h> 68 #include <netinet/in_var.h> 69 #include <netinet/ip.h> 70 #include <netinet/in_pcb.h> 71 #include <netinet/ip_var.h> 72 #include <netinet/ip_icmp.h> 73 #include <machine/in_cksum.h> 74 75 #include <sys/socketvar.h> 76 77 #ifdef IPFIREWALL 78 #include <netinet/ip_fw.h> 79 #endif 80 81 #ifdef DUMMYNET 82 #include <netinet/ip_dummynet.h> 83 #endif 84 85 int rsvp_on = 0; 86 static int ip_rsvp_on; 87 struct socket *ip_rsvpd; 88 89 int ipforwarding = 0; 90 SYSCTL_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW, 91 &ipforwarding, 0, ""); 92 93 static int ipsendredirects = 1; /* XXX */ 94 SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_RW, 95 &ipsendredirects, 0, ""); 96 97 int ip_defttl = IPDEFTTL; 98 SYSCTL_INT(_net_inet_ip, IPCTL_DEFTTL, ttl, CTLFLAG_RW, 99 &ip_defttl, 0, ""); 100 101 static int ip_dosourceroute = 0; 102 SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW, 103 &ip_dosourceroute, 0, ""); 104 105 static int ip_acceptsourceroute = 0; 106 SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute, 107 CTLFLAG_RW, &ip_acceptsourceroute, 0, ""); 108 #ifdef DIAGNOSTIC 109 static int ipprintfs = 0; 110 #endif 111 112 extern struct domain inetdomain; 113 extern struct protosw inetsw[]; 114 u_char ip_protox[IPPROTO_MAX]; 115 static int ipqmaxlen = IFQ_MAXLEN; 116 struct in_ifaddrhead in_ifaddrhead; /* first inet address */ 117 struct ifqueue ipintrq; 118 SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_queue_maxlen, CTLFLAG_RD, 119 &ipintrq.ifq_maxlen, 0, ""); 120 SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD, 121 &ipintrq.ifq_drops, 0, ""); 122 123 struct ipstat ipstat; 124 SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RD, 125 &ipstat, ipstat, ""); 126 127 /* Packet reassembly stuff */ 128 #define IPREASS_NHASH_LOG2 6 129 #define IPREASS_NHASH (1 << IPREASS_NHASH_LOG2) 130 #define IPREASS_HMASK (IPREASS_NHASH - 1) 131 #define IPREASS_HASH(x,y) \ 132 ((((x) & 0xF | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK) 133 134 static struct ipq ipq[IPREASS_NHASH]; 135 static int nipq = 0; /* total # of reass queues */ 136 static int maxnipq; 137 138 #ifdef IPCTL_DEFMTU 139 SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW, 140 &ip_mtu, 0, ""); 141 #endif 142 143 #if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1 144 #undef COMPAT_IPFW 145 #define COMPAT_IPFW 1 146 #else 147 #undef COMPAT_IPFW 148 #endif 149 150 #ifdef COMPAT_IPFW 151 152 #include <netinet/ip_fw.h> 153 154 /* Firewall hooks */ 155 ip_fw_chk_t *ip_fw_chk_ptr; 156 ip_fw_ctl_t *ip_fw_ctl_ptr; 157 158 #ifdef DUMMYNET 159 ip_dn_ctl_t *ip_dn_ctl_ptr; 160 #endif 161 162 /* IP Network Address Translation (NAT) hooks */ 163 ip_nat_t *ip_nat_ptr; 164 ip_nat_ctl_t *ip_nat_ctl_ptr; 165 #endif 166 167 #if defined(IPFILTER_LKM) || defined(IPFILTER) 168 int iplattach __P((void)); 169 int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)) = NULL; 170 #endif 171 172 173 /* 174 * We need to save the IP options in case a protocol wants to respond 175 * to an incoming packet over the same route if the packet got here 176 * using IP source routing. This allows connection establishment and 177 * maintenance when the remote end is on a network that is not known 178 * to us. 179 */ 180 static int ip_nhops = 0; 181 static struct ip_srcrt { 182 struct in_addr dst; /* final destination */ 183 char nop; /* one NOP to align */ 184 char srcopt[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN and OFFSET */ 185 struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)]; 186 } ip_srcrt; 187 188 #ifdef IPDIVERT 189 /* 190 * Shared variable between ip_input() and ip_reass() to communicate 191 * about which packets, once assembled from fragments, get diverted, 192 * and to which port. 193 */ 194 static u_short frag_divert_port; 195 #endif 196 197 struct sockaddr_in *ip_fw_fwd_addr; 198 199 static void save_rte __P((u_char *, struct in_addr)); 200 static int ip_dooptions __P((struct mbuf *)); 201 static void ip_forward __P((struct mbuf *, int)); 202 static void ip_freef __P((struct ipq *)); 203 static struct ip * 204 ip_reass __P((struct mbuf *, struct ipq *, struct ipq *)); 205 static struct in_ifaddr * 206 ip_rtaddr __P((struct in_addr)); 207 static void ipintr __P((void)); 208 /* 209 * IP initialization: fill in IP protocol switch table. 210 * All protocols not implemented in kernel go to raw IP protocol handler. 211 */ 212 void 213 ip_init() 214 { 215 register struct protosw *pr; 216 register int i; 217 218 TAILQ_INIT(&in_ifaddrhead); 219 pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); 220 if (pr == 0) 221 panic("ip_init"); 222 for (i = 0; i < IPPROTO_MAX; i++) 223 ip_protox[i] = pr - inetsw; 224 for (pr = inetdomain.dom_protosw; 225 pr < inetdomain.dom_protoswNPROTOSW; pr++) 226 if (pr->pr_domain->dom_family == PF_INET && 227 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 228 ip_protox[pr->pr_protocol] = pr - inetsw; 229 230 for (i = 0; i < IPREASS_NHASH; i++) 231 ipq[i].next = ipq[i].prev = &ipq[i]; 232 233 maxnipq = nmbclusters/4; 234 235 ip_id = time_second & 0xffff; 236 ipintrq.ifq_maxlen = ipqmaxlen; 237 #ifdef DUMMYNET 238 ip_dn_init(); 239 #endif 240 #ifdef IPNAT 241 ip_nat_init(); 242 #endif 243 #ifdef IPFILTER 244 iplattach(); 245 #endif 246 247 } 248 249 static struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; 250 static struct route ipforward_rt; 251 252 /* 253 * Ip input routine. Checksum and byte swap header. If fragmented 254 * try to reassemble. Process options. Pass to next level. 255 */ 256 void 257 ip_input(struct mbuf *m) 258 { 259 struct ip *ip; 260 struct ipq *fp; 261 struct in_ifaddr *ia; 262 int i, hlen, mff; 263 u_short sum; 264 #ifndef IPDIVERT /* dummy variable for the firewall code to play with */ 265 u_short ip_divert_cookie = 0 ; 266 #endif 267 #ifdef COMPAT_IPFW 268 struct ip_fw_chain *rule = NULL ; 269 #endif 270 271 #if defined(IPFIREWALL) && defined(DUMMYNET) 272 /* 273 * dummynet packet are prepended a vestigial mbuf with 274 * m_type = MT_DUMMYNET and m_data pointing to the matching 275 * rule. 276 */ 277 if (m->m_type == MT_DUMMYNET) { 278 struct mbuf *m0 = m ; 279 rule = (struct ip_fw_chain *)(m->m_data) ; 280 m = m->m_next ; 281 free(m0, M_IPFW); 282 ip = mtod(m, struct ip *); 283 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 284 goto iphack ; 285 } else 286 rule = NULL ; 287 #endif 288 289 #ifdef DIAGNOSTIC 290 if (m == NULL || (m->m_flags & M_PKTHDR) == 0) 291 panic("ip_input no HDR"); 292 #endif 293 /* 294 * If no IP addresses have been set yet but the interfaces 295 * are receiving, can't do anything with incoming packets yet. 296 * XXX This is broken! We should be able to receive broadcasts 297 * and multicasts even without any local addresses configured. 298 */ 299 if (TAILQ_EMPTY(&in_ifaddrhead)) 300 goto bad; 301 ipstat.ips_total++; 302 303 if (m->m_pkthdr.len < sizeof(struct ip)) 304 goto tooshort; 305 306 if (m->m_len < sizeof (struct ip) && 307 (m = m_pullup(m, sizeof (struct ip))) == 0) { 308 ipstat.ips_toosmall++; 309 return; 310 } 311 ip = mtod(m, struct ip *); 312 313 if (IP_VHL_V(ip->ip_vhl) != IPVERSION) { 314 ipstat.ips_badvers++; 315 goto bad; 316 } 317 318 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 319 if (hlen < sizeof(struct ip)) { /* minimum header length */ 320 ipstat.ips_badhlen++; 321 goto bad; 322 } 323 if (hlen > m->m_len) { 324 if ((m = m_pullup(m, hlen)) == 0) { 325 ipstat.ips_badhlen++; 326 return; 327 } 328 ip = mtod(m, struct ip *); 329 } 330 if (hlen == sizeof(struct ip)) { 331 sum = in_cksum_hdr(ip); 332 } else { 333 sum = in_cksum(m, hlen); 334 } 335 if (sum) { 336 ipstat.ips_badsum++; 337 goto bad; 338 } 339 340 /* 341 * Convert fields to host representation. 342 */ 343 NTOHS(ip->ip_len); 344 if (ip->ip_len < hlen) { 345 ipstat.ips_badlen++; 346 goto bad; 347 } 348 NTOHS(ip->ip_id); 349 NTOHS(ip->ip_off); 350 351 /* 352 * Check that the amount of data in the buffers 353 * is as at least much as the IP header would have us expect. 354 * Trim mbufs if longer than we expect. 355 * Drop packet if shorter than we expect. 356 */ 357 if (m->m_pkthdr.len < ip->ip_len) { 358 tooshort: 359 ipstat.ips_tooshort++; 360 goto bad; 361 } 362 if (m->m_pkthdr.len > ip->ip_len) { 363 if (m->m_len == m->m_pkthdr.len) { 364 m->m_len = ip->ip_len; 365 m->m_pkthdr.len = ip->ip_len; 366 } else 367 m_adj(m, ip->ip_len - m->m_pkthdr.len); 368 } 369 /* 370 * IpHack's section. 371 * Right now when no processing on packet has done 372 * and it is still fresh out of network we do our black 373 * deals with it. 374 * - Firewall: deny/allow/divert 375 * - Xlate: translate packet's addr/port (NAT). 376 * - Pipe: pass pkt through dummynet. 377 * - Wrap: fake packet's addr/port <unimpl.> 378 * - Encapsulate: put it in another IP and send out. <unimp.> 379 */ 380 381 iphack: 382 #if defined(IPFILTER) || defined(IPFILTER_LKM) 383 /* 384 * Check if we want to allow this packet to be processed. 385 * Consider it to be bad if not. 386 */ 387 if (fr_checkp) { 388 struct mbuf *m1 = m; 389 390 if ((*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m1) || !m1) 391 return; 392 ip = mtod(m = m1, struct ip *); 393 } 394 #endif 395 #ifdef COMPAT_IPFW 396 if (ip_fw_chk_ptr) { 397 #ifdef IPFIREWALL_FORWARD 398 /* 399 * If we've been forwarded from the output side, then 400 * skip the firewall a second time 401 */ 402 if (ip_fw_fwd_addr) 403 goto ours; 404 #endif /* IPFIREWALL_FORWARD */ 405 i = (*ip_fw_chk_ptr)(&ip, hlen, NULL, &ip_divert_cookie, 406 &m, &rule, &ip_fw_fwd_addr); 407 /* 408 * see the comment in ip_output for the return values 409 * produced by the firewall. 410 */ 411 if (!m) /* packet discarded by firewall */ 412 return ; 413 if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */ 414 goto pass ; 415 #ifdef DUMMYNET 416 if (i & 0x10000) { 417 /* send packet to the appropriate pipe */ 418 dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule); 419 return ; 420 } 421 #endif 422 #ifdef IPDIVERT 423 if (i > 0 && i < 0x10000) { 424 /* Divert packet */ 425 frag_divert_port = i & 0xffff ; 426 goto ours; 427 } 428 #endif 429 #ifdef IPFIREWALL_FORWARD 430 if (i == 0 && ip_fw_fwd_addr != NULL) 431 goto pass ; 432 #endif 433 /* 434 * if we get here, the packet must be dropped 435 */ 436 m_freem(m); 437 return; 438 } 439 pass: 440 441 if (ip_nat_ptr && !(*ip_nat_ptr)(&ip, &m, m->m_pkthdr.rcvif, IP_NAT_IN)) 442 return; 443 #endif /* !COMPAT_IPFW */ 444 445 /* 446 * Process options and, if not destined for us, 447 * ship it on. ip_dooptions returns 1 when an 448 * error was detected (causing an icmp message 449 * to be sent and the original packet to be freed). 450 */ 451 ip_nhops = 0; /* for source routed packets */ 452 if (hlen > sizeof (struct ip) && ip_dooptions(m)) 453 return; 454 455 /* greedy RSVP, snatches any PATH packet of the RSVP protocol and no 456 * matter if it is destined to another node, or whether it is 457 * a multicast one, RSVP wants it! and prevents it from being forwarded 458 * anywhere else. Also checks if the rsvp daemon is running before 459 * grabbing the packet. 460 */ 461 if (rsvp_on && ip->ip_p==IPPROTO_RSVP) 462 goto ours; 463 464 /* 465 * Check our list of addresses, to see if the packet is for us. 466 */ 467 for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; 468 ia = TAILQ_NEXT(ia, ia_link)) { 469 #define satosin(sa) ((struct sockaddr_in *)(sa)) 470 471 if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr) 472 goto ours; 473 #ifdef BOOTP_COMPAT 474 if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY) 475 goto ours; 476 #endif 477 #ifdef IPFIREWALL_FORWARD 478 /* 479 * If the addr to forward to is one of ours, we pretend to 480 * be the destination for this packet. 481 */ 482 if (ip_fw_fwd_addr != NULL && 483 IA_SIN(ia)->sin_addr.s_addr == 484 ip_fw_fwd_addr->sin_addr.s_addr) 485 goto ours; 486 #endif 487 if (ia->ia_ifp && ia->ia_ifp->if_flags & IFF_BROADCAST) { 488 if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == 489 ip->ip_dst.s_addr) 490 goto ours; 491 if (ip->ip_dst.s_addr == ia->ia_netbroadcast.s_addr) 492 goto ours; 493 } 494 } 495 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { 496 struct in_multi *inm; 497 if (ip_mrouter) { 498 /* 499 * If we are acting as a multicast router, all 500 * incoming multicast packets are passed to the 501 * kernel-level multicast forwarding function. 502 * The packet is returned (relatively) intact; if 503 * ip_mforward() returns a non-zero value, the packet 504 * must be discarded, else it may be accepted below. 505 * 506 * (The IP ident field is put in the same byte order 507 * as expected when ip_mforward() is called from 508 * ip_output().) 509 */ 510 ip->ip_id = htons(ip->ip_id); 511 if (ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) { 512 ipstat.ips_cantforward++; 513 m_freem(m); 514 return; 515 } 516 ip->ip_id = ntohs(ip->ip_id); 517 518 /* 519 * The process-level routing demon needs to receive 520 * all multicast IGMP packets, whether or not this 521 * host belongs to their destination groups. 522 */ 523 if (ip->ip_p == IPPROTO_IGMP) 524 goto ours; 525 ipstat.ips_forward++; 526 } 527 /* 528 * See if we belong to the destination multicast group on the 529 * arrival interface. 530 */ 531 IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm); 532 if (inm == NULL) { 533 ipstat.ips_notmember++; 534 m_freem(m); 535 return; 536 } 537 goto ours; 538 } 539 if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST) 540 goto ours; 541 if (ip->ip_dst.s_addr == INADDR_ANY) 542 goto ours; 543 544 /* 545 * Not for us; forward if possible and desirable. 546 */ 547 if (ipforwarding == 0) { 548 ipstat.ips_cantforward++; 549 m_freem(m); 550 } else 551 ip_forward(m, 0); 552 return; 553 554 ours: 555 556 /* 557 * If offset or IP_MF are set, must reassemble. 558 * Otherwise, nothing need be done. 559 * (We could look in the reassembly queue to see 560 * if the packet was previously fragmented, 561 * but it's not worth the time; just let them time out.) 562 */ 563 if (ip->ip_off & (IP_MF | IP_OFFMASK | IP_RF)) { 564 if (m->m_flags & M_EXT) { /* XXX */ 565 if ((m = m_pullup(m, hlen)) == 0) { 566 ipstat.ips_toosmall++; 567 #ifdef IPDIVERT 568 frag_divert_port = 0; 569 ip_divert_cookie = 0; 570 #endif 571 return; 572 } 573 ip = mtod(m, struct ip *); 574 } 575 sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); 576 /* 577 * Look for queue of fragments 578 * of this datagram. 579 */ 580 for (fp = ipq[sum].next; fp != &ipq[sum]; fp = fp->next) 581 if (ip->ip_id == fp->ipq_id && 582 ip->ip_src.s_addr == fp->ipq_src.s_addr && 583 ip->ip_dst.s_addr == fp->ipq_dst.s_addr && 584 ip->ip_p == fp->ipq_p) 585 goto found; 586 587 fp = 0; 588 589 /* check if there's a place for the new queue */ 590 if (nipq > maxnipq) { 591 /* 592 * drop something from the tail of the current queue 593 * before proceeding further 594 */ 595 if (ipq[sum].prev == &ipq[sum]) { /* gak */ 596 for (i = 0; i < IPREASS_NHASH; i++) { 597 if (ipq[i].prev != &ipq[i]) { 598 ip_freef(ipq[i].prev); 599 break; 600 } 601 } 602 } else 603 ip_freef(ipq[sum].prev); 604 } 605 found: 606 /* 607 * Adjust ip_len to not reflect header, 608 * set ip_mff if more fragments are expected, 609 * convert offset of this to bytes. 610 */ 611 ip->ip_len -= hlen; 612 mff = (ip->ip_off & IP_MF) != 0; 613 if (mff) { 614 /* 615 * Make sure that fragments have a data length 616 * that's a non-zero multiple of 8 bytes. 617 */ 618 if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) { 619 ipstat.ips_toosmall++; /* XXX */ 620 goto bad; 621 } 622 m->m_flags |= M_FRAG; 623 } 624 ip->ip_off <<= 3; 625 626 /* 627 * If datagram marked as having more fragments 628 * or if this is not the first fragment, 629 * attempt reassembly; if it succeeds, proceed. 630 */ 631 if (mff || ip->ip_off) { 632 ipstat.ips_fragments++; 633 m->m_pkthdr.header = ip; 634 ip = ip_reass(m, fp, &ipq[sum]); 635 if (ip == 0) { 636 #ifdef IPFIREWALL_FORWARD 637 ip_fw_fwd_addr = NULL; 638 #endif 639 return; 640 } 641 /* Get the length of the reassembled packets header */ 642 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 643 ipstat.ips_reassembled++; 644 m = dtom(ip); 645 #ifdef IPDIVERT 646 if (frag_divert_port) { 647 ip->ip_len += hlen; 648 HTONS(ip->ip_len); 649 HTONS(ip->ip_off); 650 HTONS(ip->ip_id); 651 ip->ip_sum = 0; 652 ip->ip_sum = in_cksum_hdr(ip); 653 NTOHS(ip->ip_id); 654 NTOHS(ip->ip_off); 655 NTOHS(ip->ip_len); 656 ip->ip_len -= hlen; 657 } 658 #endif 659 } else 660 if (fp) 661 ip_freef(fp); 662 } else 663 ip->ip_len -= hlen; 664 665 #ifdef IPDIVERT 666 /* 667 * Divert reassembled packets to the divert protocol if required 668 * If divert port is null then cookie should be too, 669 * so we shouldn't need to clear them here. Assume ip_divert does so. 670 */ 671 if (frag_divert_port) { 672 ipstat.ips_delivered++; 673 ip_divert_port = frag_divert_port; 674 frag_divert_port = 0; 675 (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, hlen); 676 return; 677 } 678 679 /* Don't let packets divert themselves */ 680 if (ip->ip_p == IPPROTO_DIVERT) { 681 ipstat.ips_noproto++; 682 goto bad; 683 } 684 685 #endif 686 687 /* 688 * Switch out to protocol's input routine. 689 */ 690 ipstat.ips_delivered++; 691 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); 692 #ifdef IPFIREWALL_FORWARD 693 ip_fw_fwd_addr = NULL; /* tcp needed it */ 694 #endif 695 return; 696 bad: 697 #ifdef IPFIREWALL_FORWARD 698 ip_fw_fwd_addr = NULL; 699 #endif 700 m_freem(m); 701 } 702 703 /* 704 * IP software interrupt routine - to go away sometime soon 705 */ 706 static void 707 ipintr(void) 708 { 709 int s; 710 struct mbuf *m; 711 712 while(1) { 713 s = splimp(); 714 IF_DEQUEUE(&ipintrq, m); 715 splx(s); 716 if (m == 0) 717 return; 718 ip_input(m); 719 } 720 } 721 722 NETISR_SET(NETISR_IP, ipintr); 723 724 /* 725 * Take incoming datagram fragment and try to 726 * reassemble it into whole datagram. If a chain for 727 * reassembly of this datagram already exists, then it 728 * is given as fp; otherwise have to make a chain. 729 */ 730 static struct ip * 731 ip_reass(m, fp, where) 732 register struct mbuf *m; 733 register struct ipq *fp; 734 struct ipq *where; 735 { 736 struct ip *ip = mtod(m, struct ip *); 737 register struct mbuf *p = 0, *q, *nq; 738 struct mbuf *t; 739 int hlen = IP_VHL_HL(ip->ip_vhl) << 2; 740 int i, next; 741 742 /* 743 * Presence of header sizes in mbufs 744 * would confuse code below. 745 */ 746 m->m_data += hlen; 747 m->m_len -= hlen; 748 749 /* 750 * If first fragment to arrive, create a reassembly queue. 751 */ 752 if (fp == 0) { 753 if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL) 754 goto dropfrag; 755 fp = mtod(t, struct ipq *); 756 insque(fp, where); 757 nipq++; 758 fp->ipq_ttl = IPFRAGTTL; 759 fp->ipq_p = ip->ip_p; 760 fp->ipq_id = ip->ip_id; 761 fp->ipq_src = ip->ip_src; 762 fp->ipq_dst = ip->ip_dst; 763 fp->ipq_frags = m; 764 m->m_nextpkt = NULL; 765 #ifdef IPDIVERT 766 fp->ipq_divert = 0; 767 fp->ipq_div_cookie = 0; 768 #endif 769 goto inserted; 770 } 771 772 #define GETIP(m) ((struct ip*)((m)->m_pkthdr.header)) 773 774 /* 775 * Find a segment which begins after this one does. 776 */ 777 for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt) 778 if (GETIP(q)->ip_off > ip->ip_off) 779 break; 780 781 /* 782 * If there is a preceding segment, it may provide some of 783 * our data already. If so, drop the data from the incoming 784 * segment. If it provides all of our data, drop us, otherwise 785 * stick new segment in the proper place. 786 */ 787 if (p) { 788 i = GETIP(p)->ip_off + GETIP(p)->ip_len - ip->ip_off; 789 if (i > 0) { 790 if (i >= ip->ip_len) 791 goto dropfrag; 792 m_adj(dtom(ip), i); 793 ip->ip_off += i; 794 ip->ip_len -= i; 795 } 796 m->m_nextpkt = p->m_nextpkt; 797 p->m_nextpkt = m; 798 } else { 799 m->m_nextpkt = fp->ipq_frags; 800 fp->ipq_frags = m; 801 } 802 803 /* 804 * While we overlap succeeding segments trim them or, 805 * if they are completely covered, dequeue them. 806 */ 807 for (; q != NULL && ip->ip_off + ip->ip_len > GETIP(q)->ip_off; 808 q = nq) { 809 i = (ip->ip_off + ip->ip_len) - 810 GETIP(q)->ip_off; 811 if (i < GETIP(q)->ip_len) { 812 GETIP(q)->ip_len -= i; 813 GETIP(q)->ip_off += i; 814 m_adj(q, i); 815 break; 816 } 817 nq = q->m_nextpkt; 818 m->m_nextpkt = nq; 819 m_freem(q); 820 } 821 822 inserted: 823 824 #ifdef IPDIVERT 825 /* 826 * Any fragment diverting causes the whole packet to divert 827 */ 828 if (frag_divert_port) { 829 fp->ipq_divert = frag_divert_port; 830 fp->ipq_div_cookie = ip_divert_cookie; 831 } 832 frag_divert_port = 0; 833 ip_divert_cookie = 0; 834 #endif 835 836 /* 837 * Check for complete reassembly. 838 */ 839 next = 0; 840 for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt) { 841 if (GETIP(q)->ip_off != next) 842 return (0); 843 next += GETIP(q)->ip_len; 844 } 845 /* Make sure the last packet didn't have the IP_MF flag */ 846 if (p->m_flags & M_FRAG) 847 return (0); 848 849 /* 850 * Reassembly is complete. Make sure the packet is a sane size. 851 */ 852 q = fp->ipq_frags; 853 ip = GETIP(q); 854 if (next + (IP_VHL_HL(ip->ip_vhl) << 2) > IP_MAXPACKET) { 855 ipstat.ips_toolong++; 856 ip_freef(fp); 857 return (0); 858 } 859 860 /* 861 * Concatenate fragments. 862 */ 863 m = q; 864 t = m->m_next; 865 m->m_next = 0; 866 m_cat(m, t); 867 nq = q->m_nextpkt; 868 q->m_nextpkt = 0; 869 for (q = nq; q != NULL; q = nq) { 870 nq = q->m_nextpkt; 871 q->m_nextpkt = NULL; 872 m_cat(m, q); 873 } 874 875 #ifdef IPDIVERT 876 /* 877 * extract divert port for packet, if any 878 */ 879 frag_divert_port = fp->ipq_divert; 880 ip_divert_cookie = fp->ipq_div_cookie; 881 #endif 882 883 /* 884 * Create header for new ip packet by 885 * modifying header of first packet; 886 * dequeue and discard fragment reassembly header. 887 * Make header visible. 888 */ 889 ip->ip_len = next; 890 ip->ip_src = fp->ipq_src; 891 ip->ip_dst = fp->ipq_dst; 892 remque(fp); 893 nipq--; 894 (void) m_free(dtom(fp)); 895 m->m_len += (IP_VHL_HL(ip->ip_vhl) << 2); 896 m->m_data -= (IP_VHL_HL(ip->ip_vhl) << 2); 897 /* some debugging cruft by sklower, below, will go away soon */ 898 if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ 899 register int plen = 0; 900 for (t = m; m; m = m->m_next) 901 plen += m->m_len; 902 t->m_pkthdr.len = plen; 903 } 904 return (ip); 905 906 dropfrag: 907 #ifdef IPDIVERT 908 frag_divert_port = 0; 909 ip_divert_cookie = 0; 910 #endif 911 ipstat.ips_fragdropped++; 912 m_freem(m); 913 return (0); 914 915 #undef GETIP 916 } 917 918 /* 919 * Free a fragment reassembly header and all 920 * associated datagrams. 921 */ 922 static void 923 ip_freef(fp) 924 struct ipq *fp; 925 { 926 register struct mbuf *q; 927 928 while (fp->ipq_frags) { 929 q = fp->ipq_frags; 930 fp->ipq_frags = q->m_nextpkt; 931 m_freem(q); 932 } 933 remque(fp); 934 (void) m_free(dtom(fp)); 935 nipq--; 936 } 937 938 /* 939 * IP timer processing; 940 * if a timer expires on a reassembly 941 * queue, discard it. 942 */ 943 void 944 ip_slowtimo() 945 { 946 register struct ipq *fp; 947 int s = splnet(); 948 int i; 949 950 for (i = 0; i < IPREASS_NHASH; i++) { 951 fp = ipq[i].next; 952 if (fp == 0) 953 continue; 954 while (fp != &ipq[i]) { 955 --fp->ipq_ttl; 956 fp = fp->next; 957 if (fp->prev->ipq_ttl == 0) { 958 ipstat.ips_fragtimeout++; 959 ip_freef(fp->prev); 960 } 961 } 962 } 963 ipflow_slowtimo(); 964 splx(s); 965 } 966 967 /* 968 * Drain off all datagram fragments. 969 */ 970 void 971 ip_drain() 972 { 973 int i; 974 975 for (i = 0; i < IPREASS_NHASH; i++) { 976 while (ipq[i].next != &ipq[i]) { 977 ipstat.ips_fragdropped++; 978 ip_freef(ipq[i].next); 979 } 980 } 981 in_rtqdrain(); 982 } 983 984 /* 985 * Do option processing on a datagram, 986 * possibly discarding it if bad options are encountered, 987 * or forwarding it if source-routed. 988 * Returns 1 if packet has been forwarded/freed, 989 * 0 if the packet should be processed further. 990 */ 991 static int 992 ip_dooptions(m) 993 struct mbuf *m; 994 { 995 register struct ip *ip = mtod(m, struct ip *); 996 register u_char *cp; 997 register struct ip_timestamp *ipt; 998 register struct in_ifaddr *ia; 999 int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; 1000 struct in_addr *sin, dst; 1001 n_time ntime; 1002 1003 dst = ip->ip_dst; 1004 cp = (u_char *)(ip + 1); 1005 cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip); 1006 for (; cnt > 0; cnt -= optlen, cp += optlen) { 1007 opt = cp[IPOPT_OPTVAL]; 1008 if (opt == IPOPT_EOL) 1009 break; 1010 if (opt == IPOPT_NOP) 1011 optlen = 1; 1012 else { 1013 optlen = cp[IPOPT_OLEN]; 1014 if (optlen <= 0 || optlen > cnt) { 1015 code = &cp[IPOPT_OLEN] - (u_char *)ip; 1016 goto bad; 1017 } 1018 } 1019 switch (opt) { 1020 1021 default: 1022 break; 1023 1024 /* 1025 * Source routing with record. 1026 * Find interface with current destination address. 1027 * If none on this machine then drop if strictly routed, 1028 * or do nothing if loosely routed. 1029 * Record interface address and bring up next address 1030 * component. If strictly routed make sure next 1031 * address is on directly accessible net. 1032 */ 1033 case IPOPT_LSRR: 1034 case IPOPT_SSRR: 1035 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { 1036 code = &cp[IPOPT_OFFSET] - (u_char *)ip; 1037 goto bad; 1038 } 1039 ipaddr.sin_addr = ip->ip_dst; 1040 ia = (struct in_ifaddr *) 1041 ifa_ifwithaddr((struct sockaddr *)&ipaddr); 1042 if (ia == 0) { 1043 if (opt == IPOPT_SSRR) { 1044 type = ICMP_UNREACH; 1045 code = ICMP_UNREACH_SRCFAIL; 1046 goto bad; 1047 } 1048 if (!ip_dosourceroute) 1049 goto nosourcerouting; 1050 /* 1051 * Loose routing, and not at next destination 1052 * yet; nothing to do except forward. 1053 */ 1054 break; 1055 } 1056 off--; /* 0 origin */ 1057 if (off > optlen - sizeof(struct in_addr)) { 1058 /* 1059 * End of source route. Should be for us. 1060 */ 1061 if (!ip_acceptsourceroute) 1062 goto nosourcerouting; 1063 save_rte(cp, ip->ip_src); 1064 break; 1065 } 1066 1067 if (!ip_dosourceroute) { 1068 if (ipforwarding) { 1069 char buf[16]; /* aaa.bbb.ccc.ddd\0 */ 1070 /* 1071 * Acting as a router, so generate ICMP 1072 */ 1073 nosourcerouting: 1074 strcpy(buf, inet_ntoa(ip->ip_dst)); 1075 log(LOG_WARNING, 1076 "attempted source route from %s to %s\n", 1077 inet_ntoa(ip->ip_src), buf); 1078 type = ICMP_UNREACH; 1079 code = ICMP_UNREACH_SRCFAIL; 1080 goto bad; 1081 } else { 1082 /* 1083 * Not acting as a router, so silently drop. 1084 */ 1085 ipstat.ips_cantforward++; 1086 m_freem(m); 1087 return (1); 1088 } 1089 } 1090 1091 /* 1092 * locate outgoing interface 1093 */ 1094 (void)memcpy(&ipaddr.sin_addr, cp + off, 1095 sizeof(ipaddr.sin_addr)); 1096 1097 if (opt == IPOPT_SSRR) { 1098 #define INA struct in_ifaddr * 1099 #define SA struct sockaddr * 1100 if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0) 1101 ia = (INA)ifa_ifwithnet((SA)&ipaddr); 1102 } else 1103 ia = ip_rtaddr(ipaddr.sin_addr); 1104 if (ia == 0) { 1105 type = ICMP_UNREACH; 1106 code = ICMP_UNREACH_SRCFAIL; 1107 goto bad; 1108 } 1109 ip->ip_dst = ipaddr.sin_addr; 1110 (void)memcpy(cp + off, &(IA_SIN(ia)->sin_addr), 1111 sizeof(struct in_addr)); 1112 cp[IPOPT_OFFSET] += sizeof(struct in_addr); 1113 /* 1114 * Let ip_intr's mcast routing check handle mcast pkts 1115 */ 1116 forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)); 1117 break; 1118 1119 case IPOPT_RR: 1120 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { 1121 code = &cp[IPOPT_OFFSET] - (u_char *)ip; 1122 goto bad; 1123 } 1124 /* 1125 * If no space remains, ignore. 1126 */ 1127 off--; /* 0 origin */ 1128 if (off > optlen - sizeof(struct in_addr)) 1129 break; 1130 (void)memcpy(&ipaddr.sin_addr, &ip->ip_dst, 1131 sizeof(ipaddr.sin_addr)); 1132 /* 1133 * locate outgoing interface; if we're the destination, 1134 * use the incoming interface (should be same). 1135 */ 1136 if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 && 1137 (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) { 1138 type = ICMP_UNREACH; 1139 code = ICMP_UNREACH_HOST; 1140 goto bad; 1141 } 1142 (void)memcpy(cp + off, &(IA_SIN(ia)->sin_addr), 1143 sizeof(struct in_addr)); 1144 cp[IPOPT_OFFSET] += sizeof(struct in_addr); 1145 break; 1146 1147 case IPOPT_TS: 1148 code = cp - (u_char *)ip; 1149 ipt = (struct ip_timestamp *)cp; 1150 if (ipt->ipt_len < 5) 1151 goto bad; 1152 if (ipt->ipt_ptr > ipt->ipt_len - sizeof(int32_t)) { 1153 if (++ipt->ipt_oflw == 0) 1154 goto bad; 1155 break; 1156 } 1157 sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); 1158 switch (ipt->ipt_flg) { 1159 1160 case IPOPT_TS_TSONLY: 1161 break; 1162 1163 case IPOPT_TS_TSANDADDR: 1164 if (ipt->ipt_ptr - 1 + sizeof(n_time) + 1165 sizeof(struct in_addr) > ipt->ipt_len) 1166 goto bad; 1167 ipaddr.sin_addr = dst; 1168 ia = (INA)ifaof_ifpforaddr((SA)&ipaddr, 1169 m->m_pkthdr.rcvif); 1170 if (ia == 0) 1171 continue; 1172 (void)memcpy(sin, &IA_SIN(ia)->sin_addr, 1173 sizeof(struct in_addr)); 1174 ipt->ipt_ptr += sizeof(struct in_addr); 1175 break; 1176 1177 case IPOPT_TS_PRESPEC: 1178 if (ipt->ipt_ptr - 1 + sizeof(n_time) + 1179 sizeof(struct in_addr) > ipt->ipt_len) 1180 goto bad; 1181 (void)memcpy(&ipaddr.sin_addr, sin, 1182 sizeof(struct in_addr)); 1183 if (ifa_ifwithaddr((SA)&ipaddr) == 0) 1184 continue; 1185 ipt->ipt_ptr += sizeof(struct in_addr); 1186 break; 1187 1188 default: 1189 goto bad; 1190 } 1191 ntime = iptime(); 1192 (void)memcpy(cp + ipt->ipt_ptr - 1, &ntime, 1193 sizeof(n_time)); 1194 ipt->ipt_ptr += sizeof(n_time); 1195 } 1196 } 1197 if (forward && ipforwarding) { 1198 ip_forward(m, 1); 1199 return (1); 1200 } 1201 return (0); 1202 bad: 1203 ip->ip_len -= IP_VHL_HL(ip->ip_vhl) << 2; /* XXX icmp_error adds in hdr length */ 1204 icmp_error(m, type, code, 0, 0); 1205 ipstat.ips_badoptions++; 1206 return (1); 1207 } 1208 1209 /* 1210 * Given address of next destination (final or next hop), 1211 * return internet address info of interface to be used to get there. 1212 */ 1213 static struct in_ifaddr * 1214 ip_rtaddr(dst) 1215 struct in_addr dst; 1216 { 1217 register struct sockaddr_in *sin; 1218 1219 sin = (struct sockaddr_in *) &ipforward_rt.ro_dst; 1220 1221 if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) { 1222 if (ipforward_rt.ro_rt) { 1223 RTFREE(ipforward_rt.ro_rt); 1224 ipforward_rt.ro_rt = 0; 1225 } 1226 sin->sin_family = AF_INET; 1227 sin->sin_len = sizeof(*sin); 1228 sin->sin_addr = dst; 1229 1230 rtalloc_ign(&ipforward_rt, RTF_PRCLONING); 1231 } 1232 if (ipforward_rt.ro_rt == 0) 1233 return ((struct in_ifaddr *)0); 1234 return ((struct in_ifaddr *) ipforward_rt.ro_rt->rt_ifa); 1235 } 1236 1237 /* 1238 * Save incoming source route for use in replies, 1239 * to be picked up later by ip_srcroute if the receiver is interested. 1240 */ 1241 void 1242 save_rte(option, dst) 1243 u_char *option; 1244 struct in_addr dst; 1245 { 1246 unsigned olen; 1247 1248 olen = option[IPOPT_OLEN]; 1249 #ifdef DIAGNOSTIC 1250 if (ipprintfs) 1251 printf("save_rte: olen %d\n", olen); 1252 #endif 1253 if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst))) 1254 return; 1255 bcopy(option, ip_srcrt.srcopt, olen); 1256 ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr); 1257 ip_srcrt.dst = dst; 1258 } 1259 1260 /* 1261 * Retrieve incoming source route for use in replies, 1262 * in the same form used by setsockopt. 1263 * The first hop is placed before the options, will be removed later. 1264 */ 1265 struct mbuf * 1266 ip_srcroute() 1267 { 1268 register struct in_addr *p, *q; 1269 register struct mbuf *m; 1270 1271 if (ip_nhops == 0) 1272 return ((struct mbuf *)0); 1273 m = m_get(M_DONTWAIT, MT_HEADER); 1274 if (m == 0) 1275 return ((struct mbuf *)0); 1276 1277 #define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt)) 1278 1279 /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */ 1280 m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) + 1281 OPTSIZ; 1282 #ifdef DIAGNOSTIC 1283 if (ipprintfs) 1284 printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len); 1285 #endif 1286 1287 /* 1288 * First save first hop for return route 1289 */ 1290 p = &ip_srcrt.route[ip_nhops - 1]; 1291 *(mtod(m, struct in_addr *)) = *p--; 1292 #ifdef DIAGNOSTIC 1293 if (ipprintfs) 1294 printf(" hops %lx", (u_long)ntohl(mtod(m, struct in_addr *)->s_addr)); 1295 #endif 1296 1297 /* 1298 * Copy option fields and padding (nop) to mbuf. 1299 */ 1300 ip_srcrt.nop = IPOPT_NOP; 1301 ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF; 1302 (void)memcpy(mtod(m, caddr_t) + sizeof(struct in_addr), 1303 &ip_srcrt.nop, OPTSIZ); 1304 q = (struct in_addr *)(mtod(m, caddr_t) + 1305 sizeof(struct in_addr) + OPTSIZ); 1306 #undef OPTSIZ 1307 /* 1308 * Record return path as an IP source route, 1309 * reversing the path (pointers are now aligned). 1310 */ 1311 while (p >= ip_srcrt.route) { 1312 #ifdef DIAGNOSTIC 1313 if (ipprintfs) 1314 printf(" %lx", (u_long)ntohl(q->s_addr)); 1315 #endif 1316 *q++ = *p--; 1317 } 1318 /* 1319 * Last hop goes to final destination. 1320 */ 1321 *q = ip_srcrt.dst; 1322 #ifdef DIAGNOSTIC 1323 if (ipprintfs) 1324 printf(" %lx\n", (u_long)ntohl(q->s_addr)); 1325 #endif 1326 return (m); 1327 } 1328 1329 /* 1330 * Strip out IP options, at higher 1331 * level protocol in the kernel. 1332 * Second argument is buffer to which options 1333 * will be moved, and return value is their length. 1334 * XXX should be deleted; last arg currently ignored. 1335 */ 1336 void 1337 ip_stripoptions(m, mopt) 1338 register struct mbuf *m; 1339 struct mbuf *mopt; 1340 { 1341 register int i; 1342 struct ip *ip = mtod(m, struct ip *); 1343 register caddr_t opts; 1344 int olen; 1345 1346 olen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip); 1347 opts = (caddr_t)(ip + 1); 1348 i = m->m_len - (sizeof (struct ip) + olen); 1349 bcopy(opts + olen, opts, (unsigned)i); 1350 m->m_len -= olen; 1351 if (m->m_flags & M_PKTHDR) 1352 m->m_pkthdr.len -= olen; 1353 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2); 1354 } 1355 1356 u_char inetctlerrmap[PRC_NCMDS] = { 1357 0, 0, 0, 0, 1358 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, 1359 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, 1360 EMSGSIZE, EHOSTUNREACH, 0, 0, 1361 0, 0, 0, 0, 1362 ENOPROTOOPT 1363 }; 1364 1365 /* 1366 * Forward a packet. If some error occurs return the sender 1367 * an icmp packet. Note we can't always generate a meaningful 1368 * icmp message because icmp doesn't have a large enough repertoire 1369 * of codes and types. 1370 * 1371 * If not forwarding, just drop the packet. This could be confusing 1372 * if ipforwarding was zero but some routing protocol was advancing 1373 * us as a gateway to somewhere. However, we must let the routing 1374 * protocol deal with that. 1375 * 1376 * The srcrt parameter indicates whether the packet is being forwarded 1377 * via a source route. 1378 */ 1379 static void 1380 ip_forward(m, srcrt) 1381 struct mbuf *m; 1382 int srcrt; 1383 { 1384 register struct ip *ip = mtod(m, struct ip *); 1385 register struct sockaddr_in *sin; 1386 register struct rtentry *rt; 1387 int error, type = 0, code = 0; 1388 struct mbuf *mcopy; 1389 n_long dest; 1390 struct ifnet *destifp; 1391 1392 dest = 0; 1393 #ifdef DIAGNOSTIC 1394 if (ipprintfs) 1395 printf("forward: src %lx dst %lx ttl %x\n", 1396 (u_long)ip->ip_src.s_addr, (u_long)ip->ip_dst.s_addr, 1397 ip->ip_ttl); 1398 #endif 1399 1400 1401 if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) { 1402 ipstat.ips_cantforward++; 1403 m_freem(m); 1404 return; 1405 } 1406 HTONS(ip->ip_id); 1407 if (ip->ip_ttl <= IPTTLDEC) { 1408 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0); 1409 return; 1410 } 1411 ip->ip_ttl -= IPTTLDEC; 1412 1413 sin = (struct sockaddr_in *)&ipforward_rt.ro_dst; 1414 if ((rt = ipforward_rt.ro_rt) == 0 || 1415 ip->ip_dst.s_addr != sin->sin_addr.s_addr) { 1416 if (ipforward_rt.ro_rt) { 1417 RTFREE(ipforward_rt.ro_rt); 1418 ipforward_rt.ro_rt = 0; 1419 } 1420 sin->sin_family = AF_INET; 1421 sin->sin_len = sizeof(*sin); 1422 sin->sin_addr = ip->ip_dst; 1423 1424 rtalloc_ign(&ipforward_rt, RTF_PRCLONING); 1425 if (ipforward_rt.ro_rt == 0) { 1426 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); 1427 return; 1428 } 1429 rt = ipforward_rt.ro_rt; 1430 } 1431 1432 /* 1433 * Save at most 64 bytes of the packet in case 1434 * we need to generate an ICMP message to the src. 1435 */ 1436 mcopy = m_copy(m, 0, imin((int)ip->ip_len, 64)); 1437 1438 /* 1439 * If forwarding packet using same interface that it came in on, 1440 * perhaps should send a redirect to sender to shortcut a hop. 1441 * Only send redirect if source is sending directly to us, 1442 * and if packet was not source routed (or has any options). 1443 * Also, don't send redirect if forwarding using a default route 1444 * or a route modified by a redirect. 1445 */ 1446 #define satosin(sa) ((struct sockaddr_in *)(sa)) 1447 if (rt->rt_ifp == m->m_pkthdr.rcvif && 1448 (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 && 1449 satosin(rt_key(rt))->sin_addr.s_addr != 0 && 1450 ipsendredirects && !srcrt) { 1451 #define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa)) 1452 u_long src = ntohl(ip->ip_src.s_addr); 1453 1454 if (RTA(rt) && 1455 (src & RTA(rt)->ia_subnetmask) == RTA(rt)->ia_subnet) { 1456 if (rt->rt_flags & RTF_GATEWAY) 1457 dest = satosin(rt->rt_gateway)->sin_addr.s_addr; 1458 else 1459 dest = ip->ip_dst.s_addr; 1460 /* Router requirements says to only send host redirects */ 1461 type = ICMP_REDIRECT; 1462 code = ICMP_REDIRECT_HOST; 1463 #ifdef DIAGNOSTIC 1464 if (ipprintfs) 1465 printf("redirect (%d) to %lx\n", code, (u_long)dest); 1466 #endif 1467 } 1468 } 1469 1470 error = ip_output(m, (struct mbuf *)0, &ipforward_rt, 1471 IP_FORWARDING, 0); 1472 if (error) 1473 ipstat.ips_cantforward++; 1474 else { 1475 ipstat.ips_forward++; 1476 if (type) 1477 ipstat.ips_redirectsent++; 1478 else { 1479 if (mcopy) { 1480 ipflow_create(&ipforward_rt, mcopy); 1481 m_freem(mcopy); 1482 } 1483 return; 1484 } 1485 } 1486 if (mcopy == NULL) 1487 return; 1488 destifp = NULL; 1489 1490 switch (error) { 1491 1492 case 0: /* forwarded, but need redirect */ 1493 /* type, code set above */ 1494 break; 1495 1496 case ENETUNREACH: /* shouldn't happen, checked above */ 1497 case EHOSTUNREACH: 1498 case ENETDOWN: 1499 case EHOSTDOWN: 1500 default: 1501 type = ICMP_UNREACH; 1502 code = ICMP_UNREACH_HOST; 1503 break; 1504 1505 case EMSGSIZE: 1506 type = ICMP_UNREACH; 1507 code = ICMP_UNREACH_NEEDFRAG; 1508 if (ipforward_rt.ro_rt) 1509 destifp = ipforward_rt.ro_rt->rt_ifp; 1510 ipstat.ips_cantfrag++; 1511 break; 1512 1513 case ENOBUFS: 1514 type = ICMP_SOURCEQUENCH; 1515 code = 0; 1516 break; 1517 } 1518 icmp_error(mcopy, type, code, dest, destifp); 1519 } 1520 1521 void 1522 ip_savecontrol(inp, mp, ip, m) 1523 register struct inpcb *inp; 1524 register struct mbuf **mp; 1525 register struct ip *ip; 1526 register struct mbuf *m; 1527 { 1528 if (inp->inp_socket->so_options & SO_TIMESTAMP) { 1529 struct timeval tv; 1530 1531 microtime(&tv); 1532 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv), 1533 SCM_TIMESTAMP, SOL_SOCKET); 1534 if (*mp) 1535 mp = &(*mp)->m_next; 1536 } 1537 if (inp->inp_flags & INP_RECVDSTADDR) { 1538 *mp = sbcreatecontrol((caddr_t) &ip->ip_dst, 1539 sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP); 1540 if (*mp) 1541 mp = &(*mp)->m_next; 1542 } 1543 #ifdef notyet 1544 /* XXX 1545 * Moving these out of udp_input() made them even more broken 1546 * than they already were. 1547 */ 1548 /* options were tossed already */ 1549 if (inp->inp_flags & INP_RECVOPTS) { 1550 *mp = sbcreatecontrol((caddr_t) opts_deleted_above, 1551 sizeof(struct in_addr), IP_RECVOPTS, IPPROTO_IP); 1552 if (*mp) 1553 mp = &(*mp)->m_next; 1554 } 1555 /* ip_srcroute doesn't do what we want here, need to fix */ 1556 if (inp->inp_flags & INP_RECVRETOPTS) { 1557 *mp = sbcreatecontrol((caddr_t) ip_srcroute(), 1558 sizeof(struct in_addr), IP_RECVRETOPTS, IPPROTO_IP); 1559 if (*mp) 1560 mp = &(*mp)->m_next; 1561 } 1562 #endif 1563 if (inp->inp_flags & INP_RECVIF) { 1564 struct ifnet *ifp; 1565 struct sdlbuf { 1566 struct sockaddr_dl sdl; 1567 u_char pad[32]; 1568 } sdlbuf; 1569 struct sockaddr_dl *sdp; 1570 struct sockaddr_dl *sdl2 = &sdlbuf.sdl; 1571 1572 if (((ifp = m->m_pkthdr.rcvif)) 1573 && ( ifp->if_index && (ifp->if_index <= if_index))) { 1574 sdp = (struct sockaddr_dl *)(ifnet_addrs 1575 [ifp->if_index - 1]->ifa_addr); 1576 /* 1577 * Change our mind and don't try copy. 1578 */ 1579 if ((sdp->sdl_family != AF_LINK) 1580 || (sdp->sdl_len > sizeof(sdlbuf))) { 1581 goto makedummy; 1582 } 1583 bcopy(sdp, sdl2, sdp->sdl_len); 1584 } else { 1585 makedummy: 1586 sdl2->sdl_len 1587 = offsetof(struct sockaddr_dl, sdl_data[0]); 1588 sdl2->sdl_family = AF_LINK; 1589 sdl2->sdl_index = 0; 1590 sdl2->sdl_nlen = sdl2->sdl_alen = sdl2->sdl_slen = 0; 1591 } 1592 *mp = sbcreatecontrol((caddr_t) sdl2, sdl2->sdl_len, 1593 IP_RECVIF, IPPROTO_IP); 1594 if (*mp) 1595 mp = &(*mp)->m_next; 1596 } 1597 } 1598 1599 int 1600 ip_rsvp_init(struct socket *so) 1601 { 1602 if (so->so_type != SOCK_RAW || 1603 so->so_proto->pr_protocol != IPPROTO_RSVP) 1604 return EOPNOTSUPP; 1605 1606 if (ip_rsvpd != NULL) 1607 return EADDRINUSE; 1608 1609 ip_rsvpd = so; 1610 /* 1611 * This may seem silly, but we need to be sure we don't over-increment 1612 * the RSVP counter, in case something slips up. 1613 */ 1614 if (!ip_rsvp_on) { 1615 ip_rsvp_on = 1; 1616 rsvp_on++; 1617 } 1618 1619 return 0; 1620 } 1621 1622 int 1623 ip_rsvp_done(void) 1624 { 1625 ip_rsvpd = NULL; 1626 /* 1627 * This may seem silly, but we need to be sure we don't over-decrement 1628 * the RSVP counter, in case something slips up. 1629 */ 1630 if (ip_rsvp_on) { 1631 ip_rsvp_on = 0; 1632 rsvp_on--; 1633 } 1634 return 0; 1635 } 1636