?? arplib.c
字號(hào):
if (arpCmd (SIOCDARP, &hostAddr, (u_char *) NULL, (int *) NULL) == ERROR) { errno = S_arpLib_INVALID_HOST; /* No such entry in table. */ return (ERROR); } return (OK); }/********************************************************************************* arpCmd - issues an ARP command** This routine generates the low-level ioctl call for an ARP command. Expected* values for the <cmd> parameter are SIOCSARP, SIOCGARP, or SIOCDARP. * The <pIpAddr> parameter specifies the IP address of the host. The* <pHwAddr> pointer provides the corresponding link-level address in* binary form. That parameter is only used with SIOCSARP, and is limited* to the 6-byte maximum required for Ethernet addresses. The <pFlags> * argument provides any flag settings for the entry.** RETURNS: OK, or ERROR if unsuccessful.** NOMANUAL** INTERNAL* This routine should be LOCAL, but it is also used by the proxy ARP* library. That library should call the ioctl interface directly instead* to avoid the overhead created by the additional routines in this* module which it does not use.*/STATUS arpCmd ( int cmd, /* arp command */ struct in_addr * pIpAddr, /* ip address */ u_char * pHwAddr, /* hardware address */ int * pFlags /* arp flags */ ) { struct arpreq arpRequest; /* arp request struct */ STATUS status = ERROR; /* return status */ int sock; /* socket */ /* fill in arp request structure */ bzero ((caddr_t) &arpRequest, sizeof (struct arpreq)); arpRequest.arp_pa.sa_family = AF_INET; ((struct sockaddr_in *) &(arpRequest.arp_pa))->sin_addr.s_addr = pIpAddr->s_addr; arpRequest.arp_ha.sa_family = AF_UNSPEC; if (pHwAddr != NULL) bcopy ((caddr_t) pHwAddr ,(caddr_t) arpRequest.arp_ha.sa_data, ENET_SIZE); if (pFlags != NULL) arpRequest.arp_flags = *pFlags; if ((sock = socket (AF_INET, SOCK_RAW, 0)) != ERROR) { if ((status = ioctl (sock, cmd, (int) &arpRequest)) == OK) { if (pHwAddr != NULL) bcopy ((caddr_t) arpRequest.arp_ha.sa_data, (caddr_t) pHwAddr, ENET_SIZE); if (pFlags != NULL) *pFlags = arpRequest.arp_flags; } close (sock); } return (status); }/********************************************************************************* arpFlush - flush all entries in the system ARP table** This routine flushes all non-permanent entries in the ARP cache.** RETURNS: N/A*/void arpFlush (void) { register struct llinfo_arp *la; FAST struct rtentry * pRoute; int s;#ifdef VIRTUAL_STACK virtualStackIdCheck(); la = _llinfo_arp.la_next;#else la = llinfo_arp.la_next;#endif /* VIRTUAL_STACK */ s = splnet ();#ifdef VIRTUAL_STACK while (la != &_llinfo_arp) #else while (la != &llinfo_arp) #endif { pRoute = la->la_rt; la = la->la_next; /* if entry permanent */ if ((pRoute->rt_rmx.rmx_expire == 0) || (pRoute->rt_flags == 0)) continue; arptfree(la->la_prev); /* timer has expired; clear */ } splx (s); }/********************************************************************************* etherAsciiToEnet - convert Ethernet address** This routine converts an Ethernet address in ascii format to its normal* 48 bit format. <asciiAddr> is the string Ethernet address which has the form* "x:x:x:x:x:x" where x is a hexadecimal number between 0 and ff. <retEnet> is* where the Ethernet address gets returned. This routine is similar to the* UNIX call ether_aton.** RETURNS: OK, or ERROR if unsuccessful.** ERRNO: S_arpLib_INVALID_ENET_ADDRESS*/LOCAL STATUS etherAsciiToEnet ( char * asciiAddr, /* enet addr in ascii */ u_char * retEnet /* return enet addr */ ) { int enet [ENET_SIZE]; /* Ethernet address */ int ix; /* index variable */ if (sscanf (asciiAddr, "%x:%x:%x:%x:%x:%x", &enet [0], &enet [1], &enet [2], &enet [3], &enet [4], &enet [5]) != ENET_SIZE) { printf ("arp: invalid Ethernet address %s\n", asciiAddr); errno = S_arpLib_INVALID_ENET_ADDRESS; return (ERROR); } for (ix = 0; ix < ENET_SIZE; ix++) retEnet [ix] = (u_char) enet [ix]; return (OK); }/********************************************************************************* arpResolve - resolve a hardware address for a specified Internet address** This routine uses the Address Resolution Protocol (ARP) and internal ARP* cache to resolve the hardware address of a machine that owns the Internet* address given in <targetAddr>.** The hardware address is copied to <pHwAddr> as network byte order, if the* resolution of <targetAddr> is successful. <pHwAddr> must point to a buffer* which is large enough to receive the address.** NOTE: RFC 1122 prohibits sending more than one arp request per second. Any* numTicks value that would result in a shorter time than this is ignored.** RETURNS:* OK if the address is resolved successfully, or ERROR if <pHwAddr> is NULL,* <targetAddr> is invalid, or address resolution is unsuccessful.** ERRNO:* S_arpLib_INVALID_ARGUMENT* S_arpLib_INVALID_HOST**/STATUS arpResolve ( char *targetAddr, /* name or Internet address of target */ char *pHwAddr, /* where to return the H/W address */ int numTries, /* number of times to try ARPing (-1 means try forever) */ int numTicks /* number of ticks between ARPs */ ) { struct ifnet * pIf = NULL; struct sockaddr_in sockInetAddr; struct rtentry * pRt; unsigned long addr; int retVal = 0; if (pHwAddr == NULL || numTries < -1 || numTries == 0) /* user messed up */ { errno = S_arpLib_INVALID_ARGUMENT; return (ERROR); } /* the 'targetAddr' can either be the hostname or the actual Internet * address. */ if ((addr = (unsigned long) hostGetByName (targetAddr)) == ERROR && (addr = inet_addr (targetAddr)) == ERROR) { errno = S_arpLib_INVALID_HOST; return (ERROR); } bzero ((caddr_t)&sockInetAddr, sizeof (sockInetAddr)); sockInetAddr.sin_len = sizeof(struct sockaddr_in); sockInetAddr.sin_family = AF_INET; sockInetAddr.sin_addr.s_addr = addr; /* * Get associated local interface's ifnet. This search also * clones an empty ARP entry from the interface route if one * does not already exist. */ pRt = rtalloc1 ( (struct sockaddr *)&sockInetAddr, 1); if (pRt == NULL) { errno = S_arpLib_INVALID_HOST; return (ERROR); } pIf = pRt->rt_ifp; if (pIf == NULL) { rtfree (pRt); errno = S_arpLib_INVALID_HOST; return (ERROR); } /* return 0xffffffffffff for broadcast Internet address */ if (in_broadcast (sockInetAddr.sin_addr, pIf)) { bcopy ((char *) etherbroadcastaddr, pHwAddr, sizeof (etherbroadcastaddr)); rtfree (pRt); return (OK); } /* Try to resolve the Ethernet address by calling arpresolve() which * may send out ARP request messages out onto the Ethernet wire. */ while ((numTries == -1 || numTries-- > 0) && (retVal = arpresolve ((struct arpcom *) pIf, (struct rtentry *)pRt, (struct mbuf *) NULL, (struct sockaddr *)&sockInetAddr, (UCHAR *)pHwAddr)) == 0) if (numTries) /* don't delay after last arp */ taskDelay (numTicks); rtfree (pRt); if (retVal == 0) /* unsuccessful resolution */ { errno = S_arpLib_INVALID_HOST; return (ERROR); } return (OK); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -