void * _mbufLibInit (void) { int ix; /* counter for list init */ if (mbufInit == TRUE) /* already initialized ? */ return ((void *) &mbufFunc); if ((_mbufIdHead = (MBUF_ID) KHEAP_ALLOC((sizeof (struct mbufId) * MBUF_ID_INC))) == NULL) /* alloc space for ID list */ return (NULL); if ((mbufDescHead = (MBUF_DESC) KHEAP_ALLOC((sizeof (struct mbufDesc) * MBUF_DESC_INC))) == NULL) /* alloc space for desc list */ { KHEAP_FREE((char *)_mbufIdHead); return (NULL); } /* divide up into an sll of free mbuf ID's, _mbufIdHead as the head */ for (ix = 0; ix < (MBUF_ID_INC - 1); ix++) _mbufIdHead[ix].mbufIdNext = &_mbufIdHead[ix + 1]; _mbufIdHead[ix].mbufIdNext = NULL; /* divide up into an sll of free buf desc, mbufDescHead as the head */ for (ix = 0; ix < (MBUF_DESC_INC - 1); ix++) mbufDescHead[ix].mbufDescNext = &mbufDescHead[ix + 1]; mbufDescHead[ix].mbufDescNext = NULL; mbufInit = TRUE; /* init successful */ return ((void *) &mbufFunc); /* return mbuf func table */ }
STATUS endMibIfInit ( FUNCPTR pMibAllocRtn, FUNCPTR pMibFreeRtn, FUNCPTR pMibCtrUpdate, FUNCPTR pMibVarUpdate ) { if ((pMibAllocRtn != NULL) && (pMibFreeRtn != NULL) && (pMibCtrUpdate != NULL) && (pMibVarUpdate != NULL)) { if (pMibRtn == NULL) { if ((pMibRtn = (MIB_ROUTINES *) KHEAP_ALLOC (sizeof (MIB_ROUTINES))) == NULL) { return(ERROR); } } pMibRtn->mibAlloc = (FUNCPTR)pMibAllocRtn; pMibRtn->mibFree = (FUNCPTR)pMibFreeRtn; pMibRtn->mibCntUpdate = (FUNCPTR)pMibCtrUpdate; pMibRtn->mibVarUpdate = (FUNCPTR)pMibVarUpdate; return(OK); } else { return(ERROR); } }
LOCAL STATUS hostNameFill ( FAST HOSTNAME *pHostName, char *newHostName ) { FAST char *pName = (char *) KHEAP_ALLOC((unsigned) (strlen (newHostName) + 1)); if (pName == NULL) return (ERROR); strcpy (pName, newHostName); pHostName->name = pName; pHostName->link = NULL; return (OK); }
MBUF_ID _mbufCreate (void) { MBUF_ID mbufId; /* obtained mbuf ID */ int ix; /* counter for list init */ int lockKey = intLock (); /* int lock cookie */ if ((mbufId = _mbufIdHead) != NULL) /* free list empty ? */ { _mbufIdHead = mbufId->mbufIdNext; /* pop first ID off list */ intUnlock (lockKey); mbufId->type = MBUF_VALID; /* init new ID type */ mbufId->mbufHead = NULL; /* init new ID head */ } else /* list is empty */ { intUnlock (lockKey); if ((mbufId = (MBUF_ID) KHEAP_ALLOC((sizeof (struct mbufId) * MBUF_ID_INC))) != NULL) /* alloc more IDs */ { for (ix = 0; ix < (MBUF_ID_INC - 1); ix++) /* into an sll */ mbufId[ix].mbufIdNext = &mbufId[ix + 1]; lockKey = intLock (); mbufId[ix].mbufIdNext = _mbufIdHead; _mbufIdHead = mbufId->mbufIdNext; /* hook head onto new list */ intUnlock (lockKey); mbufId->type = MBUF_VALID; /* init new ID type */ mbufId->mbufHead = NULL; /* init new ID head */ } } return (mbufId); /* return new ID */ }
STATUS virtualStackInit ( VSID vsId, /* Stack identifier from virtualStackCreate() routine */ int maxUnits /* maximum number of device to be attached to IP */ ) { int count; int vsIndex; if (!vsId) { return (ERROR); } /* Verify stack identifier. Exit if not found. */ if (virtualStackNumGet (vsId, &vsIndex) == ERROR) return (ERROR); /* Set the task variable and initialize the virtual stack. */ virtualStackNumTaskIdSet (vsIndex); /* Allocate the ipDrvCtrl array based on the given maxUnits */ ipMaxUnits = maxUnits ? maxUnits : 1; ipDrvCtrl = (IP_DRV_CTRL *)KHEAP_ALLOC(ipMaxUnits * sizeof(IP_DRV_CTRL)); if ( ipDrvCtrl == (IP_DRV_CTRL *) NULL ) return (ERROR); bzero ((char *)ipDrvCtrl,ipMaxUnits * sizeof(IP_DRV_CTRL)); ipDrvCount = 0; ipDrvIndex = 0; /* * Network buffer initialization: Reset pointers to NULL before * calling mbinit() routine to force each stack to create separate * memory pools. */ mClBlkConfig.memArea = NULL; for (count = 0; count < clDescTblNumEnt; count++) clDescTbl[count].memArea = NULL; sysMclBlkConfig.memArea = NULL; for (count = 0; count < sysClDescTblNumEnt; count++) sysClDescTbl[count].memArea = NULL; pM2IfRoot = NULL; pM2IfRootPtr = &pM2IfRoot; /* Make sure that the list is empty on the first call. */ _ifnet = NULL; /* * This code performs the same function as the static initialization * in the (no longer compiled) in_proto.c module. Since we don't get * auto-initialization from the compiler we have to do the work here. */ inetdomain.dom_family = AF_INET; inetdomain.dom_name = KHEAP_ALLOC (strlen("internet") + 1); strcpy (inetdomain.dom_name, "internet"); inetdomain.dom_init = 0; inetdomain.dom_externalize = 0; inetdomain.dom_dispose = 0; inetdomain.dom_protosw = inetsw; inetdomain.dom_protoswNPROTOSW = &inetsw[sizeof(inetsw)/sizeof(inetsw[0])]; inetdomain.dom_next = NULL; inetdomain.dom_rtattach = rn_inithead; inetdomain.dom_rtoffset = 27; inetdomain.dom_maxrtkey = sizeof(struct sockaddr_in); /* Set up for the protocol initialization. */ bzero ((caddr_t)&inetsw, sizeof(inetsw)); _protoSwIndex = 0; sb_max = SB_MAX; /* Set up for domain calls. */ domains = NULL; raw_sendspace = RAWSNDQ; raw_recvspace = RAWRCVQ; route_proto.sp_family = PF_ROUTE; return (OK); }
STATUS virtualStackCreate ( char* pName, /* Unique stack name, or NULL for default */ VSID* pVID /* Buffer for storing virtual stack identifier */ ) { int vsIndex, i; char tempName[VS_NAME_MAX + 1]; /* Lock out access until creation is complete or error is returned. */ semTake (vsTblLock, WAIT_FOREVER); /* Find the first empty slot. */ for (vsIndex = 0; vsIndex < VSID_MAX; vsIndex++) { if (vsTbl[vsIndex] == NULL) break; /* Hey, we found one! */ } if (vsIndex == VSID_MAX) { semGive (vsTblLock); return (ERROR); } /* * If no name is passed simply make the name the * VS number. */ if (pName == NULL) sprintf (tempName, "%d", vsIndex); else strncpy (tempName, pName, min(VS_NAME_MAX, (strlen(pName) + 1))); /* null-terminate it, just in case... */ tempName[VS_NAME_MAX] = EOS; /* Check that a stack with the same name doesn't already exist */ for (i = 0; i < VSID_MAX; i++) { if (vsTbl[i] == NULL) /* empty slot */ continue; if (strcmp (vsTbl[i]->pName, tempName) == 0) { semGive (vsTblLock); return (ERROR); } } /* Allocate our global structure. */ vsTbl[vsIndex] = (BSD_GLOBAL_DATA *) KHEAP_ALLOC ((sizeof(BSD_GLOBAL_DATA))); *pVID = vsTbl[vsIndex]; if (vsTbl[vsIndex] == NULL) { semGive (vsTblLock); return (ERROR); } /* Clear out the structure to NULL */ bzero ((char *)*pVID, sizeof (BSD_GLOBAL_DATA)); /* If no name is passed simply make the name the VS number. */ vsTbl[vsIndex]->pName = (char *)&vsTbl[vsIndex]->name; bcopy (tempName, vsTbl[vsIndex]->pName, sizeof(tempName)); semGive (vsTblLock); /* * Set the virtual stack number task variable. * This allows the initialization code to execute unchanged. */ virtualStackNumTaskIdSet (vsIndex); return (OK); }
int etherMultiAdd ( LIST *pList, /* pointer to list of multicast addresses */ char* pAddress /* address you want to add to list */ ) { ETHER_MULTI* pCurr; /* * Verify that we have valid Ethernet multicast addresses. */ if ((pAddress[0] & 0x01) != 1) { if (etherMultiDebug) logMsg("Invalid address!\n", 1, 2, 3, 4, 5, 6); return (EINVAL); } /* * See if the address range is already in the list. */ for (pCurr = (ETHER_MULTI *)lstFirst(pList); pCurr != NULL && (bcmp(pCurr->addr, pAddress, 6) != 0); pCurr = (ETHER_MULTI *)lstNext(&pCurr->node)); if (pCurr != NULL) { /* * Found it; just increment the reference count. */ if (etherMultiDebug) logMsg("Address already exists!\n", 1, 2, 3, 4, 5, 6); ++pCurr->refcount; return (0); } /* * New address or range; malloc a new multicast record * and link it into the interface's multicast list. */ pCurr = (ETHER_MULTI *) KHEAP_ALLOC(sizeof(ETHER_MULTI)); if (pCurr == NULL) { if (etherMultiDebug) logMsg("Cannot allocate memory!\n", 1, 2, 3, 4, 5, 6); return (ENOBUFS); } bcopy((char *)pAddress, (char *)pCurr->addr, 6); pCurr->refcount = 1; lstAdd(pList, &pCurr->node); if (etherMultiDebug) { logMsg("Added address is %x:%x:%x:%x:%x:%x\n", pCurr->addr[0], pCurr->addr[1], pCurr->addr[2], pCurr->addr[3], pCurr->addr[4], pCurr->addr[5]); } /* * Return ENETRESET to inform the driver that the list has changed * and its reception filter should be adjusted accordingly. */ return (ENETRESET); }
MBUF_SEG _mbufInsertBuf ( MBUF_ID mbufId, /* mbuf ID which buffer is inserted */ MBUF_SEG mbufSeg, /* mbuf base for <offset> */ int offset, /* relative byte offset */ caddr_t buf, /* user buffer for mbuf cluster */ int len, /* number of bytes to insert */ VOIDFUNCPTR freeRtn, /* user free routine */ int freeArg /* argument to free routine */ ) { MBUF_ID mbufIdNew; /* mbuf ID containing <buf> */ MBUF_DESC mbufDesc; /* desc for <buf> cluster */ MBUF_SEG mbufNew; /* mbuf for <buf> cluster */ CL_BLK_ID pClBlk; /* pointer to cluster blk */ int lockKey; /* int lock cookie */ int ix; /* counter for list init */ if (len <= 0) /* have to insert some bytes */ { errno = S_mbufLib_LENGTH_INVALID; return (NULL); } MBUF_ID_CREATE (mbufIdNew); /* create new mbuf ID for buf */ if (mbufIdNew == NULL) return (NULL); lockKey = intLock (); if ((mbufDesc = mbufDescHead) != NULL) /* free list empty ? */ { mbufDescHead = mbufDesc->mbufDescNext; /* pop first desc off list */ intUnlock (lockKey); } else /* list is empty */ { intUnlock (lockKey); if ((mbufDesc = (MBUF_DESC) KHEAP_ALLOC((sizeof (struct mbufDesc) * MBUF_DESC_INC))) != NULL) /* alloc more desc's */ { for (ix = 0; ix < (MBUF_DESC_INC - 1); ix++) mbufDesc[ix].mbufDescNext = &mbufDesc[ix + 1]; lockKey = intLock (); mbufDesc[ix].mbufDescNext = mbufDescHead; mbufDescHead = mbufDesc->mbufDescNext;/* hook head onto new list */ intUnlock (lockKey); } } if (mbufDesc == NULL) /* able to get a new desc ? */ { MBUF_ID_DELETE_EMPTY(mbufIdNew); return (NULL); } mbufDesc->buf = buf; /* get mbuf for cluster */ if ( (mbufNew = mBlkGet (_pNetDpool, M_WAIT, MT_DATA)) == NULL) { /* release on fail */ lockKey = intLock (); mbufDescHead = mbufDesc; intUnlock (lockKey); MBUF_ID_DELETE_EMPTY (mbufIdNew); return (NULL); } pClBlk = clBlkGet (_pNetDpool, M_WAIT); if (pClBlk == NULL) /* out of cl Blks */ { m_free (mbufNew); lockKey = intLock (); mbufDescHead = mbufDesc; intUnlock (lockKey); MBUF_ID_DELETE_EMPTY (mbufIdNew); return (NULL); } mbufNew->pClBlk = pClBlk; /* build <buf> into an mbuf cluster */ mbufNew->m_data = buf; mbufNew->m_len = len; mbufNew->m_flags |= M_EXT; mbufNew->m_extBuf = buf; mbufNew->m_extSize = len; mbufNew->m_extFreeRtn = (FUNCPTR) _mbufBufFree; mbufNew->m_extRefCnt = 1; mbufNew->m_extArg1 = (int) mbufDesc; mbufNew->m_extArg2 = (int) freeRtn; mbufNew->m_extArg3 = freeArg; mbufIdNew->mbufHead = mbufNew; /* put cluster into new ID */ /* insert the new mbuf ID with <buf> into <mbufId> */ if ((mbufSeg = _mbufInsert (mbufId, mbufSeg, offset, mbufIdNew)) == NULL) { mbufNew->m_extArg2 = (int)NULL; /* don't call freeRtn on fail */ MBUF_ID_DELETE(mbufIdNew); } return (mbufSeg); /* return inserted mbuf */ }
STATUS hostAdd ( char *hostName, /* host name */ char *hostAddr /* host addr in standard Internet format */ ) { HOSTNAME *pHostNamePrev = NULL; /* pointer to previous host name entry */ FAST HOSTNAME *pHostName; /* pointer to host name entry */ FAST HOSTENTRY *pHostEntry; struct in_addr netAddr; /* network address */ if (hostName == NULL || hostAddr == NULL) { errnoSet (S_hostLib_INVALID_PARAMETER); return (ERROR); } if ((netAddr.s_addr = inet_addr (hostAddr)) == ERROR) return (ERROR); if (semTake (hostListSem, WAIT_FOREVER) == ERROR) return (ERROR); for (pHostEntry = (HOSTENTRY *)lstFirst (&hostList); pHostEntry != NULL; pHostEntry = (HOSTENTRY *)lstNext (&pHostEntry->node)) { if (pHostEntry->netAddr.s_addr == netAddr.s_addr) { /* host internet address already in table, add name as an alias */ pHostNamePrev = &pHostEntry->hostName; for (pHostName = &pHostEntry->hostName; pHostName != NULL; pHostName = pHostName->link) { /* make sure name is not already used for this address */ if (strcmp (pHostName->name, hostName) == 0) { semGive (hostListSem); errnoSet (S_hostLib_HOST_ALREADY_ENTERED); return (ERROR); } pHostNamePrev = pHostName; } if (pHostNamePrev == NULL) { /* XXX corrupted list! */ return (ERROR); } /* name not used for this address, add it as an alias */ if ((pHostNamePrev->link = (HOSTNAME *) KHEAP_ALLOC(sizeof (HOSTNAME))) == NULL) { semGive (hostListSem); return (ERROR); } bzero ((char *)pHostNamePrev->link, sizeof(HOSTNAME)); if (hostNameFill (pHostNamePrev->link, hostName) == ERROR) { semGive (hostListSem); return (ERROR); } semGive (hostListSem); return (OK); } } /* host name and internet address not in host table, add new host */ if ((pHostEntry = (HOSTENTRY *) KHEAP_ALLOC(sizeof (HOSTENTRY))) == NULL) { semGive (hostListSem); return (ERROR); } bzero ((char *)pHostEntry, sizeof(HOSTENTRY)); if ((hostNameFill (&pHostEntry->hostName, hostName)) == ERROR) { semGive (hostListSem); return (ERROR); } pHostEntry->netAddr = netAddr; lstAdd (&hostList, &pHostEntry->node); semGive (hostListSem); return (OK); }