📄 m2iplib.c
字号:
dstIpAddr = pIpRouteTblEntry->ipRouteDest; semTake (m2RouteSem, WAIT_FOREVER); /* protect the cache */ /* Reread the route table if it has since been modified. */ if (m2RouteTableGet (m2RouteTable, m2RouteTableSize) == ERROR) { errnoSet (S_m2Lib_ENTRY_NOT_FOUND); semGive (m2RouteSem); return (ERROR); /* no such entry */ } nextLarger = 0xffffffff; /* will decrease to the proper route address */ /* Find Match */ for (ix = 0, index = m2NumRouteEntries; ix < m2NumRouteEntries; ix++) { /* XXX */ tableDest = ntohl (m2RouteTable [ix].ipRouteDest); if (search == M2_EXACT_VALUE) { if (dstIpAddr == tableDest) { index = ix; break; /* found exact match */ } } else /* (search == M2_NEXT_VALUE) */ { /* Find the next dest value. The alternative to * going through the entire array each time is to sort it. * Which is more expensive is dependent on how often * new routes get added to the table, how often this is used, * and how long the list is. */ if ((tableDest >= dstIpAddr) && (tableDest < nextLarger)) { nextLarger = tableDest; index = ix; } } } if (index >= m2NumRouteEntries) { errnoSet (S_m2Lib_ENTRY_NOT_FOUND); semGive (m2RouteSem); return (ERROR); /* no such entry */ } /* fill in return structure */ bcopy ((char *) &m2RouteTable [index], (char *) pIpRouteTblEntry, sizeof (M2_IPROUTETBL)); pIpRouteTblEntry->ipRouteAge = (tickGet () - pIpRouteTblEntry->ipRouteAge) / sysClkRateGet (); semGive (m2RouteSem); /* release cache */ pIpRouteTblEntry->ipRouteDest = ntohl (pIpRouteTblEntry->ipRouteDest); pIpRouteTblEntry->ipRouteNextHop = ntohl (pIpRouteTblEntry->ipRouteNextHop); pIpRouteTblEntry->ipRouteMask = ntohl (pIpRouteTblEntry->ipRouteMask); return (OK); }/******************************************************************************** m2IpRouteTblEntrySet - set a MIB-II routing table entry** This routine adds, changes, or deletes a network routing table entry. * The table entry to be modified is specified by the `ipRouteDest' and* `ipRouteNextHop' members of the <pIpRouteTblEntry> structure.** The <varToSet> parameter is a bit-field mask that specifies which values* in the route table entry are to be set.** If <varToSet> has the M2_IP_ROUTE_TYPE bit set and `ipRouteType' has the* value of M2_ROUTE_TYPE_INVALID, then the the routing table entry is* deleted.** If <varToSet> has the either the M2_IP_ROUTE_DEST, M2_IP_ROUTE_NEXT_HOP* and the M2_IP_ROUTE_MASK bits set, then a new route entry is added * to the table. ** RETURNS: OK if successful, otherwise ERROR.** SEE ALSO:* m2IpInit(), m2IpGroupInfoGet(), m2IpGroupInfoSet(), * m2IpAddrTblEntryGet(), m2IpRouteTblEntryGet(), m2IpRouteTblEntrySet(),* m2IpDelete()*/STATUS m2IpRouteTblEntrySet ( int varToSet, /* variable to set */ M2_IPROUTETBL * pIpRouteTblEntry /* route table entry */ ) { struct sockaddr_in ipRouteMask; struct ortentry route; /* Convert from host order to network order */ pIpRouteTblEntry->ipRouteDest = htonl(pIpRouteTblEntry->ipRouteDest); pIpRouteTblEntry->ipRouteNextHop = htonl(pIpRouteTblEntry->ipRouteNextHop); bzero ((char *)&ipRouteMask, sizeof (struct sockaddr_in)); ipRouteMask.sin_family = AF_INET; ipRouteMask.sin_len = sizeof (struct sockaddr_in); /* delete the route */ if ((varToSet & M2_IP_ROUTE_TYPE) && (pIpRouteTblEntry->ipRouteType == M2_ipRouteType_invalid)) { if (m2IpRouteTblEntryGet (M2_EXACT_VALUE, pIpRouteTblEntry) != OK) return (ERROR); ipRouteMask.sin_addr.s_addr = (u_long)pIpRouteTblEntry->ipRouteMask; routeEntryFill (&route, pIpRouteTblEntry->ipRouteDest, pIpRouteTblEntry->ipRouteNextHop, FALSE); route.rt_flags |= RTF_MGMT; /* * Remove the matching route. Report the change using * both routing socket messages and direct callbacks. */ return (rtrequestDelEqui (&route.rt_dst, (struct sockaddr *)&ipRouteMask, &route.rt_gateway, route.rt_flags, 3, TRUE, TRUE, NULL)); } /* otherwise change it */ if (varToSet & (M2_IP_ROUTE_DEST | M2_IP_ROUTE_NEXT_HOP | M2_IP_ROUTE_MASK)) { /* Fill in the route mask */ ipRouteMask.sin_addr.s_addr = (u_long)pIpRouteTblEntry->ipRouteMask; routeEntryFill (&route, pIpRouteTblEntry->ipRouteDest, pIpRouteTblEntry->ipRouteNextHop, FALSE); route.rt_flags |= RTF_MGMT; /* * Add the requested route using the default weight value. Report * the change using both routing socket messages and direct callbacks. */ if (rtrequestAddEqui (&route.rt_dst, (struct sockaddr *)&ipRouteMask, &route.rt_gateway, route.rt_flags, M2_ipRouteProto_netmgmt, 0, TRUE, TRUE, NULL) != OK) return (ERROR); } return (OK); }/* generic structure for traversing the route table XXX move elsewhere */ typedef struct { ULONG arg1; ULONG arg2; ULONG arg3; } RT_TBL_ARGS; /* * Function to pass to rn_walktree(). * Return non-zero error to abort walk. */LOCAL int routeCacheInit ( struct radix_node * rn, void * pRtArg ) { M2_IPROUTETBL * pRouteCache; /* the route table cache */ M2_IPROUTETBL * pEntry; /* pointer to route cache */ int routeCacheSize; /* size of cache */ int * pRouteCacheIx; struct sockaddr_in * pSin; /* address pointer */ struct rtentry * pRoute = (struct rtentry *)rn; pRouteCache =(M2_IPROUTETBL *)((RT_TBL_ARGS *)pRtArg)->arg1; routeCacheSize = (int )((RT_TBL_ARGS *)pRtArg)->arg2; pRouteCacheIx = (int * )&((RT_TBL_ARGS *)pRtArg)->arg3; if (*pRouteCacheIx >= routeCacheSize) /* terminate the table walk */ return (ENOMEM); if ((pRoute->rt_flags & RTF_UP) == 0) /* go to the next entry */ return (OK); /* route not up */ /* Get the next entry to add */ pEntry = &pRouteCache [*pRouteCacheIx]; pSin = (struct sockaddr_in *) pRoute->rt_gateway; /* test whether the gateway is of type AF_LINK and if so * test whether it is a real arp entry because interfaces * initialized with RTF_CLONE flag have a dummy gateway of * type AF_LINK. If it is a real arp entry then skip to next * entry, we are only dealing with gateways of type AF_INET */ if (pRoute->rt_gateway->sa_family == AF_LINK) { if (((struct sockaddr_dl *)pSin)->sdl_alen) pSin = NULL; else pSin = (struct sockaddr_in *)pRoute->rt_ifa->ifa_addr; } if (pSin == NULL) return (OK); pEntry->ipRouteNextHop = pSin->sin_addr.s_addr; pSin = (struct sockaddr_in *) rt_key(pRoute); pEntry->ipRouteDest = pSin->sin_addr.s_addr; /* Loop through the interface table looking for a match * on the ifp. */ pEntry->ipRouteIfIndex = pRoute->rt_ifp->if_index; /* fill in the route mask */ if (rt_mask(pRoute) == NULL) /* implicit mask of 0xffffffff */ pEntry->ipRouteMask = ~0L; /* host route */ else pEntry->ipRouteMask = ((struct sockaddr_in *) rt_mask(pRoute))->sin_addr.s_addr; /* XXX this may not be necessary condition taken care in the above else */ if (pEntry->ipRouteDest == 0L) pEntry->ipRouteMask = 0L; /* default route */ pEntry->ipRouteAge = pRoute->rt_mod; /* initialize last modified */ /* is it a direct or indirect route ? */ if (pRoute->rt_flags & RTF_GATEWAY) { pEntry->ipRouteMetric1 = 1; /* 1 means non local */ pEntry->ipRouteType = M2_ipRouteType_indirect; } else pEntry->ipRouteType = M2_ipRouteType_direct; if (pRoute->rt_flags & RTF_MGMT) pEntry->ipRouteProto = M2_ipRouteProto_netmgmt; else if (pRoute->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) pEntry->ipRouteProto = M2_ipRouteProto_icmp; else { /* * Routes created using the routeLib API store the correct protocol * value using the RT_PROTO_SET macro. The RT_PROTO_GET macro * retrieves that information. All routing protocols must alter * the kernel routing table using the routeLib API so that the * IP group MIB variables can return the correct settings. Both RIP * and OSPF comply with this requirement. */ pEntry->ipRouteProto = RT_PROTO_GET (pSin); if (pEntry->ipRouteProto == M2_ipRouteProto_rip) { /* * The VxWorks RIP implementation stores the advertised metric * in the (normally unused) rmx_hopcount field of the kernel's * routing table. Use that value instead of the simple 0/1 * boolean for local or remote routes assigned earlier. */ pEntry->ipRouteMetric1 = pRoute->rt_rmx.rmx_hopcount; } else if (pEntry->ipRouteProto == 0) { /* * Entries added through ioctl() calls on a routing socket or * otherwise created directly without using the API have an * undefined value of 0 in the protocol type field. Replace it * with the correct setting. */ if (pRoute->rt_flags & RTF_LLINFO) { /* * Sanity check: handle route entries for link-level * protocols such as ARP in case they are not ignored * as expected. */ pEntry->ipRouteProto = M2_ipRouteProto_other; } else { /* Handle protocol-independent locally generated entries. */ pEntry->ipRouteProto = M2_ipRouteProto_local; } } } (*pRouteCacheIx)++; /* increment the index */ return (0); }/******************************************************************************** m2RouteTableGet - get a copy of the network routing table.** This routine gets a copy of the network routing table and puts* it into a pre-allocated route table cache. The route table cache is* specified by <pRouteCache> and the size of the cache is <routeCacheSize>. ** RETURNS: the number of entries in the route table cache. ** ERRNO* S_m2Lib_INVALID_PARAMETER*/LOCAL STATUS m2RouteTableGet ( M2_IPROUTETBL * pRouteCache, /* the route table cache */ int routeCacheSize /* size of cache */ ) { M2_IPROUTETBL * pEntry; /* pointer to route cache */ int routeCacheIx; /* route cache index */ int spl; /* for splnet */ struct radix_node_head * rnh; /* pointer to radix node hd*/ RT_TBL_ARGS rtTblArgs; if (rtmodified == m2RouteTableSaved) return (OK); /* cache still valid */ /* Validate argument */ if (pRouteCache == NULL) { errnoSet (S_m2Lib_INVALID_PARAMETER); return (ERROR); /* bad parameter passed */ } /* If the network interface table has been changed, re-read it */ semTake (m2InterfaceSem, WAIT_FOREVER); /* protect interface */ /* Clear out the routing table and rebuild it */ bzero ((char *) pRouteCache, routeCacheSize * (sizeof (M2_IPROUTETBL))); for (routeCacheIx = 0; routeCacheIx < routeCacheSize; routeCacheIx++) { pEntry = &pRouteCache [routeCacheIx]; /* fill in defaults */ pEntry->ipRouteMetric2 = -1; pEntry->ipRouteMetric3 = -1; pEntry->ipRouteMetric4 = -1; pEntry->ipRouteMetric5 = -1; bcopy ((char *) &ipZeroObjectId, (char *) &pEntry->ipRouteInfo, sizeof (ipZeroObjectId)); } routeCacheIx = 0; rnh = rt_tables[AF_INET]; if (rnh == NULL) return (0); rtTblArgs.arg1 = (ULONG) pRouteCache; rtTblArgs.arg2 = (ULONG) routeCacheSize; rtTblArgs.arg3 = (ULONG) routeCacheIx; spl = splnet (); rn_walktree(rnh, routeCacheInit, (void *)&rtTblArgs); m2RouteTableSaved = rtmodified; m2NumRouteEntries = rtTblArgs.arg3; /* Number of routes in the system */ splx (spl); semGive (m2InterfaceSem); return (OK); /* return the number of entries */ }/********************************************************************************* m2IpDelete - delete all resources used to access the IP group** This routine frees all the resources allocated when the IP group was* initialized. The IP group should not be accessed after this routine has been* called.** RETURNS: OK, always.** SEE ALSO: m2IpInit(), m2IpGroupInfoGet(), m2IpGroupInfoSet(), * m2IpAddrTblEntryGet(), m2IpAtransTblEntrySet(), m2IpRouteTblEntryGet(),* m2IpRouteTblEntrySet()*/STATUS m2IpDelete (void) { /* Free route semaphore */ if (m2RouteSem != NULL) { semDelete (m2RouteSem); m2RouteSem = NULL; } /* Free route table */ if (m2RouteTable != NULL) { KHEAP_FREE((char *)m2RouteTable); m2RouteTable = NULL; } return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -