Beispiel #1
0
static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
{
    struct ETHInterface_pvt* ctx =
        Identity_containerOf(iface, struct ETHInterface_pvt, pub.generic.iface);

    struct Sockaddr* sa = (struct Sockaddr*) msg->bytes;
    Assert_true(msg->length >= Sockaddr_OVERHEAD);
    Assert_true(sa->addrLen <= ETHInterface_Sockaddr_SIZE);

    struct ETHInterface_Sockaddr sockaddr = { .generic = { .addrLen = 0 } };
    Message_pop(msg, &sockaddr, sa->addrLen, NULL);

    struct sockaddr_ll addr;
    Bits_memcpyConst(&addr, &ctx->addrBase, sizeof(struct sockaddr_ll));

    if (sockaddr.generic.flags & Sockaddr_flags_BCAST) {
        Bits_memset(addr.sll_addr, 0xff, 6);
    } else {
        Bits_memcpyConst(addr.sll_addr, sockaddr.mac, 6);
    }

    struct ETHInterface_Header hdr = {
        .version = ETHInterface_CURRENT_VERSION,
        .zero = 0,
        .length_be = Endian_hostToBigEndian16(msg->length + ETHInterface_Header_SIZE),
        .fc00_be = Endian_hostToBigEndian16(0xfc00)
    };
    Message_push(msg, &hdr, ETHInterface_Header_SIZE, NULL);
    sendMessageInternal(msg, &addr, ctx);
    return NULL;
}

static void handleEvent2(struct ETHInterface_pvt* context, struct Allocator* messageAlloc)
{
    struct Message* msg = Message_new(MAX_PACKET_SIZE, PADDING, messageAlloc);

    struct sockaddr_ll addr;
    uint32_t addrLen = sizeof(struct sockaddr_ll);

    // Knock it out of alignment by 2 bytes so that it will be
    // aligned when the idAndPadding is shifted off.
    Message_shift(msg, 2, NULL);

    int rc = recvfrom(context->socket,
                      msg->bytes,
                      msg->length,
                      0,
                      (struct sockaddr*) &addr,
                      &addrLen);

    if (rc < ETHInterface_Header_SIZE) {
        Log_debug(context->logger, "Failed to receive eth frame");
        return;
    }

    Assert_true(msg->length >= rc);
    msg->length = rc;

    //Assert_true(addrLen == SOCKADDR_LL_LEN);

    struct ETHInterface_Header hdr;
    Message_pop(msg, &hdr, ETHInterface_Header_SIZE, NULL);

    // here we could put a switch statement to handle different versions differently.
    if (hdr.version != ETHInterface_CURRENT_VERSION) {
        Log_debug(context->logger, "DROP unknown version");
        return;
    }

    uint16_t reportedLength = Endian_bigEndianToHost16(hdr.length_be);
    reportedLength -= ETHInterface_Header_SIZE;
    if (msg->length != reportedLength) {
        if (msg->length < reportedLength) {
            Log_debug(context->logger, "DROP size field is larger than frame");
            return;
        }
        msg->length = reportedLength;
    }
    if (hdr.fc00_be != Endian_hostToBigEndian16(0xfc00)) {
        Log_debug(context->logger, "DROP bad magic");
        return;
    }

    struct ETHInterface_Sockaddr  sockaddr = { .zero = 0 };
    Bits_memcpyConst(sockaddr.mac, addr.sll_addr, 6);
    sockaddr.generic.addrLen = ETHInterface_Sockaddr_SIZE;
    if (addr.sll_pkttype == PACKET_BROADCAST) {
        sockaddr.generic.flags |= Sockaddr_flags_BCAST;
    }

    Message_push(msg, &sockaddr, ETHInterface_Sockaddr_SIZE, NULL);

    Assert_true(!((uintptr_t)msg->bytes % 4) && "Alignment fault");

    Iface_send(&context->pub.generic.iface, msg);
}

static void handleEvent(void* vcontext)
{
    struct ETHInterface_pvt* context = Identity_check((struct ETHInterface_pvt*) vcontext);
    struct Allocator* messageAlloc = Allocator_child(context->pub.generic.alloc);
    handleEvent2(context, messageAlloc);
    Allocator_free(messageAlloc);
}

List* ETHInterface_listDevices(struct Allocator* alloc, struct Except* eh)
{
    struct ifaddrs* ifaddr = NULL;
    if (getifaddrs(&ifaddr) || ifaddr == NULL) {
        Except_throw(eh, "getifaddrs() -> errno:%d [%s]", errno, strerror(errno));
    }
    List* out = List_new(alloc);
    for (struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_PACKET) {
            List_addString(out, String_new(ifa->ifa_name, alloc), alloc);
        }
    }
    freeifaddrs(ifaddr);
    return out;
}

static int closeSocket(struct Allocator_OnFreeJob* j)
{
    struct ETHInterface_pvt* ctx = Identity_check((struct ETHInterface_pvt*) j->userData);
    close(ctx->socket);
    return 0;
}

struct ETHInterface* ETHInterface_new(struct EventBase* eventBase,
                                      const char* bindDevice,
                                      struct Allocator* alloc,
                                      struct Except* exHandler,
                                      struct Log* logger)
{
    struct ETHInterface_pvt* ctx = Allocator_calloc(alloc, sizeof(struct ETHInterface_pvt), 1);
    Identity_set(ctx);
    ctx->pub.generic.iface.send = sendMessage;
    ctx->pub.generic.alloc = alloc;
    ctx->logger = logger;

    struct ifreq ifr = { .ifr_ifindex = 0 };

    ctx->socket = socket(AF_PACKET, SOCK_DGRAM, Ethernet_TYPE_CJDNS);
    if (ctx->socket == -1) {
        Except_throw(exHandler, "call to socket() failed. [%s]", strerror(errno));
    }
    Allocator_onFree(alloc, closeSocket, ctx);

    CString_strncpy(ifr.ifr_name, bindDevice, IFNAMSIZ - 1);
    ctx->ifName = String_new(bindDevice, alloc);

    if (ioctl(ctx->socket, SIOCGIFINDEX, &ifr) == -1) {
        Except_throw(exHandler, "failed to find interface index [%s]", strerror(errno));
    }
    ctx->ifindex = ifr.ifr_ifindex;

    if (ioctl(ctx->socket, SIOCGIFFLAGS, &ifr) < 0) {
        Except_throw(exHandler, "ioctl(SIOCGIFFLAGS) [%s]", strerror(errno));
    }
    if (!((ifr.ifr_flags & IFF_UP) && (ifr.ifr_flags & IFF_RUNNING))) {
        Log_info(logger, "Bringing up interface [%s]", ifr.ifr_name);
        ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
        if (ioctl(ctx->socket, SIOCSIFFLAGS, &ifr) < 0) {
            Except_throw(exHandler, "ioctl(SIOCSIFFLAGS) [%s]", strerror(errno));
        }
    }

    ctx->addrBase = (struct sockaddr_ll) {
        .sll_family = AF_PACKET,
        .sll_protocol = Ethernet_TYPE_CJDNS,
        .sll_ifindex = ctx->ifindex,
        .sll_hatype = ARPHRD_ETHER,
        .sll_pkttype = PACKET_OTHERHOST,
        .sll_halen = ETH_ALEN
    };

    if (bind(ctx->socket, (struct sockaddr*) &ctx->addrBase, sizeof(struct sockaddr_ll))) {
        Except_throw(exHandler, "call to bind() failed [%s]", strerror(errno));
    }

    Socket_makeNonBlocking(ctx->socket);

    Event_socketRead(handleEvent, ctx, ctx->socket, eventBase, alloc, exHandler);

    return &ctx->pub;
}
Beispiel #2
0
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
  int* count) {
  struct ifaddrs *addrs, *ent;
  char ip[INET6_ADDRSTRLEN];
  uv_interface_address_t* address;

  if (getifaddrs(&addrs) != 0) {
    return uv__new_sys_error(errno);
  }

  *count = 0;

  /* Count the number of interfaces */
  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
        (ent->ifa_addr == NULL) ||
        (ent->ifa_addr->sa_family == AF_LINK)) {
      continue;
    }

    (*count)++;
  }

  *addresses = (uv_interface_address_t*)
    malloc(*count * sizeof(uv_interface_address_t));
  if (!(*addresses)) {
    return uv__new_artificial_error(UV_ENOMEM);
  }

  address = *addresses;

  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    bzero(&ip, sizeof (ip));
    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
      continue;
    }

    if (ent->ifa_addr == NULL) {
      continue;
    }

    /*
     * On Mac OS X getifaddrs returns information related to Mac Addresses for
     * various devices, such as firewire, etc. These are not relevant here.
     */
    if (ent->ifa_addr->sa_family == AF_LINK) {
      continue;
    }

    address->name = strdup(ent->ifa_name);

    if (ent->ifa_addr->sa_family == AF_INET6) {
      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
    } else {
      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
    }

    if (ent->ifa_netmask->sa_family == AF_INET6) {
      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
    } else {
      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
    }

    address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;

    address++;
  }

  freeifaddrs(addrs);

  return uv_ok_;
}
Beispiel #3
0
void
network_init()
{
#ifdef INET6
	struct ifaddrs *ifap, *ifp;
	struct ipv6_mreq mreq6;
	int ifindex, s;
#endif
	int ecode;
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
		if (debugging)
			fprintf(stderr, "can't get local ip4 address: %s\n",
			    gai_strerror(ecode));
	} else {
		local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4);
		if (local_in4 == NULL) {
			if (debugging)
				fprintf(stderr, "can't alloc local ip4 addr\n");
		}
		memcpy(local_in4, res->ai_addr, sizeof *local_in4);
	}

#ifdef INET6
	hints.ai_family = AF_INET6;
	if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
		if (debugging)
			fprintf(stderr, "can't get local ip6 address: %s\n",
			    gai_strerror(ecode));
	} else {
		local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6);
		if (local_in6 == NULL) {
			if (debugging)
				fprintf(stderr, "can't alloc local ip6 addr\n");
		}
		memcpy(local_in6, res->ai_addr, sizeof *local_in6);
	}

	/*
	 * Now join the RPC ipv6 multicast group on all interfaces.
	 */
	if (getifaddrs(&ifp) < 0)
		return;

	mreq6.ipv6mr_interface = 0;
	inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr);

	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);

	/*
	 * Loop through all interfaces. For each interface, see if the
	 * network portion of its address is equal to that of the client.
	 * If so, we have found the interface that we want to use.
	 */
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != AF_INET6 ||
		    !(ifap->ifa_flags & IFF_MULTICAST))
			continue;
		ifindex = if_nametoindex(ifap->ifa_name);
		if (ifindex == mreq6.ipv6mr_interface)
			/*
			 * Already did this one.
			 */
			continue;
		mreq6.ipv6mr_interface = ifindex;
		if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
		    sizeof mreq6) < 0)
			if (debugging)
				warn("setsockopt v6 multicast");
	}
#endif

	/* close(s); */
}
Beispiel #4
0
static int lc_local_addresses(lua_State *L)
{
#ifndef _WIN32
	/* Link-local IPv4 addresses; see RFC 3927 and RFC 5735 */
	const long ip4_linklocal = htonl(0xa9fe0000); /* 169.254.0.0 */
	const long ip4_mask      = htonl(0xffff0000);
	struct ifaddrs *addr = NULL, *a;
#endif
	int n = 1;
	int type = luaL_checkoption(L, 1, "both", type_strings);
	const char link_local = lua_toboolean(L, 2); /* defaults to 0 (false) */
	const char ipv4 = (type == 0 || type == 1);
	const char ipv6 = (type == 0 || type == 2);

#ifndef _WIN32
	if (getifaddrs(&addr) < 0) {
		lua_pushnil(L);
		lua_pushfstring(L, "getifaddrs failed (%d): %s", errno,
		strerror(errno));
		return 2;
	}
#endif
	lua_newtable(L);

#ifndef _WIN32
	for (a = addr; a; a = a->ifa_next) {
		int family;
		char ipaddr[INET6_ADDRSTRLEN];
		const char *tmp = NULL;

		if (a->ifa_addr == NULL || a->ifa_flags & IFF_LOOPBACK)
			continue;

		family = a->ifa_addr->sa_family;

		if (ipv4 && family == AF_INET) {
			struct sockaddr_in *sa = (struct sockaddr_in *)a->ifa_addr;
			if (!link_local &&((sa->sin_addr.s_addr & ip4_mask) == ip4_linklocal))
				continue;
			tmp = inet_ntop(family, &sa->sin_addr, ipaddr, sizeof(ipaddr));
		} else if (ipv6 && family == AF_INET6) {
			struct sockaddr_in6 *sa = (struct sockaddr_in6 *)a->ifa_addr;
			if (!link_local && IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr))
				continue;
			if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr) || IN6_IS_ADDR_V4COMPAT(&sa->sin6_addr))
				continue;
			tmp = inet_ntop(family, &sa->sin6_addr, ipaddr, sizeof(ipaddr));
		}

		if (tmp != NULL) {
			lua_pushstring(L, tmp);
			lua_rawseti(L, -2, n++);
		}
		/* TODO: Error reporting? */
	}

	freeifaddrs(addr);
#else
	if (ipv4) {
		lua_pushstring(L, "0.0.0.0");
		lua_rawseti(L, -2, n++);
	}
	if (ipv6) {
		lua_pushstring(L, "::");
		lua_rawseti(L, -2, n++);
	}
#endif
	return 1;
}
Beispiel #5
0
int sharedaemon_bcast_send(void)
{
    struct ifaddrs *if_list;
    struct ifaddrs *dev;
    shpeer_t *peer;
    char hostname[NI_MAXHOST+1];
    int err;

    err = getifaddrs(&if_list);
    if (err)
        return (-errno);

    /* cycle through all non loop-back interfaces. */
    for (dev = if_list; dev; dev = dev->ifa_next) {
        if (dev->ifa_addr == NULL)
            continue;

        err = SHERR_OPNOTSUPP;

        memset(hostname, 0, sizeof(hostname));
        switch (dev->ifa_addr->sa_family) {
        case AF_INET:
            err = getnameinfo(dev->ifa_addr, sizeof(struct sockaddr_in),
                              hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
            if (err)
                break;

            if (0 == strncmp(hostname, "127.0.0.", strlen("127.0.0."))) {
                /* local loop-back */
                err = SHERR_AGAIN;
                break;
            }

            fprintf(stderr, "DEBUG: found inet device '%s' with addr '%s'\n", dev->ifa_name, hostname);

            err = 0;
            break;

        case AF_INET6:
            err = getnameinfo(dev->ifa_addr, sizeof(struct sockaddr_in6),
                              hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
            if (err)
                break;

            if (0 == strcmp(hostname, "::1")) {
                /* local loop-back */
                err = SHERR_AGAIN;
                break;
            }
            fprintf(stderr, "DEBUG: found inet6 device '%s' with addr '%s'\n", dev->ifa_name, hostname);


            err = 0;
            break;

        default:
            fprintf(stderr, "DEBUG: found unknown (fam %d) device '%s' with addr '%s'\n", dev->ifa_addr->sa_family, dev->ifa_name, hostname);
            break;
        }
        if (err) {
            /* .. */
            continue;
        }

        sprintf(hostname + strlen(hostname), " %d", server_port);
        peer = shpeer_init("shared", hostname);
        fprintf(stderr, "DEBUG: sharedaemon_bcast_send: %d = sharedaemon_bcast_send_peer(\"%s\")\n", err, hostname);
        err = sharedaemon_bcast_send_peer(peer);
        shpeer_free(&peer);
        if (err) {
            /* .. */
        }
    }

    return (0);
}
Beispiel #6
0
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
                                int* count) {
#ifdef SUNOS_NO_IFADDRS
  return uv__new_artificial_error(UV_ENOSYS);
#else
  struct ifaddrs *addrs, *ent;
  char ip[INET6_ADDRSTRLEN];
  uv_interface_address_t *address;

  if (getifaddrs(&addrs) != 0) {
    return uv__new_sys_error(errno);
  }

  *count = 0;

  /* Count the number of interfaces */
  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
        (ent->ifa_addr == NULL) || (ent->ifa_addr->sa_family == PF_PACKET)) {
      continue;
    }

    (*count)++;
  }

  *addresses =
      (uv_interface_address_t *)malloc(*count * sizeof(uv_interface_address_t));
  if (!(*addresses)) {
    return uv__new_artificial_error(UV_ENOMEM);
  }

  address = *addresses;

  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    memset(&ip, 0, sizeof(ip));

    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
      continue;
    }

    if (ent->ifa_addr == NULL) {
      continue;
    }

    address->name = strdup(ent->ifa_name);

    if (ent->ifa_addr->sa_family == AF_INET6) {
      address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
    } else {
      address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
    }

    address->is_internal =
        ent->ifa_flags & IFF_PRIVATE || ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;

    address++;
  }

  freeifaddrs(addrs);

  return uv_ok_;
#endif /* SUNOS_NO_IFADDRS */
}
Beispiel #7
0
/*
 * Use getifaddrs() to get a list of all the attached interfaces.  For
 * each interface that's of type INET and not the loopback interface,
 * register that interface with the network I/O software, figure out
 * what subnet it's on, and add it to the list of interfaces.
 */
void
discover_interfaces(struct interface_info *iface)
{
	struct ifaddrs *ifap, *ifa;
	struct sockaddr_in foo;
	struct ifreq *tif;

	if (getifaddrs(&ifap) != 0)
		error("getifaddrs failed");

	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
		if ((ifa->ifa_flags & IFF_LOOPBACK) ||
		    (ifa->ifa_flags & IFF_POINTOPOINT) ||
		    (!(ifa->ifa_flags & IFF_UP)))
			continue;

		if (strcmp(iface->name, ifa->ifa_name))
			continue;

		/*
		 * If we have the capability, extract link information
		 * and record it in a linked list.
		 */
		if (ifa->ifa_addr->sa_family == AF_LINK) {
			struct sockaddr_dl *foo =
			    (struct sockaddr_dl *)ifa->ifa_addr;

			iface->index = foo->sdl_index;
			iface->hw_address.hlen = foo->sdl_alen;
			iface->hw_address.htype = HTYPE_ETHER; /* XXX */
			memcpy(iface->hw_address.haddr,
			    LLADDR(foo), foo->sdl_alen);
		} else if (ifa->ifa_addr->sa_family == AF_INET) {
			struct iaddr addr;

			memcpy(&foo, ifa->ifa_addr, sizeof(foo));
			if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
				continue;
			if (!iface->ifp) {
				int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
				if ((tif = malloc(len)) == NULL)
					error("no space to remember ifp");
				strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
				memcpy(&tif->ifr_addr, ifa->ifa_addr,
				    ifa->ifa_addr->sa_len);
				iface->ifp = tif;
				iface->primary_address = foo.sin_addr;
			}
			addr.len = 4;
			memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len);
		}
	}

	if (!iface->ifp)
		error("%s: not found", iface->name);

	/* Register the interface... */
	if_register_receive(iface);
	if_register_send(iface);
	add_protocol(iface->name, iface->rfdesc, got_one, iface);
	freeifaddrs(ifap);
}
Beispiel #8
0
/* return the Media Access Control (MAC) address of
   the FIRST network interface card (NIC) */
int mac_address(unsigned char *data_ptr, size_t data_len)
{
    /* sanity check arguments */
    if (data_ptr == NULL || data_len < MAC_LEN)
        return FALSE;

#if defined(HAVE_IFADDRS_H) && defined(HAVE_NET_IF_DL_H) && defined(HAVE_GETIFADDRS)
    /* use getifaddrs(3) on BSD class platforms (xxxBSD, MacOS X, etc) */
    {
        struct ifaddrs *ifap;
        struct ifaddrs *ifap_head;
        const struct sockaddr_dl *sdl;
        unsigned char *ucp;
        int i;

        if (getifaddrs(&ifap_head) < 0)
            return FALSE;
        for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) {
            if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) {
                sdl = (const struct sockaddr_dl *)ifap->ifa_addr;
                ucp = (unsigned char *)(sdl->sdl_data + sdl->sdl_nlen);
                if (ucp != NULL && sdl->sdl_alen > 0) {
                    for (i = 0; i < MAC_LEN && i < sdl->sdl_alen; i++, ucp++)
                        data_ptr[i] = (unsigned char)(*ucp & 0xff);
                    freeifaddrs(ifap_head);
                    return TRUE;
                }
            }
        }
        freeifaddrs(ifap_head);
    }
#endif

#if defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR)
    /* use SIOCGIFHWADDR ioctl(2) on Linux class platforms */
    {
        struct ifreq ifr;
        struct sockaddr *sa;
        int s;
        int i;

        if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
            return FALSE;
        sprintf(ifr.ifr_name, "eth0");
        if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
            close(s);
            return FALSE;
        }
        sa = (struct sockaddr *)&ifr.ifr_addr;
        for (i = 0; i < MAC_LEN; i++)
            data_ptr[i] = (unsigned char)(sa->sa_data[i] & 0xff);
        close(s);
        return TRUE;
    }
#endif

#if defined(SIOCGARP)
    /* use SIOCGARP ioctl(2) on SVR4 class platforms (Solaris, etc) */
    {
        char hostname[MAXHOSTNAMELEN];
        struct hostent *he;
        struct arpreq ar;
        struct sockaddr_in *sa;
        int s;
        int i;

        if (gethostname(hostname, sizeof(hostname)) < 0)
            return FALSE;
        if ((he = gethostbyname(hostname)) == NULL)
            return FALSE;
        if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
            return FALSE;
        memset(&ar, '\0', sizeof(ar));
        sa = (struct sockaddr_in *)((void *)&(ar.arp_pa));
        sa->sin_family = AF_INET;
        memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr));
        if (ioctl(s, SIOCGARP, &ar) < 0) {
            close(s);
            return FALSE;
        }
        for (i = 0; i < MAC_LEN; i++)
            data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff);
        close(s);
        return TRUE;
    }
