|
|
1.1 ! root 1: /* ! 2: * ip line discipline, to be pushed on an ethernet controller. ! 3: * collects data till a delim, passes it to ip_input(). ! 4: */ ! 5: ! 6: #include "inet.h" ! 7: #include "arp.h" ! 8: #include "uarp.h" ! 9: #if NINET > 0 ! 10: #include "../h/param.h" ! 11: #include "../h/systm.h" ! 12: #include "../h/stream.h" ! 13: #include "../h/ioctl.h" ! 14: #include "../h/ttyld.h" ! 15: #include "../h/map.h" ! 16: #include "../h/buf.h" ! 17: #include "../h/ubavar.h" ! 18: #include "../h/conf.h" ! 19: #include "../h/inet/in.h" ! 20: #include "../h/inet/ip_var.h" ! 21: #include "../h/ethernet.h" ! 22: ! 23: struct ipif ipif[NINET]; ! 24: int Ninet = NINET; /* let netstat find the number of interfaces */ ! 25: ! 26: int ipopen(), ipiput(), ipisrv(), ipclose(); ! 27: int iposrv(), ipoput(); ! 28: static struct qinit iprinit = { ipiput, ipisrv, ipopen, ipclose, IP_MSG_LIMIT, 64}; ! 29: /* was IP_MSG_LIMIT (4096), 64 originally */ ! 30: static struct qinit ipwinit = { putq, iposrv, ipopen, ipclose, 1024, 64 }; ! 31: /* was 512, 64 originally */ ! 32: struct streamtab ipinfo = { &iprinit, &ipwinit }; ! 33: ! 34: ipopen(q, dev) ! 35: register struct queue *q; ! 36: { ! 37: static int timing; ! 38: register i; ! 39: register struct ipif *fp; ! 40: ! 41: if (q->ptr) ! 42: return(1); ! 43: if(!timing){ ! 44: timing = 1; ! 45: ip_slowtimo(); ! 46: } ! 47: for (i=0; ipif[i].queue!=0 && i<NINET; i++) ! 48: ; ! 49: if (i >= NINET) ! 50: return(0); ! 51: fp = &ipif[i]; ! 52: fp->queue = q; /* that's the RD q */ ! 53: fp->flags = IFF_UP; ! 54: fp->that = fp->thishost = 0; ! 55: fp->ipackets = fp->opackets = fp->ierrors = fp->oerrors = 0; ! 56: fp->mtu = 1500; ! 57: fp->arp = -1; ! 58: fp->dev = dev; ! 59: q->flag |= QDELIM; ! 60: WR(q)->flag |= QDELIM; ! 61: q->ptr = (caddr_t)fp; ! 62: WR(q)->ptr = (caddr_t)fp; ! 63: q->flag |= QNOENB; /* ipiput calls qenable() */ ! 64: return(1); ! 65: } ! 66: ! 67: ipclose(q) ! 68: register struct queue *q; ! 69: { ! 70: register struct ipif *ifp; ! 71: ! 72: ifp = (struct ipif *)q->ptr; ! 73: #if NARP > 0 ! 74: if (ifp->arp >= 0) ! 75: arp_disable(ifp->arp); ! 76: #endif ! 77: ifp->queue = 0; ! 78: ifp->flags = 0; ! 79: } ! 80: ! 81: ipisrv(q) ! 82: register struct queue *q; ! 83: { ! 84: register struct block *bp, *head, *tail; ! 85: register struct ipif *ifp; ! 86: ! 87: /* there is now a whole packet waiting ! 88: * on this queue; strip it off and pass to ip_input(). ! 89: * things other than data or delims are forwarded directly ! 90: * by ipiput(). ! 91: */ ! 92: head = tail = (struct block *) 0; ! 93: ifp = (struct ipif *)q->ptr; ! 94: while(bp = getq(q)){ ! 95: if(bp->type == M_DELIM){ ! 96: freeb(bp); ! 97: if(head){ ! 98: if((ifp->flags & IFF_ARP) ! 99: && (head->wptr - head->rptr) >= 14){ ! 100: /* blow away ether header */ ! 101: head->rptr += 6 + 6 + 2; ! 102: } ! 103: ip_input(head); ! 104: ifp->ipackets++; ! 105: } else { ! 106: printf("ipisrv: delim, no data\n"); ! 107: ifp->ierrors++; ! 108: } ! 109: head = tail = (struct block *) 0; ! 110: } else if(bp->type == M_DATA){ ! 111: bp->next = (struct block *) 0; ! 112: if(head == (struct block *) 0){ ! 113: head = bp; ! 114: } else { ! 115: tail->next = bp; ! 116: } ! 117: tail = bp; ! 118: } else { ! 119: printf("weird type %d in ipisrv\n", bp->type); ! 120: (*q->next->qinfo->putp)(q->next, bp); ! 121: } ! 122: } ! 123: if(head || tail){ ! 124: printf("ipisrv: data & no dELIM\n"); ! 125: } ! 126: } ! 127: ! 128: ! 129: ipiput(q, bp) ! 130: register struct queue *q; ! 131: register struct block *bp; ! 132: { ! 133: switch(bp->type){ ! 134: case M_DATA: ! 135: putq(q, bp); /* putq does compression into blocks */ ! 136: break; ! 137: case M_DELIM: ! 138: putq(q, bp); ! 139: qenable(q); ! 140: break; ! 141: default: ! 142: (*q->next->qinfo->putp)(q->next, bp); ! 143: break; ! 144: } ! 145: ! 146: } ! 147: ! 148: iposrv(q) ! 149: register struct queue *q; ! 150: { ! 151: struct x{ ! 152: unsigned int in; ! 153: unsigned char en[6]; ! 154: } *xp; ! 155: register union stmsg *sp; ! 156: register struct block *bp; ! 157: register struct ipif *ifp; ! 158: register int *intp; ! 159: ! 160: ifp = (struct ipif *)q->ptr; ! 161: while(bp = getq(q)){ ! 162: if(bp->type == M_IOCTL){ ! 163: sp = (union stmsg *)bp->rptr; ! 164: switch(sp->ioc0.com){ ! 165: case IPIOARP: ! 166: #if NARP > 0 ! 167: if (ifp->arp >= 0) ! 168: printf("IP: already arping\n"); ! 169: else { ! 170: ifp->arp = arp_enable(ifp->dev, ! 171: ETHERPUP_IPTYPE, ! 172: sizeof(u_long), 1, ! 173: &ifp->thishost); ! 174: if (ifp->arp == -1) { ! 175: bp->type = M_IOCNAK; ! 176: qreply(q, bp); ! 177: break; ! 178: } ! 179: } ! 180: #endif ! 181: ifp->flags |= IFF_ARP; ! 182: bp->type = M_IOCACK; ! 183: bp->wptr = bp->rptr; ! 184: qreply(q, bp); ! 185: break; ! 186: case IPIORESOLVE: ! 187: xp = (struct x *)(sp->iocx.xxx); ! 188: #if NUARP > 0 ! 189: arp_install(xp->in, xp->en); ! 190: #endif ! 191: bp->wptr = bp->rptr; ! 192: bp->type = M_IOCACK; ! 193: qreply(q, bp); ! 194: break; ! 195: case IPIOHOST: ! 196: intp = (int *)(sp->iocx.xxx); ! 197: ifp->that = *intp; ! 198: ifp->flags |= IFF_HOST; ! 199: bp->type = M_IOCACK; ! 200: qreply(q, bp); ! 201: ip_doroute(ifp->that, 0); ! 202: break; ! 203: case IPIOMTU: ! 204: intp = (int *)(sp->iocx.xxx); ! 205: ifp->that = *intp; ! 206: ifp->mtu = *intp; ! 207: bp->type = M_IOCACK; ! 208: qreply(q, bp); ! 209: break; ! 210: case IPIONET: ! 211: intp = (int *)(sp->iocx.xxx); ! 212: ifp->that = *intp; ! 213: ifp->flags &= (~IFF_HOST); ! 214: bp->type = M_IOCACK; ! 215: qreply(q, bp); ! 216: ip_doroute(ifp->that, 0); ! 217: break; ! 218: case IPIOLOCAL: ! 219: intp = (int *)(sp->iocx.xxx); ! 220: ifp->thishost = *intp; ! 221: bp->type = M_IOCACK; ! 222: qreply(q, bp); ! 223: break; ! 224: default: ! 225: (*q->next->qinfo->putp)(q->next, bp); ! 226: break; ! 227: } ! 228: } else { ! 229: (*q->next->qinfo->putp)(q->next, bp); ! 230: if(bp->type == M_DELIM) ! 231: ifp->opackets++; ! 232: } ! 233: } ! 234: } ! 235: ! 236: struct ipif * ! 237: ip_ifonnetof(dst) ! 238: unsigned long dst; ! 239: { ! 240: extern ipprintfs; ! 241: struct ipif *ifp; ! 242: ! 243: /* point-to-point links first */ ! 244: for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){ ! 245: if((ifp->flags & IFF_UP) && (ifp->flags & IFF_HOST)){ ! 246: if(dst == ifp->that) ! 247: return(ifp); ! 248: } ! 249: } ! 250: /* now normal nets */ ! 251: for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){ ! 252: if((ifp->flags & (IFF_UP|IFF_HOST)) == IFF_UP){ ! 253: if(in_netof(dst) == ifp->that) ! 254: return(ifp); ! 255: } ! 256: } ! 257: if(ipprintfs) ! 258: printf("ifonnetof %x?\n", dst); ! 259: return(0); ! 260: } ! 261: ! 262: struct ipif * ! 263: ip_ifwithaddr(addr) ! 264: unsigned long addr; ! 265: { ! 266: struct ipif *ifp; ! 267: unsigned long net; ! 268: ! 269: net = in_netof(addr); ! 270: for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){ ! 271: if(ifp->flags & IFF_UP){ ! 272: /* address of this host */ ! 273: if(addr == ifp->thishost) ! 274: return(ifp); ! 275: /* address of this host's network */ ! 276: if(addr == in_netof(ifp->thishost)) ! 277: return(ifp); ! 278: /* address on a network simulated by this node */ ! 279: if(net == ifp->thishost) ! 280: return(ifp); ! 281: } ! 282: } ! 283: return(0); ! 284: } ! 285: ! 286: ip_ldout(bp, dst, ifp) ! 287: register struct block *bp; ! 288: unsigned long dst; /* host byte order */ ! 289: register struct ipif *ifp; ! 290: { ! 291: #if NARP > 0 || NUARP > 0 ! 292: extern struct block *arp_resolve(); ! 293: #endif ! 294: register struct block *bp1; ! 295: struct goo{ ! 296: unsigned int addr; ! 297: char unused[4]; ! 298: } *goop; ! 299: register struct queue *q; ! 300: ! 301: if(ifp->queue == 0){ ! 302: printf("ifp but no queue in ip_ldout\n"); ! 303: bp_free(bp); ! 304: return(0); ! 305: } ! 306: q = WR(ifp->queue); ! 307: if(q->next->flag & QFULL){ ! 308: bp_free(bp); ! 309: ifp->oerrors++; ! 310: return(1); ! 311: } ! 312: #if NARP > 0 ! 313: if(ifp->flags & IFF_ARP){ ! 314: bp = arp_resolve(ifp->arp, bp, &dst); ! 315: if(bp == 0) ! 316: return(1); ! 317: } ! 318: #endif ! 319: #if NUARP > 0 ! 320: if(ifp->flags & IFF_ARP){ ! 321: bp = arp_resolve(ifp->queue, bp, dst); ! 322: if(bp == 0) ! 323: return(1); ! 324: } ! 325: #endif ! 326: while(bp){ ! 327: if(bp->rptr < bp->base || bp->rptr >= bp->lim ! 328: || bp->wptr < bp->base || bp->wptr > bp->lim){ ! 329: printf("ip_ldout: bad block 0x%x\n", bp); ! 330: panic("ip_ldout"); ! 331: } ! 332: bp1 = bp->next; ! 333: (*q->next->qinfo->putp)(q->next, bp); ! 334: bp = bp1; ! 335: } ! 336: bp1 = allocb(0); ! 337: if(bp1){ ! 338: bp1->type = M_DELIM; ! 339: (*q->next->qinfo->putp)(q->next, bp1); ! 340: ifp->opackets++; ! 341: } else { ! 342: printf("ip_ldout: no allocb for delim\n"); ! 343: ifp->oerrors++; ! 344: } ! 345: return(0); ! 346: } ! 347: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.