static int ethers(int argc, char *argv[]) { char hostname[MAXHOSTNAMELEN], *hp; int i, rv = RV_OK; struct ether_addr ea, *eap; if (argc == 2) { fprintf(stderr, "%s: Enumeration not supported on ethers\n", __progname); rv = RV_NOENUM; } else { for (i = 2; i < argc; i++) { if ((eap = ether_aton(argv[i])) == NULL) { eap = &ea; hp = argv[i]; if (ether_hostton(hp, eap) != 0) { rv = RV_NOTFOUND; break; } } else { hp = hostname; if (ether_ntohost(hp, eap) != 0) { rv = RV_NOTFOUND; break; } } ETHERSPRINT; } } return rv; }
static void _addressToString(const u_int8_t *address, char *buffer) { if (ether_ntohost(buffer, (struct ether_addr *) address) == -1) { sprintf(buffer, "%2.2hhx:%2.2hhx:%2.2hhx:%2.2hhx:%2.2hhx:%2.2hhx", address[0], address[1], address[2], address[3], address[4], address[5]); } }
void testValues() { f = 2; char buf[255]; struct ether_addr addr; ether_ntohost(buf, &addr); //@ assert f == 2; //@ assert vacuous: \false; }
struct rarp_map *rarp_lookup(int ifindex, int hatype, int halen, unsigned char *lladdr) { struct rarp_map *r; for (r=rarp_db; r; r=r->next) { if (r->arp_type != hatype && r->arp_type != -1) continue; if (r->lladdr_len != halen) continue; if (r->ifindex != ifindex && r->ifindex != 0) continue; if (memcmp(r->lladdr, lladdr, halen) == 0) break; } if (r == NULL) { if (hatype == ARPHRD_ETHER && halen == 6) { struct ifaddr *ifa; struct hostent *hp; char ename[256]; static struct rarp_map emap = { NULL, 0, ARPHRD_ETHER, 6, }; if (ether_ntohost(ename, lladdr) != 0 || (hp = gethostbyname(ename)) == NULL) { if (verbose) syslog(LOG_INFO, "not found in /etc/ethers"); return NULL; } if (hp->h_addrtype != AF_INET) { syslog(LOG_ERR, "no IP address"); return NULL; } ifa = select_ipaddr(ifindex, &emap.ipaddr, (__u32 **)hp->h_addr_list); if (ifa) { memcpy(emap.lladdr, lladdr, 6); if (only_ethers || bootable(emap.ipaddr)) return &emap; if (verbose) syslog(LOG_INFO, "not bootable"); } } } return r; }
/* * Answer the RARP request in 'pkt', on the interface 'ii'. 'pkt' has * already been checked for validity. The reply is overlaid on the request. */ void rarp_process(struct if_info *ii, u_char *pkt) { char ename[HOST_NAME_MAX+1]; u_int32_t target_ipaddr; struct ether_header *ep; struct ether_addr *ea; struct hostent *hp; struct in_addr in; struct if_addr *ia; ep = (struct ether_header *) pkt; ea = (struct ether_addr *) &ep->ether_shost; debug("%s", ether_ntoa(ea)); if (ether_ntohost(ename, ea) != 0) { debug("ether_ntohost failed"); return; } if ((hp = gethostbyname(ename)) == 0) { debug("gethostbyname (%s) failed", ename); return; } /* Choose correct address from list. */ if (hp->h_addrtype != AF_INET) { error(FATAL, "cannot handle non IP addresses"); /* NOTREACHED */ } for (target_ipaddr = 0, ia = ii->ii_addrs; ia; ia = ia->ia_next) { target_ipaddr = choose_ipaddr((u_int32_t **) hp->h_addr_list, ia->ia_ipaddr & ia->ia_netmask, ia->ia_netmask); if (target_ipaddr) break; } if (target_ipaddr == 0) { for (ia = ii->ii_addrs; ia; ia = ia->ia_next) { in.s_addr = ia->ia_ipaddr & ia->ia_netmask; error(NONFATAL, "cannot find %s on net %s", ename, inet_ntoa(in)); } return; } if (tflag == 0 || rarp_bootable(htonl(target_ipaddr))) rarp_reply(ii, ia, ep, target_ipaddr, hp); debug("reply sent"); }
/* * ethers */ static int ethers(int argc, char *argv[]) { char hostname[MAXHOSTNAMELEN + 1], *hp; struct ether_addr ea, *eap; int i, rv; assert(argc > 1); assert(argv != NULL); #define ETHERSPRINT printf("%-17s %s\n", ether_ntoa(eap), hp) rv = RV_OK; if (argc == 2) { fprintf(stderr, "Enumeration not supported on ethers\n"); rv = RV_NOENUM; } else { for (i = 2; i < argc; i++) { if ((eap = ether_aton(argv[i])) == NULL) { eap = &ea; hp = argv[i]; if (ether_hostton(hp, eap) != 0) { rv = RV_NOTFOUND; break; } } else { hp = hostname; if (ether_ntohost(hp, eap) != 0) { rv = RV_NOTFOUND; break; } } ETHERSPRINT; } } return rv; }
/* This may (and will) block. Use local /etc/ethers and /etc/hosts to avoid NIS and DNS queries. */ int resolve(struct ether_addr *addr, struct in_addr *in_addr) { char hostname[4096]; memset(hostname, 0, sizeof(hostname)); /* This is not really safe, at the time of writing glibc uses a 1024 byte buffer for the answer internally ... We could parse /etc/ethers by ourselves but then we would loose nsswitch support. Alas RARP support without NIS is no fun :-( */ int ret = ether_ntohost(hostname, addr); if (ret != 0) { XLOG_DEBUG("failed to lookup %s", ether_ntoa(addr)); return -1; } XLOG_DEBUG("lookup for %s returned %s", ether_ntoa(addr), hostname); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_ADDRCONFIG; struct addrinfo *ai = NULL; ret = getaddrinfo(hostname, NULL, &hints, &ai); if (ret != 0) { XLOG_DEBUG("could not resolve '%s': %s\n", hostname, ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret)); return -1; } struct sockaddr_in *sa = (struct sockaddr_in *)(ai->ai_addr); memcpy(in_addr, &(sa->sin_addr), sizeof(struct in_addr)); return 0; }
int main(int argc, char **argv) { int i; ethernet_t *ep; nwio_ethopt_t ethopt; nwio_ethstat_t ethstat; char hostname[1024]; struct hostent *hostent; struct sigaction sa; nwio_ipconf_t ipconf; asynchio_t asyn; ssize_t n; ipaddr_t ip_addr; rarp46_t rarp46; int fd; int n_eths; program= argv[0]; asyn_init(&asyn); debug= 0; i= 1; while (i < argc && argv[i][0] == '-') { char *opt= argv[i++]+1; if (opt[0] == '-' && opt[1] == 0) break; /* -- */ while (*opt != 0) switch (*opt++) { case 'd': debug= 1; if (between('0', *opt, '9')) debug= strtoul(opt, &opt, 10); break; default: usage(); } } if ((n_eths= (argc - i)) == 0) usage(); #if __minix_vmd /* Minix-vmd can handle all nets at once using async I/O. */ ethernets= allocate(n_eths * sizeof(ethernets[0])); for (i= 0; i < n_eths; i++) { ethernets[i].n= ifname2n(argv[argc - n_eths + i]); } #else /* Minix forks n-1 times to handle each net in a process each. */ for (i= 0; i < n_eths; i++) { if (i+1 < n_eths) { switch (fork()) { case -1: fatal("fork()"); case 0: break; default: continue; } } ethernets= allocate(1 * sizeof(ethernets[0])); ethernets[0].n= ifname2n(argv[argc - n_eths + i]); } n_eths= 1; #endif sa.sa_handler= onsig; sigemptyset(&sa.sa_mask); sa.sa_flags= 0; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); for (i= 0; i < n_eths; i++) { ep= ðernets[i]; if ((ep->eth_fd= open(ethdev(ep->n), O_RDWR)) < 0) fatal(ethdev(ep->n)); if (ioctl(ep->eth_fd, NWIOGETHSTAT, ðstat) < 0) { fprintf(stderr, "%s: %s: Unable to get eth statistics: %s\n", program, ethdev(ep->n), strerror(errno)); exit(1); } ep->eth_addr= ethstat.nwes_addr; if (debug >= 1) { printf("%s: Ethernet address is %s\n", ethdev(ep->n), ether_ntoa(&ep->eth_addr)); } ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD | NWEO_TYPESPEC; ethopt.nweo_type= HTONS(ETH_RARP_PROTO); if (ioctl(ep->eth_fd, NWIOSETHOPT, ðopt) < 0) { fprintf(stderr, "%s: %s: Unable to set eth options: %s\n", program, ethdev(ep->n), strerror(errno)); exit(1); } /* What are my address and netmask? */ if ((fd= open(ipdev(ep->n), O_RDWR)) < 0) fatal(ipdev(ep->n)); if (ioctl(fd, NWIOGIPCONF, &ipconf) < 0) fatal(ipdev(ep->n)); ep->ip_addr= ipconf.nwic_ipaddr; ep->ip_mask= ipconf.nwic_netmask; close(fd); if (debug >= 1) { printf("%s: IP address is %s / ", ipdev(ep->n), inet_ntoa(ep->ip_addr)); printf("%s\n", inet_ntoa(ep->ip_mask)); } } /* Wait for RARP requests, reply, repeat. */ for(;;) { fflush(NULL); /* Wait for a RARP request. */ for (i= 0; i < n_eths; i++) { ep= ðernets[i]; n= asyn_read(&asyn, ep->eth_fd, ep->packet, sizeof(ep->packet)); if (n != -1) break; if (errno != EINPROGRESS) { report(ethdev(ep->n)); sleep(10); } } /* RARP request? */ if (i < n_eths && n >= sizeof(rarp46) && (memcpy(&rarp46, ep->packet, sizeof(rarp46)), 1) && rarp46.a46_hdr == HTONS(RARP_ETHERNET) && rarp46.a46_pro == HTONS(ETH_IP_PROTO) && rarp46.a46_hln == 6 && rarp46.a46_pln == 4 && rarp46.a46_op == HTONS(RARP_REQUEST) ) { if ((ether_ntohost(hostname, &rarp46.a46_tha) == 0 || (rarp46.a46_tha.ea_addr[0] == 'v' && (memcpy(&ip_addr, rarp46.a46_tha.ea_addr+2, 4), 1) && (hostent= gethostbyaddr((char*) &ip_addr, 4, AF_INET)) != NULL && addhostname(hostname, hostent->h_name, rarp46.a46_tha.ea_addr[1]))) && (hostent= gethostbyname(hostname)) != NULL && hostent->h_addrtype == AF_INET ) { /* Host is found in the ethers file and the DNS, or the * ethernet address denotes a special additional address * used for implementing a TCP/IP stack in user space. */ for (i= 0; hostent->h_addr_list[i] != NULL; i++) { memcpy(&ip_addr, hostent->h_addr_list[i], sizeof(ipaddr_t)); /* Check if the address is on this network. */ if (((ip_addr ^ ep->ip_addr) & ep->ip_mask) == 0) break; } if (hostent->h_addr_list[i] != NULL) { rarp_reply(ep, hostname, ip_addr, rarp46.a46_tha); } else { if (debug >= 2) { printf("%s: Host '%s' (%s) is on the wrong net\n", ethdev(ep->n), hostname, ether_ntoa(&rarp46.a46_tha)); } } } else { if (debug >= 2) { printf("%s: RARP request from unknown host '%s'\n", ethdev(ep->n), ether_ntoa(&rarp46.a46_tha)); } } } /* Wait for another request. */ if (asyn_wait(&asyn, 0, NULL) < 0) { report("asyn_wait()"); sleep(10); } } }
void runFailure() { char buf[255]; struct ether_addr addr; ether_ntohost(NULL, &addr); }
void runSuccess() { char buf[255]; struct ether_addr addr; ether_ntohost(buf, &addr); }
void runFailure2() { char buf[254]; struct ether_addr addr; ether_ntohost(buf, &addr); }
void runFailure1() { char buf[255]; struct ether_addr addr; ether_ntohost(buf, NULL); }