📄 ipproto.c
字号:
if ( (pIfp->if_flags & IFF_UP) ^ (newFlags & IFF_UP)) { s = splimp (); if ( (pIfp->if_flags & IFF_UP) == 0) if_up (pIfp); else if_down (pIfp); splx (s); } /* Set interface flags to new values, if allowed. */ newFlags = newFlags & ~IFF_CANTCHANGE; pIfp->if_flags &= IFF_CANTCHANGE; pIfp->if_flags = pIfp->if_flags | newFlags; break; case END_ERR_NO_BUF:#ifdef IP_DEBUG if (ipDebug && pError->pMesg != NULL) logMsg ("NO_BUF: Device: %s Unit: %d Msg: %s\n", (int)pEnd->devObject.name, pEnd->devObject.unit, (int)pError->pMesg, 0, 0, 0);#endif /* IP_DEBUG */ ip_drain(); /* empty the fragment Q */ break; default:#ifdef IP_DEBUG if (ipDebug && pError->pMesg != NULL) logMsg ("UNKOWN ERROR: Device: %s Unit: %d Msg: %s\n", (int)pEnd->devObject.name, pEnd->devObject.unit, (int)pError->pMesg, 0, 0, 0);#endif /* IP_DEBUG */ break; } }/******************************************************************************** ipAttach - a generic attach routine for the TCP/IP network stack** This routine takes the unit number and device name of an END or NPT* driver (e.g., "ln0", "ei0", etc.) and attaches the IP protocol to* the corresponding device. Following a successful attachment IP will* begin receiving packets from the devices.** RETURNS: OK or ERROR*/int ipAttach ( int unit, /* Unit number */ char *pDevice /* Device name (i.e. ln, ei etc.). */ ) { long flags; M2_INTERFACETBL mib2Tbl; M2_ID * pM2ID; IP_DRV_CTRL* pDrvCtrl;#ifndef VIRTUAL_STACK IMPORT int ipMaxUnits;#endif struct ifnet* pIfp = NULL; char *pName = NULL; END_OBJ* pEnd; struct ifaddr *pIfa; struct sockaddr_dl *pSdl; CL_POOL_ID pClPoolId; int ifHdrLen; int count; int limit = ipMaxUnits; int freeslot = -1; pEnd = endFindByName (pDevice, unit); if (pEnd == NULL) { logMsg ("ipAttach: Can't attach %s (unit %d). It is not an END device.\n", (int)pDevice, unit, 0, 0, 0, 0); return (ERROR); } for (count = 0; count < limit; count++) { pDrvCtrl = &ipDrvCtrl [count]; if (pDrvCtrl->attached) { /* Already attached to requested device? */ if (PCOOKIE_TO_ENDOBJ (pDrvCtrl->pIpCookie) == pEnd) return (OK); } else if (freeslot == -1) freeslot = count; } if (freeslot == -1) { /* Too many attach attempts. */ logMsg ("Protocol is out of space. Increase IP_MAX_UNITS.\n", 0, 0, 0, 0, 0, 0); return (ERROR); } pDrvCtrl = &ipDrvCtrl [freeslot]; bzero ( (char *)pDrvCtrl, sizeof (IP_DRV_CTRL)); /* * Bind IP to the device using the appropriate routines for the driver * type. NPT devices use a different receive routine since those drivers * remove the link-level header before handing incoming data to the MUX * layer. */ pDrvCtrl->nptFlag = FALSE; if (pEnd->pFuncTable->ioctl) { if ( (pEnd->pFuncTable->ioctl (pEnd, EIOCGNPT, NULL)) == OK) { /* NPT device. */ pDrvCtrl->nptFlag = TRUE; } } if (pDrvCtrl->nptFlag) { /* NPT device */ pDrvCtrl->pIpCookie = muxTkBind (pDevice, unit, ipTkReceiveRtn, ipTkShutdownRtn, ipTkTxRestart, ipTkError, ETHERTYPE_IP, "IP 4.4 TCP/IP", pDrvCtrl, NULL, NULL); if (pDrvCtrl->pIpCookie == NULL) { logMsg ("TCP/IP could not bind to the MUX: muxTkBind! %s", (int)pDevice, 0, 0, 0, 0, 0); goto ipAttachError; } } else { /* END device */ pDrvCtrl->pIpCookie = muxBind (pDevice, unit, (FUNCPTR) ipReceiveRtn, (FUNCPTR) ipShutdownRtn, (FUNCPTR) ipTxRestart, (VOIDFUNCPTR) ipError, ETHERTYPE_IP, "IP 4.4 TCP/IP", (void *) pDrvCtrl); if (pDrvCtrl->pIpCookie == NULL) { logMsg ("TCP/IP could not bind to the MUX! %s", (int)pDevice, 0, 0, 0, 0, 0); goto ipAttachError; } /* * END devices require additional memory to construct a * link-level header for outgoing data. */ pDrvCtrl->pSrc = netMblkGet (_pNetDpool, M_DONTWAIT, MT_DATA); if (pDrvCtrl->pSrc == NULL) { goto ipAttachError; } pDrvCtrl->pDst = netMblkGet (_pNetDpool, M_DONTWAIT, MT_DATA); if (pDrvCtrl->pDst == NULL) { goto ipAttachError; } } /* Get storage for link-level destination addresses. */ pClPoolId = netClPoolIdGet (_pNetDpool, MAX_ADDRLEN, TRUE); if (pClPoolId == NULL) { goto ipAttachError; } pDrvCtrl->pDstAddr = netClusterGet (_pNetDpool, pClPoolId); if (pDrvCtrl->pDstAddr == NULL) { goto ipAttachError; } /* Set the internal mBlk to access the link-level information. */ if (!pDrvCtrl->nptFlag) pDrvCtrl->pDst->m_data = pDrvCtrl->pDstAddr; pName = KHEAP_ALLOC( (strlen (pDevice) + 1)); /* +1: EOS character */ if (pName == NULL) { goto ipAttachError; } bzero (pName, strlen (pDevice) + 1); strcpy (pName, pDevice); /* Get all necessary lower-level device information. */ muxIoctl (pDrvCtrl->pIpCookie, EIOCGFLAGS, (caddr_t)&flags); if (pEnd->flags & END_MIB_2233) { if (muxIoctl(pDrvCtrl->pIpCookie, EIOCGMIB2233, (caddr_t)&pM2ID) == ERROR) { logMsg("ipAttach: could not get MIB2 Table for device %s #%d\n", (int)pDevice,unit,3,4,5,6); goto ipAttachError; } memcpy(&mib2Tbl, &(pM2ID->m2Data.mibIfTbl), sizeof(M2_INTERFACETBL)); } else /* (RFC1213 style of counters supported) XXX */ { if (muxIoctl(pDrvCtrl->pIpCookie, EIOCGMIB2, (caddr_t)&mib2Tbl) == ERROR) { logMsg("ipAttach: could not get MIB2 Table for device %s #%d\n", (int)pDevice,unit,3,4,5,6); goto ipAttachError; } } pIfp = (IFNET *)&pDrvCtrl->idr; /* Hook up the interface pointers etc. */ #ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 14, 17, WV_NETEVENT_ETHERATTACH_START, pIfp)#endif /* INCLUDE_WVNET */#endif bzero ((char *) pIfp, sizeof (*pIfp)); #ifdef VIRTUAL_STACK virtualStackIdCheck(); /* make sure the myStackNum exists */ pIfp->vsNum = myStackNum;#endif /* VIRTUAL_STACK */ pIfp->if_unit = unit; pIfp->if_name = pName; pIfp->if_mtu = mib2Tbl.ifMtu; pIfp->if_baudrate = mib2Tbl.ifSpeed; pIfp->if_init = NULL; pIfp->if_ioctl = (FUNCPTR) ipIoctl; pIfp->if_output = ipOutput; pIfp->if_reset = NULL; pIfp->if_resolve = muxAddrResFuncGet (mib2Tbl.ifType, ETHERTYPE_IP); pIfp->if_flags = flags; pIfp->if_type = mib2Tbl.ifType; pIfp->if_addrlen = mib2Tbl.ifPhysAddress.addrLength; pIfp->pCookie = (void *)pDrvCtrl; /* * Store address information for supported devices (802.x addressing) * and bind ARP to the device using the appropriate receive routine. */ switch (mib2Tbl.ifType) { case M2_ifType_ethernet_csmacd: case M2_ifType_iso88023_csmacd: case M2_ifType_iso88024_tokenBus: case M2_ifType_iso88025_tokenRing: case M2_ifType_iso88026_man: case M2_ifType_fddi: bcopy (mib2Tbl.ifPhysAddress.phyAddress, pDrvCtrl->idr.ac_enaddr, pIfp->if_addrlen); if (pDrvCtrl->nptFlag) { pDrvCtrl->pArpCookie = muxTkBind (pDevice, unit, ipTkReceiveRtn, arpTkShutdownRtn, ipTkTxRestart, NULL, ETHERTYPE_ARP, "IP 4.4 ARP", pDrvCtrl, NULL, NULL); if (pDrvCtrl->pArpCookie == NULL) { logMsg ("ARP could not bind to the MUX: muxTkBind! %s", (int)pDevice, 0, 0, 0, 0, 0); goto ipAttachError; } } else /* END device */ { pDrvCtrl->pArpCookie = muxBind (pDevice, unit, (FUNCPTR) ipReceiveRtn, (FUNCPTR) arpShutdownRtn, (FUNCPTR) ipTxRestart, NULL, ETHERTYPE_ARP, "IP 4.4 ARP", pDrvCtrl); if (pDrvCtrl->pArpCookie == NULL) { logMsg ("ARP could not bind to the MUX! %s", (int)pDevice, 0, 0, 0, 0, 0); goto ipAttachError; } } break; default: break; } /* Get the length of the header. */ if (muxIoctl (pDrvCtrl->pIpCookie, EIOCGHDRLEN, (caddr_t)&ifHdrLen) != OK) pIfp->if_hdrlen = 0; else pIfp->if_hdrlen = (short)ifHdrLen; /* Attach the interface. */ /* NOTE: if_attach must come before "common duties" below. see spr# 29152 */ if (if_attach (pIfp) == ERROR) goto ipAttachError; /* * Perform common duties while attaching to interface list */ for (pIfa = pIfp->if_addrlist; pIfa; pIfa = pIfa->ifa_next) { if ((pSdl = (struct sockaddr_dl *)pIfa->ifa_addr) && pSdl->sdl_family == AF_LINK) { pSdl->sdl_type = pIfp->if_type; pSdl->sdl_alen = pIfp->if_addrlen; bcopy (mib2Tbl.ifPhysAddress.phyAddress, LLADDR (pSdl), pSdl->sdl_alen); break; } } pIfp->if_start = (FUNCPTR)ipTxStartup; pDrvCtrl->attached = TRUE; return (OK); ipAttachError: /* Cleanup by removing any bound protocols and/or allocated memory. */ if (pDrvCtrl->pDstAddr) netClFree (_pNetDpool, pDrvCtrl->pDstAddr); if (pDrvCtrl->nptFlag) { if (pDrvCtrl->pIpCookie) muxUnbind (pDrvCtrl->pIpCookie, ETHERTYPE_IP, ipTkReceiveRtn); if (pDrvCtrl->pArpCookie) muxUnbind (pDrvCtrl->pArpCookie, ETHERTYPE_IP, ipTkReceiveRtn); } else { if (pDrvCtrl->pIpCookie) muxUnbind (pDrvCtrl->pIpCookie, ETHERTYPE_IP, ipReceiveRtn); if (pDrvCtrl->pArpCookie) muxUnbind (pDrvCtrl->pArpCookie, ETHERTYPE_IP, ipReceiveRtn); } if (pDrvCtrl->pSrc) netMblkFree (_pNetDpool, pDrvCtrl->pSrc); if (pDrvCtrl->pDst) netMblkFree (_pNetDpool, pDrvCtrl->pDst); return (ERROR); }/********************************************************************************* ipTxRestart - restart routine ** NOMANUAL*/LOCAL int ipTxRestart ( void * pCookie, /* device identifier (from muxDevLoad) */ IP_DRV_CTRL * pDrvCtrl ) { if (pDrvCtrl == NULL) return (ERROR); ipTxStartup (pDrvCtrl); return (OK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -