📄 if_ether.c
字号:
ipaddr.sin_addr.s_addr = soInAddr->sin_addr.s_addr; bzero ( (char *)&arpaddr, sizeof (arpaddr)); arpaddr.sdl_len = sizeof (arpaddr); arpaddr.sdl_family = AF_LINK; if (ar->arp_flags & ATF_INCOMPLETE) { arpaddr.sdl_type = rt->rt_ifp->if_type; arpaddr.sdl_index = rt->rt_ifp->if_index; } else { arpaddr.sdl_type = sdl->sdl_type; arpaddr.sdl_index = sdl->sdl_index; } bcopy ((caddr_t)ar->arp_ha.sa_data, LLADDR (&arpaddr), arpaddr.sdl_alen = sizeof (struct ether_addr)); flags |= (RTF_HOST | RTF_STATIC); /* * A netmask of 0 compares each route entry against the entire * key during lookups. If an overlapping network route already * exists, set it to all ones so that queries with SIN_PROXY set * will still succeed. If a matching host route exists, set the * SIN_PROXY flag in the new entry instead. */ pMask = NULL; if (proxy) { if (export) ipaddr.sin_other = SIN_PROXY; else { pMask = &rtmask; flags &= ~RTF_HOST; } } if (ar->arp_flags & ATF_INCOMPLETE) { pNewRt = rt; /* The gateway entry needs to be converted to an AF_LINK type */ error = rt_setgate (rt, (struct sockaddr *)&ipaddr, (struct sockaddr *)&arpaddr); if (error) break; /* The llinfo_arp structure needs to be allocated */ if (rt->rt_ifa->ifa_rtrequest) rt->rt_ifa->ifa_rtrequest (RTM_RESOLVE, rt, (struct sockaddr *)&arpaddr); else arp_rtrequest (RTM_RESOLVE, rt, (struct sockaddr *)&arpaddr); } else error = rtrequest (RTM_ADD, (struct sockaddr *)&ipaddr, (struct sockaddr *)&arpaddr, (struct sockaddr *)pMask, flags, &pNewRt); if (error == 0 && pNewRt) { if (ar->arp_flags & ATF_PERM) pNewRt->rt_expire = 0; else pNewRt->rt_expire = tickGet() + (sysClkRateGet() * arpt_keep); pNewRt->rt_refcnt--; } break; case SIOCDARP: /* delete entry */ if ((la = arplookup(soInAddr->sin_addr.s_addr, 0, 0)) == NULL) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 1, 6, WV_NETEVENT_ARPIOCTL_SEARCHFAIL, cmd, soInAddr->sin_addr.s_addr)#endif /* INCLUDE_WVNET */#endif return (EADDRNOTAVAIL); } arptfree(la); break; case SIOCGARP: /* get entry */ if ((la = arplookup(soInAddr->sin_addr.s_addr, 0, 0)) == NULL) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 1, 6, WV_NETEVENT_ARPIOCTL_SEARCHFAIL, cmd, soInAddr->sin_addr.s_addr)#endif /* INCLUDE_WVNET */#endif return (EADDRNOTAVAIL); } rt = la->la_rt; sdl = SDL(rt->rt_gateway); ar->arp_flags = 0; /* initialize the flags */ if (sdl->sdl_alen) { bcopy(LLADDR(sdl), (caddr_t)ar->arp_ha.sa_data, sdl->sdl_alen); ar->arp_flags |= ATF_COM; } else {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 1, 6, WV_NETEVENT_ARPIOCTL_SEARCHFAIL, cmd, soInAddr->sin_addr.s_addr)#endif /* INCLUDE_WVNET */#endif return (EADDRNOTAVAIL); } if (rt->rt_flags & RTF_UP) ar->arp_flags |= ATF_INUSE; if (rt->rt_flags & RTF_ANNOUNCE) ar->arp_flags |= ATF_PUBL; if (rt->rt_flags & RTF_PROTO1) ar->arp_flags |= ATF_PROXY; if (rt->rt_expire == 0) ar->arp_flags |= ATF_PERM; break; default : return (EINVAL); } return (error); }/********************************************************************************* _arpCmd - issues an internal ARP command** This routine directly call the arpioctl 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 called from inside the stack as from the* ifAllRoutesDelete() routine to delete ARP entries.*/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 */ /* 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 ((status = arpioctl (cmd, (caddr_t) &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; } return (status); }/******************************************************************************* arpEntryDelete - delete the oldest entry in ARP table** This routine deletes the oldest non-permanent entry in the ARP table** RETURNS: N/A** NOMANUAL*/static void arpEntryDelete () { register struct llinfo_arp *la;#ifdef VIRTUAL_STACK la = _llinfo_arp.la_prev;#else la = llinfo_arp.la_prev;#endif#ifdef VIRTUAL_STACK while (la != &_llinfo_arp)#else while (la != &llinfo_arp)#endif { register struct rtentry *rt = la->la_rt; if (rt->rt_expire) { arptfree (la); break; } la = la->la_prev; } } /* * Convert Ethernet address to printable (loggable) representation. */char *ether_sprintf(ap) register u_char *ap;{ register int i;#ifndef VIRTUAL_STACK static char etherbuf[18];#endif /* VIRTUAL_STACK */ register char *cp = etherbuf; for (i = 0; i < 6; i++) { *cp++ = digits[*ap >> 4]; *cp++ = digits[*ap++ & 0xf]; *cp++ = ':'; } *--cp = 0; return (etherbuf);}#define db_printf printfvoiddb_print_sa(sa) struct sockaddr *sa;{ int len; u_char *p; if (sa == 0) { db_printf("[NULL]\n"); return; } p = (u_char*)sa; len = sa->sa_len; db_printf("["); while (len > 0) { db_printf("%d", *p); p++; len--; if (len) db_printf(","); } db_printf("]\n");}#ifdef DDBstatic voiddb_print_ifa(ifa) struct ifaddr *ifa;{ if (ifa == 0) return; db_printf(" ifa_addr="); db_print_sa(ifa->ifa_addr); db_printf(" ifa_dsta="); db_print_sa(ifa->ifa_dstaddr); db_printf(" ifa_mask="); db_print_sa(ifa->ifa_netmask); db_printf(" flags=0x%x,refcnt=%d,metric=%d\n", ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric);}static voiddb_print_llinfo(li) caddr_t li;{ struct llinfo_arp *la; if (li == 0) return; la = (struct llinfo_arp *)li; db_printf(" la_rt=0x%x la_hold=0x%x, la_asked=0x%lx\n", (u_int) la->la_rt, (u_int) la->la_hold, la->la_asked);}/* * Function to pass to rn_walktree(). * Return non-zero error to abort walk. */static intdb_show_radix_node(rn, w) struct radix_node *rn; void *w;{ struct rtentry *rt = (struct rtentry *)rn; db_printf("rtentry=0x%x", (u_int) rt); db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n", rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire); db_printf(" key="); db_print_sa(rt_key(rt)); db_printf(" mask="); db_print_sa(rt_mask(rt)); db_printf(" gw="); db_print_sa(rt->rt_gateway); db_printf(" ifp=0x%x ", (u_int) rt->rt_ifp); if (rt->rt_ifp) db_printf("(%s%d)", rt->rt_ifp->if_name, rt->rt_ifp->if_unit); else db_printf("(NULL)"); db_printf(" ifa=0x%x\n", (u_int) rt->rt_ifa); db_print_ifa(rt->rt_ifa); db_printf(" genmask="); db_print_sa(rt->rt_genmask); db_printf(" gwroute=0x%x llinfo=0x%x\n", (u_int) rt->rt_gwroute, (u_int) rt->rt_llinfo); db_print_llinfo(rt->rt_llinfo); return (0);}/* * Internal Function to print the route tree. * Given the radix tree head. */int_db_show_arptab(struct radix_node_head *rnh){ db_printf("Route tree for AF_INET\n"); if (rnh == NULL) { db_printf(" (not initialized)\n"); return (0); } rn_walktree(rnh, db_show_radix_node, NULL); return (0);}/* * Function to print all the route trees. * Use this from ddb: "call db_show_arptab" */intdb_show_arptab(){ struct radix_node_head *rnh; rnh = rt_tables[AF_INET]; return _db_show_arptab(rnh);}#ifdef ROUTER_STACK/* * Function to print all the route trees for the fast forwarder. * Use this from ddb: "call db_show_arptab_ff" */intdb_show_arptab_ff(){ return _db_show_arptab ((struct radix_node_head *)(IPV4_FF_CACHE_COOKIE (GET_IPV4_FF_ID)));}#endif /* ROUTER_STACK */#endif /* DDB */#endif /* INET */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -