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

📄 riplib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    extern STATUS ripLeakHook();        ripState.msg = (RIP_PKT *)ripState.packet;        /* Fake out getservbyname. */    ripState.port = htons (RIP_PORT);        ripState.addr.sin_family = AF_INET;    ripState.addr.sin_port = ripState.port;    ripState.addr.sin_addr.s_addr = INADDR_ANY;            ripState.s = getsocket (AF_INET, SOCK_DGRAM, &ripState.addr);    if (ripState.s < 0)        {        if (routedDebug)            logMsg ("Unable to get input/output socket.\n", 0, 0, 0, 0, 0, 0);        return (ERROR);        }    ripState.supplier = supplier;    ripState.gateway = gateway;        /* VxWorks specific setup. */    ripState.timerDog = wdCreate ();    ripState.timerSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);    if (ripState.timerSem == NULL)        {        if (routedDebug)            logMsg ("Error creating timer semaphore.\n", 0, 0, 0, 0, 0, 0);        close (ripState.s);         wdDelete (ripState.timerDog);        return (ERROR);        }    ripLockSem = semBCreate(SEM_Q_FIFO, SEM_FULL);    if (ripLockSem == NULL)        {        if (routedDebug)            logMsg ("Error creating mutex semaphore.\n", 0, 0, 0, 0, 0, 0);        close (ripState.s);         wdDelete (ripState.timerDog);        semDelete (ripState.timerSem);        return (ERROR);        }    /*     * Setup the hash tables for route entries and create entries to     * access the directly connected networks through the current     * interfaces.      */    routedTableInit();    if (routedIfInit () == ERROR)        {        if (routedDebug)            logMsg ("Error building interface list.\n", 0, 0, 0, 0, 0, 0);        close (ripState.s);         wdDelete (ripState.timerDog);        semDelete (ripState.timerSem);        semDelete (ripLockSem);        return (ERROR);        }    /*     * If configured as a gateway to the wider Internet, add an internal     * entry to the RIP routing table so that any default routes received      * will be ignored.     */    if (ripState.gateway > 0)        rtdefault();    if (ripState.supplier < 0)        ripState.supplier = 0;    /*      * Send a request message over all available interfaces     * to retrieve the tables from neighboring RIP routers.     */    query->rip_cmd = RIPCMD_REQUEST;    query->rip_vers = ripState.version;    if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1)	/* XXX */        query->rip_nets[0].rip_dst.sa_family = htons ( (u_short)AF_UNSPEC);    else        query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;    query->rip_nets[0].rip_metric = htonl ( (u_long)HOPCNT_INFINITY);    toall (sndmsg, 0, NULL);        /* Start the watchdog used by the timer task to send periodic updates. */    ripTimerArm (ripState.timerRate);    /* Create the timer task. */    ripState.ripTimerTaskId = taskSpawn (RIP_TIMER, _ripTimerTaskPriority,                                          _ripTimerTaskOptions,                                          _ripTimerTaskStackSize, ripTimer,                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0);    if (ripState.ripTimerTaskId == ERROR)        {        if (routedDebug)            logMsg ("Error creating timer task.\n", 0, 0, 0, 0, 0, 0);        close (ripState.s);         wdCancel (ripState.timerDog);        wdDelete (ripState.timerDog);        semDelete (ripState.timerSem);        semDelete (ripLockSem);        return (ERROR);        }    FD_ZERO(&ibits);    nfd = ripState.s + 1;			/* 1 + max(fd's) */    for (;;)        {        FD_SET (ripState.s, &ibits);        if (ripState.needupdate)            {            /*             * Changes to the routing table entries occurred within the             * mandatory (random) quiet period following an earlier             * triggered update. Set the selection interval for incoming              * messages to the remaining delay so that the pending              * (cumulative) triggered update will be sent on schedule.             */            pTimeout = &waittime;            waittime = ripState.nextbcast;            timevalsub (&waittime, &ripState.now);            if (waittime.tv_sec < 0)                {                /*                  * The scheduled update time has passed. Just poll the                 * interface before sending the triggered update.                 */                waittime.tv_sec = 0;                waittime.tv_usec = 0;                }            if (routedDebug)                logMsg ("Pending dynamic update scheduled in %d/%d sec/usec\n",                        waittime.tv_sec, waittime.tv_usec, 0, 0, 0, 0);            }        else            {            /*              * No triggered updates are pending. Wait for              * messages indefinitely.              */            pTimeout = (struct timeval *)NULL;            }        n = select (nfd, &ibits, 0, 0, pTimeout);        if (n <= 0)            {            /*             * No input received during specified interval: generate              * (delayed) triggered update if needed. Ignore all other              * errors (e.g. EINTR).             */            if (n < 0)                {                if (errno == EINTR)                    continue;                if (routedDebug)                    logMsg ("Error %d (%x) from select call",                             n, errno, 0, 0, 0, 0);                }            /* Block timer task to prevent overlapping updates. */            semTake (ripLockSem, WAIT_FOREVER);            if (n == 0 && ripState.needupdate)                {                /*                  * The pending triggered update was not subsumed by a                 * regular update during the selection interval. Send it                 * and reset the update flag and timers.                 */                if (routedDebug)                    logMsg ("send delayed dynamic update\n", 0, 0, 0, 0, 0, 0);                ripTimeSet (&ripState.now);                toall (supply, RTS_CHANGED, (struct interface *)NULL);                ripState.lastbcast = ripState.now;                ripState.needupdate = 0;                ripState.nextbcast.tv_sec = 0;                }            semGive (ripLockSem);            continue;            }        ripTimeSet (&ripState.now);        /*          * Block the timer task to prevent overlapping updates or         * route deletions during message processing.         */        semTake  (ripLockSem, WAIT_FOREVER);        if (ibits.fds_bits[ripState.s/32] & (1 << ripState.s))            process(ripState.s);        semGive (ripLockSem);        /* XXX: handle ICMP redirects */	}    }void timevaladd(t1, t2)	struct timeval *t1, *t2;{	t1->tv_sec += t2->tv_sec;	if ((t1->tv_usec += t2->tv_usec) > 100000) {		t1->tv_sec++;		t1->tv_usec -= 1000000;	}}void timevalsub(t1, t2)	struct timeval *t1, *t2;{	t1->tv_sec -= t2->tv_sec;	if ((t1->tv_usec -= t2->tv_usec) < 0) {		t1->tv_sec--;		t1->tv_usec += 1000000;	}}/******************************************************************************** ripTimeSet - update a RIP timer** This routine sets the various RIP timers used to track periodic updates* to the elapsed time since startup. Because all events use relative* times, the actual (calendar) time is not necessary.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void ripTimeSet    (    struct timeval * 	pTimer 		/* destination for timestamp */    )     {    int clockrate;    ULONG tickcount;    tickcount = tickGet ();    clockrate = sysClkRateGet ();    pTimer->tv_sec = tickcount / clockrate;    pTimer->tv_usec = (1000000 * tickcount % clockrate) / clockrate;    return;    }void process(fd)	int fd;{	struct sockaddr from;	int fromlen, cc;	union {		char	buf[MAXPACKETSIZE+1];		RIP_PKT rip;	} inbuf;        bzero((char *)&from, sizeof(from));	for (;;) {		fromlen = sizeof (from);		cc = recvfrom(fd, (char *)&inbuf, sizeof (inbuf), 0,                              &from, &fromlen);		if (cc <= 0) {			if (cc < 0 && errno != EWOULDBLOCK)                            {                            if (routedDebug)				logMsg ("Error %d (%x) reading RIP message.\n",                                        0, 0, 0, 0, 0, 0);                            }			break;		}		if (fromlen != sizeof (struct sockaddr_in))			break;		routedInput(&from, &inbuf.rip, cc);	}}int getsocket(domain, type, sin)	int domain, type;	struct sockaddr_in *sin;{	int sock, on = 1;	if ((sock = socket(domain, type, 0)) < 0) {                if (routedDebug)		    logMsg ("Error creating socket.\n", 0, 0, 0, 0, 0, 0);		return (-1);	}#ifdef SO_BROADCAST	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on,                       sizeof (on)) < 0) {                if (routedDebug)		    logMsg ("error setting SO_BROADCAST option",                             0, 0, 0, 0, 0, 0);		close(sock);		return (-1);	}#endif#ifdef SO_RCVBUF	for (on = BUFSPACE; ; on -= 1024) {		if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,		    (char *)&on, sizeof (on)) == 0)			break;		if (on <= 8*1024) {                        if (routedDebug)			    logMsg ("unable to set SO_RCVBUF option",                                      0, 0, 0, 0, 0, 0);			break;		}	}	if (routedDebug)		logMsg ("Receive buffer size %d.\n", on, 0, 0, 0, 0, 0);#endif	if (bind(sock, (struct sockaddr *)sin, sizeof (*sin)) < 0) {                if (routedDebug)		    logMsg ("error binding socket.\n", 0, 0, 0, 0, 0, 0);		close(sock);		return (-1);	}        on = 1;	if (ioctl(sock, FIONBIO, (int) &on) == -1)                if (routedDebug)		    logMsg ("error setting O_NONBLOCK option.\n",                             0, 0, 0, 0, 0, 0);        /* set the socketoption to join the MULTICAST group */                if (ripState.multicast)            {            ripSetInterfaces(sock, (UINT32)RIP_MCAST_ADDR);            }        	return (sock);}/******************************************************************************** ripTimerArm - arm the timeout to do routing updates** This routine starts (or resets) the watchdog timer to trigger periodic* updates at the assigned interval.** RETURNS: N/A** NOMANUAL        */void ripTimerArm    (    long timeout 	/* update interval in seconds */    )    {    int ticks;    ticks = timeout * sysClkRateGet();        wdStart (ripState.timerDog, ticks, semGive, (int)ripState.timerSem);    }/******************************************************************************** ripSplitPacket - split up a rip packet for version 2** INTERNAL ** The <orig> parameter accesses a single route entry within the payload* of a RIP message. In order for the rtadd() routine to store the data in* the expected format, the sin_port and sin_zero fields of the overlayed* structure (which correspond to the route tag, subnet mask, and next hop* values) must be cleared after that data is extracted.** NOMANUAL*/void ripSplitPacket    (    struct interface* pIfp,    struct sockaddr_in *src, 	/* Address of router which sent update. */    struct sockaddr* orig,    struct sockaddr* gateway,    struct sockaddr* netmask    )    {    BOOL noGate = FALSE;    BOOL noMask = FALSE;    char zero[4];

⌨️ 快捷键说明

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