#endif

    return FALSE;
}
int Lwm2mCore_GetIPAddressFromInterface(const char * interface, int addressFamily, char * destAddress, size_t destAddressLength)
{
    int returnCode = 0;
#ifndef CONTIKI
    if (addressFamily != AF_INET && addressFamily != AF_INET6)
    {
        Lwm2m_Error("Unsupported address family: %d. Only AF_INET and AF_INET6 are supported.\n", addressFamily);
        returnCode = 1;
        goto error;
    }
    struct ifaddrs *interfaceAddresses, *interfaceAddress;

    char host[NI_MAXHOST];

    if (getifaddrs(&interfaceAddresses) == -1)
    {
        perror("getifaddrs");
        returnCode = 1;
        goto error;
    }

    char linkLocalIpv6Address[NI_MAXHOST] = { 0 };
    char globalIpv6Address[NI_MAXHOST] = { 0 };
    bool found = false;
    int index = 0;
    for (interfaceAddress = interfaceAddresses; interfaceAddress != NULL; interfaceAddress = interfaceAddress->ifa_next)
    {
        if (interfaceAddress->ifa_addr == NULL)
        {
            continue;
        }

        if ((strcmp(interfaceAddress->ifa_name, interface)==0)&&(interfaceAddress->ifa_addr->sa_family==addressFamily))
        {
            int socketAddressLength = 0;
            switch(addressFamily)
            {
                case AF_INET:
                    socketAddressLength = sizeof(struct sockaddr_in);
                    break;
                default:
                    socketAddressLength = sizeof(struct sockaddr_in6);
                    break;
            }

            returnCode = getnameinfo(interfaceAddress->ifa_addr, socketAddressLength, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

            if (returnCode != 0)
            {
                Lwm2m_Error("getnameinfo() failed: %s\n", gai_strerror(returnCode));
                goto error_free;
            }

            size_t addressLength = strlen(host);
            if (destAddressLength < addressLength)
            {
                Lwm2m_Error("Error: Address is longer than %zu characters\n", destAddressLength);
                goto error_free;
            }

            switch(addressFamily)
            {
                case AF_INET:
                    strcpy(destAddress, host);
                    found = true;
                    break;
                default:
                    if (strncmp(host, "fe80", 4) == 0)
                    {
                        Lwm2m_Debug("Address %d: %s (local)\n", index, host);
                        strcpy(linkLocalIpv6Address, host);
                    }
                    else
                    {
                        Lwm2m_Debug("Address %d: %s (global)\n", index, host);
                        strcpy(globalIpv6Address, host);
                    }
                    break;
            }
            index++;
        }
    }

    if (addressFamily == AF_INET6)
    {
        if (strlen(globalIpv6Address) > 0)
        {
            Lwm2m_Debug("Global IPv6 address found for interface %s: %s\n", interface, globalIpv6Address);
            strcpy(destAddress, globalIpv6Address);
            found = true;
        }
        else if (strlen(linkLocalIpv6Address) > 0)
        {
            Lwm2m_Warning("No global IPv6 address found for interface %s: using local: %s\n", interface, linkLocalIpv6Address);
            strcpy(destAddress, linkLocalIpv6Address);
            found = true;
        }
    }

    if (!found)
    {
        Lwm2m_Error("Could not find an %s IP address for interface %s\n", addressFamily == AF_INET? "IPv4" : "IPv6", interface);
        returnCode = 1;
    }

error_free:
    freeifaddrs(interfaceAddresses);
error:
#endif
    return returnCode;
}
Beispiel #10
0
static krb5_error_code
find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
{
    struct sockaddr sa_zero;
    struct ifaddrs *ifa0, *ifa;
    krb5_error_code ret = ENXIO; 
    int num, idx;
    krb5_addresses ignore_addresses;

    res->val = NULL;

    if (getifaddrs(&ifa0) == -1) {
	ret = errno;
	krb5_set_error_string(context, "getifaddrs: %s", strerror(ret));
	return (ret);
    }

    memset(&sa_zero, 0, sizeof(sa_zero));

    /* First, count all the ifaddrs. */
    for (ifa = ifa0, num = 0; ifa != NULL; ifa = ifa->ifa_next, num++)
	/* nothing */;

    if (num == 0) {
	freeifaddrs(ifa0);
	krb5_set_error_string(context, "no addresses found");
	return (ENXIO);
    }

    if (flags & EXTRA_ADDRESSES) {
	/* we'll remove the addresses we don't care about */
	ret = krb5_get_ignore_addresses(context, &ignore_addresses);
	if(ret)
	    return ret;
    }

    /* Allocate storage for them. */
    res->val = calloc(num, sizeof(*res->val));
    if (res->val == NULL) {
	krb5_free_addresses(context, &ignore_addresses);
	freeifaddrs(ifa0);
	krb5_set_error_string (context, "malloc: out of memory");
	return (ENOMEM);
    }

    /* Now traverse the list. */
    for (ifa = ifa0, idx = 0; ifa != NULL; ifa = ifa->ifa_next) {
	if ((ifa->ifa_flags & IFF_UP) == 0)
	    continue;
	if (ifa->ifa_addr == NULL)
	    continue;
	if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
	    continue;
	if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
	    continue;
	if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
	    /* We'll deal with the LOOP_IF_NONE case later. */
	    if ((flags & LOOP) == 0)
		continue;
	}

	ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]);
	if (ret) {
	    /*
	     * The most likely error here is going to be "Program
	     * lacks support for address type".  This is no big
	     * deal -- just continue, and we'll listen on the
	     * addresses who's type we *do* support.
	     */
	    continue;
	}
	/* possibly skip this address? */
	if((flags & EXTRA_ADDRESSES) && 
	   krb5_address_search(context, &res->val[idx], &ignore_addresses)) {
	    krb5_free_address(context, &res->val[idx]);
	    flags &= ~LOOP_IF_NONE; /* we actually found an address,
                                       so don't add any loop-back
                                       addresses */
	    continue;
	}

	idx++;
    }

    /*
     * If no addresses were found, and LOOP_IF_NONE is set, then find
     * the loopback addresses and add them to our list.
     */
    if ((flags & LOOP_IF_NONE) != 0 && idx == 0) {
	for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
	    if ((ifa->ifa_flags & IFF_UP) == 0)
		continue;
	    if (ifa->ifa_addr == NULL)
		continue;
	    if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
		continue;
	    if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
		continue;

	    if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
		ret = krb5_sockaddr2address(context,
					    ifa->ifa_addr, &res->val[idx]);
		if (ret) {
		    /*
		     * See comment above.
		     */
		    continue;
		}
		if((flags & EXTRA_ADDRESSES) && 
		   krb5_address_search(context, &res->val[idx], 
				       &ignore_addresses)) {
		    krb5_free_address(context, &res->val[idx]);
		    continue;
		}
		idx++;
	    }
	}
    }

    if (flags & EXTRA_ADDRESSES)
	krb5_free_addresses(context, &ignore_addresses);
    freeifaddrs(ifa0);
    if (ret)
	free(res->val);
    else
	res->len = idx;        /* Now a count. */
    return (ret);
}
Beispiel #11
0
int
ipmi_intf_socket_connect(struct ipmi_intf * intf)
{
	struct ipmi_session_params *params;

	struct sockaddr_storage addr;
	struct addrinfo hints;
	struct addrinfo *rp0 = NULL, *rp;
	char service[NI_MAXSERV];

	if (!intf) {
		return -1;
	}

	params = &intf->ssn_params;

	if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) {
		lprintf(LOG_ERR, "No hostname specified!");
		return -1;
	}

	/* open port to BMC */
	memset(&addr, 0, sizeof(addr));

	sprintf(service, "%d", params->port);
	/* Obtain address(es) matching host/port */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family   = intf->ai_family;    /* Allow IPv4 or IPv6 */
	hints.ai_socktype = SOCK_DGRAM;   /* Datagram socket */
	hints.ai_flags    = 0;            /* use AI_NUMERICSERV for no name resolution */
	hints.ai_protocol = IPPROTO_UDP; /*  */

	if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) {
		lprintf(LOG_ERR, "Address lookup for %s failed",
				params->hostname);
		return -1;
	}

	/* getaddrinfo() returns a list of address structures.
	 * Try each address until we successfully connect(2).
	 * If socket(2) (or connect(2)) fails, we (close the socket
	 * and) try the next address.
	 */

	for (rp = rp0; rp != NULL; rp = rp->ai_next) {
		/* We are only interested in IPv4 and IPv6 */
		if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) {
			continue;
		}

		intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (intf->fd == -1) {
			continue;
		}

		if (rp->ai_family == AF_INET) {
			if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
				hints.ai_family = rp->ai_family;
				break;  /* Success */
			}
		}  else if (rp->ai_family == AF_INET6) {
			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr;
			char hbuf[NI_MAXHOST];
			socklen_t len;

			/* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */
			if (addr6->sin6_scope_id != 0) {
				len = sizeof(struct sockaddr_in6);
				if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
					lprintf(LOG_DEBUG, "Trying address: %s scope=%d",
						hbuf,
						addr6->sin6_scope_id);
				}
				if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
					hints.ai_family = rp->ai_family;
					break;  /* Success */
				}
			} else {
				/* No scope specified, try to get this from the list of interfaces */
				struct ifaddrs *ifaddrs = NULL;
				struct ifaddrs *ifa = NULL;

				if (getifaddrs(&ifaddrs) < 0) {
					lprintf(LOG_ERR, "Interface address lookup for %s failed",
						params->hostname);
					break;
				}

				for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
					if (ifa->ifa_addr == NULL) {
						continue;
					}

					if (ifa->ifa_addr->sa_family == AF_INET6) {
						struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *)ifa->ifa_addr;

						/* Skip unwanted addresses */
						if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) {
							continue;
						}
						if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) {
							continue;
						}
						len = sizeof(struct sockaddr_in6);
						if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
							lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",
								ifa->ifa_name != NULL ? ifa->ifa_name : "???",
								hbuf,
								tmp6->sin6_scope_id);
						}

						if (tmp6->sin6_scope_id != 0) {
							addr6->sin6_scope_id = tmp6->sin6_scope_id;
						} else {
							/*
							 * No scope information in interface address information
							 * On some OS'es, getifaddrs() is returning out the 'kernel' representation
							 * of scoped addresses which stores the scope in the 3rd and 4th
							 * byte. See also this page:
							 * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html
							 */
							if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)
									&& (tmp6->sin6_addr.s6_addr[1] != 0)) {
								addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]);
							}
						}

						/* OK, now try to connect with the scope id from this interface address */
						if (addr6->sin6_scope_id != 0 || !IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)) {
							if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
								hints.ai_family = rp->ai_family;
								lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);
								break;  /* Success */
							}
						}
					}
				}
				freeifaddrs(ifaddrs);
			}
		}
		if (hints.ai_family != AF_UNSPEC) {
			break;
		}
		close(intf->fd);
		intf->fd = -1;
	}

	/* No longer needed */
	freeaddrinfo(rp0);

	return ((intf->fd != -1) ? 0 : -1);
}
Beispiel #12
0
/* configure using getifaddrs(3) */
static int if_bsdx_open(void)
{
    struct ifaddrs **ifadd_list;
    struct ifaddrs *cur_ifaddrs;
    struct sockaddr_in* sin_addr;

    /* 
     * the manpage claims that getifaddrs() allocates the memory,
     * and freeifaddrs() is later used to release the allocated memory.
     * however, without this malloc the call to getifaddrs() segfaults
     */
    ifadd_list = (struct ifaddrs **) malloc(sizeof(struct ifaddrs*));

    /* create the linked list of ifaddrs structs */
    if (getifaddrs(ifadd_list) < 0) {
        opal_output(0, "opal_ifinit: getifaddrs() failed with error=%d\n",
                    errno);
        return OPAL_ERROR;
    }

    for (cur_ifaddrs = *ifadd_list; NULL != cur_ifaddrs; 
         cur_ifaddrs = cur_ifaddrs->ifa_next) {
        opal_if_t *intf;
        struct in_addr a4;

        /* skip non- af_inet interface addresses */
        if (AF_INET != cur_ifaddrs->ifa_addr->sa_family) {
            continue;
        }

        /* skip interface if it is down (IFF_UP not set) */
        if (0 == (cur_ifaddrs->ifa_flags & IFF_UP)) {
            continue;
        }

        /* skip interface if it is a loopback device (IFF_LOOPBACK set) */
        if (!opal_if_retain_loopback && 0 != (cur_ifaddrs->ifa_flags & IFF_LOOPBACK)) {
            continue;
        }

        /* or if it is a point-to-point interface */
        /* TODO: do we really skip p2p? */
        if (0 != (cur_ifaddrs->ifa_flags & IFF_POINTOPOINT)) {
            continue;
        }

        sin_addr = (struct sockaddr_in *) cur_ifaddrs->ifa_addr;

        intf = OBJ_NEW(opal_if_t);
        if (NULL == intf) {
            opal_output(0, "opal_ifinit: unable to allocate %d bytes\n",
                        (int) sizeof(opal_if_t));
            return OPAL_ERR_OUT_OF_RESOURCE;
        }
        intf->af_family = AF_INET;

        /* fill values into the opal_if_t */
        memcpy(&a4, &(sin_addr->sin_addr), sizeof(struct in_addr));
            
        strncpy(intf->if_name, cur_ifaddrs->ifa_name, IF_NAMESIZE);
        intf->if_index = opal_list_get_size(&opal_if_list) + 1;
        ((struct sockaddr_in*) &intf->if_addr)->sin_addr = a4;
        ((struct sockaddr_in*) &intf->if_addr)->sin_family = AF_INET;
        ((struct sockaddr_in*) &intf->if_addr)->sin_len =  cur_ifaddrs->ifa_addr->sa_len;

        intf->if_mask = prefix( sin_addr->sin_addr.s_addr);
        intf->if_flags = cur_ifaddrs->ifa_flags;

        intf->if_kernel_index = 
            (uint16_t) if_nametoindex(cur_ifaddrs->ifa_name);

        opal_list_append(&opal_if_list, &(intf->super));
    }   /*  of for loop over ifaddrs list */

    return OPAL_SUCCESS;
}
Beispiel #13
0
/* for when all other options fail, as can happen on Android,
   if the permissions for the socket-based method are broken.
   Down side is that it while it gets the interface name and
   broadcast, it doesn't get the local address for that
   interface. 
*/
int scrapeProcNetRoute()
{
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called");

  FILE *f=fopen("/proc/net/route","r");
  if (!f) return WHY_perror("fopen(\"/proc/net/route\")");

  char line[1024],name[1024],dest[1024],mask[1024];

  /* skip header line */
  line[0]=0; fgets(line,1024,f);

  line[0]=0; fgets(line,1024,f);
  while(line[0]) {
    int r;
    if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3)
      {
	struct in_addr addr = {.s_addr=strtol(dest,NULL,16)};
	struct in_addr netmask = {.s_addr=strtol(mask,NULL,16)};
	
	overlay_interface_register(name,addr,netmask);
      }

    line[0]=0; fgets(line,1024,f);    
  }
  fclose(f);
  return 0;
}
#endif

#ifdef SIOCGIFCONF

/* Not present in Linux */
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(x) sizeof(struct ifreq)
#endif

int
lsif(void) {
  char            buf[8192];
  struct ifconf   ifc;
  int             sck, nInterfaces, ofs;
  struct ifreq    *ifr;
  struct in_addr  addr, netmask;

  if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called");

  /* Get a socket handle. */
  sck = socket(PF_INET, SOCK_DGRAM, 0);
  if(sck < 0) {
    WHY_perror("socket");
    return 1;
  }
 
  /* Query available interfaces. */
  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
    WHY_perror("ioctl(SIOCGIFCONF)");
    close(sck);
    return 1;
  }

  /* Iterate through the list of interfaces. */
  nInterfaces = 0;
  ofs = 0;
  
  while (ofs < ifc.ifc_len && ofs < sizeof(buf)) {
    ifr = (struct ifreq *)(ifc.ifc_ifcu.ifcu_buf + ofs);
    ofs += _SIZEOF_ADDR_IFREQ(*ifr);

    /* We're only interested in IPv4 addresses */
    if (ifr->ifr_ifru.ifru_addr.sa_family != AF_INET) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifr->ifr_name);
      continue;
    }
  
    addr = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
    
    /* Get interface flags */
    if (ioctl(sck, SIOCGIFFLAGS, ifr) == -1)
      FATAL_perror("ioctl(SIOCGIFFLAGS)");
    
    /* Not broadcast? Not interested.. */
    if ((ifr->ifr_ifru.ifru_flags & IFF_BROADCAST) == 0) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifr->ifr_name);
      continue;
    }
    
    /* Get netmask */
    if (ioctl(sck, SIOCGIFNETMASK, ifr, sizeof(*ifr)) != 0) {
      WHY_perror("ioctl(SIOCGIFNETMASK)");
      continue;
    }
    netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
    
    overlay_interface_register(ifr->ifr_name, addr, netmask);
    nInterfaces++;
  }
  
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Examined %d interface addresses", nInterfaces);

  close(sck); 
  return 0;
}

#endif

#ifdef HAVE_IFADDRS_H
int
doifaddrs(void) {
  struct ifaddrs	*ifaddr, *ifa;
  char 			*name;
  struct in_addr	addr, netmask;
  
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("called");
  
  if (getifaddrs(&ifaddr) == -1)
    return WHY_perror("getifaddr()");

  for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) {
    /* We're only interested in IPv4 addresses */
    if (ifa->ifa_addr->sa_family != AF_INET) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifa->ifa_name);
      continue;
    }
    
    /* Not broadcast? Not interested.. */
    if ((ifa->ifa_flags & IFF_BROADCAST) == 0) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifa->ifa_name);
      continue;
    }

    name = ifa->ifa_name;
    addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;

    overlay_interface_register(name, addr, netmask);
  }
  freeifaddrs(ifaddr);

  return 0;
}
__private_extern__ int
si_inet_config(uint32_t *inet4, uint32_t *inet6)
{
	int status, checkit;
	struct ifaddrs *ifa, *ifap;

	pthread_mutex_lock(&net_config_mutex);

	checkit = 1;

	if (net_config_token < 0)
	{
		status = notify_register_check(kNotifySCNetworkChange, &net_config_token);
		if (status != 0) net_config_token = -1;
	}

	if (net_config_token >= 0)
	{
		status = notify_check(net_config_token, &checkit);
		if (status != 0) checkit = 1;
	}

	status = 0;

	if (checkit != 0)
	{
		if (getifaddrs(&ifa) < 0)
		{
			status = -1;
		}
		else
		{
			net_v4_count = 0;
			net_v6_count = 0;

			for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next)
			{
				if (ifap->ifa_addr == NULL) continue;
				if ((ifap->ifa_flags & IFF_UP) == 0) continue;

				if (ifap->ifa_addr->sa_family == AF_INET)
				{
					net_v4_count++;
				}
				else if (ifap->ifa_addr->sa_family == AF_INET6)
				{
					net_v6_count++;
				}
			}
            freeifaddrs(ifa);
		}

	}

	if (inet4 != NULL) *inet4 = net_v4_count;
	if (inet6 != NULL) *inet6 = net_v6_count;

	pthread_mutex_unlock(&net_config_mutex);

	return status;
}
/*
 * this function gets the hardware type and address of an interface,
 * determines the link layer token length and checks it against
 * the defined prefixes
 */
int
setup_deviceinfo(int sock, struct Interface *iface)
{
	struct ifaddrs *addresses, *ifa;

	struct ifreq ifr;
	struct AdvPrefix *prefix;
	char zero[sizeof(iface->if_addr)];

 	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1);
	ifr.ifr_name[IFNAMSIZ-1] = '\0';

	if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
		flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno));
		goto ret;
	}	

	dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu);
	iface->if_maxmtu = ifr.ifr_mtu;

	if (getifaddrs(&addresses) != 0)
	{
		flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno);
		goto ret;
	}

	for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next)
	{
		if (strcmp(ifa->ifa_name, iface->Name) != 0)
			continue;

		if (ifa->ifa_addr == NULL)
			continue;

		if (ifa->ifa_addr->sa_family != AF_LINK)
			continue;

		struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr;


		if (dl->sdl_alen > sizeof(iface->if_addr))
		{
			flog(LOG_ERR, "address length %d too big for",
				dl->sdl_alen,
				iface->Name);
			goto ret;
		}
		
		memcpy(iface->if_hwaddr, LLADDR(dl), dl->sdl_alen);
		iface->if_hwaddr_len = dl->sdl_alen << 3;

		switch(dl->sdl_type) {
		case IFT_ETHER:
		case IFT_ISO88023:
			iface->if_prefix_len = 64;
			break;
		case IFT_FDDI:
			iface->if_prefix_len = 64;
			break;
		default:
			iface->if_prefix_len = -1;
			iface->if_maxmtu = -1;
			break;
		}

		dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name,
			iface->if_hwaddr_len);

		dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name,
			iface->if_prefix_len);

		if (iface->if_prefix_len != -1) {
			memset(zero, 0, dl->sdl_alen);
			if (!memcmp(iface->if_hwaddr, zero, dl->sdl_alen))
				flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!",
					iface->Name);
		}
		
		prefix = iface->AdvPrefixList;
		while (prefix)
		{
			if ((iface->if_prefix_len != -1) &&
				(iface->if_prefix_len != prefix->PrefixLen))
			{
				flog(LOG_WARNING, "prefix length should be %d for %s",
					iface->if_prefix_len, iface->Name);
			}

			prefix = prefix->next;
		}

		freeifaddrs(addresses);
		return 0;
	}


ret:
	iface->if_maxmtu = -1;
	iface->if_hwaddr_len = -1;
	iface->if_prefix_len = -1;
	freeifaddrs(addresses);
	return -1;
}
int main(int argc,char *argv[])
{
	char *dev,errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *handle;				/* Session handle */
	struct bpf_program fp;			/* compiled filter expression */
	char filter_exp[]="ether proto \\ip";	//"ip proto \\udp or \\tcp or \\icmp";	/* Filter expression */
	bpf_u_int32 mask;			/* netmask of sniffing device */
	bpf_u_int32 net;			/* IP address of const struct pcap_pkthdrsniffing device */
        struct sigaction *act_alarm,*act_int;
	
	struct pcap_pkthdr header;
	const u_char *packet=NULL;


	act_alarm=(struct sigaction*)malloc(sizeof(struct sigaction));
	act_int=(struct sigaction*)malloc(sizeof(struct sigaction));	
	memset(act_alarm,'\0',sizeof(act_alarm));
	memset(act_int,'\0',sizeof(act_int));
	
	act_alarm->sa_handler=alarm_printhandler;	
	sigemptyset(&act_alarm->sa_mask);
	act_alarm->sa_flags=0;	
	sigaction(SIGALRM,act_alarm,NULL);
	
	act_int->sa_handler=INT_handler;
	sigemptyset(&act_int->sa_mask);
	act_int->sa_flags=0;
	sigaction(SIGINT,act_int,NULL);	
	
	
	if(gettimeofday(&current_time,NULL) != 0)
	{
		fprintf(stderr,"Error in gettimeofday(): %s\n",strerror(errno));
		exit(1);
	} 
	
	/* Handle commandline here */
	
	memset(interface,'\0',sizeof(interface));
	memset(filename,'\0',sizeof(filename));
	memset(my_ip,'\0',sizeof(my_ip));

	handle_commandline(argc,argv);
	
	newvalue=(struct itimerval*)malloc(sizeof(struct itimerval));
	newvalue->it_interval.tv_sec=epoch;
	newvalue->it_interval.tv_usec=0;
	newvalue->it_value.tv_sec=epoch;
	newvalue->it_value.tv_usec=0;
	setitimer(ITIMER_REAL,newvalue,NULL);  

	/* fetch ip address */
	getifaddrs(&addr);
	while(addr)
	{
		if(addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET && strcmp(addr->ifa_name,interface)==0)
		{
			struct sockaddr_in *paddr = (struct sockaddr_in *)addr->ifa_addr;
			//fprintf(stdout,"%s %s\n",addr->ifa_name,inet_ntoa(paddr->sin_addr));  //project
			strcpy(filename,inet_ntoa(paddr->sin_addr));
			strcpy(my_ip,inet_ntoa(paddr->sin_addr));
			break;
		}
		addr = addr->ifa_next;
	}
	//printf("Filename: %s",filename);
	if(epoch == 0)
	{
		epoch=1;	// default is 1 sec
	}
	if(interface[0] == '\0')
	{
		dev=" ";
	}
	else
	{
		dev=interface;
	}
	
	//fprintf(stdout,"Device is %s\n",dev);
	
	/* Lookup network */
	if(pcap_lookupnet(dev,&net,&mask,errbuf) == -1)
	{
		 //fprintf(stderr, "Can't get netmask for device %s\n", dev);
		 net = 0;
		 mask = 0;
	} 
	//printf("IP: %d\n",net);
	//printf("Mask: %d\n",mask);	

	 /* Opening device for sniffing */
	if(read_file == NULL)
	{
								
		if((handle=pcap_create(dev,errbuf)) == NULL)
		{
			fprintf(stderr,"Error in pcap_create: %s",errbuf);
			exit(1);
		}
		if(pcap_set_promisc(handle,5) == PCAP_ERROR_ACTIVATED || pcap_set_timeout(handle,epoch*1000) == PCAP_ERROR_ACTIVATED )
		{
			fprintf(stderr,"Capture handle already activated");
			exit(1);
		}
		
		pcap_activate(handle);  
		
	}
	else
	{
		filer=fopen(read_file,"r");
		/* block the alarm handler too */
		sigaddset(&act_alarm->sa_mask,SIGALRM);
		sigprocmask(SIG_BLOCK,&act_alarm->sa_mask,NULL);		
		if(filer == NULL)
		{
			perror("Error in fopen file");
			exit(1);
		}
				
		handle=pcap_fopen_offline(filer,errbuf);
		if(handle == NULL)
		{
			fprintf(stderr,"Error in pcap_open_offline(): %s",errbuf);
			exit(1);
		}
		
	}
	if(write_file != NULL)
	{
		filew=fopen(write_file,"w");			
	}
		
	if(handle == NULL)
	{
		fprintf(stderr,"Couldn't open device %s: %s\n",dev,errbuf);
		exit(1);
	}
	
	
	/* Determine the type of link-headers the device provides */
	if(pcap_datalink(handle) != DLT_EN10MB)
	{
		fprintf(stderr,"Usage: ./traffana -v [-r filename] [-i interface] [-T epoch] [-w filename]\n");
		exit(1);
	}

	/* Complie filter */
	if(pcap_compile(handle,&fp, filter_exp,0,net) == -1)
	{
		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
		exit(1);
	}

	/* Set filter */
	if (pcap_setfilter(handle, &fp) == -1) 
	{
		 fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
		 exit(1);
	}
	/* set the diection */
	//pcap_setdirection(handle,PCAP_D_IN);

	
	

	/* Grab the packets */
	if(read_file == NULL)
	{
		err_loop=pcap_loop(handle,-1,got_packet,(u_char *)filew);	// count -1 or 0 for infinity packets AND pass argument the name
									// of th file
		if(err_loop == -1)
		{
			pcap_perror(handle,errbuf);
			fprintf(stderr,"Error in pcap_loop(): %s\n",errbuf);
			exit(1);
		}
	}
	
	if(read_file !=NULL)
	{
		
		while((packet = pcap_next(handle,&header))!=NULL)
		{
			got_packet(0,&header,packet);
		}
	}

	/* Close session */
	
	if(read_file != NULL)
	{
		print_readfile_stats(sec1,usec1);	/* to read the last epoch */	
	}
	pcap_freecode(&fp);
	pcap_close(handle);
	return 0;

}
Beispiel #17
0
/*
 * NetBSD support auto-clonning, but only for tap device.
 * To access /dev/tapN we have to create it before.
 */
static int
tuntap_sys_start_tap(struct device *dev, int tun) {
	int fd;
	struct ifreq ifr;
	struct ifaddrs *ifa;
	char name[IF_NAMESIZE + 5]; /* For /dev/IFNAMSIZ */

	fd = -1;
	(void)memset(&ifr, '\0', sizeof ifr);
	(void)memset(name, '\0', sizeof name);

	/* Set the device path to open */
	if (tun < TUNTAP_ID_MAX) {
		/* Create the wanted device */
		tuntap_sys_create_dev(dev, TUNTAP_MODE_ETHERNET, tun);
		(void)snprintf(name, sizeof name, "/dev/tap%i", tun);
	} else if (tun == TUNTAP_ID_ANY) {
		/* Or use autocloning */
		(void)memcpy(name, "/dev/tap", 8);
	} else {
		return -1;
	}

	if ((fd = open(name, O_RDWR)) == -1) {
		char buf[11 + MAXPATHLEN];

		(void)memset(buf, 0, sizeof buf);
		snprintf(buf, sizeof buf, "Can't open %s", name);
		tuntap_log(TUNTAP_LOG_DEBUG, buf);
		return -1;
	}

	/* Get the interface name */
	if (ioctl(fd, TAPGIFNAME, &ifr) == -1) {
		tuntap_log(TUNTAP_LOG_ERR, "Can't get interface name");
		return -1;
	}
	(void)strlcpy(dev->if_name, ifr.ifr_name, sizeof dev->if_name);

	/* Get the interface default values */
	if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
		tuntap_log(TUNTAP_LOG_ERR, "Can't get interface values");
		return -1;
	}

	/* Save flags for tuntap_{up, down} */
	dev->flags = ifr.ifr_flags;

	/* Save pre-existing MAC address */
	if (getifaddrs(&ifa) == 0) {
		struct ifaddrs *pifa;

		for (pifa = ifa; pifa != NULL; pifa = pifa->ifa_next) {
			if (strcmp(pifa->ifa_name, dev->if_name) == 0) {
				struct ether_addr eth_addr;

				/*
				 * The MAC address is from 10 to 15.
				 *
				 * And yes, I know, the buffer is supposed
				 * to have a size of 14 bytes.
				 */
				(void)memcpy(dev->hwaddr,
				  pifa->ifa_addr->sa_data + 10,
				  ETHER_ADDR_LEN);

				(void)memset(&eth_addr.ether_addr_octet, 0,
				  ETHER_ADDR_LEN);
				(void)memcpy(&eth_addr.ether_addr_octet,
				  pifa->ifa_addr->sa_data + 10,
				  ETHER_ADDR_LEN);
				break;
			}
		}
		if (pifa == NULL)
			tuntap_log(TUNTAP_LOG_WARN,
			    "Can't get link-layer address");
		freeifaddrs(ifa);
	}
	return fd;
}
Beispiel #18
0
void CNetworkLinux::queryInterfaceList()
{
  char macAddrRaw[6];
  m_interfaces.clear();

#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD)

   // Query the list of interfaces.
   struct ifaddrs *list;
   if (getifaddrs(&list) < 0)
     return;

   struct ifaddrs *cur;
   for(cur = list; cur != NULL; cur = cur->ifa_next)
   {
     if(cur->ifa_addr->sa_family != AF_INET)
       continue;

     GetMacAddress(cur->ifa_name, macAddrRaw);
     // Add the interface.
     m_interfaces.push_back(new CNetworkInterfaceLinux(this, cur->ifa_name, macAddrRaw));
   }

   freeifaddrs(list);

#else
   FILE* fp = fopen("/proc/net/dev", "r");
   if (!fp)
   {
     // TBD: Error
     return;
   }

   char* line = NULL;
   size_t linel = 0;
   int n;
   char* p;
   int linenum = 0;
   while (getdelim(&line, &linel, '\n', fp) > 0)
   {
      // skip first two lines
      if (linenum++ < 2)
         continue;

    // search where the word begins
      p = line;
      while (isspace(*p))
      ++p;

      // read word until :
      n = strcspn(p, ": \t");
      p[n] = 0;

      // save the result
      std::string interfaceName = p;
      GetMacAddress(interfaceName, macAddrRaw);
      m_interfaces.push_back(new CNetworkInterfaceLinux(this, interfaceName, macAddrRaw));
   }
   free(line);
   fclose(fp);
#endif
}
Beispiel #19
0
int tap_init(char *name)
{

#ifdef __MACH__ /* OSX */
    char clonedev[255] = "/dev/"; /* XXX bad size */
    strncpy(clonedev+5, name, 250);
#else /* Linux */
    struct ifreq ifr;
    const char *clonedev = "/dev/net/tun";
#endif

    /* implicitly create the tap interface */
    if ((_native_tap_fd = open(clonedev , O_RDWR)) == -1) {
        err(EXIT_FAILURE, "open(%s)", clonedev);
    }

#ifdef __MACH__ /* OSX */
    struct ifaddrs* iflist;
    if (getifaddrs(&iflist) == 0) {
        for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) {
            if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) {
                struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr;
                memcpy(_native_tap_mac, LLADDR(sdl), sdl->sdl_alen);
                break;
            }
        }

        freeifaddrs(iflist);
    }
#else /* Linux */
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
    strncpy(ifr.ifr_name, name, IFNAMSIZ);

    if (ioctl(_native_tap_fd, TUNSETIFF, (void *)&ifr) == -1) {
        _native_in_syscall++;
        warn("ioctl TUNSETIFF");
        warnx("probably the tap interface (%s) does not exist or is already in use", name);
        exit(EXIT_FAILURE);
    }

    /* TODO: use strncpy */
    strcpy(name, ifr.ifr_name);


    /* get MAC address */
    memset (&ifr, 0, sizeof (ifr));
    snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", name);
    if (ioctl(_native_tap_fd, SIOCGIFHWADDR, &ifr) == -1) {
        _native_in_syscall++;
        warn("ioctl SIOCGIFHWADDR");
        if (close(_native_tap_fd) == -1) {
            warn("close");
        }
        exit(EXIT_FAILURE);
    }
    memcpy(_native_tap_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
#endif
    DEBUG("_native_tap_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", _native_tap_mac[0], _native_tap_mac[1], _native_tap_mac[2], _native_tap_mac[3], _native_tap_mac[4], _native_tap_mac[5]);

    unsigned char *eui_64 = (unsigned char*)&_native_net_addr_long;
    eui_64[0] = _native_tap_mac[0];
    eui_64[1] = _native_tap_mac[1];
    eui_64[2] = _native_tap_mac[2];
    eui_64[3] = 0xff;
    eui_64[4] = 0xfe;
    eui_64[5] = _native_tap_mac[3];
    eui_64[6] = _native_tap_mac[4];
    eui_64[7] = _native_tap_mac[5];

    /* configure signal handler for fds */
    register_interrupt(SIGIO, _native_handle_tap_input);

#ifdef __MACH__
    /* tuntap signalled IO is not working in OSX,
     * check http://sourceforge.net/p/tuntaposx/bugs/17/ */
    sigio_child();
#else
    /* configure fds to send signals on io */
    if (fcntl(_native_tap_fd, F_SETOWN, getpid()) == -1) {
        err(EXIT_FAILURE, "tap_init(): fcntl(F_SETOWN)");
    }

    /* set file access mode to nonblocking */
    if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK|O_ASYNC) == -1) {
        err(EXIT_FAILURE, "tap_init(): fcntl(F_SETFL)");
    }
#endif /* not OSX */

    DEBUG("RIOT native tap initialized.\n");
    return _native_tap_fd;
}
Beispiel #20
0
/*
 * Figure out whether the local machine is the same
 * as the remote machine (RM) entry (if it exists).
 */
char *
checkremote(void)
{
	char lname[NI_MAXHOST], rname[NI_MAXHOST];
	struct addrinfo hints, *res, *res0;
	static char errbuf[128];
	int error;
	struct ifaddrs *ifap, *ifa;
	const int niflags = NI_NUMERICHOST;
#ifdef __KAME__
	struct sockaddr_in6 sin6;
	struct sockaddr_in6 *sin6p;
#endif

	remote = 0;	/* assume printer is local on failure */

	if (RM == NULL || *RM == '\0')
		return NULL;

	/* get the local interface addresses */
	siginterrupt(SIGINT, 1);
	if (getifaddrs(&ifap) < 0) {
		(void)snprintf(errbuf, sizeof(errbuf),
		    "unable to get local interface address: %s",
		    strerror(errno));
		siginterrupt(SIGINT, 0);
		return errbuf;
	}
	siginterrupt(SIGINT, 0);

	/* get the remote host addresses (RM) */
	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	res = NULL;
	siginterrupt(SIGINT, 1);
	error = getaddrinfo(RM, NULL, &hints, &res0);
	siginterrupt(SIGINT, 0);
	if (error) {
		(void)snprintf(errbuf, sizeof(errbuf),
		    "unable to resolve remote machine %s: %s",
		    RM, gai_strerror(error));
		freeifaddrs(ifap);
		return errbuf;
	}

	remote = 1;	/* assume printer is remote */

	for (res = res0; res; res = res->ai_next) {
		siginterrupt(SIGINT, 1);
		error = getnameinfo(res->ai_addr, res->ai_addrlen,
		    rname, sizeof(rname), NULL, 0, niflags);
		siginterrupt(SIGINT, 0);
		if (error != 0)
			continue;
		for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
#ifdef __KAME__
			sin6p = (struct sockaddr_in6 *)ifa->ifa_addr;
			if (ifa->ifa_addr->sa_family == AF_INET6 &&
			    ifa->ifa_addr->sa_len == sizeof(sin6) &&
			    IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr) &&
			    *(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]) {
				/* kame scopeid hack */
				memcpy(&sin6, ifa->ifa_addr, sizeof(sin6));
				sin6.sin6_scope_id =
				    ntohs(*(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]);
				sin6.sin6_addr.s6_addr[2] = 0;
				sin6.sin6_addr.s6_addr[3] = 0;
				siginterrupt(SIGINT, 1);
				error = getnameinfo((struct sockaddr *)&sin6,
				    sin6.sin6_len, lname, sizeof(lname),
				    NULL, 0, niflags);
				siginterrupt(SIGINT, 0);
				if (error != 0)
					continue;
			} else
#endif
			siginterrupt(SIGINT, 1);
			error = getnameinfo(ifa->ifa_addr,
			    ifa->ifa_addr->sa_len, lname, sizeof(lname), NULL,
			    0, niflags);
			siginterrupt(SIGINT, 0);
			if (error != 0)
				continue;

			if (strcmp(rname, lname) == 0) {
				remote = 0;
				goto done;
			}
		}
	}
done:
	freeaddrinfo(res0);
	freeifaddrs(ifap);
	return NULL;
}
Beispiel #21
0
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
  int* count) {
#ifndef HAVE_IFADDRS_H
  return uv__new_artificial_error(UV_ENOSYS);
#else
  struct ifaddrs *addrs, *ent;
  char ip[INET6_ADDRSTRLEN];
  uv_interface_address_t* address;

  if (getifaddrs(&addrs) != 0) {
    return uv__new_sys_error(errno);
  }

  *count = 0;

  /* Count the number of interfaces */
  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
        (ent->ifa_addr == NULL) ||
        (ent->ifa_addr->sa_family == PF_PACKET)) {
      continue;
    }

    (*count)++;
  }

  *addresses = (uv_interface_address_t*)
    malloc(*count * sizeof(uv_interface_address_t));
  if (!(*addresses)) {
    return uv__new_artificial_error(UV_ENOMEM);
  }

  address = *addresses;

  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    bzero(&ip, sizeof (ip));
    if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
      continue;
    }

    if (ent->ifa_addr == NULL) {
      continue;
    }

    /*
     * On Linux getifaddrs returns information related to the raw underlying
     * devices. We're not interested in this information.
     */
    if (ent->ifa_addr->sa_family == PF_PACKET) {
      continue;
    }

    address->name = strdup(ent->ifa_name);

    if (ent->ifa_addr->sa_family == AF_INET6) {
      address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
    } else {
      address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
    }

    address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;

    address++;
  }

  freeifaddrs(addrs);

  return uv_ok_;
#endif
}
Beispiel #22
0
void chk_reader(char *token, char *value, struct s_reader *rdr)
{
	int32_t i;
	char *ptr, *ptr2, *ptr3, *saveptr1 = NULL;
	/*
	 *  case sensitive first
	 */
	if (!strcmp(token, "device")) {
		for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) {
			trim(ptr);
			switch(i) {
				case 0:
					cs_strncpy(rdr->device, ptr, sizeof(rdr->device));
					break;

				case 1:
					rdr->r_port = atoi(ptr);
					break;

				case 2:
					rdr->l_port = atoi(ptr);
					break;
			}
		}
		return;
	}

#ifdef WITH_LIBUSB
	if (!strcmp(token, "device_out_endpoint")) {
		if (strlen(value) > 0) {
			sscanf(value, "0x%2X", &i);
			rdr->device_endpoint = i;
		} else {
			rdr->device_endpoint = 0;
		}
		return;
	}
#endif

	if (!strcmp(token, "key")) {
		if (strlen(value) == 0){
			return;
		} else if (key_atob_l(value, rdr->ncd_key, 28)) {
			fprintf(stderr, "Configuration newcamd: Error in Key\n");
			memset(rdr->ncd_key, 0, sizeof(rdr->ncd_key));
		}
		return;
	}

	if (!strcmp(token, "password")) {
		cs_strncpy(rdr->r_pwd, value, sizeof(rdr->r_pwd));
		return;
	}

	if (!strcmp(token, "user")) {
		cs_strncpy(rdr->r_usr, value, sizeof(rdr->r_usr));
		return;
	}

#ifdef WEBIF
	if (!strcmp(token, "description")) {
		NULLFREE(rdr->description);
		if(strlen(value) > 0 && cs_malloc(&rdr->description, strlen(value)+1, -1)){
			cs_strncpy(rdr->description, value, strlen(value)+1);
		}
		return;
	}
#endif

  if (!strcmp(token, "mg-encrypted")) {
    uchar key[16];
    uchar mac[6];
    char tmp_dbg[13];
    uchar *buf = NULL;
    int32_t len = 0;

    memset(&key, 0, 16);
    memset(&mac, 0, 6);

    for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) {
      trim(ptr);
      switch(i) {
        case 0:
          len = strlen(ptr) / 2 + (16 - (strlen(ptr) / 2) % 16);
          if(!cs_malloc(&buf,len, -1)) return;
          key_atob_l(ptr, buf, strlen(ptr));
          cs_log("enc %d: %s", len, ptr);
          break;

        case 1:
          key_atob_l(ptr, mac, 12);
          cs_log("mac: %s", ptr);
          break;
      }
    }

    if (!memcmp(mac, "\x00\x00\x00\x00\x00\x00", 6)) {
#if defined(__APPLE__) || defined(__FreeBSD__)
      // no mac address specified so use mac of en0 on local box
      struct ifaddrs *ifs, *current;

      if (getifaddrs(&ifs) == 0)
      {
         for (current = ifs; current != 0; current = current->ifa_next)
         {
            if (current->ifa_addr->sa_family == AF_LINK && strcmp(current->ifa_name, "en0") == 0)
            {
               struct sockaddr_dl *sdl = (struct sockaddr_dl *)current->ifa_addr;
               memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
               break;
            }
         }
         freeifaddrs(ifs);
      }
#elif defined(__SOLARIS__)
			// no mac address specified so use first filled mac
			int32_t j, sock, niccount;
			struct ifreq nicnumber[16];
			struct ifconf ifconf;
			struct arpreq arpreq;

			if ((sock=socket(AF_INET,SOCK_DGRAM,0)) > -1){
				ifconf.ifc_buf = (caddr_t)nicnumber;
				ifconf.ifc_len = sizeof(nicnumber);
				if (!ioctl(sock,SIOCGIFCONF,(char*)&ifconf)){
					niccount = ifconf.ifc_len/(sizeof(struct ifreq));
					for(i = 0; i < niccount, ++i){
						memset(&arpreq, 0, sizeof(arpreq));
						((struct sockaddr_in*)&arpreq.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)&nicnumber[i].ifr_addr)->sin_addr.s_addr;
						if (!(ioctl(sock,SIOCGARP,(char*)&arpreq))){
							for (j = 0; j < 6; ++j)
								mac[j] = (unsigned char)arpreq.arp_ha.sa_data[j];
							if(check_filled(mac, 6) > 0) break;
						}
					}
				}
				close(sock);
			}
Beispiel #23
0
int uv_interface_addresses(uv_interface_address_t** addresses,
  int* count) {
#ifndef HAVE_IFADDRS_H
  return -ENOSYS;
#else
  struct ifaddrs *addrs, *ent;
  uv_interface_address_t* address;
  int i;
  struct sockaddr_ll *sll;

  if (getifaddrs(&addrs))
    return -errno;

  *count = 0;
  *addresses = NULL;

  /* Count the number of interfaces */
  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
        (ent->ifa_addr == NULL) ||
        (ent->ifa_addr->sa_family == PF_PACKET)) {
      continue;
    }

    (*count)++;
  }

  if (*count == 0)
    return 0;

  *addresses = uv__malloc(*count * sizeof(**addresses));
  if (!(*addresses)) {
    freeifaddrs(addrs);
    return -ENOMEM;
  }

  address = *addresses;

  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
      continue;

    if (ent->ifa_addr == NULL)
      continue;

    /*
     * On Linux getifaddrs returns information related to the raw underlying
     * devices. We're not interested in this information yet.
     */
    if (ent->ifa_addr->sa_family == PF_PACKET)
      continue;

    address->name = uv__strdup(ent->ifa_name);

    if (ent->ifa_addr->sa_family == AF_INET6) {
      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
    } else {
      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
    }

    if (ent->ifa_netmask->sa_family == AF_INET6) {
      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
    } else {
      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
    }

    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);

    address++;
  }

  /* Fill in physical addresses for each interface */
  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
        (ent->ifa_addr == NULL) ||
        (ent->ifa_addr->sa_family != PF_PACKET)) {
      continue;
    }

    address = *addresses;

    for (i = 0; i < (*count); i++) {
      if (strcmp(address->name, ent->ifa_name) == 0) {
        sll = (struct sockaddr_ll*)ent->ifa_addr;
        memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
      }
      address++;
    }
  }

  freeifaddrs(addrs);

  return 0;
#endif
}
Beispiel #24
0
bool net_ifinfo_new(net_ifinfo_t *list)
{
   unsigned k              = 0;
#if defined(_WIN32) && !defined(_XBOX)
   DWORD size;
   PIP_ADAPTER_ADDRESSES adapter_addresses, aa;
   PIP_ADAPTER_UNICAST_ADDRESS ua;

   DWORD rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &size);

   adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);

   rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adapter_addresses, &size);

   memset(list, 0, sizeof(net_ifinfo_t));

   if (rv != ERROR_SUCCESS)
      goto error;

   for (aa = adapter_addresses; aa != NULL; aa = aa->Next)
   {
      char name[PATH_MAX_LENGTH];
      memset(name, 0, sizeof(name));

      WideCharToMultiByte(CP_ACP, 0, aa->FriendlyName, wcslen(aa->FriendlyName),
            name, PATH_MAX_LENGTH, NULL, NULL);

      for (ua = aa->FirstUnicastAddress; ua != NULL; ua = ua->Next)
      {
         char host[PATH_MAX_LENGTH];
         struct net_ifinfo_entry *ptr = (struct net_ifinfo_entry*)
            realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));

         if (!ptr)
            goto error;

         list->entries          = ptr;

         memset(host, 0, sizeof(host));

         getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength,
               host, sizeof(host), NULL, NI_MAXSERV, NI_NUMERICHOST);

         list->entries[k].name  = strdup(name);
         list->entries[k].host  = strdup(host);
         list->size             = k + 1;

         k++;
      }
   }

   free(adapter_addresses);
#else
   struct ifaddrs *ifa     = NULL;
   struct ifaddrs *ifaddr  = NULL;

   memset(list, 0, sizeof(net_ifinfo_t));

   if (getifaddrs(&ifaddr) == -1)
      goto error;

   if (!list)
      goto error;

   for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
   {
      char host[NI_MAXHOST];
      struct net_ifinfo_entry *ptr = NULL;

      if (!ifa->ifa_addr)
         continue;

      if (ifa->ifa_addr->sa_family != AF_INET)
         continue;

      if (getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
               host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
         goto error;

      ptr = (struct net_ifinfo_entry*)
         realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));

      if (!ptr)
         goto error;

      list->entries          = ptr;

      list->entries[k].name  = strdup(ifa->ifa_name);
      list->entries[k].host  = strdup(host);
      list->size             = k + 1;

      k++;
   }

   freeifaddrs(ifaddr);
#endif
   return true;

error:
#ifdef _WIN32
   if (adapter_addresses)
      free(adapter_addresses);
#else
   freeifaddrs(ifaddr);
#endif
   net_ifinfo_free(list);

   return false;
}
Beispiel #25
0
/*
 * Return NICs information a-la ifconfig as a list of tuples.
 * TODO: on Solaris we won't get any MAC address.
 */
static PyObject*
psutil_net_if_addrs(PyObject* self, PyObject* args) {
    struct ifaddrs *ifaddr, *ifa;
    int family;

    PyObject *py_retlist = PyList_New(0);
    PyObject *py_tuple = NULL;
    PyObject *py_address = NULL;
    PyObject *py_netmask = NULL;
    PyObject *py_broadcast = NULL;
    PyObject *py_ptp = NULL;

    if (py_retlist == NULL)
        return NULL;
    if (getifaddrs(&ifaddr) == -1) {
        PyErr_SetFromErrno(PyExc_OSError);
        goto error;
    }

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr)
            continue;
        family = ifa->ifa_addr->sa_family;
        py_address = psutil_convert_ipaddr(ifa->ifa_addr, family);
        // If the primary address can't be determined just skip it.
        // I've never seen this happen on Linux but I did on FreeBSD.
        if (py_address == Py_None)
            continue;
        if (py_address == NULL)
            goto error;
        py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family);
        if (py_netmask == NULL)
            goto error;

        if (ifa->ifa_flags & IFF_BROADCAST) {
            py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
            Py_INCREF(Py_None);
            py_ptp = Py_None;
        }
        else if (ifa->ifa_flags & IFF_POINTOPOINT) {
            py_ptp = psutil_convert_ipaddr(ifa->ifa_dstaddr, family);
            Py_INCREF(Py_None);
            py_broadcast = Py_None;
        }
        else {
            Py_INCREF(Py_None);
            Py_INCREF(Py_None);
            py_broadcast = Py_None;
            py_ptp = Py_None;
        }

        if ((py_broadcast == NULL) || (py_ptp == NULL))
            goto error;
        py_tuple = Py_BuildValue(
            "(siOOOO)",
            ifa->ifa_name,
            family,
            py_address,
            py_netmask,
            py_broadcast,
            py_ptp
        );

        if (! py_tuple)
            goto error;
        if (PyList_Append(py_retlist, py_tuple))
            goto error;
        Py_DECREF(py_tuple);
        Py_DECREF(py_address);
        Py_DECREF(py_netmask);
        Py_DECREF(py_broadcast);
        Py_DECREF(py_ptp);
    }

    freeifaddrs(ifaddr);
    return py_retlist;

error:
    if (ifaddr != NULL)
        freeifaddrs(ifaddr);
    Py_DECREF(py_retlist);
    Py_XDECREF(py_tuple);
    Py_XDECREF(py_address);
    Py_XDECREF(py_netmask);
    Py_XDECREF(py_broadcast);
    Py_XDECREF(py_ptp);
    return NULL;
}
Beispiel #26
0
__private_extern__
void
interface_update_ipv6(struct ifaddrs *ifap, const char *if_name)
{
	struct ifaddrs		*ifa;
	struct ifaddrs		*ifap_temp	= NULL;
	CFStringRef		interface;
	boolean_t		interfaceFound	= FALSE;
	CFStringRef		key		= NULL;
	CFMutableDictionaryRef	oldIFs;
	CFMutableDictionaryRef	newDict		= NULL;
	CFMutableDictionaryRef	newIFs;
	int			sock		= -1;

	oldIFs = CFDictionaryCreateMutable(NULL,
					   0,
					   &kCFTypeDictionaryKeyCallBacks,
					   &kCFTypeDictionaryValueCallBacks);
	newIFs = CFDictionaryCreateMutable(NULL,
					   0,
					   &kCFTypeDictionaryKeyCallBacks,
					   &kCFTypeDictionaryValueCallBacks);

	if (!ifap) {
		if (getifaddrs(&ifap_temp) == -1) {
			SC_log(LOG_NOTICE, "getifaddrs() failed: %s", strerror(errno));
			goto error;
		}
		ifap = ifap_temp;
	}

	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		struct in6_ifreq	ifr6;
#define	flags6	ifr6.ifr_ifru.ifru_flags6
		struct sockaddr_in6	*sin6;

		if (ifa->ifa_addr->sa_family != AF_INET6) {
			continue;			/* sorry, not interested */
		}

		/* check if this is the requested interface */
		if (if_name) {
			if (strncmp(if_name, ifa->ifa_name, IFNAMSIZ) == 0) {
				interfaceFound = TRUE;	/* yes, this is the one I want */
			} else {
				continue;		/* sorry, not interested */
			}
		}

		if (sock == -1) {
			sock = dgram_socket(AF_INET6);
			if (sock == -1) {
				goto error;
			}
		}

		/* get the current cache information */
		interface = CFStringCreateWithCString(NULL, ifa->ifa_name, kCFStringEncodingMacRoman);
		key       = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
									  kSCDynamicStoreDomainState,
									  interface,
									  kSCEntNetIPv6);
		CFRelease(interface);

		newDict = copyIF(key, oldIFs, newIFs);

		/* ALIGN: ifa->ifa_addr aligned (getifaddrs), cast ok. */
		sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;

		/* XXX: embedded link local addr check */
		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) {
			u_int16_t	index;

			index = sin6->sin6_addr.s6_addr16[1];
			if (index != 0) {
				sin6->sin6_addr.s6_addr16[1] = 0;
				if (sin6->sin6_scope_id == 0) {
					sin6->sin6_scope_id = ntohs(index);
				}
			}
		}

		bzero((char *)&ifr6, sizeof(ifr6));
		strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
		ifr6.ifr_addr = *sin6;
		if (ioctl(sock, SIOCGIFAFLAG_IN6, &ifr6) == -1) {
			/* if flags not available for this address */
			SC_log((errno != EADDRNOTAVAIL) ? LOG_NOTICE : LOG_DEBUG, "ioctl() failed: %s",
			      strerror(errno));
		}

		appendAddress  (newDict, kSCPropNetIPv6Addresses, sin6);
#ifdef	NOTYET
		appendScopeID  (newDict, sin6);
#endif	/* NOTYET */
		/* ALIGN: ifa should be aligned (from getifaddrs), cast ok.
		 * appendPrefixLen expect byte alignment */
		appendPrefixLen(newDict, (struct sockaddr_in6 *)(void *)ifa->ifa_netmask);
		appendFlags    (newDict, flags6);


		if (ifa->ifa_flags & IFF_POINTOPOINT
		    && ifa->ifa_dstaddr != NULL) {
			struct sockaddr_in6	*dst6;

			/* ALIGN: ifa should be aligned (from getifaddrs), cast ok. */
			dst6 = (struct sockaddr_in6 *)(void *)ifa->ifa_dstaddr;

			/* XXX: embedded link local addr check */
			if (IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&dst6->sin6_addr)) {
				u_int16_t	index;

				index = dst6->sin6_addr.s6_addr16[1];
				if (index != 0) {
					dst6->sin6_addr.s6_addr16[1] = 0;
					if (dst6->sin6_scope_id == 0) {
						dst6->sin6_scope_id = ntohs(index);
					}
				}
			}

			appendAddress(newDict, kSCPropNetIPv6DestAddresses, dst6);
		}

		CFDictionarySetValue(newIFs, key, newDict);
		CFRelease(newDict);
		CFRelease(key);
	}

	/* if the last address[es] were removed from the target interface */
	if (if_name && !interfaceFound) {
		interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
		key       = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
									  kSCDynamicStoreDomainState,
									  interface,
									  kSCEntNetIPv6);
		CFRelease(interface);

		newDict = copyIF(key, oldIFs, newIFs);

		CFDictionarySetValue(newIFs, key, newDict);
		CFRelease(newDict);
		CFRelease(key);
	}

	CFDictionaryApplyFunction(newIFs, updateStore, oldIFs);

    error :

	if (ifap_temp)	freeifaddrs(ifap_temp);
	if (sock != -1)	close(sock);
	CFRelease(oldIFs);
	CFRelease(newIFs);

	return;
}
Beispiel #27
0
char *
addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
	  char *netid)
{
	struct ifaddrs *ifap, *ifp, *bestif;
#ifdef INET6
	struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6;
	struct sockaddr_in6 *newsin6;
#endif
	struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin;
	struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf;
	struct sockaddr *serv_sa;
	struct sockaddr *clnt_sa;
	struct sockaddr_storage ss;
	struct netconfig *nconf;
	struct sockaddr *clnt = caller->buf;
	char *ret = NULL;

#ifdef INET6
	servsin6 = ifsin6 = newsin6 = NULL;	/* XXXGCC -Wuninitialized */
#endif
	servsin = newsin = NULL;		/* XXXGCC -Wuninitialized */

#ifdef RPCBIND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
		    clnt_uaddr, netid);
#endif
	nconf = getnetconfigent(netid);
	if (nconf == NULL)
		return NULL;

	/*
	 * Local merge, just return a duplicate.
	 */
	if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0)
		return strdup(clnt_uaddr);

	serv_nbp = uaddr2taddr(nconf, serv_uaddr);
	if (serv_nbp == NULL)
		return NULL;

	serv_sa = (struct sockaddr *)serv_nbp->buf;
	if (clnt_uaddr != NULL) {
		clnt_nbp = uaddr2taddr(nconf, clnt_uaddr);
		if (clnt_nbp == NULL) {
			free(serv_nbp);
			return NULL;
		}
		clnt_sa = (struct sockaddr *)clnt_nbp->buf;
		if (clnt_sa->sa_family == AF_LOCAL) {
			free(serv_nbp);
			free(clnt_nbp);
			free(clnt_sa);
			return strdup(serv_uaddr);
		}
	} else {
		clnt_sa = (struct sockaddr *)
		    malloc(sizeof (struct sockaddr_storage));
		memcpy(clnt_sa, clnt, clnt->sa_len);
	}

	if (getifaddrs(&ifp) < 0) {
		free(serv_nbp);
		free(clnt_sa);
		if (clnt_nbp != NULL)
			free(clnt_nbp);
		return 0;
	}

	/*
	 * Loop through all interfaces. For each interface, see if the
	 * network portion of its address is equal to that of the client.
	 * If so, we have found the interface that we want to use.
	 */
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != clnt->sa_family ||
		    !(ifap->ifa_flags & IFF_UP))
			continue;

		switch (clnt->sa_family) {
		case AF_INET:
			/*
			 * realsin: address that recvfrom gave us.
			 * ifsin: address of interface being examined.
			 * clntsin: address that client want us to contact
			 *           it on
			 * servsin: local address of RPC service.
			 * sinmask: netmask of this interface
			 * newsin: initially a copy of clntsin, eventually
			 *         the merged address
			 */
			servsin = (struct sockaddr_in *)serv_sa;
			clntsin = (struct sockaddr_in *)clnt_sa;
			sinmask = (struct sockaddr_in *)ifap->ifa_netmask;
			newsin = (struct sockaddr_in *)&ss;
			ifsin = (struct sockaddr_in *)ifap->ifa_addr;
			if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr,
			    &sinmask->sin_addr, sizeof (struct in_addr))) {
				goto found;
			}
			break;
#ifdef INET6
		case AF_INET6:
			/*
			 * realsin6: address that recvfrom gave us.
			 * ifsin6: address of interface being examined.
			 * clntsin6: address that client want us to contact
			 *           it on
			 * servsin6: local address of RPC service.
			 * sin6mask: netmask of this interface
			 * newsin6: initially a copy of clntsin, eventually
			 *          the merged address
			 *
			 * For v6 link local addresses, if the client contacted
			 * us via a link-local address, and wants us to reply
			 * to one, use the scope id to see which one.
			 */
			realsin6 = (struct sockaddr_in6 *)clnt;
			ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
			in6_fillscopeid(ifsin6);
			clntsin6 = (struct sockaddr_in6 *)clnt_sa;
			servsin6 = (struct sockaddr_in6 *)serv_sa;
			sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
			newsin6 = (struct sockaddr_in6 *)&ss;
			if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) &&
			    IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) &&
			    IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) {
				if (ifsin6->sin6_scope_id !=
				    realsin6->sin6_scope_id)
					continue;
				goto found;
			}
			if (!bitmaskcmp(&ifsin6->sin6_addr,
			    &clntsin6->sin6_addr, &sin6mask->sin6_addr,
			    sizeof (struct in6_addr)))
				goto found;
			break;
#endif
		default:
			goto freeit;
		}
	}
	/*
	 * Didn't find anything. Get the first possibly useful interface,
	 * preferring "normal" interfaces to point-to-point and loopback
	 * ones.
	 */
	bestif = NULL;
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != clnt->sa_family ||
		    !(ifap->ifa_flags & IFF_UP))
			continue;
		if (!(ifap->ifa_flags & IFF_LOOPBACK) &&
		    !(ifap->ifa_flags & IFF_POINTOPOINT)) {
			bestif = ifap;
			break;
		}
		if (bestif == NULL)
			bestif = ifap;
		else if ((bestif->ifa_flags & IFF_LOOPBACK) &&
		    !(ifap->ifa_flags & IFF_LOOPBACK))
			bestif = ifap;
	}
	ifap = bestif;
found:
	switch (clnt->sa_family) {
	case AF_INET:
		memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len);
		newsin->sin_port = servsin->sin_port;
		tbuf.len = clnt_sa->sa_len;
		tbuf.maxlen = sizeof (struct sockaddr_storage);
		tbuf.buf = newsin;
		break;				
#ifdef INET6
	case AF_INET6:
		assert(newsin6);
		memcpy(newsin6, ifsin6, clnt_sa->sa_len);
		newsin6->sin6_port = servsin6->sin6_port;
		tbuf.maxlen = sizeof (struct sockaddr_storage);
		tbuf.len = clnt_sa->sa_len;
		tbuf.buf = newsin6;
		break;
#endif
	default:
		goto freeit;
	}
	if (ifap != NULL)
		ret = taddr2uaddr(nconf, &tbuf);
freeit:
	freenetconfigent(nconf);
	free(serv_sa);
	free(serv_nbp);
	if (clnt_sa != NULL)
		free(clnt_sa);
	if (clnt_nbp != NULL)
		free(clnt_nbp);
	freeifaddrs(ifp);

#ifdef RPCBIND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge: returning %s\n", ret);
#endif
	return ret;
}
Beispiel #28
0
/* Builds a list of interfaces that correspond to active verbs devices */
static int fi_ibv_getifaddrs(struct dlist_entry *verbs_devs)
{
	struct ifaddrs *ifaddr, *ifa;
	char name[INET6_ADDRSTRLEN];
	struct rdma_addrinfo *rai;
	struct rdma_cm_id *id;
	const char *ret_ptr;
	int ret, num_verbs_ifs = 0;

	char *iface = NULL;
	size_t iface_len = 0;
	int exact_match = 0;

	ret = getifaddrs(&ifaddr);
	if (ret) {
	       VERBS_WARN(FI_LOG_FABRIC,
			  "Unable to get interface addresses\n");
		return ret;
	}

	/* select best iface name based on user's input */
	if (fi_param_get_str(&fi_ibv_prov, "iface", &iface) == FI_SUCCESS) {
		iface_len = strlen(iface);
		if (iface_len > IFNAMSIZ) {
			VERBS_INFO(FI_LOG_EP_CTRL,
				   "Too long iface name: %s, max: %d\n",
				   iface, IFNAMSIZ);
			return -FI_EINVAL;
		}
		for (ifa = ifaddr; ifa && !exact_match; ifa = ifa->ifa_next)
			exact_match = !strcmp(ifa->ifa_name, iface);
	}

	for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
		if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_UP) ||
				!strcmp(ifa->ifa_name, "lo"))
			continue;

		if(iface) {
			if(exact_match) {
				if(strcmp(ifa->ifa_name, iface))
					continue;
			} else {
				if(strncmp(ifa->ifa_name, iface, iface_len))
					continue;
			}
		}

		switch (ifa->ifa_addr->sa_family) {
		case AF_INET:
			ret_ptr = inet_ntop(AF_INET, &ofi_sin_addr(ifa->ifa_addr),
				name, INET6_ADDRSTRLEN);
			break;
		case AF_INET6:
			ret_ptr = inet_ntop(AF_INET6, &ofi_sin6_addr(ifa->ifa_addr),
				name, INET6_ADDRSTRLEN);
			break;
		default:
			continue;
		}
		if (!ret_ptr) {
			VERBS_WARN(FI_LOG_FABRIC,
				   "inet_ntop failed: %s(%d)\n",
				   strerror(errno), errno);
			goto err1;
		}

		ret = fi_ibv_create_ep(name, NULL, FI_NUMERICHOST | FI_SOURCE,
				NULL, &rai, &id);
		if (ret)
			continue;

		ret = fi_ibv_add_rai(verbs_devs, id, rai);
		if (ret)
			goto err2;

		VERBS_DBG(FI_LOG_FABRIC, "Found active interface for verbs device: "
			  "%s with address: %s\n",
			  ibv_get_device_name(id->verbs->device), name);

		rdma_destroy_ep(id);

		num_verbs_ifs++;
	}
	freeifaddrs(ifaddr);
	return num_verbs_ifs ? 0 : -FI_ENODATA;
err2:
	rdma_destroy_ep(id);
err1:
	fi_ibv_verbs_devs_free(verbs_devs);
	freeifaddrs(ifaddr);
	return ret;
}
Beispiel #29
0
/*
 * Gets a unique id for this process instance
 * Uses the mac address right now
 * And combine with the unique port number, which is why it needs to be passed in
 * Needs to be a little more subtle:
 * Should stash the mac address or something, in case you have to replace a card.
 *
 * parameters-
 * Input params:
 * port - used in setting Node ID
 * hb_mode - Controls whether hb_addrp is filled out with the IP address.
 * config_interface_names - Pointer to an array of interface names if specified in the config file,
 *			    NULL if absent.
 *
 * Output params:
 * id - Node ID (address and port)
 * node_ipp - Pointer wherein the IP address is stored
 * hb_addrp - Pointer to a string wherein the heartbeat address is stored, as specified by hb_mode
 */
int
cf_nodeid_get(unsigned short port, cf_node *id, char **node_ipp, hb_mode_enum hb_mode, char **hb_addrp, const char **config_interface_names)
{
	// The default interface names can be overridden by the interface name passed into config
	const char **interface_names = default_interface_names;
	bool default_config = true;
	int jlimit = 11;

	if (config_interface_names) {
		interface_names = config_interface_names;
		default_config = false;
		jlimit = 1;
	}

	int fdesc = socket(AF_INET, SOCK_STREAM, 0);

	if (fdesc <= 0) {
		cf_warning(CF_MISC, "can't open socket: %d %s", errno, cf_strerror(errno));
		return(-1);
	}

	struct ifreq req;
	bool done = false;

	for (int i = 0; interface_names[i]; i++) {
		for (int j = 0; j < jlimit; j++) {
			if (default_config) {
				sprintf(req.ifr_name, interface_names[i], j);
			}
			else {
				sprintf(req.ifr_name, interface_names[i]);
			}

			if (0 == ioctl(fdesc, SIOCGIFHWADDR, &req)) {
				if (cf_ipaddr_get(fdesc, req.ifr_name, node_ipp) == 0) {
					done = true;
					break;
				}
			}

			cf_debug(CF_MISC, "can't get physical address of interface %s: %d %s", req.ifr_name, errno, cf_strerror(errno));
		}

		if (done) {
			break;
		}
	}

	if (! done) {
		if (default_config) {
			struct ifaddrs *interface_addrs = NULL;

			if (getifaddrs(&interface_addrs) == -1) {
				cf_warning(CF_MISC, "getifaddrs failed %d %s", errno, cf_strerror(errno));
				return -1;
			}

			if (! interface_addrs) {
				cf_warning(CF_MISC, "getifaddrs returned NULL");
				return -1;
			}

			struct ifaddrs *ifa;

			for (ifa = interface_addrs; ifa != NULL; ifa = ifa->ifa_next) {
				if (! ifa->ifa_data) {
					continue;
				}

				if (! is_biosdevname(ifa->ifa_name)) {
					continue;
				}

				if (check_mac_and_get_ipaddr(fdesc, ifa->ifa_name, &req, node_ipp)) {
					done = true;
					break;
				}
			}

			for (ifa = interface_addrs; ifa != NULL && (! done); ifa = ifa->ifa_next) {
				if (! ifa->ifa_data) {
					continue;
				}

				if (check_mac_and_get_ipaddr(fdesc, ifa->ifa_name, &req, node_ipp)) {
					done = true;
					break;
				}
			}

			freeifaddrs(interface_addrs);
		}
		else {
			cf_warning(CF_MISC, "can't get physical address of interface name specified in config file, tried %s. fatal: %d %s", interface_names[0], errno, cf_strerror(errno));
			close(fdesc);
			return(-1);
		}
	}

	close(fdesc);

	if (! done) {
		cf_warning(CF_MISC, "Tried eth,bond,wlan,em and list of all available interfaces on device. Failed to retrieve physical address with errno %d %s\n", errno, cf_strerror(errno));
		return(-1);
	}

	/*
	 * Set the hb_addr to be the same as the ip address if the mode is mesh and the hb_addr parameter is empty
	 * Configuration file overrides the automatic node ip detection
	 *	- this gives us a work around in case the node ip is somehow detected wrong in production
	 */
	if (hb_mode == AS_HB_MODE_MESH)	{
		if (*hb_addrp == NULL) {
			*hb_addrp = cf_strdup(*node_ipp);
		}
		cf_info(CF_MISC, "Heartbeat address for mesh: %s", *hb_addrp);
	}

	*id = 0;
	memcpy(id, req.ifr_hwaddr.sa_data, 6);
	memcpy(((byte *)id) + 6, &port, 2);

	cf_debug(CF_MISC, "port %d id %"PRIx64, port, *id);

	return(0);
}
Beispiel #30
0
int interface_add(const char *name)
{
	struct interface *v4 = NULL, *v6 = NULL, *unicast;
	struct ifaddrs *ifap, *ifa;

	getifaddrs(&ifap);

	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		if (strcmp(ifa->ifa_name, name))
			continue;
		if (ifa->ifa_addr->sa_family == AF_INET && !v4) {
			struct sockaddr_in *sa;

			if (cfg_proto && (cfg_proto != 4))
				continue;

			unicast = _interface_add(name, 0, 0);
			if (!unicast)
				continue;
			v4 = _interface_add(name, 1, 0);
			if (!v4)
				continue;

			sa = (struct sockaddr_in *) ifa->ifa_addr;
			memcpy(&v4->v4_addr, &sa->sin_addr, sizeof(v4->v4_addr));
			memcpy(&unicast->v4_addr, &sa->sin_addr, sizeof(unicast->v4_addr));

			inet_ntop(AF_INET, &sa->sin_addr, v4->v4_addrs, sizeof(v4->v4_addrs));
			inet_ntop(AF_INET, &sa->sin_addr, unicast->v4_addrs, sizeof(unicast->v4_addrs));

			sa = (struct sockaddr_in *) ifa->ifa_netmask;
			memcpy(&unicast->v4_netmask, &sa->sin_addr, sizeof(unicast->v4_netmask));
			memcpy(&v4->v4_netmask, &sa->sin_addr, sizeof(v4->v4_netmask));

			v4->peer = unicast;
			unicast->peer = v4;
		}

		if (ifa->ifa_addr->sa_family == AF_INET6 && !v6) {
			uint8_t ll_prefix[] = {0xfe, 0x80 };
			struct sockaddr_in6 *sa6;

			if (cfg_proto && (cfg_proto != 6))
				continue;

			sa6 = (struct sockaddr_in6 *) ifa->ifa_addr;
			if (memcmp(&sa6->sin6_addr, &ll_prefix, 2))
				continue;

			unicast = _interface_add(name, 0, 1);
			if (!unicast)
				continue;
			v6 = _interface_add(name, 1, 1);
			if (!v6)
				continue;

			memcpy(&v6->v6_addr, &sa6->sin6_addr, sizeof(v6->v6_addr));
			memcpy(&unicast->v6_addr, &sa6->sin6_addr, sizeof(unicast->v6_addr));

			inet_ntop(AF_INET6, &sa6->sin6_addr, v6->v6_addrs, sizeof(v6->v6_addrs));
			inet_ntop(AF_INET6, &sa6->sin6_addr, unicast->v6_addrs, sizeof(unicast->v6_addrs));

			sa6 = (struct sockaddr_in6 *) ifa->ifa_netmask;
			memcpy(&v6->v6_netmask, &sa6->sin6_addr, sizeof(v6->v6_netmask));
			memcpy(&unicast->v6_netmask, &sa6->sin6_addr, sizeof(unicast->v6_netmask));

			v6->peer = unicast;
			unicast->peer = v6;
		}
	}

	freeifaddrs(ifap);

	return !v4 && !v6;
}