123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*
- * ZMap Copyright 2013 Regents of the University of Michigan
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
- */
- #ifndef ZMAP_GET_GATEWAY_BSD_H
- #define ZMAP_GET_GATEWAY_BSD_H
- #ifdef ZMAP_GET_GATEWAY_LINUX_H
- #error "Don't include both get_gateway-bsd.h and get_gateway-linux.h"
- #endif
- #include <net/route.h>
- #include <net/if.h>
- #include <net/if_dl.h>
- #if !defined(__APPLE__)
- #include <dnet/os.h>
- #include <dnet/eth.h>
- #include <dnet/ip.h>
- #include <dnet/ip6.h>
- #include <dnet/addr.h>
- #include <dnet/arp.h>
- #endif
- #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int))
- #define UNUSED __attribute__((unused))
- int get_hw_addr(struct in_addr *gw_ip, UNUSED char *iface, unsigned char *hw_mac)
- {
- arp_t *arp;
- struct arp_entry entry;
- if (!gw_ip || !hw_mac) {
- return EXIT_FAILURE;
- }
- if ((arp = arp_open()) == NULL) {
- log_error("get_hw_addr", "failed to open arp table");
- return EXIT_FAILURE;
- }
- // Convert gateway ip to dnet struct format
- memset(&entry, 0, sizeof(struct arp_entry));
- entry.arp_pa.addr_type = ADDR_TYPE_IP;
- entry.arp_pa.addr_bits = IP_ADDR_BITS;
- entry.arp_pa.addr_ip = gw_ip->s_addr;
- if (arp_get(arp, &entry) < 0) {
- log_debug("get_hw_addr", "failed to fetch arp entry");
- return EXIT_FAILURE;
- } else {
- log_debug("get_hw_addr", "found ip %s at hw_addr %s",
- addr_ntoa(&entry.arp_pa),
- addr_ntoa(&entry.arp_ha));
- memcpy(hw_mac, &entry.arp_ha.addr_eth, ETHER_ADDR_LEN);
- }
- arp_close(arp);
- return EXIT_SUCCESS;
- }
- int get_iface_ip(char *iface, struct in_addr *ip)
- {
- assert(iface);
- struct ifaddrs *ifaddr, *ifa;
- if (getifaddrs(&ifaddr)) {
- log_fatal("get-iface-ip", "unable able to retrieve list of network interfaces: %s",
- strerror(errno));
- }
- for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) {
- continue;
- }
- if (!strcmp(iface, ifa->ifa_name)) {
- struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr;
- ip->s_addr = sin->sin_addr.s_addr;
- log_debug("get-iface-ip", "ip address found for %s: %s",
- iface, inet_ntoa(*ip));
- return EXIT_SUCCESS;
- }
- }
- log_fatal("get-iface-ip", "specified interface does not"
- " exist or have an IPv4 address");
- return EXIT_FAILURE;
- }
- int get_iface_hw_addr(char *iface, unsigned char *hw_mac)
- {
- eth_t *e = eth_open(iface);
- if (e) {
- eth_addr_t eth_addr;
- int res = eth_get(e, ð_addr);
- log_debug("gateway", "res: %d", res);
- if (res == 0) {
- memcpy(hw_mac, eth_addr.data, ETHER_ADDR_LEN);
- return EXIT_SUCCESS;
- }
- }
- return EXIT_FAILURE;
- }
- int _get_default_gw(struct in_addr *gw, char **iface)
- {
- char buf[4096];
- struct rt_msghdr *rtm = (struct rt_msghdr*) &buf;
- memset(rtm, 0, sizeof(buf));
- int seq = 0x00FF;
- rtm->rtm_msglen = sizeof(buf);
- rtm->rtm_type = RTM_GET;
- rtm->rtm_flags = RTF_GATEWAY;
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_seq = seq;
- rtm->rtm_addrs = RTA_DST | RTA_IFP;
- rtm->rtm_pid = getpid();
- int fd = socket(PF_ROUTE, SOCK_RAW, 0);
- assert (fd > 0);
- if (!write(fd, (char*) rtm, sizeof(buf))) {
- log_fatal("get-gateway", "unable to send request");
- }
- size_t len;
- while (rtm->rtm_type == RTM_GET && (len = read(fd, rtm, sizeof(buf))) > 0) {
- if (len < (int)sizeof(*rtm)) {
- return (-1);
- }
- if (rtm->rtm_type == RTM_GET && rtm->rtm_pid == getpid() && rtm->rtm_seq == seq) {
- if (rtm->rtm_errno) {
- errno = rtm->rtm_errno;
- return (-1);
- }
- break;
- }
- }
- struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
- for (int i = 0; i < RTAX_MAX; i++) {
- if (rtm->rtm_addrs & (1 << i)) {
- if ((1<<i) == RTA_IFP) {
- struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa;
- if (!sdl) {
- log_fatal("get-gateway", "fuck");
- }
- char *_iface = xmalloc(sdl->sdl_nlen+1);
- memcpy(_iface, sdl->sdl_data, sdl->sdl_nlen);
- _iface[sdl->sdl_nlen+1] = 0;
- *iface = _iface;
- }
- if ((1<<i) == RTA_GATEWAY) {
- struct sockaddr_in *sin = (struct sockaddr_in *) sa;
- gw->s_addr = sin->sin_addr.s_addr;
- }
- // next element
- sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
- }
- }
- close(fd);
- return EXIT_SUCCESS;
- }
- char* get_default_iface(void)
- {
- struct in_addr t;
- char *retv = NULL;
- _get_default_gw(&t, &retv);
- return retv;
- }
- int get_default_gw(struct in_addr *gw, UNUSED char *iface)
- {
- char *_iface = NULL;
- _get_default_gw(gw, &_iface);
- return EXIT_SUCCESS;
- }
- #endif /* ZMAP_GET_GATEWAY_BSD_H */
|