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