📄 riplib.c
字号:
** RETURNS: N/A** NOMANUAL*/void ripClearInterfaces ( INT32 sock, UINT32 mcastAddr /* Address to join. */ ) { struct ip_mreq ipMreq; /* Multicast structure for version 2 */ struct ifreq ifbuf[32]; struct ifreq *ifrp; struct ifreq *ifend; struct ifconf ifc; int n = 0; UINT32 addr; ifc.ifc_buf = (char *)ifbuf; ifc.ifc_len = sizeof(ifbuf); if (ioctl(sock, SIOCGIFCONF, (UINT32)(char *)&ifc) < 0) if (routedDebug) logMsg ("SIOCGIFCONF error removing multicast address", 0, 0, 0, 0, 0, 0); ifrp = (struct ifreq *)ifbuf; ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len); /* * Loop through all of the interfaces. */ for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) { n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) n = sizeof(*ifrp); /* * Ignore any interface for an address family other than IP. */ if (ifrp->ifr_addr.sa_family != AF_INET) continue; addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr; ipMreq.imr_multiaddr.s_addr = htonl (mcastAddr); ipMreq.imr_interface.s_addr = addr; if (setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ipMreq, sizeof (ipMreq)) < 0) { if (routedDebug) logMsg ("setsockopt IP_DROP_MEMBERSHIP error:\n", 0, 0, 0, 0, 0, 0); } } }/******************************************************************************** ripAuthHookAdd - add an authentication hook to a RIP interface** This routine installs a hook routine to validate incoming RIP messages* for a registered interface given by <pIpAddr>. (Interfaces created or* changed after a RIP session has started may be installed/updated with the* ripIfSearch() and ripIfReset() routines). The hook is only called if* an SNMP agent enables authentication for the corresponding interface.* It uses the following prototype:** .CS* STATUS ripAuthHookRtn (char *pKey, RIP_PKT *pRip);* .CE* The first argument contains the authentication key for the message* stored in the rip2IfConfAuthKey MIB variable and the second argument * uses the RIP_PKT structure (defined in rip/ripLib.h) to access the message * body. The routine must return OK if the message is acceptable, or ERROR * otherwise. All RIP-2 messages sent to that routine already contain an * authentication entry, but have not been verified. (Any unauthenticated* RIP-2 messages have already been discarded as required by the RFC * specification). RIP-1 messages may be accepted or rejected. RIP-2 messages* requesting simple password authentication which match the key are* accepted automatically before the hook is called. The remaining RIP-2* messages either did not match that key or are using an unknown * authentication type. If any messages are rejected, the MIB-II counters are * updated appropriately outside of the hook routine.** The current RIP implementation contains a sample authentication hook which* may be added as follows:** .CS* if (ripAuthHookAdd ("90.0.0.1", ripAuthHook) == ERROR) logMsg ("Unable to add authorization hook.\n", 0, 0, 0, 0, 0, 0);* .CE** The sample routine only supports simple password authentication against* the key included in the MIB variable. Since all such messages have already* been accepted, all RIP-2 messages received by the routine are discarded.* All RIP-1 messages are also discarded, so the hook actually has no* effect. The body of that routine is:** .CS* STATUS ripAuthHook* (* char * pKey, /@ rip2IfConfAuthKey entry from MIB-II family @/* RIP_PKT * pRip /@ received RIP message @/* )* {* if (pRip->rip_vers == 1)* {* /@ * @ The RFC specification recommends, but does not require, rejecting* @ version 1 packets when authentication is enabled.* @/** return (ERROR);* }** /@* @ The authentication type field in the RIP message corresponds to* @ the first two bytes of the sa_data field overlayed on that* @ message by the sockaddr structure contained within the RIP_PKT * @ structure (see rip/ripLib.h).* @/** if ( (pRip->rip_nets[0].rip_dst.sa_data[0] != 0) ||* (pRip->rip_nets[0].rip_dst.sa_data[1] !=* M2_rip2IfConfAuthType_simplePassword))* {* /@ Unrecognized authentication type. @/** return (ERROR);* }** /@ * @ Discard version 2 packets requesting simple password authentication* @ which did not match the MIB variable. * @/** return (ERROR);* }*.CE** A comparison against a different key could be performed as follows:** .CS* bzero ( (char *)&key, AUTHKEYLEN); /@ AUTHKEYLEN from rip/m2RipLib.h @/** /@* @ The start of the authorization key corresponds to the third byte* @ of the sa_data field in the sockaddr structure overlayed on the* @ body of the RIP message by the RIP_PKT structure. It continues* @ for the final 14 bytes of that structure and the first two bytes* @ of the following rip_metric field.* @/** bcopy ( (char *)(pRip->rip_nets[0].rip_dst.sa_data + 2),* (char *)&key, AUTHKEYLEN);** if (bcmp ( (char *)key, privateKey, AUTHKEYLEN) != 0)* {* /@ Key does not match: reject message. @/** return (ERROR);* }* return (OK);* .CE** The ripAuthHookDelete() routine will remove the installed function. If* authentication is still enabled for the interface, all incoming messages* which do not use simple password authentication will be rejected until a* routine is provided.** RETURNS: OK if hook added, or ERROR otherwise.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripAuthHookAdd ( char* pIpAddr, /* IP address in dotted decimal notation */ FUNCPTR pAuthHook /* routine to handle message authentication */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet(S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr (pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup ((struct sockaddr *)&address); if (pIfp == NULL) { errnoSet(S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with input processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->authHook = pAuthHook; semGive (ripLockSem); return (OK); }/******************************************************************************** ripAuthHookDelete - remove an authentication hook from a RIP interface** This routine removes an assigned authentication hook from a registered* interface indicated by <pIpAddr>. (Interfaces created or changed after * a RIP session has started may be installed/updated with the ripIfSearch() * and ripIfReset() routines). If authentication is still enabled for the * interface, RIP-2 messages using simple password authentication will be* accepted if they match the key in the MIB variable, but all other incoming * messages will be rejected until a routine is provided.** RETURNS: OK, or ERROR if the interface could not be found.** ERRNO:* S_m2Lib_INVALID_PARAMETER* S_m2Lib_ENTRY_NOT_FOUND*/STATUS ripAuthHookDelete ( char* pIpAddr /* IP address in dotted decimal notation */ ) { struct interface* pIfp; struct sockaddr_in address; if (!ripInitFlag) return (ERROR); if (pIpAddr == NULL) { errnoSet (S_m2Lib_INVALID_PARAMETER); return (ERROR); } address.sin_addr.s_addr = inet_addr (pIpAddr); address.sin_family = AF_INET; pIfp = ripIfLookup ( (struct sockaddr *)&address); if (pIfp == NULL) { errnoSet (S_m2Lib_ENTRY_NOT_FOUND); return (ERROR); } /* Short critical section with input processing. */ semTake (ripLockSem, WAIT_FOREVER); pIfp->authHook = NULL; semGive (ripLockSem); return (OK); }/******************************************************************************** ripAuthCheck - verify RIP messages if authentication is enabled** This routine accepts all RIP-2 messages using simple password* authentication which match the key in the MIB variable. It is* called automatically when authentication is enabled. All other* RIP-2 messages and any RIP-1 messages may be accepted by an* authentication hook, or will be discarded if no hook is present.** RETURNS: OK if message is acceptable, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/STATUS ripAuthCheck ( char * pKey, /* rip2IfConfAuthKey entry from MIB-II family */ RIP_PKT * pRip /* received RIP message */ ) { if (pRip->rip_vers == 1) { /* * The RFC specification recommends, but does not require, rejecting * version 1 packets when authentication is enabled. Those packets * will be discarded unless accepted by the hook. */ return (ERROR); } /* * The authentication type field in the RIP message corresponds to * the first two bytes of the sa_data field overlayed on that * message by the sockaddr structure contained within the RIP_PKT * structure (see rip/ripLib.h). */ if ((pRip->rip_nets[0].rip_dst.sa_data[0] != 0) || (pRip->rip_nets[0].rip_dst.sa_data[1] != M2_rip2IfConfAuthType_simplePassword)) { /* * Reject messages with an unrecognized authentication type. This * behavior can be overridden by the user's authentication hook. */ return (ERROR); } /* * The start of the authorization key corresponds to the third byte * of the sa_data field in the sockaddr structure and continues for * AUTHKEYLEN bytes (defined in rip/m2RipLib.h). */ if (bcmp ( (char *)(pRip->rip_nets[0].rip_dst.sa_data + 2), pKey, AUTHKEYLEN) != 0) { return (ERROR); } /* * Accept version 2 packets requesting simple password * authentication which did matched the MIB variable. */ return (OK); }/******************************************************************************** ripAuthHook - sample authentication hook** This hook demonstrates one possible authentication mechanism. It rejects* all RIP-2 messages which used simple password authentication since they* did not match the key contained in the MIB variable. All other RIP-2* messages are also rejected since no other authentication type is* supported and all RIP-1 messages are also rejected, as recommended by* the RFC specification. This behavior is the same as if no hook were * installed.** RETURNS: OK if message is acceptable, or ERROR otherwise.** ERRNO: N/A*/STATUS ripAuthHook ( char * pKey, /* rip2IfConfAuthKey entry from MIB-II family */ RIP_PKT * pRip /* received RIP message */ ) { if (pRip->rip_vers == 1) { /* * The RFC specification recommends, but does not require, rejecting * version 1 packets when authentication is enabled. */ return (ERROR); } /* * The authentication type field in the RIP message corresponds to * the first two bytes of the sa_data field overlayed on that * message by the sockaddr structure contained within the RIP_PKT * structure (see rip/ripLib.h). */ if ((pRip->rip_nets[0].rip_dst.sa_data[0] != 0) || (pRip->rip_nets[0].rip_dst.sa_data[1] != M2_rip2IfConfAuthType_simplePassword)) { /* Unrecognized authentication type. */ return (ERROR); } /* * Discard version 2 packets requesting simple password * authentication which did not match the MIB variable. */ return (ERROR); }/******************************************************************************** ripLeakHookAdd - add a hook to bypass the RIP and kernel routing tables** This routine installs a hook routine to support alternative routing* protocols for the registered interface given by <pIpAddr>. (Interfaces * created or changed after a RIP session has started may be installed/updated* with the ripIfSearch() and ripIfReset() routines).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -