static int _intf_delete_addrs(intf_t *intf, struct intf_entry *entry) { #if defined(SIOCDIFADDR) struct dnet_ifaliasreq ifra; memset(&ifra, 0, sizeof(ifra)); strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name)); if (entry->intf_addr.addr_type == ADDR_TYPE_IP) { addr_ntos(&entry->intf_addr, &ifra.ifra_addr); ioctl(intf->fd, SIOCDIFADDR, &ifra); } if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) { addr_ntos(&entry->intf_dst_addr, &ifra.ifra_addr); ioctl(intf->fd, SIOCDIFADDR, &ifra); } #elif defined(SIOCLIFREMOVEIF) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name)); /* XXX - overloading Solaris lifreq with ifreq */ ioctl(intf->fd, SIOCLIFREMOVEIF, &ifr); #endif return (0); }
static int _intf_add_aliases(intf_t *intf, const struct intf_entry *entry) { int i; #ifdef SIOCAIFADDR struct dnet_ifaliasreq ifra; struct addr bcast; memset(&ifra, 0, sizeof(ifra)); strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name)); for (i = 0; i < (int)entry->intf_alias_num; i++) { if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP) continue; if (addr_ntos(&entry->intf_alias_addrs[i], &ifra.ifra_addr) < 0) return (-1); addr_bcast(&entry->intf_alias_addrs[i], &bcast); addr_ntos(&bcast, &ifra.ifra_brdaddr); addr_btos(entry->intf_alias_addrs[i].addr_bits, &ifra.ifra_mask); if (ioctl(intf->fd, SIOCAIFADDR, &ifra) < 0) return (-1); } #else struct ifreq ifr; int n = 1; for (i = 0; i < entry->intf_alias_num; i++) { if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP) continue; snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s:%d", entry->intf_name, n++); # ifdef SIOCLIFADDIF if (ioctl(intf->fd, SIOCLIFADDIF, &ifr) < 0) return (-1); # endif if (addr_ntos(&entry->intf_alias_addrs[i], &ifr.ifr_addr) < 0) return (-1); if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0) return (-1); } strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name)); #endif return (0); }
static int _intf_delete_aliases(intf_t *intf, struct intf_entry *entry) { int i; #if defined(SIOCDIFADDR) && !defined(__linux__) /* XXX - see Linux below */ struct dnet_ifaliasreq ifra; memset(&ifra, 0, sizeof(ifra)); strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name)); for (i = 0; i < (int)entry->intf_alias_num; i++) { addr_ntos(&entry->intf_alias_addrs[i], &ifra.ifra_addr); ioctl(intf->fd, SIOCDIFADDR, &ifra); } #else struct ifreq ifr; for (i = 0; i < entry->intf_alias_num; i++) { snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s:%d", entry->intf_name, i + 1); # ifdef SIOCLIFREMOVEIF /* XXX - overloading Solaris lifreq with ifreq */ ioctl(intf->fd, SIOCLIFREMOVEIF, &ifr); # else /* XXX - only need to set interface down on Linux */ ifr.ifr_flags = 0; ioctl(intf->fd, SIOCSIFFLAGS, &ifr); # endif } #endif return (0); }
in_addr_t anubis_default_route(void) { route_t *handle = route_open(); struct route_entry route_entry = {0}; in_addr_t addr = 0; if(!handle) { anubis_perror("route_open()"); return addr; }//end if int ret = route_loop(handle, route_default_route_callback, (void *)&route_entry); if(ret == 1) { struct sockaddr_in sa = {0}; addr_ntos(&route_entry.route_gw, (struct sockaddr *)&sa); addr = sa.sin_addr.s_addr; anubis_verbose("Default route: %s\n", anubis_ip_ntoa(addr)); }//end if else { anubis_err("anubis_default_route(): Default gateway is not found\n"); }//end else route_close(handle); return addr; }//end anubis_default_route
/* XXX - aliases on IRIX don't show up in SIOCGIFCONF */ static int _intf_get_aliases(intf_t *intf, struct intf_entry *entry) { struct dnet_ifaliasreq ifra; struct addr *ap, *lap; strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name)); addr_ntos(&entry->intf_addr, &ifra.ifra_addr); addr_btos(entry->intf_addr.addr_bits, &ifra.ifra_mask); memset(&ifra.ifra_brdaddr, 0, sizeof(ifra.ifra_brdaddr)); ifra.ifra_cookie = 1; ap = entry->intf_alias_addrs; lap = (struct addr *)((u_char *)entry + entry->intf_len); while (ioctl(intf->fd, SIOCLIFADDR, &ifra) == 0 && ifra.ifra_cookie > 0 && (ap + 1) < lap) { if (addr_ston(&ifra.ifra_addr, ap) < 0) break; ap++, entry->intf_alias_num++; } entry->intf_len = (u_char *)ap - (u_char *)entry; return (0); }
int intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst) { struct sockaddr_in sin; int n; if (dst->addr_type != ADDR_TYPE_IP) { errno = EINVAL; return (-1); } addr_ntos(dst, (struct sockaddr *)&sin); sin.sin_port = htons(666); if (connect(intf->fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) return (-1); n = sizeof(sin); if (getsockname(intf->fd, (struct sockaddr *)&sin, &n) < 0) return (-1); addr_ston((struct sockaddr *)&sin, &entry->intf_addr); if (intf_loop(intf, _match_intf_src, entry) != 1) return (-1); return (0); }
int arp_get(arp_t *a, struct arp_entry *entry) { struct arpreq ar; memset(&ar, 0, sizeof(ar)); if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0) return (-1); #ifdef HAVE_ARPREQ_ARP_DEV if (intf_loop(a->intf, _arp_set_dev, &ar) != 1) { errno = ESRCH; return (-1); } #endif if (ioctl(a->fd, SIOCGARP, &ar) < 0) return (-1); if ((ar.arp_flags & ATF_COM) == 0) { errno = ESRCH; return (-1); } return (addr_ston(&ar.arp_ha, &entry->arp_ha)); }
static void RecordNetworkAddress(GuestNicV3 *nic, // IN: operand NIC const struct addr *addr) // IN: dnet(3) address to process { struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; memset(&ss, 0, sizeof ss); addr_ntos(addr, sa); GuestInfoAddIpAddress(nic, sa, addr->addr_bits, NULL, NULL); }
static int route_default_route_callback(const struct route_entry *entry, void *arg) { struct route_entry *route = (struct route_entry *)arg; struct sockaddr_in sock = {0}; addr_ntos(&entry->route_dst, (struct sockaddr *)&sock); if(sock.sin_addr.s_addr == 0) { memmove(&route->route_gw, &entry->route_gw, sizeof(route->route_gw)); return 1; }//end if return 0; }//end route_default_route_callback
int route_add(route_t *r, const struct route_entry *entry) { struct rtentry rt; struct addr dst; memset(&rt, 0, sizeof(rt)); rt.rt_flags = RTF_UP | RTF_GATEWAY; if (ADDR_ISHOST(&entry->route_dst)) { rt.rt_flags |= RTF_HOST; memcpy(&dst, &entry->route_dst, sizeof(dst)); } else addr_net(&entry->route_dst, &dst); if (addr_ntos(&dst, &rt.rt_dst) < 0 || addr_ntos(&entry->route_gw, &rt.rt_gateway) < 0 || addr_btos(entry->route_dst.addr_bits, &rt.rt_genmask) < 0) return (-1); return (ioctl(r->fd, SIOCADDRT, &rt)); }
int eth_set(eth_t *e, const eth_addr_t *ea) { struct addr ha; ha.addr_type = ADDR_TYPE_ETH; ha.addr_bits = ETH_ADDR_BITS; memcpy(&ha.addr_eth, ea, ETH_ADDR_LEN); addr_ntos(&ha, &e->ifr.ifr_hwaddr); return (ioctl(e->fd, SIOCSIFHWADDR, &e->ifr)); }
int arp_delete(arp_t *a, const struct arp_entry *entry) { struct arpreq ar; memset(&ar, 0, sizeof(ar)); if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0) return (-1); if (ioctl(a->fd, SIOCDARP, &ar) < 0) return (-1); return (0); }
int eth_set(eth_t *e, const eth_addr_t *ea) { struct ifreq ifr; struct addr ha; ha.addr_type = ADDR_TYPE_ETH; ha.addr_bits = ETH_ADDR_BITS; memcpy(&ha.addr_eth, ea, ETH_ADDR_LEN); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, e->device, sizeof(ifr.ifr_name)); addr_ntos(&ha, &ifr.ifr_addr); return (ioctl(e->fd, SIOCSIFLLADDR, &ifr)); }
int arp_delete(arp_t *arp, const struct arp_entry *entry) { struct arpmsg msg; struct sockaddr_in *sin; struct sockaddr *sa; if (entry->arp_pa.addr_type != ADDR_TYPE_IP) { errno = EAFNOSUPPORT; return (-1); } sin = (struct sockaddr_in *)msg.addrs; sa = (struct sockaddr *)(sin + 1); if (addr_ntos(&entry->arp_pa, (struct sockaddr *)sin) < 0) return (-1); memset(&msg.rtm, 0, sizeof(msg.rtm)); msg.rtm.rtm_type = RTM_GET; msg.rtm.rtm_addrs = RTA_DST; msg.rtm.rtm_msglen = sizeof(msg.rtm) + sizeof(*sin); if (arp_msg(arp, &msg) < 0) return (-1); if (msg.rtm.rtm_msglen < (int)sizeof(msg.rtm) + sizeof(*sin) + sizeof(*sa)) { errno = ESRCH; return (-1); } if (sin->sin_addr.s_addr == entry->arp_pa.addr_ip) { if ((msg.rtm.rtm_flags & RTF_LLINFO) == 0 || (msg.rtm.rtm_flags & RTF_GATEWAY) != 0) { errno = EADDRINUSE; return (-1); } } if (sa->sa_family != AF_LINK) { errno = ESRCH; return (-1); } msg.rtm.rtm_type = RTM_DELETE; return (arp_msg(arp, &msg)); }
int arp_get(arp_t *arp, struct arp_entry *entry) { struct arpmsg msg; struct sockaddr_in *sin; struct sockaddr *sa; if (entry->arp_pa.addr_type != ADDR_TYPE_IP) { errno = EAFNOSUPPORT; return (-1); } sin = (struct sockaddr_in *)msg.addrs; sa = (struct sockaddr *)(sin + 1); if (addr_ntos(&entry->arp_pa, (struct sockaddr *)sin) < 0) return (-1); memset(&msg.rtm, 0, sizeof(msg.rtm)); msg.rtm.rtm_type = RTM_GET; msg.rtm.rtm_addrs = RTA_DST; msg.rtm.rtm_flags = RTF_LLINFO; msg.rtm.rtm_msglen = sizeof(msg.rtm) + sizeof(*sin); if (arp_msg(arp, &msg) < 0) return (-1); if (msg.rtm.rtm_msglen < (int)sizeof(msg.rtm) + sizeof(*sin) + sizeof(*sa) || sin->sin_addr.s_addr != entry->arp_pa.addr_ip || sa->sa_family != AF_LINK) { errno = ESRCH; return (-1); } if (addr_ston(sa, &entry->arp_ha) < 0) return (-1); return (0); }
/* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in pcapdev (up to a length of pcapdevlen). Returns 0 and fills in pcapdev if successful. */ int intf_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) { int i; intf_t *intf; struct intf_entry ie; pcap_if_t *pcapdevs; pcap_if_t *pdev; char pname[128]; struct sockaddr_in devip; pcap_addr_t *pa; if ((intf = intf_open()) == NULL) return -1; pname[0] = '\0'; memset(&ie, 0, sizeof(ie)); strlcpy(ie.intf_name, ifname, sizeof(ie.intf_name)); if (intf_get(intf, &ie) != 0) { intf_close(intf); return -1; } intf_close(intf); /* Find the first IPv4 address for ie */ if (ie.intf_addr.addr_type == ADDR_TYPE_IP) { addr_ntos(&ie.intf_addr, (struct sockaddr *) &devip); } else { for(i=0; i < (int) ie.intf_alias_num; i++) { if (ie.intf_alias_addrs[i].addr_type == ADDR_TYPE_IP) { addr_ntos(&ie.intf_alias_addrs[i], (struct sockaddr *) &devip); break; } } if (i == ie.intf_alias_num) return -1; // Failed to find IPv4 address, which is currently a requirement } /* Next we must find the pcap device name corresponding to the device. The device description used to be compared with those from PacketGetAdapterNames(), but that was unrelaible because dnet and pcap sometimes give different descriptions. For example, dnet gave me "AMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport" for one of my adapters (in vmware), while pcap described it as "VMware Accelerated AMD PCNet Adapter (Microsoft's Packet Scheduler)". Plus, Packet* functions aren't really supported for external use by the WinPcap folks. So I have rewritten this to compare interface addresses (which has its own problems -- what if you want to listen an an interface with no IP address set?) --Fyodor */ if (pcap_findalldevs(&pcapdevs, NULL) == -1) return -1; for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) { for (pa=pdev->addresses; pa && !pname[0]; pa = pa->next) { if (pa->addr->sa_family != AF_INET) continue; if (((struct sockaddr_in *)pa->addr)->sin_addr.s_addr == devip.sin_addr.s_addr) { strlcpy(pname, pdev->name, sizeof(pname)); /* Found it -- Yay! */ break; } } } pcap_freealldevs(pcapdevs); if (pname[0]) { strlcpy(pcapdev, pname, pcapdevlen); return 0; } return -1; }
int intf_set(intf_t *intf, const struct intf_entry *entry) { struct ifreq ifr; struct intf_entry *orig; struct addr bcast; u_char buf[BUFSIZ]; orig = (struct intf_entry *)buf; orig->intf_len = sizeof(buf); strcpy(orig->intf_name, entry->intf_name); if (intf_get(intf, orig) < 0) return (-1); /* Delete any existing aliases. */ if (_intf_delete_aliases(intf, orig) < 0) return (-1); /* Delete any existing addrs. */ if (_intf_delete_addrs(intf, orig) < 0) return (-1); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name)); /* Set interface MTU. */ if (entry->intf_mtu != 0) { ifr.ifr_mtu = entry->intf_mtu; #ifdef SIOCSIFMTU if (ioctl(intf->fd, SIOCSIFMTU, &ifr) < 0) #endif return (-1); } /* Set interface address. */ if (entry->intf_addr.addr_type == ADDR_TYPE_IP) { #ifdef BSD /* XXX - why must this happen before SIOCSIFADDR? */ if (addr_btos(entry->intf_addr.addr_bits, &ifr.ifr_addr) == 0) { if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0) return (-1); } #endif if (addr_ntos(&entry->intf_addr, &ifr.ifr_addr) < 0) return (-1); if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0 && errno != EEXIST) return (-1); if (addr_btos(entry->intf_addr.addr_bits, &ifr.ifr_addr) == 0 #ifdef __linux__ && entry->intf_addr.addr_ip != 0 #endif ) { if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0) return (-1); } if (addr_bcast(&entry->intf_addr, &bcast) == 0) { if (addr_ntos(&bcast, &ifr.ifr_broadaddr) == 0) { /* XXX - ignore error from non-broadcast ifs */ ioctl(intf->fd, SIOCSIFBRDADDR, &ifr); } } } /* Set link-level address. */ if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH && addr_cmp(&entry->intf_link_addr, &orig->intf_link_addr) != 0) { #if defined(SIOCSIFHWADDR) if (addr_ntos(&entry->intf_link_addr, &ifr.ifr_hwaddr) < 0) return (-1); if (ioctl(intf->fd, SIOCSIFHWADDR, &ifr) < 0) return (-1); #elif defined (SIOCSIFLLADDR) memcpy(ifr.ifr_addr.sa_data, &entry->intf_link_addr.addr_eth, ETH_ADDR_LEN); ifr.ifr_addr.sa_len = ETH_ADDR_LEN; if (ioctl(intf->fd, SIOCSIFLLADDR, &ifr) < 0) return (-1); #else eth_t *eth; if ((eth = eth_open(entry->intf_name)) == NULL) return (-1); if (eth_set(eth, &entry->intf_link_addr.addr_eth) < 0) { eth_close(eth); return (-1); } eth_close(eth); #endif } /* Set point-to-point destination. */ if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) { if (addr_ntos(&entry->intf_dst_addr, &ifr.ifr_dstaddr) < 0) return (-1); if (ioctl(intf->fd, SIOCSIFDSTADDR, &ifr) < 0 && errno != EEXIST) return (-1); } /* Add aliases. */ if (_intf_add_aliases(intf, entry) < 0) return (-1); /* Set interface flags. */ if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0) return (-1); ifr.ifr_flags = intf_flags_to_iff(entry->intf_flags, ifr.ifr_flags); if (ioctl(intf->fd, SIOCSIFFLAGS, &ifr) < 0) return (-1); return (0); }
static int route_msg(route_t *r, int type, struct addr *dst, struct addr *gw) { struct addr net; struct rt_msghdr *rtm; struct sockaddr *sa; u_char buf[BUFSIZ]; pid_t pid; int len; memset(buf, 0, sizeof(buf)); rtm = (struct rt_msghdr *)buf; rtm->rtm_version = RTM_VERSION; if ((rtm->rtm_type = type) != RTM_DELETE) rtm->rtm_flags = RTF_UP; rtm->rtm_addrs = RTA_DST; rtm->rtm_seq = ++r->seq; /* Destination */ sa = (struct sockaddr *)(rtm + 1); if (addr_net(dst, &net) < 0 || addr_ntos(&net, sa) < 0) return (-1); sa = NEXTSA(sa); /* Gateway */ if (gw != NULL && type != RTM_GET) { rtm->rtm_flags |= RTF_GATEWAY; rtm->rtm_addrs |= RTA_GATEWAY; if (addr_ntos(gw, sa) < 0) return (-1); sa = NEXTSA(sa); } /* Netmask */ if (dst->addr_ip == IP_ADDR_ANY || dst->addr_bits < IP_ADDR_BITS) { rtm->rtm_addrs |= RTA_NETMASK; if (addr_btos(dst->addr_bits, sa) < 0) return (-1); sa = NEXTSA(sa); } else rtm->rtm_flags |= RTF_HOST; rtm->rtm_msglen = (u_char *)sa - buf; #ifdef DEBUG route_msg_print(rtm); #endif #ifdef HAVE_STREAMS_ROUTE if (ioctl(r->fd, RTSTR_SEND, rtm) < 0) return (-1); #else if (write(r->fd, buf, rtm->rtm_msglen) < 0) return (-1); pid = getpid(); while (type == RTM_GET && (len = read(r->fd, buf, sizeof(buf))) > 0) { if (len < (int)sizeof(*rtm)) { return (-1); } if (rtm->rtm_type == type && rtm->rtm_pid == pid && rtm->rtm_seq == r->seq) { if (rtm->rtm_errno) { errno = rtm->rtm_errno; return (-1); } break; } } #endif if (type == RTM_GET && (rtm->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) { sa = (struct sockaddr *)(rtm + 1); sa = NEXTSA(sa); if (addr_ston(sa, gw) < 0 || gw->addr_type != ADDR_TYPE_IP) { errno = ESRCH; return (-1); } } return (0); }
int arp_add(arp_t *arp, const struct arp_entry *entry) { struct arpmsg msg; struct sockaddr_in *sin; struct sockaddr *sa; int index, type; if (entry->arp_pa.addr_type != ADDR_TYPE_IP || entry->arp_ha.addr_type != ADDR_TYPE_ETH) { errno = EAFNOSUPPORT; return (-1); } sin = (struct sockaddr_in *)msg.addrs; sa = (struct sockaddr *)(sin + 1); if (addr_ntos(&entry->arp_pa, (struct sockaddr *)sin) < 0) return (-1); memset(&msg.rtm, 0, sizeof(msg.rtm)); msg.rtm.rtm_type = RTM_GET; msg.rtm.rtm_addrs = RTA_DST; msg.rtm.rtm_msglen = sizeof(msg.rtm) + sizeof(*sin); if (arp_msg(arp, &msg) < 0) return (-1); if (msg.rtm.rtm_msglen < (int)sizeof(msg.rtm) + sizeof(*sin) + sizeof(*sa)) { errno = EADDRNOTAVAIL; return (-1); } if (sin->sin_addr.s_addr == entry->arp_pa.addr_ip) { if ((msg.rtm.rtm_flags & RTF_LLINFO) == 0 || (msg.rtm.rtm_flags & RTF_GATEWAY) != 0) { errno = EADDRINUSE; return (-1); } } if (sa->sa_family != AF_LINK) { errno = EADDRNOTAVAIL; return (-1); } else { index = ((struct sockaddr_dl *)sa)->sdl_index; type = ((struct sockaddr_dl *)sa)->sdl_type; } if (addr_ntos(&entry->arp_pa, (struct sockaddr *)sin) < 0 || addr_ntos(&entry->arp_ha, sa) < 0) return (-1); ((struct sockaddr_dl *)sa)->sdl_index = index; ((struct sockaddr_dl *)sa)->sdl_type = type; memset(&msg.rtm, 0, sizeof(msg.rtm)); msg.rtm.rtm_type = RTM_ADD; msg.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; msg.rtm.rtm_inits = RTV_EXPIRE; msg.rtm.rtm_flags = RTF_HOST | RTF_STATIC; #ifdef HAVE_SOCKADDR_SA_LEN msg.rtm.rtm_msglen = sizeof(msg.rtm) + sin->sin_len + sa->sa_len; #else msg.rtm.rtm_msglen = sizeof(msg.rtm) + sizeof(*sin) + sizeof(*sa); #endif return (arp_msg(arp, &msg)); }
int arp_add(arp_t *a, const struct arp_entry *entry) { struct arpreq ar; memset(&ar, 0, sizeof(ar)); if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0) return (-1); /* XXX - see arp(7) for details... */ #ifdef __linux__ if (addr_ntos(&entry->arp_ha, &ar.arp_ha) < 0) return (-1); ar.arp_ha.sa_family = ARP_HRD_ETH; #else /* XXX - Solaris, HP-UX, IRIX, other Mentat stacks? */ ar.arp_ha.sa_family = AF_UNSPEC; memcpy(ar.arp_ha.sa_data, &entry->arp_ha.addr_eth, ETH_ADDR_LEN); #endif #ifdef HAVE_ARPREQ_ARP_DEV if (intf_loop(a->intf, _arp_set_dev, &ar) != 1) { errno = ESRCH; return (-1); } #endif ar.arp_flags = ATF_PERM | ATF_COM; #ifdef hpux /* XXX - screwy extended arpreq struct */ { struct sockaddr_in *sin; ar.arp_hw_addr_len = ETH_ADDR_LEN; sin = (struct sockaddr_in *)&ar.arp_pa_mask; sin->sin_family = AF_INET; sin->sin_addr.s_addr = IP_ADDR_BROADCAST; } #endif if (ioctl(a->fd, SIOCSARP, &ar) < 0) return (-1); #ifdef HAVE_STREAMS_MIB2 /* XXX - force entry into ipNetToMediaTable. */ { struct sockaddr_in sin; int fd; addr_ntos(&entry->arp_pa, (struct sockaddr *)&sin); sin.sin_port = htons(666); if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (-1); if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { close(fd); return (-1); } write(fd, NULL, 0); close(fd); } #endif return (0); }