1 /* 2 * Copyright (c) 1982, 1986, 1988, 1993 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ip_input.c 7.28 (Berkeley) 05/31/93 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/malloc.h> 13 #include <sys/mbuf.h> 14 #include <sys/domain.h> 15 #include <sys/protosw.h> 16 #include <sys/socket.h> 17 #include <sys/errno.h> 18 #include <sys/time.h> 19 #include <sys/kernel.h> 20 21 #include <net/if.h> 22 #include <net/route.h> 23 24 #include <netinet/in.h> 25 #include <netinet/in_systm.h> 26 #include <netinet/ip.h> 27 #include <netinet/in_pcb.h> 28 #include <netinet/in_var.h> 29 #include <netinet/ip_var.h> 30 #include <netinet/ip_icmp.h> 31 32 #ifndef IPFORWARDING 33 #ifdef GATEWAY 34 #define IPFORWARDING 1 /* forward IP packets not for us */ 35 #else /* GATEWAY */ 36 #define IPFORWARDING 0 /* don't forward IP packets not for us */ 37 #endif /* GATEWAY */ 38 #endif /* IPFORWARDING */ 39 #ifndef IPSENDREDIRECTS 40 #define IPSENDREDIRECTS 1 41 #endif 42 int ipforwarding = IPFORWARDING; 43 int ipsendredirects = IPSENDREDIRECTS; 44 int ip_defttl = IPDEFTTL; 45 #ifdef DIAGNOSTIC 46 int ipprintfs = 0; 47 #endif 48 49 extern struct domain inetdomain; 50 extern struct protosw inetsw[]; 51 u_char ip_protox[IPPROTO_MAX]; 52 int ipqmaxlen = IFQ_MAXLEN; 53 struct in_ifaddr *in_ifaddr; /* first inet address */ 54 struct ifqueue ipintrq; 55 56 /* 57 * We need to save the IP options in case a protocol wants to respond 58 * to an incoming packet over the same route if the packet got here 59 * using IP source routing. This allows connection establishment and 60 * maintenance when the remote end is on a network that is not known 61 * to us. 62 */ 63 int ip_nhops = 0; 64 static struct ip_srcrt { 65 struct in_addr dst; /* final destination */ 66 char nop; /* one NOP to align */ 67 char srcopt[IPOPT_OFFSET + 1]; /* OPTVAL, OLEN and OFFSET */ 68 struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)]; 69 } ip_srcrt; 70 71 #ifdef GATEWAY 72 extern int if_index; 73 u_long *ip_ifmatrix; 74 #endif 75 76 /* 77 * IP initialization: fill in IP protocol switch table. 78 * All protocols not implemented in kernel go to raw IP protocol handler. 79 */ 80 ip_init() 81 { 82 register struct protosw *pr; 83 register int i; 84 85 pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); 86 if (pr == 0) 87 panic("ip_init"); 88 for (i = 0; i < IPPROTO_MAX; i++) 89 ip_protox[i] = pr - inetsw; 90 for (pr = inetdomain.dom_protosw; 91 pr < inetdomain.dom_protoswNPROTOSW; pr++) 92 if (pr->pr_domain->dom_family == PF_INET && 93 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 94 ip_protox[pr->pr_protocol] = pr - inetsw; 95 ipq.next = ipq.prev = &ipq; 96 ip_id = time.tv_sec & 0xffff; 97 ipintrq.ifq_maxlen = ipqmaxlen; 98 #ifdef GATEWAY 99 i = (if_index + 1) * (if_index + 1) * sizeof (u_long); 100 ip_ifmatrix = (u_long *) malloc(i, M_RTABLE, M_WAITOK); 101 bzero((char *)ip_ifmatrix, i); 102 #endif 103 } 104 105 struct ip *ip_reass(); 106 struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET }; 107 struct route ipforward_rt; 108 109 /* 110 * Ip input routine. Checksum and byte swap header. If fragmented 111 * try to reassemble. Process options. Pass to next level. 112 */ 113 ipintr() 114 { 115 register struct ip *ip; 116 register struct mbuf *m; 117 register struct ipq *fp; 118 register struct in_ifaddr *ia; 119 int hlen, s; 120 121 next: 122 /* 123 * Get next datagram off input queue and get IP header 124 * in first mbuf. 125 */ 126 s = splimp(); 127 IF_DEQUEUE(&ipintrq, m); 128 splx(s); 129 if (m == 0) 130 return; 131 #ifdef DIAGNOSTIC 132 if ((m->m_flags & M_PKTHDR) == 0) 133 panic("ipintr no HDR"); 134 #endif 135 /* 136 * If no IP addresses have been set yet but the interfaces 137 * are receiving, can't do anything with incoming packets yet. 138 */ 139 if (in_ifaddr == NULL) 140 goto bad; 141 ipstat.ips_total++; 142 if (m->m_len < sizeof (struct ip) && 143 (m = m_pullup(m, sizeof (struct ip))) == 0) { 144 ipstat.ips_toosmall++; 145 goto next; 146 } 147 ip = mtod(m, struct ip *); 148 if (ip->ip_v != IPVERSION) { 149 ipstat.ips_badvers++; 150 goto bad; 151 } 152 hlen = ip->ip_hl << 2; 153 if (hlen < sizeof(struct ip)) { /* minimum header length */ 154 ipstat.ips_badhlen++; 155 goto bad; 156 } 157 if (hlen > m->m_len) { 158 if ((m = m_pullup(m, hlen)) == 0) { 159 ipstat.ips_badhlen++; 160 goto next; 161 } 162 ip = mtod(m, struct ip *); 163 } 164 if (ip->ip_sum = in_cksum(m, hlen)) { 165 ipstat.ips_badsum++; 166 goto bad; 167 } 168 169 /* 170 * Convert fields to host representation. 171 */ 172 NTOHS(ip->ip_len); 173 if (ip->ip_len < hlen) { 174 ipstat.ips_badlen++; 175 goto bad; 176 } 177 NTOHS(ip->ip_id); 178 NTOHS(ip->ip_off); 179 180 /* 181 * Check that the amount of data in the buffers 182 * is as at least much as the IP header would have us expect. 183 * Trim mbufs if longer than we expect. 184 * Drop packet if shorter than we expect. 185 */ 186 if (m->m_pkthdr.len < ip->ip_len) { 187 ipstat.ips_tooshort++; 188 goto bad; 189 } 190 if (m->m_pkthdr.len > ip->ip_len) { 191 if (m->m_len == m->m_pkthdr.len) { 192 m->m_len = ip->ip_len; 193 m->m_pkthdr.len = ip->ip_len; 194 } else 195 m_adj(m, ip->ip_len - m->m_pkthdr.len); 196 } 197 198 /* 199 * Process options and, if not destined for us, 200 * ship it on. ip_dooptions returns 1 when an 201 * error was detected (causing an icmp message 202 * to be sent and the original packet to be freed). 203 */ 204 ip_nhops = 0; /* for source routed packets */ 205 if (hlen > sizeof (struct ip) && ip_dooptions(m)) 206 goto next; 207 208 /* 209 * Check our list of addresses, to see if the packet is for us. 210 */ 211 for (ia = in_ifaddr; ia; ia = ia->ia_next) { 212 #define satosin(sa) ((struct sockaddr_in *)(sa)) 213 214 if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr) 215 goto ours; 216 if ( 217 #ifdef DIRECTED_BROADCAST 218 ia->ia_ifp == m->m_pkthdr.rcvif && 219 #endif 220 (ia->ia_ifp->if_flags & IFF_BROADCAST)) { 221 u_long t; 222 223 if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == 224 ip->ip_dst.s_addr) 225 goto ours; 226 if (ip->ip_dst.s_addr == ia->ia_netbroadcast.s_addr) 227 goto ours; 228 /* 229 * Look for all-0's host part (old broadcast addr), 230 * either for subnet or net. 231 */ 232 t = ntohl(ip->ip_dst.s_addr); 233 if (t == ia->ia_subnet) 234 goto ours; 235 if (t == ia->ia_net) 236 goto ours; 237 } 238 } 239 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { 240 struct in_multi *inm; 241 #ifdef MROUTING 242 extern struct socket *ip_mrouter; 243 244 if (ip_mrouter) { 245 /* 246 * If we are acting as a multicast router, all 247 * incoming multicast packets are passed to the 248 * kernel-level multicast forwarding function. 249 * The packet is returned (relatively) intact; if 250 * ip_mforward() returns a non-zero value, the packet 251 * must be discarded, else it may be accepted below. 252 * 253 * (The IP ident field is put in the same byte order 254 * as expected when ip_mforward() is called from 255 * ip_output().) 256 */ 257 ip->ip_id = htons(ip->ip_id); 258 if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) { 259 ipstat.ips_cantforward++; 260 m_freem(m); 261 goto next; 262 } 263 ip->ip_id = ntohs(ip->ip_id); 264 265 /* 266 * The process-level routing demon needs to receive 267 * all multicast IGMP packets, whether or not this 268 * host belongs to their destination groups. 269 */ 270 if (ip->ip_p == IPPROTO_IGMP) 271 goto ours; 272 ipstat.ips_forward++; 273 } 274 #endif 275 /* 276 * See if we belong to the destination multicast group on the 277 * arrival interface. 278 */ 279 IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm); 280 if (inm == NULL) { 281 ipstat.ips_cantforward++; 282 m_freem(m); 283 goto next; 284 } 285 goto ours; 286 } 287 if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST) 288 goto ours; 289 if (ip->ip_dst.s_addr == INADDR_ANY) 290 goto ours; 291 292 /* 293 * Not for us; forward if possible and desirable. 294 */ 295 if (ipforwarding == 0) { 296 ipstat.ips_cantforward++; 297 m_freem(m); 298 } else 299 ip_forward(m, 0); 300 goto next; 301 302 ours: 303 /* 304 * If offset or IP_MF are set, must reassemble. 305 * Otherwise, nothing need be done. 306 * (We could look in the reassembly queue to see 307 * if the packet was previously fragmented, 308 * but it's not worth the time; just let them time out.) 309 */ 310 if (ip->ip_off &~ IP_DF) { 311 if (m->m_flags & M_EXT) { /* XXX */ 312 if ((m = m_pullup(m, sizeof (struct ip))) == 0) { 313 ipstat.ips_toosmall++; 314 goto next; 315 } 316 ip = mtod(m, struct ip *); 317 } 318 /* 319 * Look for queue of fragments 320 * of this datagram. 321 */ 322 for (fp = ipq.next; fp != &ipq; fp = fp->next) 323 if (ip->ip_id == fp->ipq_id && 324 ip->ip_src.s_addr == fp->ipq_src.s_addr && 325 ip->ip_dst.s_addr == fp->ipq_dst.s_addr && 326 ip->ip_p == fp->ipq_p) 327 goto found; 328 fp = 0; 329 found: 330 331 /* 332 * Adjust ip_len to not reflect header, 333 * set ip_mff if more fragments are expected, 334 * convert offset of this to bytes. 335 */ 336 ip->ip_len -= hlen; 337 ((struct ipasfrag *)ip)->ipf_mff &= ~1; 338 if (ip->ip_off & IP_MF) 339 ((struct ipasfrag *)ip)->ipf_mff |= 1; 340 ip->ip_off <<= 3; 341 342 /* 343 * If datagram marked as having more fragments 344 * or if this is not the first fragment, 345 * attempt reassembly; if it succeeds, proceed. 346 */ 347 if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { 348 ipstat.ips_fragments++; 349 ip = ip_reass((struct ipasfrag *)ip, fp); 350 if (ip == 0) 351 goto next; 352 ipstat.ips_reassembled++; 353 m = dtom(ip); 354 } else 355 if (fp) 356 ip_freef(fp); 357 } else 358 ip->ip_len -= hlen; 359 360 /* 361 * Switch out to protocol's input routine. 362 */ 363 ipstat.ips_delivered++; 364 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); 365 goto next; 366 bad: 367 m_freem(m); 368 goto next; 369 } 370 371 /* 372 * Take incoming datagram fragment and try to 373 * reassemble it into whole datagram. If a chain for 374 * reassembly of this datagram already exists, then it 375 * is given as fp; otherwise have to make a chain. 376 */ 377 struct ip * 378 ip_reass(ip, fp) 379 register struct ipasfrag *ip; 380 register struct ipq *fp; 381 { 382 register struct mbuf *m = dtom(ip); 383 register struct ipasfrag *q; 384 struct mbuf *t; 385 int hlen = ip->ip_hl << 2; 386 int i, next; 387 388 /* 389 * Presence of header sizes in mbufs 390 * would confuse code below. 391 */ 392 m->m_data += hlen; 393 m->m_len -= hlen; 394 395 /* 396 * If first fragment to arrive, create a reassembly queue. 397 */ 398 if (fp == 0) { 399 if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL) 400 goto dropfrag; 401 fp = mtod(t, struct ipq *); 402 insque(fp, &ipq); 403 fp->ipq_ttl = IPFRAGTTL; 404 fp->ipq_p = ip->ip_p; 405 fp->ipq_id = ip->ip_id; 406 fp->ipq_next = fp->ipq_prev = (struct ipasfrag *)fp; 407 fp->ipq_src = ((struct ip *)ip)->ip_src; 408 fp->ipq_dst = ((struct ip *)ip)->ip_dst; 409 q = (struct ipasfrag *)fp; 410 goto insert; 411 } 412 413 /* 414 * Find a segment which begins after this one does. 415 */ 416 for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next) 417 if (q->ip_off > ip->ip_off) 418 break; 419 420 /* 421 * If there is a preceding segment, it may provide some of 422 * our data already. If so, drop the data from the incoming 423 * segment. If it provides all of our data, drop us. 424 */ 425 if (q->ipf_prev != (struct ipasfrag *)fp) { 426 i = q->ipf_prev->ip_off + q->ipf_prev->ip_len - ip->ip_off; 427 if (i > 0) { 428 if (i >= ip->ip_len) 429 goto dropfrag; 430 m_adj(dtom(ip), i); 431 ip->ip_off += i; 432 ip->ip_len -= i; 433 } 434 } 435 436 /* 437 * While we overlap succeeding segments trim them or, 438 * if they are completely covered, dequeue them. 439 */ 440 while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { 441 i = (ip->ip_off + ip->ip_len) - q->ip_off; 442 if (i < q->ip_len) { 443 q->ip_len -= i; 444 q->ip_off += i; 445 m_adj(dtom(q), i); 446 break; 447 } 448 q = q->ipf_next; 449 m_freem(dtom(q->ipf_prev)); 450 ip_deq(q->ipf_prev); 451 } 452 453 insert: 454 /* 455 * Stick new segment in its place; 456 * check for complete reassembly. 457 */ 458 ip_enq(ip, q->ipf_prev); 459 next = 0; 460 for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next) { 461 if (q->ip_off != next) 462 return (0); 463 next += q->ip_len; 464 } 465 if (q->ipf_prev->ipf_mff & 1) 466 return (0); 467 468 /* 469 * Reassembly is complete; concatenate fragments. 470 */ 471 q = fp->ipq_next; 472 m = dtom(q); 473 t = m->m_next; 474 m->m_next = 0; 475 m_cat(m, t); 476 q = q->ipf_next; 477 while (q != (struct ipasfrag *)fp) { 478 t = dtom(q); 479 q = q->ipf_next; 480 m_cat(m, t); 481 } 482 483 /* 484 * Create header for new ip packet by 485 * modifying header of first packet; 486 * dequeue and discard fragment reassembly header. 487 * Make header visible. 488 */ 489 ip = fp->ipq_next; 490 ip->ip_len = next; 491 ip->ipf_mff &= ~1; 492 ((struct ip *)ip)->ip_src = fp->ipq_src; 493 ((struct ip *)ip)->ip_dst = fp->ipq_dst; 494 remque(fp); 495 (void) m_free(dtom(fp)); 496 m = dtom(ip); 497 m->m_len += (ip->ip_hl << 2); 498 m->m_data -= (ip->ip_hl << 2); 499 /* some debugging cruft by sklower, below, will go away soon */ 500 if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ 501 register int plen = 0; 502 for (t = m; m; m = m->m_next) 503 plen += m->m_len; 504 t->m_pkthdr.len = plen; 505 } 506 return ((struct ip *)ip); 507 508 dropfrag: 509 ipstat.ips_fragdropped++; 510 m_freem(m); 511 return (0); 512 } 513 514 /* 515 * Free a fragment reassembly header and all 516 * associated datagrams. 517 */ 518 ip_freef(fp) 519 struct ipq *fp; 520 { 521 register struct ipasfrag *q, *p; 522 523 for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = p) { 524 p = q->ipf_next; 525 ip_deq(q); 526 m_freem(dtom(q)); 527 } 528 remque(fp); 529 (void) m_free(dtom(fp)); 530 } 531 532 /* 533 * Put an ip fragment on a reassembly chain. 534 * Like insque, but pointers in middle of structure. 535 */ 536 ip_enq(p, prev) 537 register struct ipasfrag *p, *prev; 538 { 539 540 p->ipf_prev = prev; 541 p->ipf_next = prev->ipf_next; 542 prev->ipf_next->ipf_prev = p; 543 prev->ipf_next = p; 544 } 545 546 /* 547 * To ip_enq as remque is to insque. 548 */ 549 ip_deq(p) 550 register struct ipasfrag *p; 551 { 552 553 p->ipf_prev->ipf_next = p->ipf_next; 554 p->ipf_next->ipf_prev = p->ipf_prev; 555 } 556 557 /* 558 * IP timer processing; 559 * if a timer expires on a reassembly 560 * queue, discard it. 561 */ 562 ip_slowtimo() 563 { 564 register struct ipq *fp; 565 int s = splnet(); 566 567 fp = ipq.next; 568 if (fp == 0) { 569 splx(s); 570 return; 571 } 572 while (fp != &ipq) { 573 --fp->ipq_ttl; 574 fp = fp->next; 575 if (fp->prev->ipq_ttl == 0) { 576 ipstat.ips_fragtimeout++; 577 ip_freef(fp->prev); 578 } 579 } 580 splx(s); 581 } 582 583 /* 584 * Drain off all datagram fragments. 585 */ 586 ip_drain() 587 { 588 589 while (ipq.next != &ipq) { 590 ipstat.ips_fragdropped++; 591 ip_freef(ipq.next); 592 } 593 } 594 595 struct in_ifaddr *ip_rtaddr(); 596 597 /* 598 * Do option processing on a datagram, 599 * possibly discarding it if bad options are encountered, 600 * or forwarding it if source-routed. 601 * Returns 1 if packet has been forwarded/freed, 602 * 0 if the packet should be processed further. 603 */ 604 ip_dooptions(m) 605 struct mbuf *m; 606 { 607 register struct ip *ip = mtod(m, struct ip *); 608 register u_char *cp; 609 register struct ip_timestamp *ipt; 610 register struct in_ifaddr *ia; 611 int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; 612 struct in_addr *sin, dst; 613 n_time ntime; 614 615 dst = ip->ip_dst; 616 cp = (u_char *)(ip + 1); 617 cnt = (ip->ip_hl << 2) - sizeof (struct ip); 618 for (; cnt > 0; cnt -= optlen, cp += optlen) { 619 opt = cp[IPOPT_OPTVAL]; 620 if (opt == IPOPT_EOL) 621 break; 622 if (opt == IPOPT_NOP) 623 optlen = 1; 624 else { 625 optlen = cp[IPOPT_OLEN]; 626 if (optlen <= 0 || optlen > cnt) { 627 code = &cp[IPOPT_OLEN] - (u_char *)ip; 628 goto bad; 629 } 630 } 631 switch (opt) { 632 633 default: 634 break; 635 636 /* 637 * Source routing with record. 638 * Find interface with current destination address. 639 * If none on this machine then drop if strictly routed, 640 * or do nothing if loosely routed. 641 * Record interface address and bring up next address 642 * component. If strictly routed make sure next 643 * address is on directly accessible net. 644 */ 645 case IPOPT_LSRR: 646 case IPOPT_SSRR: 647 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { 648 code = &cp[IPOPT_OFFSET] - (u_char *)ip; 649 goto bad; 650 } 651 ipaddr.sin_addr = ip->ip_dst; 652 ia = (struct in_ifaddr *) 653 ifa_ifwithaddr((struct sockaddr *)&ipaddr); 654 if (ia == 0) { 655 if (opt == IPOPT_SSRR) { 656 type = ICMP_UNREACH; 657 code = ICMP_UNREACH_SRCFAIL; 658 goto bad; 659 } 660 /* 661 * Loose routing, and not at next destination 662 * yet; nothing to do except forward. 663 */ 664 break; 665 } 666 off--; /* 0 origin */ 667 if (off > optlen - sizeof(struct in_addr)) { 668 /* 669 * End of source route. Should be for us. 670 */ 671 save_rte(cp, ip->ip_src); 672 break; 673 } 674 /* 675 * locate outgoing interface 676 */ 677 bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr, 678 sizeof(ipaddr.sin_addr)); 679 if (opt == IPOPT_SSRR) { 680 #define INA struct in_ifaddr * 681 #define SA struct sockaddr * 682 if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0) 683 ia = (INA)ifa_ifwithnet((SA)&ipaddr); 684 } else 685 ia = ip_rtaddr(ipaddr.sin_addr); 686 if (ia == 0) { 687 type = ICMP_UNREACH; 688 code = ICMP_UNREACH_SRCFAIL; 689 goto bad; 690 } 691 ip->ip_dst = ipaddr.sin_addr; 692 bcopy((caddr_t)&(IA_SIN(ia)->sin_addr), 693 (caddr_t)(cp + off), sizeof(struct in_addr)); 694 cp[IPOPT_OFFSET] += sizeof(struct in_addr); 695 /* 696 * Let ip_intr's mcast routing check handle mcast pkts 697 */ 698 forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)); 699 break; 700 701 case IPOPT_RR: 702 if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { 703 code = &cp[IPOPT_OFFSET] - (u_char *)ip; 704 goto bad; 705 } 706 /* 707 * If no space remains, ignore. 708 */ 709 off--; /* 0 origin */ 710 if (off > optlen - sizeof(struct in_addr)) 711 break; 712 bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, 713 sizeof(ipaddr.sin_addr)); 714 /* 715 * locate outgoing interface; if we're the destination, 716 * use the incoming interface (should be same). 717 */ 718 if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 && 719 (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) { 720 type = ICMP_UNREACH; 721 code = ICMP_UNREACH_HOST; 722 goto bad; 723 } 724 bcopy((caddr_t)&(IA_SIN(ia)->sin_addr), 725 (caddr_t)(cp + off), sizeof(struct in_addr)); 726 cp[IPOPT_OFFSET] += sizeof(struct in_addr); 727 break; 728 729 case IPOPT_TS: 730 code = cp - (u_char *)ip; 731 ipt = (struct ip_timestamp *)cp; 732 if (ipt->ipt_len < 5) 733 goto bad; 734 if (ipt->ipt_ptr > ipt->ipt_len - sizeof (long)) { 735 if (++ipt->ipt_oflw == 0) 736 goto bad; 737 break; 738 } 739 sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); 740 switch (ipt->ipt_flg) { 741 742 case IPOPT_TS_TSONLY: 743 break; 744 745 case IPOPT_TS_TSANDADDR: 746 if (ipt->ipt_ptr + sizeof(n_time) + 747 sizeof(struct in_addr) > ipt->ipt_len) 748 goto bad; 749 ipaddr.sin_addr = dst; 750 ia = (INA)ifaof_ifpforaddr((SA)&ipaddr, 751 m->m_pkthdr.rcvif); 752 if (ia == 0) 753 continue; 754 bcopy((caddr_t)&IA_SIN(ia)->sin_addr, 755 (caddr_t)sin, sizeof(struct in_addr)); 756 ipt->ipt_ptr += sizeof(struct in_addr); 757 break; 758 759 case IPOPT_TS_PRESPEC: 760 if (ipt->ipt_ptr + sizeof(n_time) + 761 sizeof(struct in_addr) > ipt->ipt_len) 762 goto bad; 763 bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, 764 sizeof(struct in_addr)); 765 if (ifa_ifwithaddr((SA)&ipaddr) == 0) 766 continue; 767 ipt->ipt_ptr += sizeof(struct in_addr); 768 break; 769 770 default: 771 goto bad; 772 } 773 ntime = iptime(); 774 bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, 775 sizeof(n_time)); 776 ipt->ipt_ptr += sizeof(n_time); 777 } 778 } 779 if (forward) { 780 ip_forward(m, 1); 781 return (1); 782 } 783 return (0); 784 bad: 785 ip->ip_len -= ip->ip_hl << 2; /* XXX icmp_error adds in hdr length */ 786 icmp_error(m, type, code, 0, 0); 787 ipstat.ips_badoptions++; 788 return (1); 789 } 790 791 /* 792 * Given address of next destination (final or next hop), 793 * return internet address info of interface to be used to get there. 794 */ 795 struct in_ifaddr * 796 ip_rtaddr(dst) 797 struct in_addr dst; 798 { 799 register struct sockaddr_in *sin; 800 801 sin = (struct sockaddr_in *) &ipforward_rt.ro_dst; 802 803 if (ipforward_rt.ro_rt == 0 || dst.s_addr != sin->sin_addr.s_addr) { 804 if (ipforward_rt.ro_rt) { 805 RTFREE(ipforward_rt.ro_rt); 806 ipforward_rt.ro_rt = 0; 807 } 808 sin->sin_family = AF_INET; 809 sin->sin_len = sizeof(*sin); 810 sin->sin_addr = dst; 811 812 rtalloc(&ipforward_rt); 813 } 814 if (ipforward_rt.ro_rt == 0) 815 return ((struct in_ifaddr *)0); 816 return ((struct in_ifaddr *) ipforward_rt.ro_rt->rt_ifa); 817 } 818 819 /* 820 * Save incoming source route for use in replies, 821 * to be picked up later by ip_srcroute if the receiver is interested. 822 */ 823 save_rte(option, dst) 824 u_char *option; 825 struct in_addr dst; 826 { 827 unsigned olen; 828 829 olen = option[IPOPT_OLEN]; 830 #ifdef DIAGNOSTIC 831 if (ipprintfs) 832 printf("save_rte: olen %d\n", olen); 833 #endif 834 if (olen > sizeof(ip_srcrt) - (1 + sizeof(dst))) 835 return; 836 bcopy((caddr_t)option, (caddr_t)ip_srcrt.srcopt, olen); 837 ip_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr); 838 ip_srcrt.dst = dst; 839 } 840 841 /* 842 * Retrieve incoming source route for use in replies, 843 * in the same form used by setsockopt. 844 * The first hop is placed before the options, will be removed later. 845 */ 846 struct mbuf * 847 ip_srcroute() 848 { 849 register struct in_addr *p, *q; 850 register struct mbuf *m; 851 852 if (ip_nhops == 0) 853 return ((struct mbuf *)0); 854 m = m_get(M_DONTWAIT, MT_SOOPTS); 855 if (m == 0) 856 return ((struct mbuf *)0); 857 858 #define OPTSIZ (sizeof(ip_srcrt.nop) + sizeof(ip_srcrt.srcopt)) 859 860 /* length is (nhops+1)*sizeof(addr) + sizeof(nop + srcrt header) */ 861 m->m_len = ip_nhops * sizeof(struct in_addr) + sizeof(struct in_addr) + 862 OPTSIZ; 863 #ifdef DIAGNOSTIC 864 if (ipprintfs) 865 printf("ip_srcroute: nhops %d mlen %d", ip_nhops, m->m_len); 866 #endif 867 868 /* 869 * First save first hop for return route 870 */ 871 p = &ip_srcrt.route[ip_nhops - 1]; 872 *(mtod(m, struct in_addr *)) = *p--; 873 #ifdef DIAGNOSTIC 874 if (ipprintfs) 875 printf(" hops %lx", ntohl(mtod(m, struct in_addr *)->s_addr)); 876 #endif 877 878 /* 879 * Copy option fields and padding (nop) to mbuf. 880 */ 881 ip_srcrt.nop = IPOPT_NOP; 882 ip_srcrt.srcopt[IPOPT_OFFSET] = IPOPT_MINOFF; 883 bcopy((caddr_t)&ip_srcrt.nop, 884 mtod(m, caddr_t) + sizeof(struct in_addr), OPTSIZ); 885 q = (struct in_addr *)(mtod(m, caddr_t) + 886 sizeof(struct in_addr) + OPTSIZ); 887 #undef OPTSIZ 888 /* 889 * Record return path as an IP source route, 890 * reversing the path (pointers are now aligned). 891 */ 892 while (p >= ip_srcrt.route) { 893 #ifdef DIAGNOSTIC 894 if (ipprintfs) 895 printf(" %lx", ntohl(q->s_addr)); 896 #endif 897 *q++ = *p--; 898 } 899 /* 900 * Last hop goes to final destination. 901 */ 902 *q = ip_srcrt.dst; 903 #ifdef DIAGNOSTIC 904 if (ipprintfs) 905 printf(" %lx\n", ntohl(q->s_addr)); 906 #endif 907 return (m); 908 } 909 910 /* 911 * Strip out IP options, at higher 912 * level protocol in the kernel. 913 * Second argument is buffer to which options 914 * will be moved, and return value is their length. 915 * XXX should be deleted; last arg currently ignored. 916 */ 917 ip_stripoptions(m, mopt) 918 register struct mbuf *m; 919 struct mbuf *mopt; 920 { 921 register int i; 922 struct ip *ip = mtod(m, struct ip *); 923 register caddr_t opts; 924 int olen; 925 926 olen = (ip->ip_hl<<2) - sizeof (struct ip); 927 opts = (caddr_t)(ip + 1); 928 i = m->m_len - (sizeof (struct ip) + olen); 929 bcopy(opts + olen, opts, (unsigned)i); 930 m->m_len -= olen; 931 if (m->m_flags & M_PKTHDR) 932 m->m_pkthdr.len -= olen; 933 ip->ip_hl = sizeof(struct ip) >> 2; 934 } 935 936 u_char inetctlerrmap[PRC_NCMDS] = { 937 0, 0, 0, 0, 938 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, 939 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, 940 EMSGSIZE, EHOSTUNREACH, 0, 0, 941 0, 0, 0, 0, 942 ENOPROTOOPT 943 }; 944 945 /* 946 * Forward a packet. If some error occurs return the sender 947 * an icmp packet. Note we can't always generate a meaningful 948 * icmp message because icmp doesn't have a large enough repertoire 949 * of codes and types. 950 * 951 * If not forwarding, just drop the packet. This could be confusing 952 * if ipforwarding was zero but some routing protocol was advancing 953 * us as a gateway to somewhere. However, we must let the routing 954 * protocol deal with that. 955 * 956 * The srcrt parameter indicates whether the packet is being forwarded 957 * via a source route. 958 */ 959 ip_forward(m, srcrt) 960 struct mbuf *m; 961 int srcrt; 962 { 963 register struct ip *ip = mtod(m, struct ip *); 964 register struct sockaddr_in *sin; 965 register struct rtentry *rt; 966 int error, type = 0, code; 967 struct mbuf *mcopy; 968 n_long dest; 969 struct ifnet *destifp; 970 971 dest = 0; 972 #ifdef DIAGNOSTIC 973 if (ipprintfs) 974 printf("forward: src %x dst %x ttl %x\n", ip->ip_src, 975 ip->ip_dst, ip->ip_ttl); 976 #endif 977 if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) { 978 ipstat.ips_cantforward++; 979 m_freem(m); 980 return; 981 } 982 HTONS(ip->ip_id); 983 if (ip->ip_ttl <= IPTTLDEC) { 984 icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0); 985 return; 986 } 987 ip->ip_ttl -= IPTTLDEC; 988 989 sin = (struct sockaddr_in *)&ipforward_rt.ro_dst; 990 if ((rt = ipforward_rt.ro_rt) == 0 || 991 ip->ip_dst.s_addr != sin->sin_addr.s_addr) { 992 if (ipforward_rt.ro_rt) { 993 RTFREE(ipforward_rt.ro_rt); 994 ipforward_rt.ro_rt = 0; 995 } 996 sin->sin_family = AF_INET; 997 sin->sin_len = sizeof(*sin); 998 sin->sin_addr = ip->ip_dst; 999 1000 rtalloc(&ipforward_rt); 1001 if (ipforward_rt.ro_rt == 0) { 1002 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); 1003 return; 1004 } 1005 rt = ipforward_rt.ro_rt; 1006 } 1007 1008 /* 1009 * Save at most 64 bytes of the packet in case 1010 * we need to generate an ICMP message to the src. 1011 */ 1012 mcopy = m_copy(m, 0, imin((int)ip->ip_len, 64)); 1013 1014 #ifdef GATEWAY 1015 ip_ifmatrix[rt->rt_ifp->if_index + 1016 if_index * m->m_pkthdr.rcvif->if_index]++; 1017 #endif 1018 /* 1019 * If forwarding packet using same interface that it came in on, 1020 * perhaps should send a redirect to sender to shortcut a hop. 1021 * Only send redirect if source is sending directly to us, 1022 * and if packet was not source routed (or has any options). 1023 * Also, don't send redirect if forwarding using a default route 1024 * or a route modified by a redirect. 1025 */ 1026 #define satosin(sa) ((struct sockaddr_in *)(sa)) 1027 if (rt->rt_ifp == m->m_pkthdr.rcvif && 1028 (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 && 1029 satosin(rt_key(rt))->sin_addr.s_addr != 0 && 1030 ipsendredirects && !srcrt) { 1031 #define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa)) 1032 u_long src = ntohl(ip->ip_src.s_addr); 1033 u_long dst = ntohl(ip->ip_dst.s_addr); 1034 1035 if (RTA(rt) && 1036 (src & RTA(rt)->ia_subnetmask) == RTA(rt)->ia_subnet) { 1037 if (rt->rt_flags & RTF_GATEWAY) 1038 dest = satosin(rt->rt_gateway)->sin_addr.s_addr; 1039 else 1040 dest = ip->ip_dst.s_addr; 1041 /* Router requirements says to only send host redirects */ 1042 type = ICMP_REDIRECT; 1043 code = ICMP_REDIRECT_HOST; 1044 #ifdef DIAGNOSTIC 1045 if (ipprintfs) 1046 printf("redirect (%d) to %lx\n", code, (u_long)dest); 1047 #endif 1048 } 1049 } 1050 1051 error = ip_output(m, (struct mbuf *)0, &ipforward_rt, IP_FORWARDING 1052 #ifdef DIRECTED_BROADCAST 1053 | IP_ALLOWBROADCAST 1054 #endif 1055 , 0); 1056 if (error) 1057 ipstat.ips_cantforward++; 1058 else { 1059 ipstat.ips_forward++; 1060 if (type) 1061 ipstat.ips_redirectsent++; 1062 else { 1063 if (mcopy) 1064 m_freem(mcopy); 1065 return; 1066 } 1067 } 1068 if (mcopy == NULL) 1069 return; 1070 destifp = NULL; 1071 1072 switch (error) { 1073 1074 case 0: /* forwarded, but need redirect */ 1075 /* type, code set above */ 1076 break; 1077 1078 case ENETUNREACH: /* shouldn't happen, checked above */ 1079 case EHOSTUNREACH: 1080 case ENETDOWN: 1081 case EHOSTDOWN: 1082 default: 1083 type = ICMP_UNREACH; 1084 code = ICMP_UNREACH_HOST; 1085 break; 1086 1087 case EMSGSIZE: 1088 type = ICMP_UNREACH; 1089 code = ICMP_UNREACH_NEEDFRAG; 1090 if (ipforward_rt.ro_rt) 1091 destifp = ipforward_rt.ro_rt->rt_ifp; 1092 ipstat.ips_cantfrag++; 1093 break; 1094 1095 case ENOBUFS: 1096 type = ICMP_SOURCEQUENCH; 1097 code = 0; 1098 break; 1099 } 1100 icmp_error(mcopy, type, code, dest, destifp); 1101 } 1102 1103 ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1104 int *name; 1105 u_int namelen; 1106 void *oldp; 1107 size_t *oldlenp; 1108 void *newp; 1109 size_t newlen; 1110 { 1111 extern int ip_ttl; 1112 1113 /* all sysctl names at this level are terminal */ 1114 if (namelen != 1) 1115 return (ENOTDIR); 1116 1117 switch (name[0]) { 1118 case IPCTL_FORWARDING: 1119 return (sysctl_int(oldp, oldlenp, newp, newlen, &ipforwarding)); 1120 case IPCTL_SENDREDIRECTS: 1121 return (sysctl_int(oldp, oldlenp, newp, newlen, 1122 &ipsendredirects)); 1123 case IPCTL_DEFTTL: 1124 return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_defttl)); 1125 #ifdef notyet 1126 case IPCTL_DEFMTU: 1127 return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu)); 1128 #endif 1129 default: 1130 return (EOPNOTSUPP); 1131 } 1132 /* NOTREACHED */ 1133 } 1134