📄 riplib.c
字号:
* <supplier> | 0 (FALSE) | RIP_SUPPLIER* <gateway> | 0 (FALSE) | RIP_GATEWAY* <multicast> | 0 (FALSE) | RIP_MULTICAST* <version> | 1 | RIP_VERSION* <timerRate> | 1 | RIP_TIMER_RATE* <supplyInterval> | 30 | RIP_SUPPLY_INTERVAL* <expire> | 180 | RIP_EXPIRE_TIME* <garbage> | 300 | RIP_GARBAGE_TIME* <authType> | 1 | RIP_AUTH_TYPE* \te** INTERNAL* This routine creates two tasks, 'tRip' and 'tRipTimer'. The first is the * main loop of the routing task that monitors the routing port (520) for * updates and request messages. The second task uses a watchdog timer and* signalling semaphore to update the internal RIP routing table. The * 'ripLockSem' blocking semaphore provides any necessary interlocking between * each of the tasks and the user routines that alter the RIP configuration.* * RETURNS: OK; or ERROR, if configuration fails.**/STATUS ripLibInit ( BOOL supplier, /* operate in silent mode? */ BOOL gateway, /* act as gateway to the Internet? */ BOOL multicast, /* use multicast or broadcast addresses? */ int version, /* 1 or 2: selects format of outgoing messages */ int timerRate, /* update frequency for internal routing table */ int supplyInterval, /* update frequency for neighboring routers */ int expire, /* maximum interval for renewing learned routes */ int garbage, /* elapsed time before deleting stale route */ int authType /* default authentication type to use */ ) { IMPORT STATUS m2RipInit ();#ifdef VIRTUAL_STACK if ((vsTbl [myStackNum]->pRipGlobals != NULL) && (ripInitFlag)) return (OK);#else if (ripInitFlag) return (OK);#endif /* VIRTUAL_STACK */ if (version < 1 || version > 2) return (ERROR); if ((version < 2) && (multicast == TRUE)) return (ERROR); if (timerRate < 1) return (ERROR); if (supplyInterval < 1) return (ERROR); if (expire < 1) return (ERROR); if (garbage < 1) return (ERROR);#ifdef VIRTUAL_STACK /* Allocate space for former global variables. */ if (vsTbl[myStackNum]->pRipGlobals == NULL) { vsTbl[myStackNum]->pRipGlobals = malloc (sizeof (VS_RIP)); if (vsTbl[myStackNum]->pRipGlobals == NULL) return (ERROR); } bzero ((char *)vsTbl [myStackNum]->pRipGlobals, sizeof (VS_RIP));#else bzero ((char *)&ripState, sizeof (ripState));#endif /* VIRTUAL_STACK */ /* Set the global state. */ ripState.version = version; ripState.multicast = multicast; ripState.timerRate = timerRate; ripState.supplyInterval = supplyInterval; ripState.expire = expire; ripState.garbage = garbage; ripState.pRouteHook = NULL; ripFilterFlag = TRUE; /* Enable border gateway filtering. */ routedDebug = 0; /* Disable debugging messages by default. */ /* Initialize the list of interfaces on which RIP should not be started */ lstInit (&ripIfExcludeList);#ifdef VIRTUAL_STACK /* * Assign (former) global variables previously initialized by the compiler. * Setting 0 is repeated for clarity - the vsLib.c setup zeroes all values. */ _ripTaskPriority = RIP_TASK_PRIORITY; /* ripLib.c */ _ripTaskOptions = RIP_TASK_OPTIONS; /* ripLib.c */ _ripTaskStackSize = RIP_TASK_STACK_SIZE; /* ripLib.c */ _ripTimerTaskPriority = RIP_TIMER_TASK_PRIORITY; /* ripLib.c */ _ripTimerTaskOptions = RIP_TIMER_TASK_OPTIONS; /* ripLib.c */ _ripTimerTaskStackSize = RIP_TIMER_TASK_STACK_SIZE; /* ripLib.c */ ifnext = &ripIfNet;#endif /* * This all has to do with RIP MIB II stuff. * * We set a global configuration that all interfaces will have * at startup time. SNMP agents can then modify these values * on a per interface basis. */ m2RipInit (); if (version == 1) ripState.ripConf.rip2IfConfSend = M2_rip2IfConfSend_ripVersion1; else if (multicast) ripState.ripConf.rip2IfConfSend = M2_rip2IfConfSend_ripVersion2; else ripState.ripConf.rip2IfConfSend = M2_rip2IfConfSend_rip1Compatible; if (version == 1) ripState.ripConf.rip2IfConfReceive = M2_rip2IfConfReceive_rip1; else if (multicast) ripState.ripConf.rip2IfConfReceive = M2_rip2IfConfReceive_rip2; else ripState.ripConf.rip2IfConfReceive = M2_rip2IfConfReceive_rip1OrRip2; ripState.ripConf.rip2IfConfAuthType = authType; ripState.ripConf.rip2IfConfStatus = M2_rip2IfConfStatus_valid; /* Create the monitor task to receive and process RIP messages. */ ripState.ripTaskId = taskSpawn (RIP_TASK, _ripTaskPriority, _ripTaskOptions, _ripTaskStackSize, ripTask, supplier, gateway, multicast, #ifdef VIRTUAL_STACK myStackNum, 0, 0, 0, 0, 0, 0);#else 0, 0, 0, 0, 0, 0, 0);#endif if (ripState.ripTaskId == ERROR) {#ifdef VIRTUAL_STACK free (vsTbl[myStackNum]->pRipGlobals); vsTbl[myStackNum]->pRipGlobals = NULL;#endif return (ERROR); } ripInitFlag = TRUE; return (OK); }STATUS ripTask ( BOOL supplier, BOOL gateway, BOOL multicast#ifdef VIRTUAL_STACK , int stackNum#endif ) { int n, nfd, on; struct timeval *pTimeout; struct timeval waittime; fd_set ibits; extern STATUS ripLeakHook ();#ifdef VIRTUAL_STACK register RIP_PKT *query; /* Assign virtual stack number to access appropriate data structures. */ if (virtualStackNumTaskIdSet (stackNum) == ERROR) { if (routedDebug) logMsg ("Unable to access stack data.\n", 0, 0, 0, 0, 0, 0); return (ERROR); } query = (RIP_PKT *)ripState.packet;#else register RIP_PKT *query = (RIP_PKT *)ripState.packet;#endif 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); } /* * Now open a routing socket so that we can receive routing messages * from the Routing system */ ripState.routeSocket = socket (AF_ROUTE, SOCK_RAW, 0); if (ripState.routeSocket < 0) { if (routedDebug) logMsg ("Unable to get route socket.\n", 0, 0, 0, 0, 0, 0); close (ripState.s); return (ERROR); } /* Set the non-block option on the routing socket */ on = 1; if (ioctl (ripState.routeSocket, FIONBIO, (int) &on) == -1) if (routedDebug) logMsg ("error setting O_NONBLOCK option on route socket.\n", 0, 0, 0, 0, 0, 0); /* * Turn off the loopback option on the socket as we do not want * routing messages for events generated a write on this socket. * Currently we only read from this socket, never write to it. * So this operation is a virtual no-op, but will come in handy * if we ever use routing sockets to add/delete/change routes. */ on = 0; if (setsockopt (ripState.routeSocket, SOL_SOCKET, SO_USELOOPBACK, (char *)&on, sizeof (on)) == ERROR) if (routedDebug) logMsg ("error resetting SO_USELOOPBACK option on route socket.\n", 0, 0, 0, 0, 0, 0); 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); close (ripState.routeSocket); 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); close (ripState.routeSocket); 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 (TRUE, 0) == ERROR) { if (routedDebug) logMsg ("Error building interface list.\n", 0, 0, 0, 0, 0, 0); close (ripState.s); close (ripState.routeSocket); 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, (FUNCPTR)ripTimer,#ifdef VIRTUAL_STACK stackNum, 0, 0, 0, 0, 0, 0, 0, 0, 0);#else 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);#endif if (ripState.ripTimerTaskId == ERROR) { if (routedDebug) logMsg ("Error creating timer task. : errno=0x%x\n", errno, 0, 0, 0, 0, 0); close (ripState.s); close (ripState.routeSocket); wdCancel (ripState.timerDog); wdDelete (ripState.timerDog); semDelete (ripState.timerSem); semDelete (ripLockSem); return (ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -