1: /* 2: * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms are permitted 6: * provided that this notice is preserved and that due credit is given 7: * to the University of California at Berkeley. The name of the University 8: * may not be used to endorse or promote products derived from this 9: * software without specific prior written permission. This software 10: * is provided ``as is'' without express or implied warranty. 11: * 12: * @(#)tcp_input.c 7.15.1.2 (Berkeley) 3/16/88 13: */ 14: 15: #include "param.h" 16: #include "systm.h" 17: #include "mbuf.h" 18: #include "protosw.h" 19: #include "socket.h" 20: #include "socketvar.h" 21: #include "errno.h" 22: 23: #include "../net/if.h" 24: #include "../net/route.h" 25: 26: #include "domain.h" 27: #include "in.h" 28: #include "in_pcb.h" 29: #include "in_systm.h" 30: #include "ip.h" 31: #include "ip_var.h" 32: #include "tcp.h" 33: #include "tcp_fsm.h" 34: #include "tcp_seq.h" 35: #include "tcp_timer.h" 36: #include "tcp_var.h" 37: #include "tcpip.h" 38: #include "tcp_debug.h" 39: 40: int tcpprintfs = 0; 41: int tcpcksum = 1; 42: int tcprexmtthresh = 3; 43: struct tcpiphdr tcp_saveti; 44: extern tcpnodelack; 45: 46: struct tcpcb *tcp_newtcpcb(); 47: 48: /* 49: * Insert segment ti into reassembly queue of tcp with 50: * control block tp. Return TH_FIN if reassembly now includes 51: * a segment with FIN. The macro form does the common case inline 52: * (segment is the next to be received on an established connection, 53: * and the queue is empty), avoiding linkage into and removal 54: * from the queue and repetition of various conversions. 55: */ 56: #define TCP_REASS(tp, ti, m, so, flags) { \ 57: if ((ti)->ti_seq == (tp)->rcv_nxt && \ 58: (tp)->seg_next == (struct tcpiphdr *)(tp) && \ 59: (tp)->t_state == TCPS_ESTABLISHED) { \ 60: (tp)->rcv_nxt += (ti)->ti_len; \ 61: flags = (ti)->ti_flags & TH_FIN; \ 62: tcpstat.tcps_rcvpack++;\ 63: tcpstat.tcps_rcvbyte += (ti)->ti_len;\ 64: sbappend(&(so)->so_rcv, (m)); \ 65: sorwakeup(so); \ 66: } else \ 67: (flags) = tcp_reass((tp), (ti)); \ 68: } 69: 70: tcp_reass(tp, ti) 71: register struct tcpcb *tp; 72: register struct tcpiphdr *ti; 73: { 74: register struct tcpiphdr *q; 75: struct socket *so = tp->t_inpcb->inp_socket; 76: struct mbuf *m; 77: int flags; 78: 79: /* 80: * Call with ti==0 after become established to 81: * force pre-ESTABLISHED data up to user socket. 82: */ 83: if (ti == 0) 84: goto present; 85: 86: /* 87: * Find a segment which begins after this one does. 88: */ 89: for (q = tp->seg_next; q != (struct tcpiphdr *)tp; 90: q = (struct tcpiphdr *)q->ti_next) 91: if (SEQ_GT(q->ti_seq, ti->ti_seq)) 92: break; 93: 94: /* 95: * If there is a preceding segment, it may provide some of 96: * our data already. If so, drop the data from the incoming 97: * segment. If it provides all of our data, drop us. 98: */ 99: if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { 100: register int i; 101: q = (struct tcpiphdr *)q->ti_prev; 102: /* conversion to int (in i) handles seq wraparound */ 103: i = q->ti_seq + q->ti_len - ti->ti_seq; 104: if (i > 0) { 105: if (i >= ti->ti_len) { 106: tcpstat.tcps_rcvduppack++; 107: tcpstat.tcps_rcvdupbyte += ti->ti_len; 108: goto drop; 109: } 110: m_adj(dtom(ti), i); 111: ti->ti_len -= i; 112: ti->ti_seq += i; 113: } 114: q = (struct tcpiphdr *)(q->ti_next); 115: } 116: tcpstat.tcps_rcvoopack++; 117: tcpstat.tcps_rcvoobyte += ti->ti_len; 118: 119: /* 120: * While we overlap succeeding segments trim them or, 121: * if they are completely covered, dequeue them. 122: */ 123: while (q != (struct tcpiphdr *)tp) { 124: register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 125: if (i <= 0) 126: break; 127: if (i < q->ti_len) { 128: q->ti_seq += i; 129: q->ti_len -= i; 130: m_adj(dtom(q), i); 131: break; 132: } 133: q = (struct tcpiphdr *)q->ti_next; 134: m = dtom(q->ti_prev); 135: remque(q->ti_prev); 136: m_freem(m); 137: } 138: 139: /* 140: * Stick new segment in its place. 141: */ 142: insque(ti, q->ti_prev); 143: 144: present: 145: /* 146: * Present data to user, advancing rcv_nxt through 147: * completed sequence space. 148: */ 149: if (TCPS_HAVERCVDSYN(tp->t_state) == 0) 150: return (0); 151: ti = tp->seg_next; 152: if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) 153: return (0); 154: if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) 155: return (0); 156: do { 157: tp->rcv_nxt += ti->ti_len; 158: flags = ti->ti_flags & TH_FIN; 159: remque(ti); 160: m = dtom(ti); 161: ti = (struct tcpiphdr *)ti->ti_next; 162: if (so->so_state & SS_CANTRCVMORE) 163: m_freem(m); 164: else 165: sbappend(&so->so_rcv, m); 166: } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); 167: sorwakeup(so); 168: return (flags); 169: drop: 170: m_freem(dtom(ti)); 171: return (0); 172: } 173: 174: /* 175: * TCP input routine, follows pages 65-76 of the 176: * protocol specification dated September, 1981 very closely. 177: */ 178: tcp_input(m0) 179: struct mbuf *m0; 180: { 181: register struct tcpiphdr *ti; 182: struct inpcb *inp; 183: register struct mbuf *m; 184: struct mbuf *om = 0; 185: int len, tlen, off; 186: register struct tcpcb *tp = 0; 187: register int tiflags; 188: struct socket *so; 189: int todrop, acked, ourfinisacked, needoutput = 0; 190: short ostate; 191: struct in_addr laddr; 192: int dropsocket = 0; 193: long iss = 0; 194: 195: tcpstat.tcps_rcvtotal++; 196: /* 197: * Get IP and TCP header together in first mbuf. 198: * Note: IP leaves IP header in first mbuf. 199: */ 200: m = m0; 201: ti = mtod(m, struct tcpiphdr *); 202: if (((struct ip *)ti)->ip_hl > (sizeof (struct ip) >> 2)) 203: ip_stripoptions((struct ip *)ti, (struct mbuf *)0); 204: if (m->m_off > MMAXOFF || m->m_len < sizeof (struct tcpiphdr)) { 205: if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) { 206: tcpstat.tcps_rcvshort++; 207: return; 208: } 209: ti = mtod(m, struct tcpiphdr *); 210: } 211: 212: /* 213: * Checksum extended TCP header and data. 214: */ 215: tlen = ((struct ip *)ti)->ip_len; 216: len = sizeof (struct ip) + tlen; 217: if (tcpcksum) { 218: ti->ti_next = ti->ti_prev = 0; 219: ti->ti_x1 = 0; 220: ti->ti_pad = 0; 221: ti->ti_len = (u_short)tlen; 222: ti->ti_len = htons((u_short)ti->ti_len); 223: if (ti->ti_sum = in_cksum(m, len)) { 224: if (tcpprintfs) 225: printf("tcp sum: src %x\n", ti->ti_src); 226: tcpstat.tcps_rcvbadsum++; 227: goto drop; 228: } 229: } 230: 231: /* 232: * Check that TCP offset makes sense, 233: * pull out TCP options and adjust length. 234: */ 235: off = ti->ti_off << 2; 236: if (off < sizeof (struct tcphdr) || off > tlen) { 237: if (tcpprintfs) 238: printf("tcp off: src %x off %d\n", ti->ti_src, off); 239: tcpstat.tcps_rcvbadoff++; 240: goto drop; 241: } 242: tlen -= off; 243: ti->ti_len = tlen; 244: if (off > sizeof (struct tcphdr)) { 245: if (m->m_len < sizeof(struct ip) + off) { 246: if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) { 247: tcpstat.tcps_rcvshort++; 248: return; 249: } 250: ti = mtod(m, struct tcpiphdr *); 251: } 252: om = m_get(M_DONTWAIT, MT_DATA); 253: if (om == 0) 254: goto drop; 255: om->m_len = off - sizeof (struct tcphdr); 256: { caddr_t op = mtod(m, caddr_t) + sizeof (struct tcpiphdr); 257: bcopy(op, mtod(om, caddr_t), (unsigned)om->m_len); 258: m->m_len -= om->m_len; 259: bcopy(op+om->m_len, op, 260: (unsigned)(m->m_len-sizeof (struct tcpiphdr))); 261: } 262: } 263: tiflags = ti->ti_flags; 264: 265: /* 266: * Drop TCP and IP headers; TCP options were dropped above. 267: */ 268: m->m_off += sizeof(struct tcpiphdr); 269: m->m_len -= sizeof(struct tcpiphdr); 270: 271: /* 272: * Convert TCP protocol specific fields to host format. 273: */ 274: ti->ti_seq = ntohl(ti->ti_seq); 275: ti->ti_ack = ntohl(ti->ti_ack); 276: ti->ti_win = ntohs(ti->ti_win); 277: ti->ti_urp = ntohs(ti->ti_urp); 278: 279: /* 280: * Locate pcb for segment. 281: */ 282: findpcb: 283: inp = in_pcblookup 284: (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport, 285: INPLOOKUP_WILDCARD); 286: 287: /* 288: * If the state is CLOSED (i.e., TCB does not exist) then 289: * all data in the incoming segment is discarded. 290: * If the TCB exists but is in CLOSED state, it is embryonic, 291: * but should either do a listen or a connect soon. 292: */ 293: if (inp == 0) 294: goto dropwithreset; 295: tp = intotcpcb(inp); 296: if (tp == 0) 297: goto dropwithreset; 298: if (tp->t_state == TCPS_CLOSED) 299: goto drop; 300: so = inp->inp_socket; 301: if (so->so_options & SO_DEBUG) { 302: ostate = tp->t_state; 303: tcp_saveti = *ti; 304: } 305: if (so->so_options & SO_ACCEPTCONN) { 306: so = sonewconn(so); 307: if (so == 0) 308: goto drop; 309: /* 310: * This is ugly, but .... 311: * 312: * Mark socket as temporary until we're 313: * committed to keeping it. The code at 314: * ``drop'' and ``dropwithreset'' check the 315: * flag dropsocket to see if the temporary 316: * socket created here should be discarded. 317: * We mark the socket as discardable until 318: * we're committed to it below in TCPS_LISTEN. 319: */ 320: dropsocket++; 321: inp = (struct inpcb *)so->so_pcb; 322: inp->inp_laddr = ti->ti_dst; 323: inp->inp_lport = ti->ti_dport; 324: #if BSD>=43 325: inp->inp_options = ip_srcroute(); 326: #endif 327: tp = intotcpcb(inp); 328: tp->t_state = TCPS_LISTEN; 329: } 330: 331: /* 332: * Segment received on connection. 333: * Reset idle time and keep-alive timer. 334: */ 335: tp->t_idle = 0; 336: tp->t_timer[TCPT_KEEP] = tcp_keepidle; 337: 338: /* 339: * Process options if not in LISTEN state, 340: * else do it below (after getting remote address). 341: */ 342: if (om && tp->t_state != TCPS_LISTEN) { 343: tcp_dooptions(tp, om, ti); 344: om = 0; 345: } 346: 347: /* 348: * Calculate amount of space in receive window, 349: * and then do TCP input processing. 350: * Receive window is amount of space in rcv queue, 351: * but not less than advertised window. 352: */ 353: { int win; 354: 355: win = sbspace(&so->so_rcv); 356: if (win < 0) 357: win = 0; 358: tp->rcv_wnd = MAX(win, (int)(tp->rcv_adv - tp->rcv_nxt)); 359: } 360: 361: switch (tp->t_state) { 362: 363: /* 364: * If the state is LISTEN then ignore segment if it contains an RST. 365: * If the segment contains an ACK then it is bad and send a RST. 366: * If it does not contain a SYN then it is not interesting; drop it. 367: * Don't bother responding if the destination was a broadcast. 368: * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial 369: * tp->iss, and send a segment: 370: * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK> 371: * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. 372: * Fill in remote peer address fields if not previously specified. 373: * Enter SYN_RECEIVED state, and process any other fields of this 374: * segment in this state. 375: */ 376: case TCPS_LISTEN: { 377: struct mbuf *am; 378: register struct sockaddr_in *sin; 379: 380: if (tiflags & TH_RST) 381: goto drop; 382: if (tiflags & TH_ACK) 383: goto dropwithreset; 384: if ((tiflags & TH_SYN) == 0) 385: goto drop; 386: if (in_broadcast(ti->ti_dst)) 387: goto drop; 388: am = m_get(M_DONTWAIT, MT_SONAME); 389: if (am == NULL) 390: goto drop; 391: am->m_len = sizeof (struct sockaddr_in); 392: sin = mtod(am, struct sockaddr_in *); 393: sin->sin_family = AF_INET; 394: sin->sin_addr = ti->ti_src; 395: sin->sin_port = ti->ti_sport; 396: laddr = inp->inp_laddr; 397: if (inp->inp_laddr.s_addr == INADDR_ANY) 398: inp->inp_laddr = ti->ti_dst; 399: if (in_pcbconnect(inp, am)) { 400: inp->inp_laddr = laddr; 401: (void) m_free(am); 402: goto drop; 403: } 404: (void) m_free(am); 405: tp->t_template = tcp_template(tp); 406: if (tp->t_template == 0) { 407: tp = tcp_drop(tp, ENOBUFS); 408: dropsocket = 0; /* socket is already gone */ 409: goto drop; 410: } 411: if (om) { 412: tcp_dooptions(tp, om, ti); 413: om = 0; 414: } 415: if (iss) 416: tp->iss = iss; 417: else 418: tp->iss = tcp_iss; 419: tcp_iss += TCP_ISSINCR/2; 420: tp->irs = ti->ti_seq; 421: tcp_sendseqinit(tp); 422: tcp_rcvseqinit(tp); 423: tp->t_flags |= TF_ACKNOW; 424: tp->t_state = TCPS_SYN_RECEIVED; 425: tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 426: dropsocket = 0; /* committed to socket */ 427: tcpstat.tcps_accepts++; 428: goto trimthenstep6; 429: } 430: 431: /* 432: * If the state is SYN_SENT: 433: * if seg contains an ACK, but not for our SYN, drop the input. 434: * if seg contains a RST, then drop the connection. 435: * if seg does not contain SYN, then drop it. 436: * Otherwise this is an acceptable SYN segment 437: * initialize tp->rcv_nxt and tp->irs 438: * if seg contains ack then advance tp->snd_una 439: * if SYN has been acked change to ESTABLISHED else SYN_RCVD state 440: * arrange for segment to be acked (eventually) 441: * continue processing rest of data/controls, beginning with URG 442: */ 443: case TCPS_SYN_SENT: 444: if ((tiflags & TH_ACK) && 445: (SEQ_LEQ(ti->ti_ack, tp->iss) || 446: SEQ_GT(ti->ti_ack, tp->snd_max))) 447: goto dropwithreset; 448: if (tiflags & TH_RST) { 449: if (tiflags & TH_ACK) 450: tp = tcp_drop(tp, ECONNREFUSED); 451: goto drop; 452: } 453: if ((tiflags & TH_SYN) == 0) 454: goto drop; 455: if (tiflags & TH_ACK) { 456: tp->snd_una = ti->ti_ack; 457: if (SEQ_LT(tp->snd_nxt, tp->snd_una)) 458: tp->snd_nxt = tp->snd_una; 459: } 460: tp->t_timer[TCPT_REXMT] = 0; 461: tp->irs = ti->ti_seq; 462: tcp_rcvseqinit(tp); 463: tp->t_flags |= TF_ACKNOW; 464: if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { 465: tcpstat.tcps_connects++; 466: soisconnected(so); 467: tp->t_state = TCPS_ESTABLISHED; 468: tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp)); 469: (void) tcp_reass(tp, (struct tcpiphdr *)0); 470: /* 471: * if we didn't have to retransmit the SYN, 472: * use its rtt as our initial srtt & rtt var. 473: */ 474: if (tp->t_rtt) { 475: tp->t_srtt = tp->t_rtt << 3; 476: tp->t_rttvar = tp->t_rtt << 1; 477: TCPT_RANGESET(tp->t_rxtcur, 478: ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, 479: TCPTV_MIN, TCPTV_REXMTMAX); 480: tp->t_rtt = 0; 481: } 482: } else 483: tp->t_state = TCPS_SYN_RECEIVED; 484: 485: trimthenstep6: 486: /* 487: * Advance ti->ti_seq to correspond to first data byte. 488: * If data, trim to stay within window, 489: * dropping FIN if necessary. 490: */ 491: ti->ti_seq++; 492: if (ti->ti_len > tp->rcv_wnd) { 493: todrop = ti->ti_len - tp->rcv_wnd; 494: #if BSD>=43 495: m_adj(m, -todrop); 496: #else 497: /* XXX work around 4.2 m_adj bug */ 498: if (m->m_len) { 499: m_adj(m, -todrop); 500: } else { 501: /* skip tcp/ip header in first mbuf */ 502: m_adj(m->m_next, -todrop); 503: } 504: #endif 505: ti->ti_len = tp->rcv_wnd; 506: tiflags &= ~TH_FIN; 507: tcpstat.tcps_rcvpackafterwin++; 508: tcpstat.tcps_rcvbyteafterwin += todrop; 509: } 510: tp->snd_wl1 = ti->ti_seq - 1; 511: tp->rcv_up = ti->ti_seq; 512: goto step6; 513: } 514: 515: /* 516: * States other than LISTEN or SYN_SENT. 517: * First check that at least some bytes of segment are within 518: * receive window. If segment begins before rcv_nxt, 519: * drop leading data (and SYN); if nothing left, just ack. 520: */ 521: todrop = tp->rcv_nxt - ti->ti_seq; 522: if (todrop > 0) { 523: if (tiflags & TH_SYN) { 524: tiflags &= ~TH_SYN; 525: ti->ti_seq++; 526: if (ti->ti_urp > 1) 527: ti->ti_urp--; 528: else 529: tiflags &= ~TH_URG; 530: todrop--; 531: } 532: if (todrop > ti->ti_len || 533: todrop == ti->ti_len && (tiflags&TH_FIN) == 0) { 534: tcpstat.tcps_rcvduppack++; 535: tcpstat.tcps_rcvdupbyte += ti->ti_len; 536: /* 537: * If segment is just one to the left of the window, 538: * check two special cases: 539: * 1. Don't toss RST in response to 4.2-style keepalive. 540: * 2. If the only thing to drop is a FIN, we can drop 541: * it, but check the ACK or we will get into FIN 542: * wars if our FINs crossed (both CLOSING). 543: * In either case, send ACK to resynchronize, 544: * but keep on processing for RST or ACK. 545: */ 546: if ((tiflags & TH_FIN && todrop == ti->ti_len + 1) 547: #ifdef TCP_COMPAT_42 548: || (tiflags & TH_RST && ti->ti_seq == tp->rcv_nxt - 1) 549: #endif 550: ) { 551: todrop = ti->ti_len; 552: tiflags &= ~TH_FIN; 553: tp->t_flags |= TF_ACKNOW; 554: } else 555: goto dropafterack; 556: } else { 557: tcpstat.tcps_rcvpartduppack++; 558: tcpstat.tcps_rcvpartdupbyte += todrop; 559: } 560: m_adj(m, todrop); 561: ti->ti_seq += todrop; 562: ti->ti_len -= todrop; 563: if (ti->ti_urp > todrop) 564: ti->ti_urp -= todrop; 565: else { 566: tiflags &= ~TH_URG; 567: ti->ti_urp = 0; 568: } 569: } 570: 571: /* 572: * If new data are received on a connection after the 573: * user processes are gone, then RST the other end. 574: */ 575: if ((so->so_state & SS_NOFDREF) && 576: tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { 577: tp = tcp_close(tp); 578: tcpstat.tcps_rcvafterclose++; 579: goto dropwithreset; 580: } 581: 582: /* 583: * If segment ends after window, drop trailing data 584: * (and PUSH and FIN); if nothing left, just ACK. 585: */ 586: todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); 587: if (todrop > 0) { 588: tcpstat.tcps_rcvpackafterwin++; 589: if (todrop >= ti->ti_len) { 590: tcpstat.tcps_rcvbyteafterwin += ti->ti_len; 591: /* 592: * If a new connection request is received 593: * while in TIME_WAIT, drop the old connection 594: * and start over if the sequence numbers 595: * are above the previous ones. 596: */ 597: if (tiflags & TH_SYN && 598: tp->t_state == TCPS_TIME_WAIT && 599: SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { 600: iss = tp->rcv_nxt + TCP_ISSINCR; 601: (void) tcp_close(tp); 602: goto findpcb; 603: } 604: /* 605: * If window is closed can only take segments at 606: * window edge, and have to drop data and PUSH from 607: * incoming segments. Continue processing, but 608: * remember to ack. Otherwise, drop segment 609: * and ack. 610: */ 611: if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { 612: tp->t_flags |= TF_ACKNOW; 613: tcpstat.tcps_rcvwinprobe++; 614: } else 615: goto dropafterack; 616: } else 617: tcpstat.tcps_rcvbyteafterwin += todrop; 618: #if BSD>=43 619: m_adj(m, -todrop); 620: #else 621: /* XXX work around m_adj bug */ 622: if (m->m_len) { 623: m_adj(m, -todrop); 624: } else { 625: /* skip tcp/ip header in first mbuf */ 626: m_adj(m->m_next, -todrop); 627: } 628: #endif 629: ti->ti_len -= todrop; 630: tiflags &= ~(TH_PUSH|TH_FIN); 631: } 632: 633: /* 634: * If the RST bit is set examine the state: 635: * SYN_RECEIVED STATE: 636: * If passive open, return to LISTEN state. 637: * If active open, inform user that connection was refused. 638: * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: 639: * Inform user that connection was reset, and close tcb. 640: * CLOSING, LAST_ACK, TIME_WAIT STATES 641: * Close the tcb. 642: */ 643: if (tiflags&TH_RST) switch (tp->t_state) { 644: 645: case TCPS_SYN_RECEIVED: 646: so->so_error = ECONNREFUSED; 647: goto close; 648: 649: case TCPS_ESTABLISHED: 650: case TCPS_FIN_WAIT_1: 651: case TCPS_FIN_WAIT_2: 652: case TCPS_CLOSE_WAIT: 653: so->so_error = ECONNRESET; 654: close: 655: tp->t_state = TCPS_CLOSED; 656: tcpstat.tcps_drops++; 657: tp = tcp_close(tp); 658: goto drop; 659: 660: case TCPS_CLOSING: 661: case TCPS_LAST_ACK: 662: case TCPS_TIME_WAIT: 663: tp = tcp_close(tp); 664: goto drop; 665: } 666: 667: /* 668: * If a SYN is in the window, then this is an 669: * error and we send an RST and drop the connection. 670: */ 671: if (tiflags & TH_SYN) { 672: tp = tcp_drop(tp, ECONNRESET); 673: goto dropwithreset; 674: } 675: 676: /* 677: * If the ACK bit is off we drop the segment and return. 678: */ 679: if ((tiflags & TH_ACK) == 0) 680: goto drop; 681: 682: /* 683: * Ack processing. 684: */ 685: switch (tp->t_state) { 686: 687: /* 688: * In SYN_RECEIVED state if the ack ACKs our SYN then enter 689: * ESTABLISHED state and continue processing, otherwise 690: * send an RST. 691: */ 692: case TCPS_SYN_RECEIVED: 693: if (SEQ_GT(tp->snd_una, ti->ti_ack) || 694: SEQ_GT(ti->ti_ack, tp->snd_max)) 695: goto dropwithreset; 696: tcpstat.tcps_connects++; 697: soisconnected(so); 698: tp->t_state = TCPS_ESTABLISHED; 699: tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp)); 700: (void) tcp_reass(tp, (struct tcpiphdr *)0); 701: tp->snd_wl1 = ti->ti_seq - 1; 702: /* fall into ... */ 703: 704: /* 705: * In ESTABLISHED state: drop duplicate ACKs; ACK out of range 706: * ACKs. If the ack is in the range 707: * tp->snd_una < ti->ti_ack <= tp->snd_max 708: * then advance tp->snd_una to ti->ti_ack and drop 709: * data from the retransmission queue. If this ACK reflects 710: * more up to date window information we update our window information. 711: */ 712: case TCPS_ESTABLISHED: 713: case TCPS_FIN_WAIT_1: 714: case TCPS_FIN_WAIT_2: 715: case TCPS_CLOSE_WAIT: 716: case TCPS_CLOSING: 717: case TCPS_LAST_ACK: 718: case TCPS_TIME_WAIT: 719: 720: if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { 721: if (ti->ti_len == 0 && ti->ti_win == tp->snd_wnd) { 722: tcpstat.tcps_rcvdupack++; 723: /* 724: * If we have outstanding data (not a 725: * window probe), this is a completely 726: * duplicate ack (ie, window info didn't 727: * change), the ack is the biggest we've 728: * seen and we've seen exactly our rexmt 729: * threshhold of them, assume a packet 730: * has been dropped and retransmit it. 731: * Kludge snd_nxt & the congestion 732: * window so we send only this one 733: * packet. If this packet fills the 734: * only hole in the receiver's seq. 735: * space, the next real ack will fully 736: * open our window. This means we 737: * have to do the usual slow-start to 738: * not overwhelm an intermediate gateway 739: * with a burst of packets. Leave 740: * here with the congestion window set 741: * to allow 2 packets on the next real 742: * ack and the exp-to-linear thresh 743: * set for half the current window 744: * size (since we know we're losing at 745: * the current window size). 746: */ 747: if (tp->t_timer[TCPT_REXMT] == 0 || 748: ti->ti_ack != tp->snd_una) 749: tp->t_dupacks = 0; 750: else if (++tp->t_dupacks == tcprexmtthresh) { 751: tcp_seq onxt = tp->snd_nxt; 752: u_int win = 753: MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / 754: tp->t_maxseg; 755: 756: if (win < 2) 757: win = 2; 758: tp->snd_ssthresh = win * tp->t_maxseg; 759: 760: tp->t_timer[TCPT_REXMT] = 0; 761: tp->t_rtt = 0; 762: tp->snd_nxt = ti->ti_ack; 763: tp->snd_cwnd = tp->t_maxseg; 764: (void) tcp_output(tp); 765: 766: if (SEQ_GT(onxt, tp->snd_nxt)) 767: tp->snd_nxt = onxt; 768: goto drop; 769: } 770: } else 771: tp->t_dupacks = 0; 772: break; 773: } 774: tp->t_dupacks = 0; 775: if (SEQ_GT(ti->ti_ack, tp->snd_max)) { 776: tcpstat.tcps_rcvacktoomuch++; 777: goto dropafterack; 778: } 779: acked = ti->ti_ack - tp->snd_una; 780: tcpstat.tcps_rcvackpack++; 781: tcpstat.tcps_rcvackbyte += acked; 782: 783: /* 784: * If transmit timer is running and timed sequence 785: * number was acked, update smoothed round trip time. 786: * Since we now have an rtt measurement, cancel the 787: * timer backoff (cf., Phil Karn's retransmit alg.). 788: * Recompute the initial retransmit timer. 789: */ 790: if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) { 791: tcpstat.tcps_rttupdated++; 792: if (tp->t_srtt != 0) { 793: register short delta; 794: 795: /* 796: * srtt is stored as fixed point with 3 bits 797: * after the binary point (i.e., scaled by 8). 798: * The following magic is equivalent 799: * to the smoothing algorithm in rfc793 800: * with an alpha of .875 801: * (srtt = rtt/8 + srtt*7/8 in fixed point). 802: * Adjust t_rtt to origin 0. 803: */ 804: delta = tp->t_rtt - 1 - (tp->t_srtt >> 3); 805: if ((tp->t_srtt += delta) <= 0) 806: tp->t_srtt = 1; 807: /* 808: * We accumulate a smoothed rtt variance 809: * (actually, a smoothed mean difference), 810: * then set the retransmit timer to smoothed 811: * rtt + 2 times the smoothed variance. 812: * rttvar is stored as fixed point 813: * with 2 bits after the binary point 814: * (scaled by 4). The following is equivalent 815: * to rfc793 smoothing with an alpha of .75 816: * (rttvar = rttvar*3/4 + |delta| / 4). 817: * This replaces rfc793's wired-in beta. 818: */ 819: if (delta < 0) 820: delta = -delta; 821: delta -= (tp->t_rttvar >> 2); 822: if ((tp->t_rttvar += delta) <= 0) 823: tp->t_rttvar = 1; 824: } else { 825: /* 826: * No rtt measurement yet - use the 827: * unsmoothed rtt. Set the variance 828: * to half the rtt (so our first 829: * retransmit happens at 2*rtt) 830: */ 831: tp->t_srtt = tp->t_rtt << 3; 832: tp->t_rttvar = tp->t_rtt << 1; 833: } 834: tp->t_rtt = 0; 835: tp->t_rxtshift = 0; 836: TCPT_RANGESET(tp->t_rxtcur, 837: ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, 838: TCPTV_MIN, TCPTV_REXMTMAX); 839: } 840: 841: /* 842: * If all outstanding data is acked, stop retransmit 843: * timer and remember to restart (more output or persist). 844: * If there is more data to be acked, restart retransmit 845: * timer, using current (possibly backed-off) value. 846: */ 847: if (ti->ti_ack == tp->snd_max) { 848: tp->t_timer[TCPT_REXMT] = 0; 849: needoutput = 1; 850: } else if (tp->t_timer[TCPT_PERSIST] == 0) 851: tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 852: /* 853: * When new data is acked, open the congestion window. 854: * If the window gives us less than ssthresh packets 855: * in flight, open exponentially (maxseg per packet). 856: * Otherwise open linearly (maxseg per window, 857: * or maxseg^2 / cwnd per packet). 858: */ 859: { 860: u_long incr = tp->t_maxseg; 861: 862: if (tp->snd_cwnd > tp->snd_ssthresh) 863: incr = MAX((long)(incr * incr / tp->snd_cwnd), 1L); 864: 865: tp->snd_cwnd = MIN((long)(tp->snd_cwnd + incr), IP_MAXPACKET); /* XXX */ 866: } 867: if (acked > so->so_snd.sb_cc) { 868: tp->snd_wnd -= so->so_snd.sb_cc; 869: sbdrop(&so->so_snd, (int)so->so_snd.sb_cc); 870: ourfinisacked = 1; 871: } else { 872: sbdrop(&so->so_snd, acked); 873: tp->snd_wnd -= acked; 874: ourfinisacked = 0; 875: } 876: if ((so->so_snd.sb_flags & SB_WAIT) || so->so_snd.sb_sel) 877: sowwakeup(so); 878: tp->snd_una = ti->ti_ack; 879: if (SEQ_LT(tp->snd_nxt, tp->snd_una)) 880: tp->snd_nxt = tp->snd_una; 881: 882: switch (tp->t_state) { 883: 884: /* 885: * In FIN_WAIT_1 STATE in addition to the processing 886: * for the ESTABLISHED state if our FIN is now acknowledged 887: * then enter FIN_WAIT_2. 888: */ 889: case TCPS_FIN_WAIT_1: 890: if (ourfinisacked) { 891: /* 892: * If we can't receive any more 893: * data, then closing user can proceed. 894: * Starting the timer is contrary to the 895: * specification, but if we don't get a FIN 896: * we'll hang forever. 897: */ 898: if (so->so_state & SS_CANTRCVMORE) { 899: soisdisconnected(so); 900: tp->t_timer[TCPT_2MSL] = tcp_maxidle; 901: } 902: tp->t_state = TCPS_FIN_WAIT_2; 903: } 904: break; 905: 906: /* 907: * In CLOSING STATE in addition to the processing for 908: * the ESTABLISHED state if the ACK acknowledges our FIN 909: * then enter the TIME-WAIT state, otherwise ignore 910: * the segment. 911: */ 912: case TCPS_CLOSING: 913: if (ourfinisacked) { 914: tp->t_state = TCPS_TIME_WAIT; 915: tcp_canceltimers(tp); 916: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 917: soisdisconnected(so); 918: } 919: break; 920: 921: /* 922: * In LAST_ACK, we may still be waiting for data to drain 923: * and/or to be acked, as well as for the ack of our FIN. 924: * If our FIN is now acknowledged, delete the TCB, 925: * enter the closed state and return. 926: */ 927: case TCPS_LAST_ACK: 928: if (ourfinisacked) { 929: tp = tcp_close(tp); 930: goto drop; 931: } 932: break; 933: 934: /* 935: * In TIME_WAIT state the only thing that should arrive 936: * is a retransmission of the remote FIN. Acknowledge 937: * it and restart the finack timer. 938: */ 939: case TCPS_TIME_WAIT: 940: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 941: goto dropafterack; 942: } 943: } 944: 945: step6: 946: /* 947: * Update window information. 948: * Don't look at window if no ACK: TAC's send garbage on first SYN. 949: */ 950: if ((tiflags & TH_ACK) && 951: (SEQ_LT(tp->snd_wl1, ti->ti_seq) || tp->snd_wl1 == ti->ti_seq && 952: (SEQ_LT(tp->snd_wl2, ti->ti_ack) || 953: tp->snd_wl2 == ti->ti_ack && ti->ti_win > tp->snd_wnd))) { 954: /* keep track of pure window updates */ 955: if (ti->ti_len == 0 && 956: tp->snd_wl2 == ti->ti_ack && ti->ti_win > tp->snd_wnd) 957: tcpstat.tcps_rcvwinupd++; 958: tp->snd_wnd = ti->ti_win; 959: tp->snd_wl1 = ti->ti_seq; 960: tp->snd_wl2 = ti->ti_ack; 961: if (tp->snd_wnd > tp->max_sndwnd) 962: tp->max_sndwnd = tp->snd_wnd; 963: needoutput = 1; 964: } 965: 966: /* 967: * Process segments with URG. 968: */ 969: if ((tiflags & TH_URG) && ti->ti_urp && 970: TCPS_HAVERCVDFIN(tp->t_state) == 0) { 971: /* 972: * This is a kludge, but if we receive and accept 973: * random urgent pointers, we'll crash in 974: * soreceive. It's hard to imagine someone 975: * actually wanting to send this much urgent data. 976: */ 977: if (ti->ti_urp + so->so_rcv.sb_cc > SB_MAX) { 978: ti->ti_urp = 0; /* XXX */ 979: tiflags &= ~TH_URG; /* XXX */ 980: goto dodata; /* XXX */ 981: } 982: /* 983: * If this segment advances the known urgent pointer, 984: * then mark the data stream. This should not happen 985: * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since 986: * a FIN has been received from the remote side. 987: * In these states we ignore the URG. 988: * 989: * According to RFC961 (Assigned Protocols), 990: * the urgent pointer points to the last octet 991: * of urgent data. We continue, however, 992: * to consider it to indicate the first octet 993: * of data past the urgent section 994: * as the original spec states. 995: */ 996: if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { 997: tp->rcv_up = ti->ti_seq + ti->ti_urp; 998: so->so_oobmark = so->so_rcv.sb_cc + 999: (tp->rcv_up - tp->rcv_nxt) - 1; 1000: if (so->so_oobmark == 0) 1001: so->so_state |= SS_RCVATMARK; 1002: sohasoutofband(so); 1003: tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); 1004: } 1005: /* 1006: * Remove out of band data so doesn't get presented to user. 1007: * This can happen independent of advancing the URG pointer, 1008: * but if two URG's are pending at once, some out-of-band 1009: * data may creep in... ick. 1010: */ 1011: if (ti->ti_urp <= ti->ti_len 1012: #ifdef SO_OOBINLINE 1013: && (so->so_options & SO_OOBINLINE) == 0 1014: #endif 1015: ) 1016: tcp_pulloutofband(so, ti); 1017: } else 1018: /* 1019: * If no out of band data is expected, 1020: * pull receive urgent pointer along 1021: * with the receive window. 1022: */ 1023: if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) 1024: tp->rcv_up = tp->rcv_nxt; 1025: dodata: /* XXX */ 1026: 1027: /* 1028: * Process the segment text, merging it into the TCP sequencing queue, 1029: * and arranging for acknowledgment of receipt if necessary. 1030: * This process logically involves adjusting tp->rcv_wnd as data 1031: * is presented to the user (this happens in tcp_usrreq.c, 1032: * case PRU_RCVD). If a FIN has already been received on this 1033: * connection then we just ignore the text. 1034: */ 1035: if ((ti->ti_len || (tiflags&TH_FIN)) && 1036: TCPS_HAVERCVDFIN(tp->t_state) == 0) { 1037: TCP_REASS(tp, ti, m, so, tiflags); 1038: if (tcpnodelack == 0) 1039: tp->t_flags |= TF_DELACK; 1040: else 1041: tp->t_flags |= TF_ACKNOW; 1042: /* 1043: * Note the amount of data that peer has sent into 1044: * our window, in order to estimate the sender's 1045: * buffer size. 1046: */ 1047: len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); 1048: if (len > tp->max_rcvd) 1049: tp->max_rcvd = len; 1050: } else { 1051: m_freem(m); 1052: tiflags &= ~TH_FIN; 1053: } 1054: 1055: /* 1056: * If FIN is received ACK the FIN and let the user know 1057: * that the connection is closing. 1058: */ 1059: if (tiflags & TH_FIN) { 1060: if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { 1061: socantrcvmore(so); 1062: tp->t_flags |= TF_ACKNOW; 1063: tp->rcv_nxt++; 1064: } 1065: switch (tp->t_state) { 1066: 1067: /* 1068: * In SYN_RECEIVED and ESTABLISHED STATES 1069: * enter the CLOSE_WAIT state. 1070: */ 1071: case TCPS_SYN_RECEIVED: 1072: case TCPS_ESTABLISHED: 1073: tp->t_state = TCPS_CLOSE_WAIT; 1074: break; 1075: 1076: /* 1077: * If still in FIN_WAIT_1 STATE FIN has not been acked so 1078: * enter the CLOSING state. 1079: */ 1080: case TCPS_FIN_WAIT_1: 1081: tp->t_state = TCPS_CLOSING; 1082: break; 1083: 1084: /* 1085: * In FIN_WAIT_2 state enter the TIME_WAIT state, 1086: * starting the time-wait timer, turning off the other 1087: * standard timers. 1088: */ 1089: case TCPS_FIN_WAIT_2: 1090: tp->t_state = TCPS_TIME_WAIT; 1091: tcp_canceltimers(tp); 1092: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 1093: soisdisconnected(so); 1094: break; 1095: 1096: /* 1097: * In TIME_WAIT state restart the 2 MSL time_wait timer. 1098: */ 1099: case TCPS_TIME_WAIT: 1100: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; 1101: break; 1102: } 1103: } 1104: if (so->so_options & SO_DEBUG) 1105: tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0); 1106: 1107: /* 1108: * Return any desired output. 1109: */ 1110: if (needoutput || (tp->t_flags & TF_ACKNOW)) 1111: (void) tcp_output(tp); 1112: return; 1113: 1114: dropafterack: 1115: /* 1116: * Generate an ACK dropping incoming segment if it occupies 1117: * sequence space, where the ACK reflects our state. 1118: */ 1119: if (tiflags & TH_RST) 1120: goto drop; 1121: m_freem(m); 1122: tp->t_flags |= TF_ACKNOW; 1123: (void) tcp_output(tp); 1124: return; 1125: 1126: dropwithreset: 1127: if (om) { 1128: (void) m_free(om); 1129: om = 0; 1130: } 1131: /* 1132: * Generate a RST, dropping incoming segment. 1133: * Make ACK acceptable to originator of segment. 1134: * Don't bother to respond if destination was broadcast. 1135: */ 1136: if ((tiflags & TH_RST) || in_broadcast(ti->ti_dst)) 1137: goto drop; 1138: if (tiflags & TH_ACK) 1139: tcp_respond(tp, ti, (tcp_seq)0, ti->ti_ack, TH_RST); 1140: else { 1141: if (tiflags & TH_SYN) 1142: ti->ti_len++; 1143: tcp_respond(tp, ti, ti->ti_seq+ti->ti_len, (tcp_seq)0, 1144: TH_RST|TH_ACK); 1145: } 1146: /* destroy temporarily created socket */ 1147: if (dropsocket) 1148: (void) soabort(so); 1149: return; 1150: 1151: drop: 1152: if (om) 1153: (void) m_free(om); 1154: /* 1155: * Drop space held by incoming segment and return. 1156: */ 1157: if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) 1158: tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0); 1159: m_freem(m); 1160: /* destroy temporarily created socket */ 1161: if (dropsocket) 1162: (void) soabort(so); 1163: return; 1164: } 1165: 1166: tcp_dooptions(tp, om, ti) 1167: struct tcpcb *tp; 1168: struct mbuf *om; 1169: struct tcpiphdr *ti; 1170: { 1171: register u_char *cp; 1172: int opt, optlen, cnt; 1173: 1174: cp = mtod(om, u_char *); 1175: cnt = om->m_len; 1176: for (; cnt > 0; cnt -= optlen, cp += optlen) { 1177: opt = UCHAR(cp[0]); 1178: if (opt == TCPOPT_EOL) 1179: break; 1180: if (opt == TCPOPT_NOP) 1181: optlen = 1; 1182: else { 1183: optlen = UCHAR(cp[1]); 1184: if (optlen <= 0) 1185: break; 1186: } 1187: switch (opt) { 1188: 1189: default: 1190: break; 1191: 1192: case TCPOPT_MAXSEG: 1193: if (optlen != 4) 1194: continue; 1195: if (!(ti->ti_flags & TH_SYN)) 1196: continue; 1197: tp->t_maxseg = *(u_short *)(cp + 2); 1198: tp->t_maxseg = ntohs((u_short)tp->t_maxseg); 1199: tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp)); 1200: break; 1201: } 1202: } 1203: (void) m_free(om); 1204: } 1205: 1206: /* 1207: * Pull out of band byte out of a segment so 1208: * it doesn't appear in the user's data queue. 1209: * It is still reflected in the segment length for 1210: * sequencing purposes. 1211: */ 1212: tcp_pulloutofband(so, ti) 1213: struct socket *so; 1214: struct tcpiphdr *ti; 1215: { 1216: register struct mbuf *m; 1217: int cnt = ti->ti_urp - 1; 1218: 1219: m = dtom(ti); 1220: while (cnt >= 0) { 1221: if (m->m_len > cnt) { 1222: char *cp = mtod(m, caddr_t) + cnt; 1223: struct tcpcb *tp = sototcpcb(so); 1224: 1225: tp->t_iobc = *cp; 1226: tp->t_oobflags |= TCPOOB_HAVEDATA; 1227: bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); 1228: m->m_len--; 1229: return; 1230: } 1231: cnt -= m->m_len; 1232: m = m->m_next; 1233: if (m == 0) 1234: break; 1235: } 1236: panic("tcp_pulloutofband"); 1237: } 1238: 1239: /* 1240: * Determine a reasonable value for maxseg size. 1241: * If the route is known, use one that can be handled 1242: * on the given interface without forcing IP to fragment. 1243: * If bigger than an mbuf cluster (MCLBYTES), round down to nearest size 1244: * to utilize large mbufs. 1245: * If interface pointer is unavailable, or the destination isn't local, 1246: * use a conservative size (512 or the default IP max size, but no more 1247: * than the mtu of the interface through which we route), 1248: * as we can't discover anything about intervening gateways or networks. 1249: * We also initialize the congestion/slow start window to be a single 1250: * segment if the destination isn't local; this information should 1251: * probably all be saved with the routing entry at the transport level. 1252: * 1253: * This is ugly, and doesn't belong at this level, but has to happen somehow. 1254: */ 1255: tcp_mss(tp) 1256: register struct tcpcb *tp; 1257: { 1258: struct route *ro; 1259: struct ifnet *ifp; 1260: int mss; 1261: struct inpcb *inp; 1262: 1263: inp = tp->t_inpcb; 1264: ro = &inp->inp_route; 1265: if ((ro->ro_rt == (struct rtentry *)0) || 1266: (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0) { 1267: /* No route yet, so try to acquire one */ 1268: if (inp->inp_faddr.s_addr != INADDR_ANY) { 1269: ro->ro_dst.sa_family = AF_INET; 1270: ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 1271: inp->inp_faddr; 1272: rtalloc(ro); 1273: } 1274: if ((ro->ro_rt == 0) || (ifp = ro->ro_rt->rt_ifp) == 0) 1275: return (TCP_MSS); 1276: } 1277: 1278: mss = ifp->if_mtu - sizeof(struct tcpiphdr); 1279: #if (MCLBYTES & (MCLBYTES - 1)) == 0 1280: if (mss > MCLBYTES) 1281: mss &= ~(MCLBYTES-1); 1282: #else 1283: if (mss > MCLBYTES) 1284: mss = mss / MCLBYTES * MCLBYTES; 1285: #endif 1286: if (in_localaddr(inp->inp_faddr)) 1287: return (mss); 1288: 1289: mss = MIN(mss, TCP_MSS); 1290: tp->snd_cwnd = mss; 1291: return (mss); 1292: } 1293: 1294: #if BSD<43 1295: /* XXX this belongs in netinet/in.c */ 1296: in_localaddr(in) 1297: struct in_addr in; 1298: { 1299: register u_long i = ntohl(in.s_addr); 1300: register struct ifnet *ifp; 1301: register struct sockaddr_in *sin; 1302: register u_long mask; 1303: 1304: if (IN_CLASSA(i)) 1305: mask = IN_CLASSA_NET; 1306: else if (IN_CLASSB(i)) 1307: mask = IN_CLASSB_NET; 1308: else if (IN_CLASSC(i)) 1309: mask = IN_CLASSC_NET; 1310: else 1311: return (0); 1312: 1313: i &= mask; 1314: for (ifp = ifnet; ifp; ifp = ifp->if_next) { 1315: if (ifp->if_addr.sa_family != AF_INET) 1316: continue; 1317: sin = (struct sockaddr_in *)&ifp->if_addr; 1318: if ((sin->sin_addr.s_addr & mask) == i) 1319: return (1); 1320: } 1321: return (0); 1322: } 1323: #endif