⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdisclib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
* Is called in rdCtl to verify the input parameter** Returns: pointer to valid interface if successfull, else NULL**/LOCAL struct ifrd* searchInterface(const char* ifName){    struct ifrd* t = pIfDisc;    int index;        /* find matching RD interface */     if (NULL == ifName){    	logMsg("rdCtl: no interface specified\n",1,2,3,4,5,6);	return NULL;    }    for( index=0; index < rdiscNumInterfaces ; index++)        {        if( strcmp(t[index].ifName, ifName) == 0)                break;        }    if (index == rdiscNumInterfaces)        {	logMsg("rdCtl: could not find interface %s\n", (int)ifName,2,3,4,5,6);        return NULL;        }    return &t[index];        }/********************************************************************************* returnFromRdCtl - central return from rdCtl function** gives the central semaphore before returning from rdCtl** Returns: STATUS which is passed is parameter**/LOCAL STATUS returnFromRdCtl(STATUS retVal)    {    semGive (rdiscIfSem);    return retVal;    }/********************************************************************************* rdCtl - implement the ICMP router discovery control function ** This routine allows a user to get and set router discovery parameters, and* control the mode of operation.  ** OPTIONS* The following section discuss the various flags that may be passed* to rdCtl().** .SS "SET_MODE -- Set debug mode or exit router discovery"* This flag does not require an <interface> to be specified* it is best to specify NULL.** This flag is used in conjunction with the following values:** .SS "MODE_DEBUG_ON -- Turn debugging messages on. "* * .CS*     rdCtl (NULL, SET_MODE, MODE_DEBUG_ON);* .CE** .SS "MODE_DEBUG_OFF -- Turn debugging messages off."** .CS*     rdCtl (NULL, SET_MODE, MODE_DEBUG_OFF);* .CE** .SS "MODE_STOP -- Exit from router discovery."** .CS*     rdCtl (NULL, SET_MODE, MODE_STOP);* .CE** .SS "SET_MIN_ADVERT_INT -- set minimum advertisement interval in seconds"* Specify the minimum time between advertisements in seconds.  The minimum* value allowed is 4 seconds, the maximum is 1800.** .CS*     rdCtl (NULL, SET_MIN_ADVERT_INT, <seconds>);* .CE** .SS "SET_MAX_ADVERT_INT -- set maximum advertisement interval in seconds"* Specify the maximum time between advertisements in seconds.  The minimum* value allowed is 4 seconds, the maximum is 1800.** .CS*     rdCtl (NULL, SET_MAX_ADVERT_INT, <seconds>);* .CE** .SS "SET_FLAG -- Set whether advertisements are sent on an interface."* If this flag is 1 then advertisements are sent on this interface.  * If it is 0 then they are not.** .CS*    rdCtl (<interface>, SET_FLAG, <0 or 1>);* .CE** .SS "SET_ADVERT_ADDRESS -- Set the IP address to which advertisements are sent. "*  Set the multicast IP address to which advertisements are sent.** .CS*    rdCtl (<interface>, SET_ADVERT_ADDRESS, <multicast address>);* .CE** .SS "SET_ADVERT_LIFETIME -- Set the lifetime for advertisements in seconds. "* Set the lifetime in seconds to be contained in each advertisement.** .CS*    rdCtl (<interface>, SET_ADVERT_LIFETIME, seconds);* .CE** .SS "SET_ADVERT_PREF -- Set the preference level contained in advertisements."* Set the preference level contained in advertisements.** .CS*    rdCtl (<interface>, SET_ADVERT_PREF, value);* .CE** .SS "GET_MIN_ADVERT_INT -- Get the minimum advertisement interval. "* .CS*    rdCtl (NULL, GET_MIN_ADVERT_INT, &value);* .CE** .SS "GET_MAX_ADVERT_INT -- Get the maximum advertisement interval. "* .CS*    rdCtl (NULL, GET_MAX_ADVERT_INT, &value);* .CE** .SS "GET_FLAG -- Get the flag on an interface.. "* .CS*    rdCtl (<interface>, GET_FLAG, &value);* .CE** .SS "GET_ADVERT_ADDRESS -- Get the advertisement address for an interface. "* .CS*    rdCtl (<interface>, GET_ADVERT_ADDRESS, &value);* .CE** .SS "GET_ADVERT_LIFETIME -- Get the advertisement lifetime. "* .CS*    rdCtl (<interface>, GET_ADVERT_LIFETIME, &value);* .CE** .SS "GET_ADVERT_PREF -- Get the advertisement preference. "* .CS*    rdCtl (<interface>, GET_ADVERT_PREF, value);* .CE** Returns: OK on success, ERROR on failure**/STATUS rdCtl    (    char *ifName,     int cmd,     void* value		/* my be an int (set-cmds) or an int* (get-cmds) */    )    {        /* Check the interface list lock. */    semTake (rdiscIfSem, WAIT_FOREVER);    /* execute command */        switch(cmd)	{        	case SET_MODE:            if ((int)value == MODE_DEBUG_OFF)                {                logMsg("rdisc: debug mode off\n",0,0,0,0,0,0);                debugFlag = 0;                }            else                {		if ((int)value == MODE_DEBUG_ON)		    {		    logMsg("rdisc: debug mode on\n",0,0,0,0,0,0);		    debugFlag = 1;		    }		else                     {                    if ((int)value == MODE_STOP)                        {			int i;                        logMsg("rdisc: received termination message\n",0,0,0,0,0,0);                        semGive (rdiscIfSem);                        terminateFlag = 1;                        for(i=0; i<rdiscNumInterfaces; i++)                            pIfDisc[i].AdvertLifetime = 0;                        sendAdvertAll(); /* recvfrom is blocked */                        }                    }                }            break;            	case SET_MIN_ADVERT_INT:	    {	    int numSeconds = (int)value;            if ((numSeconds < 4) ||                 (numSeconds > 1800) ||                 (numSeconds >= MaxAdvertInterval))                {                return returnFromRdCtl(ERROR);                }            MinAdvertInterval = numSeconds;                        wdCancel(wdId);            startWdTimer();	    }            break;            	case SET_MAX_ADVERT_INT:	    {	    int numSeconds = (int)value;            if ((numSeconds < 4) ||                 (numSeconds > 1800) ||                 (numSeconds <= MinAdvertInterval))                {                return returnFromRdCtl(ERROR);                }            MaxAdvertInterval = numSeconds;                        wdCancel(wdId);            startWdTimer();	    }            break;            	case SET_FLAG:	    {	    struct ifrd* interface = searchInterface(ifName);	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            interface->Advertise = (int)value ? 1:0 ;	    }            break;	            	case SET_ADVERT_ADDRESS:	    {	    struct ifrd* interface = searchInterface(ifName);	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            if ((int)value == INADDR_BROADCAST)                {                if (debugFlag == TRUE)                    logMsg ("rdisc broadcast not yet supported%d\n",                            1, 2, 3, 4, 5, 6);                return returnFromRdCtl(ERROR);                }            interface->AdvertAddress.s_addr = (int)value;	    }            break;	            	case SET_ADVERT_LIFETIME:	    {	    int numSeconds = (int)value;	    struct ifrd* interface = searchInterface(ifName);	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            if ((numSeconds < MaxAdvertInterval) ||                (numSeconds > 9000))                {                return returnFromRdCtl(ERROR);                }            interface->AdvertLifetime = numSeconds;	    }            break;	            	case SET_ADVERT_PREF:	    {	    struct ifrd* interface = searchInterface(ifName);	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            interface->PrefLevel = (int)value;	    }            break;	                    case GET_MIN_ADVERT_INT:	    {	    int* intPtr = (int *)value;            *intPtr = MinAdvertInterval ;	    }            break;                    case GET_MAX_ADVERT_INT:	    {	    int* intPtr = (int *)value;            *intPtr = MaxAdvertInterval;	    }            break;                    case GET_FLAG:	    {	    struct ifrd* interface = searchInterface(ifName);	    int* intPtr = (int *)value;	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            *intPtr = interface->Advertise;	    }            break;                    case GET_ADVERT_ADDRESS:	    {	    struct ifrd* interface = searchInterface(ifName);	    int* intPtr = (int *)value;	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            *intPtr = interface->AdvertAddress.s_addr;	    }            break;                    case GET_ADVERT_LIFETIME:	    {	    struct ifrd* interface = searchInterface(ifName);	    int* intPtr = (int *)value;	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            *intPtr = interface->AdvertLifetime;	    }            break;                    case GET_ADVERT_PREF:	    {	    struct ifrd* interface = searchInterface(ifName);	    int* intPtr = (int *)value;	    if (0 == interface)	    	return returnFromRdCtl(ERROR);            *intPtr = interface->PrefLevel;	    }            break;            	default:	    logMsg("rdCtl: illegal cmd %d\n",cmd,2,3,4,5,6);            return returnFromRdCtl(ERROR);        }        return returnFromRdCtl(OK) ;        }/******************************************************************************** rdiscIfReset - check for new or removed interfaces for router discovery** This routine MUST be called any time an interface is added to or removed* from the system so that the router discovery code can deal with this* case.  Failure to do so will cause the sending of packets on missing* interfaces to fail as well as no transmission of packets on new interfaces.**/STATUS rdiscIfReset ()    {        struct in_ifaddr *ia = NULL;    int i;    int status;    struct ifnet *ifp=NULL;    struct ifaddr *ifa=NULL;    char *t=NULL;    struct sockaddr_in *tt=0;    struct ip_mreq ipMreq;    struct ifrd *pTmp=NULL;    /* Take the lock. */    semTake (rdiscIfSem, WAIT_FOREVER);        /* If we had an old list then free it. */    if (pIfDisc != NULL)        {        /* First drop the multicast stuff on all interfaces. */        for(i = 0; i < rdiscNumInterfaces; i++)            {            pTmp = &pIfDisc[i];            /* drop multicast membership for this IF */            ipMreq.imr_multiaddr.s_addr = htonl(0xe0000002);             ipMreq.imr_interface.s_addr = pTmp->NetAddress.s_addr;             /*             * The reason we DON'T check the return status here             * is that if we did and the interface has been removed             * then we what would we do?  This is a best effort             * attempt to do remove the multicast address from             * all UP interfaces, an interface that is missing             * will simply return ERROR which is OK in this case.             */            setsockopt(rdiscSock, IPPROTO_IP,IP_DROP_MEMBERSHIP,                        (char *)&ipMreq, sizeof(ipMreq));            }        free (pIfDisc);        }    /* count interfaces for discovery */ #ifdef VIRTUAL_STACK    for(ifp = _ifnet, i=0; ifp != 0; ifp = ifp->if_next)#else    for(ifp = ifnet, i=0; ifp != 0; ifp = ifp->if_next)#endif        {	/* reject unwanted interfaces */        if (!(ifp->if_flags & IFF_MULTICAST))             continue;	if (strcmp(ifp->if_name, "lo") == 0) 	   continue;	i++;        }    rdiscNumInterfaces = i;    t = malloc(sizeof(struct ifrd) * rdiscNumInterfaces);    if (t == NULL)        {        logMsg("rdiscIfReset: error allocating memory\n",0,0,0,0,0,0);        semGive (rdiscIfSem);        rdiscNumInterfaces = 0; /* So rdCtl won't walk an empty list. */        rdCtl (NULL, SET_MODE, (void*)MODE_STOP);	return ERROR;	}    bzero(t, sizeof(struct ifrd) * rdiscNumInterfaces);    /* set global to head of list */    pIfDisc = (struct ifrd *)t;    /* set each interface for discovery */ #ifdef VIRTUAL_STACK    for(ifp = _ifnet, i=0; ifp != 0; ifp = ifp->if_next)#else    for(ifp = ifnet, i=0; ifp != 0; ifp = ifp->if_next)#endif	{	/* reject unwanted interfaces */        if (!(ifp->if_flags & IFF_MULTICAST))             continue;	if (strcmp(ifp->if_name, "lo") == 0) 	   continue;        for (ifa = ifp->if_addrlist;  ifa != NULL;  ifa = ifa->ifa_next)            {            if (ifa->ifa_addr->sa_family == AF_INET)                {		tt = (struct sockaddr_in *)ifa->ifa_addr;		break;                }            }	/* find subnetmask */#ifdef VIRTUAL_STACK	for (ia = _in_ifaddr;  ia != NULL;  ia = ia->ia_next)#else	for (ia = in_ifaddr;  ia != NULL;  ia = ia->ia_next)#endif	   {	      if (ia->ia_ifp == ifp)		   break;	   }	/* fill in router discovery params for this IF */        pTmp = &pIfDisc[i];	sprintf(pTmp->ifName,"%s%d", ifp->if_name, ifp->if_unit);        pTmp->NetAddress.s_addr = tt->sin_addr.s_addr;        pTmp->AdvertAddress.s_addr = htonl(0xe0000001);         pTmp->subnet = ia->ia_subnet;        pTmp->mask = ia->ia_subnetmask;        pTmp->AdvertLifetime = 1800;        pTmp->Advertise = 1;        pTmp->PrefLevel = 0; 	/* add multicast membership for this IF */        ipMreq.imr_multiaddr.s_addr = htonl(0xe0000002);         ipMreq.imr_interface.s_addr = pTmp->NetAddress.s_addr;         status = setsockopt(rdiscSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,             (char *)&ipMreq, sizeof(ipMreq));        if (status == ERROR)	    {                logMsg("rdisc: could not join multicast group, errno is %d\n", 			errno,0,0,0,0,0);                semGive (rdiscIfSem);                rdiscNumInterfaces = 0; /* So rdCtl won't walk a bad list. */                rdCtl (NULL, SET_MODE, (void*)MODE_STOP);		return ERROR;            } 		MaxAdvertInterval = 600; /* max interval in seconds */	MinAdvertInterval = 450; /* max interval in seconds */	i++;        }    /* create random number stream per IF address */    srand((uint_t)pTmp->NetAddress.s_addr);    semGive (rdiscIfSem);        return (OK);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -