static int bsd_get_mac(const char ifname[], uint8_t eth_addr[])
{
    struct ifreq *ifrp;
    struct ifconf ifc;
    char buffer[720];
    int socketfd,error,len,space=0;
    ifc.ifc_len=sizeof(buffer);
    len=ifc.ifc_len;
    ifc.ifc_buf=buffer;

    socketfd=socket(AF_INET,SOCK_DGRAM,0);

    if((error=ioctl(socketfd,SIOCGIFCONF,&ifc))<0)
    {
        perror("ioctl faild");
        exit(1);
    }
    if(ifc.ifc_len<=len)
    {
        ifrp=ifc.ifc_req;
        do
        {
            struct sockaddr *sa=&ifrp->ifr_addr;

            if(((struct sockaddr_dl *)sa)->sdl_type==IFT_ETHER) {
                if (strcmp(ifname, ifrp->ifr_name) == 0){
                    memcpy (eth_addr, LLADDR((struct sockaddr_dl *)&ifrp->ifr_addr), 6);
                    return 0;
                }
            }
            ifrp=(struct ifreq*)(sa->sa_len+(caddr_t)&ifrp->ifr_addr);
            space+=(int)sa->sa_len+sizeof(ifrp->ifr_name);
        }
        while(space<ifc.ifc_len);
    }
    return 1;
}
/*
 * Perform common duties while attaching to interface list
 */
void
iso88025_ifattach(struct ifnet *ifp, const u_int8_t *lla, int bpf)
{
    struct ifaddr *ifa;
    struct sockaddr_dl *sdl;

    ifa = NULL;

    ifp->if_type = IFT_ISO88025;
    ifp->if_addrlen = ISO88025_ADDR_LEN;
    ifp->if_hdrlen = ISO88025_HDR_LEN;

    if_attach(ifp);	/* Must be called before additional assignments */

    ifp->if_output = iso88025_output;
    ifp->if_input = iso88025_input;
    ifp->if_resolvemulti = iso88025_resolvemulti;
    ifp->if_broadcastaddr = iso88025_broadcastaddr;

    if (ifp->if_baudrate == 0)
        ifp->if_baudrate = TR_16MBPS; /* 16Mbit should be a safe default */
    if (ifp->if_mtu == 0)
        ifp->if_mtu = ISO88025_DEFAULT_MTU;

    ifa = ifp->if_addr;
    KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));

    sdl = (struct sockaddr_dl *)ifa->ifa_addr;
    sdl->sdl_type = IFT_ISO88025;
    sdl->sdl_alen = ifp->if_addrlen;
    bcopy(lla, LLADDR(sdl), ifp->if_addrlen);

    if (bpf)
        bpfattach(ifp, DLT_IEEE802, ISO88025_HDR_LEN);

    return;
}
Example #3
0
const char *
log_sockaddr(struct sockaddr *sa)
{
	static char	buf[NI_MAXHOST];

	if (sa == NULL)
		return "(none)";

	if (sa->sa_family == AF_UNIX) {
		if (strlen(((struct sockaddr_un *)sa)->sun_path))
			return ((struct sockaddr_un *)sa)->sun_path;
		else
			return "(local user)";

	} else if (sa->sa_family == AF_LINK) {
		return ether_ntoa((struct ether_addr *)LLADDR((struct sockaddr_dl *)sa));
	}

	if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0,
	    NI_NUMERICHOST))
		return "(unknown)";
	else
		return buf;
}
Example #4
0
bool getGatewayMacAddress(quint32 ipv4Host, QByteArray& mac)
{
	std::vector<char> data(512 * 1024);

	int mib[6];
	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = AF_INET;
	mib[4] = NET_RT_FLAGS;
	mib[5] = RTF_LLINFO;

	size_t cb = data.size();
	if (sysctl(mib, 6, &data[0], &cb, NULL, 0)  == 0) {
		const char *p = &data[0];
		const char *pe = p + cb;
		const rt_msghdr *rtm;
		for (; p != pe; p += rtm->rtm_msglen) {
	        rtm = reinterpret_cast<const rt_msghdr*>(p);

			const sockaddr_inarp *sin = reinterpret_cast<const sockaddr_inarp*>(rtm + 1);
			const sockaddr_dl *sdl = reinterpret_cast<const sockaddr_dl*>(sin + 1);

			if (sdl->sdl_alen) {
				if (ntohl(sin->sin_addr.s_addr) == ipv4Host) {
					u_char *cp = (u_char*)LLADDR(sdl);
					for (int i = 0; i < 6; i++) {
						mac.push_back(cp[i]);
					}
					return true;
				}
			}
		}
	}
	return false;
}
Example #5
0
/*
 * sifproxyarp - Make a proxy ARP entry for the peer.
 */
int
sifproxyarp(
    int unit,
    uint32_t hisaddr)
{
    struct arpreq arpreq;
    struct {
	struct sockaddr_dl	sdl;
	char			space[128];
    } dls;

    BZERO(&arpreq, sizeof(arpreq));

    /*
     * Get the hardware address of an interface on the same subnet
     * as our local address.
     */
    if (!get_ether_addr(hisaddr, &dls.sdl)) {
	error("Cannot determine ethernet address for proxy ARP");
	return 0;
    }

    arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
    arpreq.arp_ha.sa_family = AF_UNSPEC;
    BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);
    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
    arpreq.arp_flags = ATF_PERM | ATF_PUBL;
    if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {
	error("Couldn't add proxy arp entry: %m");
	return 0;
    }

    proxy_arp_addr = hisaddr;
    return 1;
}
Example #6
0
void
lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
{
	char *addr;

	ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */

	switch (sdl->sdl_type) {
	case IFT_ETHER:
#ifdef IFT_IEEE80211
	case IFT_IEEE80211:
#endif
		ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3;
		addr = (char *)(ndopt + 1);
		memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN);
		break;
	default:
		warnmsg(LOG_ERR, __func__,
		    "unsupported link type(%d)", sdl->sdl_type);
		exit(1);
	}

	return;
}
Example #7
0
/*
 * Perform common duties while attaching to interface list.
 */
void
atm_ifattach(struct ifnet *ifp)
{
	struct ifaddr *ifa;
	struct sockaddr_dl *sdl;
	struct ifatm *ifatm = ifp->if_l2com;

	ifp->if_addrlen = 0;
	ifp->if_hdrlen = 0;
	if_attach(ifp);
	ifp->if_mtu = ATMMTU;
	ifp->if_output = atm_output;
#if 0
	ifp->if_input = atm_input;
#endif
	ifp->if_snd.ifq_maxlen = 50;	/* dummy */

	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
		if (ifa->ifa_addr->sa_family == AF_LINK) {
			sdl = (struct sockaddr_dl *)ifa->ifa_addr;
			sdl->sdl_type = IFT_ATM;
			sdl->sdl_alen = ifp->if_addrlen;
#ifdef notyet /* if using ATMARP, store hardware address using the next line */
			bcopy(ifp->hw_addr, LLADDR(sdl), ifp->if_addrlen);
#endif
			break;
		}

	ifp->if_linkmib = &ifatm->mib;
	ifp->if_linkmiblen = sizeof(ifatm->mib);

	if(ng_atm_attach_p)
		(*ng_atm_attach_p)(ifp);
	if (atm_harp_attach_p)
		(*atm_harp_attach_p)(ifp);
}
QT_BEGIN_INCLUDE_NAMESPACE
#  include <net/if_dl.h>
QT_END_INCLUDE_NAMESPACE

static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
{
    QList<QNetworkInterfacePrivate *> interfaces;

    // on NetBSD we use AF_LINK and sockaddr_dl
    // scan the list for that family
    for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next)
        if (ptr->ifa_addr && ptr->ifa_addr->sa_family == AF_LINK) {
            QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
            interfaces << iface;

            sockaddr_dl *sdl = (sockaddr_dl *)ptr->ifa_addr;
            iface->index = sdl->sdl_index;
            iface->name = QString::fromLatin1(ptr->ifa_name);
            iface->flags = convertFlags(ptr->ifa_flags);
            iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl));
        }

    return interfaces;
}
Example #9
0
static uint64_t _system_hostid_lookup( struct ifaddrs* ifaddr )
{
	unsigned int j;
	union
	{
		uint64_t               id;
		unsigned char ALIGN(8) buffer[8];
	} hostid;

	if( ifaddr->ifa_addr && ( ifaddr->ifa_addr->sa_family == AF_LINK ) )
	{
		struct sockaddr_dl* addr_dl = (struct sockaddr_dl*)ifaddr->ifa_addr;
		
		FOUNDATION_ASSERT( addr_dl->sdl_alen == 6 );

		hostid.id = 0;
		for( j = 0; j < 6; ++j )
			hostid.buffer[5-j] = LLADDR(addr_dl)[j];
		
		return hostid.id;
	}
	
	return 0;
}
static int eth_get(const char *device, u8 ea[ETH_ALEN])
{
	struct if_msghdr *ifm;
	struct sockaddr_dl *sdl;
	u_char *p, *buf;
	size_t len;
	int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };

	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
		return -1;
	if ((buf = os_malloc(len)) == NULL)
		return -1;
	if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
		os_free(buf);
		return -1;
	}
	for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
		ifm = (struct if_msghdr *)p;
		sdl = (struct sockaddr_dl *)(ifm + 1);
		if (ifm->ifm_type != RTM_IFINFO ||
		    (ifm->ifm_addrs & RTA_IFP) == 0)
			continue;
		if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
		    os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
			continue;
		os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
		break;
	}
	os_free(buf);

	if (p >= buf + len) {
		errno = ESRCH;
		return -1;
	}
	return 0;
}
Example #11
0
/* Send router advertisement packet. */
static void
rtadv_send_packet (int sock, struct interface *ifp)
{
  struct msghdr msg;
  struct iovec iov;
  struct cmsghdr  *cmsgptr;
  struct in6_pktinfo *pkt;
  struct sockaddr_in6 addr;
#ifdef HAVE_STRUCT_SOCKADDR_DL
  struct sockaddr_dl *sdl;
#endif /* HAVE_STRUCT_SOCKADDR_DL */
  static void *adata = NULL;
  unsigned char buf[RTADV_MSG_SIZE];
  struct nd_router_advert *rtadv;
  int ret;
  int len = 0;
  struct zebra_if *zif;
  struct rtadv_prefix *rprefix;
  u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
  struct listnode *node;

  /*
   * Allocate control message bufffer.  This is dynamic because
   * CMSG_SPACE is not guaranteed not to call a function.  Note that
   * the size will be different on different architectures due to
   * differing alignment rules.
   */
  if (adata == NULL)
    {
      /* XXX Free on shutdown. */
      adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
	   
      if (adata == NULL)
	zlog_err("rtadv_send_packet: can't malloc control data\n");
    }

  /* Logging of packet. */
  if (IS_ZEBRA_DEBUG_PACKET)
    zlog_debug ("Router advertisement send to %s", ifp->name);

  /* Fill in sockaddr_in6. */
  memset (&addr, 0, sizeof (struct sockaddr_in6));
  addr.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  addr.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */
  addr.sin6_port = htons (IPPROTO_ICMPV6);
  memcpy (&addr.sin6_addr, all_nodes_addr, sizeof (struct in6_addr));

  /* Fetch interface information. */
  zif = ifp->info;

  /* Make router advertisement message. */
  rtadv = (struct nd_router_advert *) buf;

  rtadv->nd_ra_type = ND_ROUTER_ADVERT;
  rtadv->nd_ra_code = 0;
  rtadv->nd_ra_cksum = 0;

  rtadv->nd_ra_curhoplimit = 64;

  /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
  rtadv->nd_ra_flags_reserved =
    zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
  rtadv->nd_ra_flags_reserved <<= 3;

  if (zif->rtadv.AdvManagedFlag)
    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
  if (zif->rtadv.AdvOtherConfigFlag)
    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
  if (zif->rtadv.AdvHomeAgentFlag)
    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
  rtadv->nd_ra_router_lifetime = htons (zif->rtadv.AdvDefaultLifetime);
  rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
  rtadv->nd_ra_retransmit = htonl (0);

  len = sizeof (struct nd_router_advert);

  if (zif->rtadv.AdvHomeAgentFlag)
    {
      struct nd_opt_homeagent_info *ndopt_hai = 
	(struct nd_opt_homeagent_info *)(buf + len);
      ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
      ndopt_hai->nd_opt_hai_len = 1;
      ndopt_hai->nd_opt_hai_reserved = 0;
      ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
      ndopt_hai->nd_opt_hai_lifetime = htons(zif->rtadv.HomeAgentLifetime);
      len += sizeof(struct nd_opt_homeagent_info);
    }

  if (zif->rtadv.AdvIntervalOption)
    {
      struct nd_opt_adv_interval *ndopt_adv = 
	(struct nd_opt_adv_interval *)(buf + len);
      ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
      ndopt_adv->nd_opt_ai_len = 1;
      ndopt_adv->nd_opt_ai_reserved = 0;
      ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
      len += sizeof(struct nd_opt_adv_interval);
    }

  /* Fill in prefix. */
  for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
    {
      struct nd_opt_prefix_info *pinfo;

      pinfo = (struct nd_opt_prefix_info *) (buf + len);

      pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
      pinfo->nd_opt_pi_len = 4;
      pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;

      pinfo->nd_opt_pi_flags_reserved = 0;
      if (rprefix->AdvOnLinkFlag)
	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
      if (rprefix->AdvAutonomousFlag)
	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
      if (rprefix->AdvRouterAddressFlag)
	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;

      pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
      pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
      pinfo->nd_opt_pi_reserved2 = 0;

      memcpy (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.u.prefix6,
	      sizeof (struct in6_addr));

#ifdef DEBUG
      {
	u_char buf[INET6_ADDRSTRLEN];

	zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix, 
	           buf, INET6_ADDRSTRLEN));

      }
#endif /* DEBUG */

      len += sizeof (struct nd_opt_prefix_info);
    }

  /* Hardware address. */
#ifdef HAVE_STRUCT_SOCKADDR_DL
  sdl = &ifp->sdl;
  if (sdl != NULL && sdl->sdl_alen != 0)
    {
      buf[len++] = ND_OPT_SOURCE_LINKADDR;

      /* Option length should be rounded up to next octet if
         the link address does not end on an octet boundary. */
      buf[len++] = (sdl->sdl_alen + 9) >> 3;

      memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
      len += sdl->sdl_alen;

      /* Pad option to end on an octet boundary. */
      memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7);
      len += -(sdl->sdl_alen + 2) & 0x7;
    }
Example #12
0
int get_macaddr(const char *ifname, U8 *addr)
{
#if defined(__NBR_OSX__)
    kern_return_t	kernResult = KERN_SUCCESS;
    io_iterator_t	intfIterator;
    UInt8			MACAddress[kIOEthernetAddressSize];

    kernResult = FindEthernetInterfaces(&intfIterator);

    if (KERN_SUCCESS != kernResult) {
        //OSDEP_ERROUT(ERROR,SYSCALL,"FindEthernetInterfaces returned 0x%08x\n", kernResult);
        return NBR_ESYSCALL;
    }
    else {
        kernResult = GetMACAddress(intfIterator, addr, sizeof(MACAddress));

        if (KERN_SUCCESS != kernResult) {
            //OSDEP_ERROUT(ERROR,SYSCALL,"GetMACAddress returned 0x%08x\n", kernResult);
        }
		else {
			TRACE("This system's built-in MAC address is %02x:%02x:%02x:%02x:%02x:%02x.\n",
					addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
		}
    }

    (void) IOObjectRelease(intfIterator);	// Release the iterator.

    return kernResult == KERN_SUCCESS ? NBR_OK : NBR_ESYSCALL;
#elif defined(__NBR_IOS__)
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex(ifname)) == 0) {
        TRACE("Error: if_nametoindex error\n");
        return NBR_ESYSCALL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        TRACE("Error: sysctl, take 1\n");
        return NBR_ESYSCALL;
    }
    
    if ((buf = (char *)util::mem::alloc(len)) == NULL) {
        TRACE("Could not allocate memory. error!\n");
        return NBR_EMALLOC;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        TRACE("Error: sysctl, take 2");
        util::mem::free(buf);
        return NBR_ESYSCALL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);

    util::mem::copy(addr, ptr, 6);
    util::mem::free(buf);
	TRACE("MAC ADDRESS (%s): [%02X:%02X:%02X:%02X:%02X:%02X]\n", ifname,
          *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5));
    return NBR_OK;
#else
	int				soc, ret;
	struct ifreq	req;

	if ((soc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		TRACE("socket fail: ret=%d,errno=%d",soc,errno);
		ret = soc;
		goto error;
	}
	util::str::copy(req.ifr_name, ifname, sizeof(req.ifr_name));
	req.ifr_addr.sa_family = AF_INET;

	if ((ret = ioctl(soc, SIOCGIFHWADDR, &req)) < 0) {
		TRACE("ioctl fail: soc=%d,ret=%d,errno=%d",soc,ret,errno);
		goto error;
	}
	util::mem::copy(addr, &(req.ifr_addr.sa_data), 6);
	ret = 0;
	TRACE("MAC ADDRESS (%s): [%02X:%02X:%02X:%02X:%02X:%02X]\n", ifname,
		*addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5));
error:
	if (soc >= 0) {
		close(soc);
	}
	return ret;
#endif
}
Example #13
0
struct libnet_ether_addr *
libnet_get_hwaddr(libnet_t *l)
{
    int mib[6];
    size_t len;
    int8_t *buf, *next, *end;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    /* This implementation is not-reentrant. */
    static struct libnet_ether_addr ea;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    mib[5] = 0;

    if (l == NULL)
    { 
        return (NULL);
    } 

    if (l->device == NULL)
    {           
        if (libnet_select_device(l) == -1)
        {
            /* err msg set in libnet_select_device */ 
            return (NULL);
        }
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s",
                __func__, strerror(errno));
        return (NULL);
    }

    buf = (int8_t *)malloc(len);
    if (buf == NULL)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s",
                __func__, strerror(errno));
        return (NULL);
    }
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s",
                __func__, strerror(errno));
        free(buf);
        return (NULL);
    }
    end = buf + len;

    for (next = buf ; next < end ; next += ifm->ifm_msglen)
    {
        ifm = (struct if_msghdr *)next;
        if (ifm->ifm_version != RTM_VERSION)
            continue;
        if (ifm->ifm_type == RTM_IFINFO)
        {
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (sdl->sdl_type != IFT_ETHER
                && sdl->sdl_type != IFT_FASTETHER
                && sdl->sdl_type != IFT_FASTETHERFX
                && sdl->sdl_type != IFT_GIGABITETHERNET
                && sdl->sdl_type != IFT_L2VLAN)
                continue;
            if (strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0)
            {
                memcpy(ea.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
                break;
            }
        }
    }
    free(buf);
    if (next == end) {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                 "%s(): interface %s of known type not found.",
                 __func__, l->device);
        return NULL;
    }
    return (&ea);
}
char *
get_iface_mac(char *ifname)
{
#if defined(__linux__)
    int r, s;
    struct ifreq ifr;
    char *hwaddr, mac[13];
    
    strcpy(ifr.ifr_name, ifname);

    s = socket(PF_INET, SOCK_DGRAM, 0);
    if (-1 == s) {
       debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno));
       return NULL;
    }

    r = ioctl(s, SIOCGIFHWADDR, &ifr);
    if (r == -1) {
       debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno));
       close(s);
       return NULL;
    }

    hwaddr = ifr.ifr_hwaddr.sa_data;
    close(s);
    snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", 
       hwaddr[0] & 0xFF,
       hwaddr[1] & 0xFF,
       hwaddr[2] & 0xFF,
       hwaddr[3] & 0xFF,
       hwaddr[4] & 0xFF,
       hwaddr[5] & 0xFF
       );
       
    return safe_strdup(mac);
#elif defined(__NetBSD__)
	struct ifaddrs *ifa, *ifap;
	const char *hwaddr;
	char mac[13], *str = NULL;
	struct sockaddr_dl *sdl;

	if (getifaddrs(&ifap) == -1) {
		debug(LOG_ERR, "getifaddrs(): %s", strerror(errno));
		return NULL;
	}
	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
		if (strcmp(ifa->ifa_name, ifname) == 0 &&
		    ifa->ifa_addr->sa_family == AF_LINK)
			break;
	}
	if (ifa == NULL) {
		debug(LOG_ERR, "%s: no link-layer address assigned");
		goto out;
	}
	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
	hwaddr = LLADDR(sdl);
	snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X",
	    hwaddr[0] & 0xFF, hwaddr[1] & 0xFF,
	    hwaddr[2] & 0xFF, hwaddr[3] & 0xFF,
	    hwaddr[4] & 0xFF, hwaddr[5] & 0xFF);

	str = safe_strdup(mac);
out:
	freeifaddrs(ifap);
	return str;
#else
    return NULL;
#endif
}
Example #15
0
/*
 * Set an individual arp entry
 */
int
arptab_set(u_char *eaddr, u_int32_t host)
{
	struct sockaddr_inarp *sin = &sin_m;
	struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
	struct sockaddr_dl *sdl;
	struct timeval now;
	int rt;

	getsocket();
	pid = getpid();

	sdl_m = blank_sdl;
	sin_m = blank_sin;
	sin->sin_addr.s_addr = host;
	memcpy((u_char *)LLADDR(&sdl_m), (char *)eaddr, 6);
	sdl_m.sdl_alen = 6;
	expire_time = 0;
	doing_proxy = flags = export_only = 0;
	gettimeofday(&now, 0);
	expire_time = now.tv_sec + 20 * 60;

tryagain:
	if (rtmsg(RTM_GET) < 0) {
		syslog(LOG_ERR,"%s: %m", inet_ntoa(sin->sin_addr));
		close(s);
		s = -1;
		return (1);
	}
	sin = (struct sockaddr_inarp *)((char *)rtm + rtm->rtm_hdrlen);
	sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
	if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
		if (sdl->sdl_family == AF_LINK &&
		    (rtm->rtm_flags & RTF_LLINFO) &&
		    !(rtm->rtm_flags & RTF_GATEWAY))
			switch (sdl->sdl_type) {
			case IFT_ETHER:
			case IFT_FDDI:
			case IFT_ISO88023:
			case IFT_ISO88024:
			case IFT_ISO88025:
				goto overwrite;
			default:
				break;
		}
		if (doing_proxy == 0) {
			syslog(LOG_ERR, "arptab_set: can only proxy for %s",
			    inet_ntoa(sin->sin_addr));
			close(s);
			s = -1;
			return (1);
		}
		if (sin_m.sin_other & SIN_PROXY) {
			syslog(LOG_ERR,
			    "arptab_set: proxy entry exists for non 802 device");
			close(s);
			s = -1;
			return(1);
		}
		sin_m.sin_other = SIN_PROXY;
		export_only = 1;
		goto tryagain;
	}
overwrite:
	if (sdl->sdl_family != AF_LINK) {
		syslog(LOG_ERR,
		    "arptab_set: cannot intuit interface index and type for %s",
		    inet_ntoa(sin->sin_addr));
		close(s);
		s = -1;
		return (1);
	}
	sdl_m.sdl_type = sdl->sdl_type;
	sdl_m.sdl_index = sdl->sdl_index;
	rt = rtmsg(RTM_ADD);
	close(s);
	s = -1;
	return (rt);
}
Example #16
0
signed openchannel (struct channel * channel)

{

#if defined (__linux__)

	struct ifreq ifreq;
	struct sockaddr_ll sockaddr_ll =
	{
		PF_PACKET,
		0x0000,
		0x0000,
		ARPHRD_ETHER,
		PACKET_HOST,
		ETHER_ADDR_LEN,
		{
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00,
			0x00
		}
	};

/*
 *      raw packets require root privileges on linux; one does not have to be
 *      root when this program is installed setuid using 'chown root:root' and
 *      'chmod 4555';
 */

	if (geteuid ())
	{
		error (1, EPERM, ERROR_NOTROOT);
	}

	memset (&ifreq, 0, sizeof (ifreq));
	sockaddr_ll.sll_protocol = htons (channel->type);
	if ((channel->fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == -1)
	{
		error (1, errno, "%s", channel->ifname);
	}
	memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel->fd, SIOCGIFINDEX, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex;
	if (ioctl (channel->fd, SIOCGIFHWADDR, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr));
	if (bind (channel->fd, (struct sockaddr *) (&sockaddr_ll), sizeof (sockaddr_ll)) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (channel->host, sockaddr_ll.sll_addr, sizeof (channel->host));
	if (ioctl (channel->fd, SIOCGIFFLAGS, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->ifstate = ifreq.ifr_flags;
	_setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST));
	_clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC));
	if (ioctl (channel->fd, SIOCSIFFLAGS, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}

#else

	struct bpf_program bpf_program;
	static struct bpf_insn bpf_insn [] =
	{
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			12
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			18,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			10,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			1
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			8,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			2
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			6,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			3
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0
		},
		{
			BPF_LD + BPF_B + BPF_ABS,
			0,
			0,
			5
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			4,
			0,
			0
		},
		{
			BPF_LD + BPF_W + BPF_ABS,
			0,
			0,
			0
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			4,
			0xFFFFFFFF
		},
		{
			BPF_LD + BPF_H + BPF_ABS,
			0,
			0,
			4
		},
		{
			BPF_JMP + BPF_JEQ + BPF_K,
			0,
			2,
			0xFFFF
		},
		{
			BPF_LD + BPF_W + BPF_LEN,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_A,
			0,
			0,
			0
		},
		{
			BPF_RET + BPF_K,
			0,
			0,
			0
		}
	};

#if defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__)

	struct ifreq ifreq;
	struct timeval timeval;
	struct bpf * bpf;
	char filename [sizeof (CHANNEL_BPFDEVICE) + 1];
	unsigned count;
	unsigned state;
	int stat_errno = 0;
	int open_errno = 0;
	for (count = 0; count < 100; count++)
	{
		struct stat st;
		snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count);
		if (stat(filename, &st) == -1)
		{
			stat_errno = errno;
			continue;
		}
		if ((channel->fd = open (filename, O_RDWR)) != -1)
		{
			break;
		}
		else
		{
			open_errno = errno;
		}
	}
	if (channel->fd == -1)
	{
		if (open_errno)
		{
			error (1, open_errno, "Could not open bpf device");
		}
		else
		{
			error (1, stat_errno, "No bpf device found");
		}
	}
	memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
	if (ioctl (channel->fd, BIOCSETIF, &ifreq) == -1)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	channel->bpf = bpf = malloc (sizeof (* bpf));
	if (ioctl (channel->fd, BIOCGBLEN, &bpf->bpf_length) == -1)
	{
		error (1, errno, "Can't determine buffer length: %s", ifreq.ifr_name);
	}
	bpf->bpf_bp = bpf->bpf_buffer = malloc (bpf->bpf_length);
	if (bpf->bpf_buffer == NULL)
	{
		error (1, errno, "Can't allocate receive buffer");
	}

#if defined (__APPLE__) || defined (__NetBSD__)

	state = 0;
	if (ioctl (channel->fd, BIOCSSEESENT, &state) == -1)
	{
		error (1, errno, "Can't hide outgoing frames: %s", ifreq.ifr_name);
	}

#elif defined (__OpenBSD__)

	state = BPF_DIRECTION_OUT;
	if (ioctl (channel->fd, BIOCSDIRFILT, &state) == -1)
	{
		error (0, errno, "Can't hide outgoing frames");
	}

#else
#error "Abandon all hope"
#endif

	if (channel->capture > 1000)
	{
		timeval.tv_sec = channel->capture / 1000;
		timeval.tv_usec = 0;
	}
	else
	{

#if defined (__MAC_10_6)

/*
 *	accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read
 *	operations to block indefinitely if no frames are waiting because tv_usec gets
 *      clobbered;
 */

		timeval.tv_sec = 1;
		timeval.tv_usec = 0;

#else

		timeval.tv_sec = 0;
		timeval.tv_usec = channel->capture * 1000;

#endif

	}
	if (ioctl (channel->fd, BIOCSRTIMEOUT, &timeval) == -1)
	{
		error (1, errno, "Can't set channel timeout: %s", ifreq.ifr_name);
	}
	state = 1;
	if (ioctl (channel->fd, BIOCIMMEDIATE, &state) == -1)
	{
		error (1, errno, "Can't set immediate mode: %s", ifreq.ifr_name);
	}

#if 1

	state = 1;
	if (ioctl (channel->fd, BIOCSHDRCMPLT, &state) == -1)
	{
		error (1, errno, "Can't set header complete mode: %s", ifreq.ifr_name);
	}

#endif

#if 1

	gethwaddr (channel->host, channel->ifname);

#else

	if (ioctl (channel->fd, SIOCGIFADDR, &ifreq) > 0)
	{
		error (1, errno, "%s", ifreq.ifr_name);
	}
	memcpy (channel->host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel->host));

#endif

	bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel->type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel->type;
	}
	bpf_insn [3].k = channel->host [0];
	bpf_insn [5].k = channel->host [1];
	bpf_insn [7].k = channel->host [2];
	bpf_insn [9].k = channel->host [3];
	bpf_insn [11].k = channel->host [4];
	bpf_insn [13].k = channel->host [5];
	if (ioctl (channel->fd, BIOCSETF, &bpf_program) == -1)
	{
		error (1, errno, "Can't store filter: %s", channel->ifname);
	}

#elif defined (WINPCAP) || defined (LIBPCAP)

	channel->ifname = getifname (channel->ifindex);
	gethwaddr (channel->host, channel->ifname);
	channel->socket = pcap_open_live (channel->ifname, 65536, 0, channel->capture, channel->errbuf);
	snprintf ((char *)(channel->ifname), strlen (channel->ifname), "nic%d", channel->ifindex);
	if (!channel->socket)
	{
		error (1, errno, "Can't open interface: %s", channel->ifname);
	}
	bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn);
	bpf_program.bf_insns = bpf_insn;
	if (channel->type == ETH_P_802_2)
	{
		bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
		bpf_insn [1].jt = 18;
		bpf_insn [1].jf = 0;
		bpf_insn [1].k = ETHERMTU;
	}
	else
	{
		bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
		bpf_insn [1].jt = 0;
		bpf_insn [1].jf = 18;
		bpf_insn [1].k = channel->type;
	}
	bpf_insn [3].k = channel->host [0];
	bpf_insn [5].k = channel->host [1];
	bpf_insn [7].k = channel->host [2];
	bpf_insn [9].k = channel->host [3];
	bpf_insn [11].k = channel->host [4];
	bpf_insn [13].k = channel->host [5];
	if (pcap_setfilter (channel->socket, &bpf_program) < 0)
	{
		error (1, errno, "Can't store filter: %s", channel->ifname);
	}
	if (pcap_setmintocopy (channel->socket, ETHER_MIN_LEN) < 0)
	{
		error (1, errno, "Can't set pcap mintocopy: %s", channel->ifname);
	}

#else
#error "Unknown Environment"
#endif
#endif

	return (0);
}
Example #17
0
/*
 * Set an individual neighbor cache entry
 */
int
set(int argc, char **argv)
{
	struct sockaddr_in6 *sin = &sin_m;
	struct sockaddr_dl *sdl;
	struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
	struct addrinfo hints, *res;
	int gai_error;
	u_char *ea;
	char *host = argv[0], *eaddr = argv[1];

	getsocket();
	argc -= 2;
	argv += 2;
	sdl_m = blank_sdl;
	sin_m = blank_sin;

	bzero(&hints, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai_error = getaddrinfo(host, NULL, &hints, &res);
	if (gai_error) {
		fprintf(stderr, "ndp: %s: %s\n", host,
			gai_strerror(gai_error));
		return 1;
	}
	sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
#ifdef __KAME__
	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
		*(u_int16_t *)&sin->sin6_addr.s6_addr[2] =
			htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id);
	}
#endif
	ea = (u_char *)LLADDR(&sdl_m);
	if (ndp_ether_aton(eaddr, ea) == 0)
		sdl_m.sdl_alen = 6;
	flags = 0;
	expire_time = 0;
	while (argc-- > 0) {
		if (strncmp(argv[0], "temp", 4) == 0) {
			struct timespec sp;

			clock_gettime(CLOCK_MONOTONIC, &sp);
			expire_time = sp.tv_sec + 20 * 60;
		} else if (strncmp(argv[0], "proxy", 5) == 0)
			flags |= RTF_ANNOUNCE;
		argv++;
	}
	if (rtmsg(RTM_GET) < 0) {
		perror(host);
		return (1);
	}
	sin = (struct sockaddr_in6 *)(rtm + 1);
	sdl = (struct sockaddr_dl *)(RT_ROUNDUP(sin->sin6_len) + (char *)sin);
	if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) {
		if (sdl->sdl_family == AF_LINK &&
		    (rtm->rtm_flags & RTF_LLINFO) &&
		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
		case IFT_ISO88024: case IFT_ISO88025:
			goto overwrite;
		}
		/*
		 * IPv4 arp command retries with sin_other = SIN_PROXY here.
		 */
		fprintf(stderr, "set: cannot configure a new entry\n");
		return 1;
	}

overwrite:
	if (sdl->sdl_family != AF_LINK) {
		printf("cannot intuit interface index and type for %s\n", host);
		return (1);
	}
	sdl_m.sdl_type = sdl->sdl_type;
	sdl_m.sdl_index = sdl->sdl_index;
	return (rtmsg(RTM_ADD));
}
Example #18
0
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
 PDWORD type)
{
  DWORD ret;
  struct if_msghdr *ifm;
  struct sockaddr_dl *sdl;
  u_char *p, *buf;
  size_t mibLen;
  int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
  int addrLen;
  BOOL found = FALSE;

  if (!name || !len || !addr || !type)
    return ERROR_INVALID_PARAMETER;

  if (sysctl(mib, 6, NULL, &mibLen, NULL, 0) < 0)
    return ERROR_NO_MORE_FILES;

  buf = HeapAlloc(GetProcessHeap(), 0, mibLen);
  if (!buf)
    return ERROR_NOT_ENOUGH_MEMORY;

  if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) {
    HeapFree(GetProcessHeap(), 0, buf);
    return ERROR_NO_MORE_FILES;
  }

  ret = ERROR_INVALID_DATA;
  for (p = buf; !found && p < buf + mibLen; p += ifm->ifm_msglen) {
    ifm = (struct if_msghdr *)p;
    sdl = (struct sockaddr_dl *)(ifm + 1);

    if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0)
      continue;

    if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
     memcmp(sdl->sdl_data, name, max(sdl->sdl_nlen, strlen(name))) != 0)
      continue;

    found = TRUE;
    addrLen = min(MAX_INTERFACE_PHYSADDR, sdl->sdl_alen);
    if (addrLen > *len) {
      ret = ERROR_INSUFFICIENT_BUFFER;
      *len = addrLen;
    }
    else {
      if (addrLen > 0)
        memcpy(addr, LLADDR(sdl), addrLen);
      /* zero out remaining bytes for broken implementations */
      memset(addr + addrLen, 0, *len - addrLen);
      *len = addrLen;
#if defined(HAVE_NET_IF_TYPES_H)
      switch (sdl->sdl_type)
      {
        case IFT_ETHER:
          *type = MIB_IF_TYPE_ETHERNET;
          break;
        case IFT_FDDI:
          *type = MIB_IF_TYPE_FDDI;
          break;
        case IFT_ISO88024: /* Token Bus */
          *type = MIB_IF_TYPE_TOKENRING;
          break;
        case IFT_ISO88025: /* Token Ring */
          *type = MIB_IF_TYPE_TOKENRING;
          break;
        case IFT_PPP:
          *type = MIB_IF_TYPE_PPP;
          break;
        case IFT_SLIP:
          *type = MIB_IF_TYPE_SLIP;
          break;
        case IFT_LOOP:
          *type = MIB_IF_TYPE_LOOPBACK;
          break;
        default:
          *type = MIB_IF_TYPE_OTHER;
      }
#else
      /* default if we don't know */
      *type = MIB_IF_TYPE_ETHERNET;
#endif
      ret = NO_ERROR;
    }
  }
  HeapFree(GetProcessHeap(), 0, buf);
  return ret;
}
Example #19
0
/*
 * Set an individual neighbor cache entry
 */
static int
set(int argc, char **argv)
{
	register struct sockaddr_in6 *sin = &sin_m;
	register struct sockaddr_dl *sdl;
	register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
	struct addrinfo hints, *res;
	int gai_error;
	u_char *ea;
	char *host = argv[0], *eaddr = argv[1];

	getsocket();
	argc -= 2;
	argv += 2;
	sdl_m = blank_sdl;
	sin_m = blank_sin;

	bzero(&hints, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai_error = getaddrinfo(host, NULL, &hints, &res);
	if (gai_error) {
		fprintf(stderr, "ndp: %s: %s\n", host,
			gai_strerror(gai_error));
		return 1;
	}
	sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
	sin->sin6_scope_id =
	    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
	ea = (u_char *)LLADDR(&sdl_m);
	if (ndp_ether_aton(eaddr, ea) == 0)
		sdl_m.sdl_alen = 6;
	flags = expire_time = 0;
	while (argc-- > 0) {
		if (strncmp(argv[0], "temp", 4) == 0) {
			struct timeval now;

			gettimeofday(&now, 0);
			expire_time = now.tv_sec + 20 * 60;
		} else if (strncmp(argv[0], "proxy", 5) == 0)
			flags |= RTF_ANNOUNCE;
		argv++;
	}
	if (rtmsg(RTM_GET) < 0) {
		errx(1, "RTM_GET(%s) failed", host);
		/* NOTREACHED */
	}
	sin = (struct sockaddr_in6 *)(rtm + 1);
	sdl = (struct sockaddr_dl *)(ALIGN(sin->sin6_len) + (char *)sin);
	if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) {
		if (sdl->sdl_family == AF_LINK &&
		    !(rtm->rtm_flags & RTF_GATEWAY)) {
			switch (sdl->sdl_type) {
			case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
			case IFT_ISO88024: case IFT_ISO88025:
			case IFT_L2VLAN: case IFT_BRIDGE:
				goto overwrite;
			}
		}
		fprintf(stderr, "set: cannot configure a new entry\n");
		return 1;
	}

overwrite:
	if (sdl->sdl_family != AF_LINK) {
		printf("cannot intuit interface index and type for %s\n", host);
		return (1);
	}
	sdl_m.sdl_type = sdl->sdl_type;
	sdl_m.sdl_index = sdl->sdl_index;
	return (rtmsg(RTM_ADD));
}
Example #20
0
uint8*
BNetworkAddress::LinkLevelAddress() const
{
	return LLADDR(&(sockaddr_dl&)fAddress);
}
Example #21
0
/*
 * Attach/setup the common net80211 state.  Called by
 * the driver on attach to prior to creating any vap's.
 */
void
ieee80211_ifattach(struct ieee80211com *ic,
	const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
	struct ifnet *ifp = ic->ic_ifp;
	struct sockaddr_dl *sdl;
	struct ifaddr *ifa;

	KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));

	TAILQ_INIT(&ic->ic_vaps);

	/* Create a taskqueue for all state changes */
	ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
	    taskqueue_thread_enqueue, &ic->ic_tq);
	taskqueue_start_threads(&ic->ic_tq, 1, TDPRI_KERN_DAEMON, -1,
	    "%s taskq", ifp->if_xname);
	/*
	 * Fill in 802.11 available channel set, mark all
	 * available channels as active, and pick a default
	 * channel if not already specified.
	 */
	ieee80211_media_init(ic);

	ic->ic_update_mcast = null_update_mcast;
	ic->ic_update_promisc = null_update_promisc;

	ic->ic_hash_key = karc4random();
	ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
	ic->ic_lintval = ic->ic_bintval;
	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;

	ieee80211_crypto_attach(ic);
	ieee80211_node_attach(ic);
	ieee80211_power_attach(ic);
	ieee80211_proto_attach(ic);
#ifdef IEEE80211_SUPPORT_SUPERG
	ieee80211_superg_attach(ic);
#endif
	ieee80211_ht_attach(ic);
	ieee80211_scan_attach(ic);
	ieee80211_regdomain_attach(ic);
	ieee80211_dfs_attach(ic);

	ieee80211_sysctl_attach(ic);

	ifp->if_addrlen = IEEE80211_ADDR_LEN;
	ifp->if_hdrlen = 0;
	if_attach(ifp, NULL);
	ifp->if_mtu = IEEE80211_MTU_MAX;
	ifp->if_broadcastaddr = ieee80211broadcastaddr;
	ifp->if_output = null_output;
	ifp->if_input = null_input;	/* just in case */
	ifp->if_resolvemulti = NULL;	/* NB: callers check */

	ifa = ifaddr_byindex(ifp->if_index);
	KASSERT(ifa != NULL, ("%s: no lladdr!", __func__));
	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
	sdl->sdl_type = IFT_ETHER;		/* XXX IFT_IEEE80211? */
	sdl->sdl_alen = IEEE80211_ADDR_LEN;
	IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
//	IFAFREE(ifa);
}
Example #22
0
bool
bootpc_init(bool update_files, bool forever)
{
  struct bootp_packet call;
  struct bootp_packet reply;
  static u_int32_t xid = ~0xFF;
  
  struct ifreq ireq;
  struct ifnet *ifp;
  struct socket *so;
  int j;
  int error;
  struct sockaddr_in myaddr;
  struct ifaddr *ifa;
  struct sockaddr_dl *sdl = NULL;
  char *delim;
  struct proc *procp = NULL;

  /*
   * If already filled in, don't touch it here 
   */
  if (nfs_diskless_valid)
    return true;

  /*
   * If we are to update the files create the root
   * file structure.
   */
  if (update_files)
    if (rtems_create_root_fs () < 0) {
      printf("Error creating the root filesystem.\nFile not created.\n");
      update_files = 0;
    }

  if (dhcp_hostname != NULL) {
	/* free it */
    dhcp_hostname=bootp_strdup_realloc(dhcp_hostname,0);
  }

  /*
   * Find a network interface.
   */
  for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
    if ((ifp->if_flags &
      (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
	break;
  if (ifp == NULL) {
    printf("bootpc_init: no suitable interface\n");
    return false;
  }
  bzero(&ireq,sizeof(ireq));
  sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit);
  printf("bootpc_init: using network interface '%s'\n",
	 ireq.ifr_name);

  if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0) {
    printf("bootpc_init: socreate, error=%d", error);
    return false;
  }
  if (bootpc_fakeup_interface(&ireq,so,procp) != 0) {
    soclose(so);
    return false;
  }

  /* Get HW address */

  for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)
    if (ifa->ifa_addr->sa_family == AF_LINK &&
        (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) &&
        sdl->sdl_type == IFT_ETHER)
      break;
  
  if (!sdl) {
    printf("bootpc: Unable to find HW address\n");
    soclose(so);
    return false;
  }
  if (sdl->sdl_alen != EALEN ) {
    printf("bootpc: HW address len is %d, expected value is %d\n",
	   sdl->sdl_alen,EALEN);
    soclose(so);
    return false;
  }

  printf("bootpc hw address is ");
  delim="";
  for (j=0;j<sdl->sdl_alen;j++) {
    printf("%s%x",delim,((unsigned char *)LLADDR(sdl))[j]);
    delim=":";
  }
  printf("\n");

#if 0
  bootpboot_p_iflist();
  bootpboot_p_rtlist();
#endif

  while (true) {
    bzero((caddr_t) &call, sizeof(call));

    /* bootpc part */
    call.op = 1; 			/* BOOTREQUEST */
    call.htype= 1;		/* 10mb ethernet */
    call.hlen=sdl->sdl_alen;	/* Hardware address length */
    call.hops=0;	
    xid++;
    call.xid = txdr_unsigned(xid);
    bcopy(LLADDR(sdl),&call.chaddr,sdl->sdl_alen);
  
    call.vend[0]=99;
    call.vend[1]=130;
    call.vend[2]=83;
    call.vend[3]=99;
    call.vend[4]=255;
  
    call.secs = 0;
    call.flags = htons(0x8000); /* We need an broadcast answer */
  
    error = bootpc_call(&call,&reply,procp);
  
    if (!error)
      break;
    
    printf("BOOTP call failed -- error %d", error);

    if (!forever) {
      soclose(so);
      return false;
    }
  }
  
  /*
   * Initialize network address structures
   */
  bzero(&myaddr,sizeof(myaddr));
  bzero(&dhcp_netmask,sizeof(dhcp_netmask));
  bzero(&dhcp_gw,sizeof(dhcp_gw));
  myaddr.sin_len = sizeof(myaddr);
  myaddr.sin_family = AF_INET;
  dhcp_netmask.sin_len = sizeof(dhcp_netmask);
  dhcp_netmask.sin_family = AF_INET;
  dhcp_gw.sin_len = sizeof(dhcp_gw);
  dhcp_gw.sin_family= AF_INET;

  /*
   * Set our address
   */
  myaddr.sin_addr = reply.yiaddr;
  printip("My ip address",myaddr.sin_addr);

  /*
   * Process BOOTP/DHCP options
   */
  if (reply.vend[0]==99 && reply.vend[1]==130 &&
      reply.vend[2]==83 && reply.vend[3]==99) {
    processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
  }
  if (dhcpOptionOverload & 1) {
    processOptions ((unsigned char *)reply.file, sizeof reply.file);
  }
  else {
    if (reply.file[0])
      rtems_bsdnet_bootp_boot_file_name = 
	bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,reply.file);
  }
  if (dhcpOptionOverload & 2) {
    processOptions ((unsigned char *)reply.sname, sizeof reply.sname);
  }
  else {
    if (reply.sname[0])
      rtems_bsdnet_bootp_server_name = 
	bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,reply.sname);
  }
  if (rtems_bsdnet_bootp_server_name)
    printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
  if (rtems_bsdnet_bootp_boot_file_name)
    printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
  if (rtems_bsdnet_bootp_cmdline)
    printf ("Command line is %s\n", rtems_bsdnet_bootp_cmdline);

  /*
   * Use defaults if values were not supplied by BOOTP/DHCP options
   */
  if (!dhcp_gotnetmask) {
    if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
      dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
    else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
      dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
    else 
      dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
  }
  printip ("Subnet mask", dhcp_netmask.sin_addr);
  if (!dhcp_gotserver)
   rtems_bsdnet_bootp_server_address = reply.siaddr;
  printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
  if (!dhcp_gotgw)
    dhcp_gw.sin_addr = reply.giaddr;
  printip ("Gateway ip address", dhcp_gw.sin_addr);
  if (!dhcp_gotlogserver)
    rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
  printip ("Log server ip address", rtems_bsdnet_log_host_address);

  /*
   * Update the files if we are asked too.
   */
  if (update_files) {
    char *dn = rtems_bsdnet_domain_name;
    char *hn = dhcp_hostname;
    if (!dn)
      dn = "mydomain";
    if (!hn)
      hn = "me";
    rtems_rootfs_append_host_rec(myaddr.sin_addr.s_addr, hn, dn);

    /*
     * Should the given domainname be used here ?
     */
    if (dhcp_gotserver) {
      if (rtems_bsdnet_bootp_server_name)
        hn = rtems_bsdnet_bootp_server_name;
      else
        hn = "bootps";
      rtems_rootfs_append_host_rec(rtems_bsdnet_bootp_server_address.s_addr,
                                   hn, dn);
    }

    if (dhcp_gotlogserver) {
      rtems_rootfs_append_host_rec(rtems_bsdnet_log_host_address.s_addr,
                                   "logs", dn);
    }

    /*
     * Setup the DNS configuration file /etc/resolv.conf.
     */
    if (rtems_bsdnet_nameserver_count) {
      int        i;
      char       buf[64];
      const char *bufl[1];

      bufl[0] = buf;
      
#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
      
      if (rtems_bsdnet_domain_name &&
          (strlen(rtems_bsdnet_domain_name) < (sizeof(buf) - 1))) {
        strcpy(buf, "search ");
        strcat(buf, rtems_bsdnet_domain_name);
        strcat(buf, "\n");
        rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl);
      }

      for (i = 0; i < rtems_bsdnet_nameserver_count; i++) {
        strcpy(buf, "nameserver ");
        strcat(buf, inet_ntoa(rtems_bsdnet_nameserver[i]));
        strcat(buf, "\n");
        if (rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl))
          break;
      }
    }
  }

  /*
   * Configure the interface with the new settings
   */
  error = bootpc_adjust_interface(&ireq,so,
				  &myaddr,&dhcp_netmask,&dhcp_gw,procp);
  soclose(so);

  return true;
}
Example #23
0
File: lsif.c Project: Slixbits/lsif
int main(int argc, char **argv)
{
  char            buf[8192] = {0};
  struct ifconf   ifc = {0};
  struct ifreq   *ifr = NULL;
  int             sck = 0;
  int             nInterfaces = 0;
  int             i = 0;
  char            ip[INET6_ADDRSTRLEN] = {0};
  struct ifreq    *item;
  struct sockaddr *addr;
  socklen_t       salen;
  char            hostname[NI_MAXHOST];
  struct ifreq    *flagsStruct;
  char            *ignoreLoopbackFlag = "--ignoreloopback";
  int             ignoreLoopback = 0;
  int             argIndex = 1;

  /* Process command-line arguments. */
  for(; argIndex < argc; argIndex++) {
    if(strcmp(argv[argIndex], ignoreLoopbackFlag) == 0)
        ignoreLoopback = 1;
    else {
        fprintf(stderr, "Invalid argument (%s)\n", argv[argIndex]);
		return 1;
    }
  }


  /* Get a socket handle. */
  sck = socket(PF_INET, SOCK_DGRAM, 0);
  if(sck < 0) {
    fatal_perror("socket");
    return 1;
  }
 
  /* Query available interfaces. */
  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
    fatal_perror("ioctl(SIOCGIFCONF)");
    return 1;
  }
  /* Iterate through the list of interfaces. */
  ifr = ifc.ifc_req;
  nInterfaces = ifc.ifc_len / sizeof(struct ifreq); 
  for(i = 0; i < nInterfaces; i++) {
    bzero(hostname, NI_MAXHOST);
    item = &ifr[i];

	if(get_flags(sck, flagsStruct))
		return 1;

    /* Check if this is a loopback adapter and skip it if requested. */
    if(ignoreLoopback && ((flagsStruct->ifr_flags & IFF_LOOPBACK) != 0)) {
        free(flagsStruct);
        continue;
    }
    
    /* Show the device name and IP address */
    addr = &(item->ifr_addr);

    switch(addr->sa_family) {
    case AF_INET:
      salen = sizeof(struct sockaddr_in);
      break;
    case AF_INET6:
      salen = sizeof(struct sockaddr_in6);
      break;
    default:
      salen = 0;
    }
   
    /* the call to get the mac address changes what is stored in the
       item, meaning that we need to determine the hostname now */
    getnameinfo(addr, salen, hostname, sizeof(hostname), NULL, 0, NI_NAMEREQD);


    /* Get the address 
     * This may seem silly but it seems to be needed on some systems 
     */
    if(ioctl(sck, SIOCGIFADDR, item) < 0) {
      fatal_perror("ioctl(OSIOCGIFADDR)");
    }
    printf("%s %s",
       item->ifr_name,
       get_ip_str(addr, ip, INET6_ADDRSTRLEN));
    
    /* Lots of different ways to get the ethernet address */
#ifdef SIOCGIFHWADDR
    /* Linux */
    /* Get the MAC address */
    if(ioctl(sck, SIOCGIFHWADDR, item) < 0) {
      fatal_perror("ioctl(SIOCGIFHWADDR)");
      return 1;
    }
    
    /* display result */
    printf(" %02x:%02x:%02x:%02x:%02x:%02x",
       (unsigned char)item->ifr_hwaddr.sa_data[0],
       (unsigned char)item->ifr_hwaddr.sa_data[1],
       (unsigned char)item->ifr_hwaddr.sa_data[2],
       (unsigned char)item->ifr_hwaddr.sa_data[3],
       (unsigned char)item->ifr_hwaddr.sa_data[4],
       (unsigned char)item->ifr_hwaddr.sa_data[5]);
    
#elif SIOCGENADDR
    /* Solaris and possibly all SysVR4 */
    /* Get the MAC address */
    if(ioctl(sck, SIOCGENADDR, item) < 0) {
      fatal_perror("ioctl(SIOCGENADDR)");
    }
    
    /* display result */
    printf(" %02x:%02x:%02x:%02x:%02x:%02x",
       (unsigned char)item->ifr_enaddr[0],
       (unsigned char)item->ifr_enaddr[1],
       (unsigned char)item->ifr_enaddr[2],
       (unsigned char)item->ifr_enaddr[3],
       (unsigned char)item->ifr_enaddr[4],
       (unsigned char)item->ifr_enaddr[5]);
    
#elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__
    /* MacOS X and all modern BSD implementations (I hope) */
    int                mib[6] = {0};
    int                len = 0;
    char               *macbuf; 
    struct if_msghdr   *ifm;
    struct sockaddr_dl *sdl;
    unsigned char      *ptr;
      
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    mib[5] = if_nametoindex(item->ifr_name);
    if(mib[5] == 0)
      continue;

    if(sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0) {
      fatal_perror("sysctl");
    }

    macbuf = (char *) malloc(len);
    if(macbuf == NULL) {
      fprintf(stderr, "\nUnable to allocate necessary memory: %d\n", len);
      exit(1);
    }

    if(sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0) {
      fatal_perror("sysctl");
    }

    ifm = (struct if_msghdr *)macbuf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);

    printf(" %02x:%02x:%02x:%02x:%02x:%02x", 
       ptr[0], ptr[1], ptr[2], 
       ptr[3], ptr[4], ptr[5]);

    free(macbuf);
      
#else
#error OS Distribution Not Recognized
#endif

    printf(" %s\n", hostname);

    free(flagsStruct);

  }

  return 0;
}
jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName)
{
    int sock = -1;
    struct ifreq ifr;
    jbyteArray hwaddr = NULL;
    char* name = NULL;
    jbyte* addr = NULL;
    int hwlen = 6;

    name = (char*)(*env)->GetStringUTFChars(env, ifName, NULL);

    if(!name)
    {
        return NULL;
    }

#ifdef __linux__

    sock = socket(AF_INET, SOCK_DGRAM, 0);

    if(sock == -1)
    {
        (*env)->ReleaseStringUTFChars(env, ifName, name);
        return NULL;
    }
    
    memset(&ifr, 0x00, sizeof(struct ifreq));

    strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
    ifr.ifr_name[IFNAMSIZ - 1] = 0x00;

    if(ioctl(sock, SIOCGIFHWADDR, &ifr) != 0)
    {
        (*env)->ReleaseStringUTFChars(env, ifName, name);
        close(sock);
        return NULL;
    }
    
    close(sock);
    addr = (const jbyte*)ifr.ifr_hwaddr.sa_data;

#else /* BSD like */

    struct ifaddrs* addrs = NULL;
    struct ifaddrs* ifa = NULL;
    jbyte buf[hwlen];

    if(getifaddrs(&addrs) != -1)
    {
        for(ifa = addrs ; ifa != NULL ; ifa = ifa->ifa_next)
        {
            if(ifa->ifa_addr->sa_family == AF_LINK && !strcmp(ifa->ifa_name, name))
            {
                struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr;

                if(sdl->sdl_type == IFT_ETHER)
                {
                    memcpy(buf, LLADDR(sdl), hwlen);
                    addr = buf;
                    break;
                }
            }
        }

        freeifaddrs(addrs);
    }

#endif

    if(addr)
    {
        hwaddr = (*env)->NewByteArray(env, hwlen);

        if(hwaddr)
        {
            /* copy the hardware address and return it */
            (*env)->SetByteArrayRegion(env, hwaddr, 0, hwlen, addr);
        }
    }

    /* cleanup */
    (*env)->ReleaseStringUTFChars(env, ifName, name);
    return hwaddr;
}
Example #25
0
static int
ARP_Scan_Next(in_addr_t * IPAddr, char *PhysAddr, int *PhysAddrLen,
              u_long * ifType)
#endif
{
#ifndef NETSNMP_CAN_USE_SYSCTL
#ifdef linux
    if (arptab_current < arptab_size) {
        /*
         * copy values 
         */
        *IPAddr = at[arptab_current].at_iaddr.s_addr;
        *ifType =
            (at[arptab_current].
             at_flags & ATF_PERM) ? 4 /*static */ : 3 /*dynamic */ ;
        *ifIndex = at[arptab_current].if_index;
        memcpy(PhysAddr, &at[arptab_current].at_enaddr,
               sizeof(at[arptab_current].at_enaddr));
        *PhysAddrLen = at[arptab_current].at_enaddr_len;

        /*
         * increment to point next entry 
         */
        arptab_current++;
        /*
         * return success 
         */
        return (1);
    }
#elif defined(hpux11)
    if (arptab_current < arptab_size) {
        /*
         * copy values 
         */
        *IPAddr = at[arptab_current].NetAddr;
        memcpy(PhysAddr, at[arptab_current].PhysAddr.o_bytes,
               at[arptab_current].PhysAddr.o_length);
        *ifType = at[arptab_current].Type;
        *ifIndex = at[arptab_current].IfIndex;
        *PhysAddrLen = at[arptab_current].PhysAddr.o_length;
        /*
         * increment to point next entry 
         */
        arptab_current++;
        /*
         * return success 
         */
        return (1);
    }
#elif !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux)
    register struct arptab *atab;

    while (arptab_current < arptab_size) {
#ifdef STRUCT_ARPHD_HAS_AT_NEXT
        /*
         * The arp table is an array of linked lists of arptab entries.
         * Unused slots have pointers back to the array entry itself 
         */

        if (at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) +
                       arptab_current * sizeof(struct arphd))) {
            /*
             * Usused 
             */
            arptab_current++;
            at_ptr = at[arptab_current].at_next;
            continue;
        }

        if (!NETSNMP_KLOOKUP(at_ptr, (char *) &at_entry, sizeof(struct arptab))) {
            DEBUGMSGTL(("mibII/at:ARP_Scan_Next", "klookup failed\n"));
            break;
        }

        if (!NETSNMP_KLOOKUP(at_entry.at_ac, (char *) &at_com, sizeof(struct arpcom))) {
            DEBUGMSGTL(("mibII/at:ARP_Scan_Next", "klookup failed\n"));
            break;
        }

        at_ptr = at_entry.at_next;
        atab = &at_entry;
        *ifIndex = at_com.ac_if.if_index;       /* not strictly ARPHD */
#else                           /* STRUCT_ARPHD_HAS_AT_NEXT */
        atab = &at[arptab_current++];
#endif                          /* STRUCT_ARPHD_HAS_AT_NEXT */
        if (!(atab->at_flags & ATF_COM))
            continue;
        *ifType = (atab->at_flags & ATF_PERM) ? 4 : 3;
        *IPAddr = atab->at_iaddr.s_addr;
#if defined (sunV3) || defined(sparc) || defined(hpux)
        memcpy(PhysAddr, (char *) &atab->at_enaddr,
               sizeof(atab->at_enaddr));
        *PhysAddrLen = sizeof(atab->at_enaddr);
#endif
#if defined(mips) || defined(ibm032)
        memcpy(PhysAddr, (char *) atab->at_enaddr,
               sizeof(atab->at_enaddr));
        *PhysAddrLen = sizeof(atab->at_enaddr);
#endif
        return (1);
    }
#endif                          /* linux || hpux11 || !ARP_SCAN_FOUR_ARGUMENTS || hpux */

    return 0;                   /* we need someone with an irix box to fix this section */

#else                           /* !NETSNMP_CAN_USE_SYSCTL */
    struct rt_msghdr *rtm;
    struct sockaddr_inarp *sin;
    struct sockaddr_dl *sdl;

    while (rtnext < lim) {
        rtm = (struct rt_msghdr *) rtnext;
        sin = (struct sockaddr_inarp *) (rtm + 1);
        sdl = (struct sockaddr_dl *) (sin + 1);
        rtnext += rtm->rtm_msglen;
        if (sdl->sdl_alen) {
#ifdef irix6
            *IPAddr = sin->sarp_addr.s_addr;
#else
            *IPAddr = sin->sin_addr.s_addr;
#endif
            memcpy(PhysAddr, (char *) LLADDR(sdl), sdl->sdl_alen);
            *PhysAddrLen = sdl->sdl_alen;
            *ifIndex = sdl->sdl_index;
            *ifType = 1;        /* XXX */
            return (1);
        }
    }
    return (0);                 /* "EOF" */
#endif                          /* !NETSNMP_CAN_USE_SYSCTL */
}
Example #26
0
/*
 * returns interface list with detailed informations
 */
struct iface * if_list_get() {

    /*
     * Translating between Mac OS X internal representation of link and IP address
     * and Dibbler internal format.
     */
    struct ifaddrs *addrs_lst = NULL; // list returned by system
    struct ifaddrs *addr_ptr = NULL; // single address
    struct iface *iface_lst = NULL;  // interface list
    struct iface *iface_ptr = NULL;  // pointer to single interface

    if (getifaddrs(&addrs_lst) != 0) {
        perror("Error in getifaddrs: ");
        return iface_lst;
    }

    /* First pass through entire addrs_lst: collect unique interface names and flags */
    addr_ptr = addrs_lst;
    while (addr_ptr != NULL) {
        // check if this interface name is already on target list
        iface_ptr = iface_lst;
        while (iface_ptr!=NULL) {
            if (!strcmp(addr_ptr->ifa_name, iface_ptr->name))
                break;
            iface_ptr = iface_ptr->next;
        }
        if (!iface_ptr) { // interface with that name not found, let's add one!
            iface_ptr = malloc(sizeof(struct iface));
            memset(iface_ptr, 0, sizeof(struct iface));

            strncpy(iface_ptr->name, addr_ptr->ifa_name, MAX_IFNAME_LENGTH - 1);
	    iface_ptr->name[MAX_IFNAME_LENGTH-1] = 0;
            iface_ptr->id = if_nametoindex(iface_ptr->name);
            iface_ptr->flags = addr_ptr->ifa_flags;
#ifdef LOWLEVEL_DEBUG
            printf("Detected interface %s, ifindex=%d, flags=%d\n",
                   iface_ptr->name, iface_ptr->id, iface_ptr->flags);
#endif

            // add this new structure to the end of the interfaces list
            iface_lst = if_list_add(iface_lst, iface_ptr);
        }

        addr_ptr = addr_ptr->ifa_next;
    }

    /*
     * Second pass through addrs_lst: collect link and IP layer info for each interface
     * by name
     */

    // for each address...
    for (addr_ptr = addrs_lst; addr_ptr != NULL; addr_ptr = addr_ptr->ifa_next) {
        for (iface_ptr = iface_lst; iface_ptr != NULL; iface_ptr = iface_ptr->next) {
            // ... find its corresponding interface
            if (strncmp(iface_ptr->name, addr_ptr->ifa_name, strlen(addr_ptr->ifa_name)))
                continue;

            switch (addr_ptr->ifa_addr->sa_family)
                {
                case AF_INET6:
                    {
                        char * ptr = (char*)(&((struct sockaddr_in6 *) addr_ptr->ifa_addr)->sin6_addr);
                        if (ptr[0] == 0xfe && ptr[1] == 0x80) { // link-local IPv6 address
                            char * addrs = malloc( (iface_ptr->linkaddrcount+1)*16);
                            memcpy(addrs, iface_ptr->linkaddr, 16*iface_ptr->linkaddrcount);
                            memcpy(addrs + 16*iface_ptr->linkaddrcount, ptr, 16);
                            free(iface_ptr->linkaddr);
                            iface_ptr->linkaddr = addrs;
                            iface_ptr->linkaddrcount++;
                        } else { // this is global address
                            char * addrs = malloc( (iface_ptr->globaladdrcount+1)*16);
                            memcpy(addrs, iface_ptr->globaladdr, 16*iface_ptr->globaladdrcount);
                            memcpy(addrs + 16*iface_ptr->globaladdrcount, ptr, 16);
                            free(iface_ptr->globaladdr);
                            iface_ptr->globaladdr = addrs;
                            iface_ptr->globaladdrcount++;
                        }
                        break;
                    } // end of AF_INET6 handling
                case AF_LINK:
                    {
                        struct sockaddr_dl *linkInfo;
                        linkInfo = (struct sockaddr_dl *) addr_ptr->ifa_addr;

                        // Note: sdl_type is unsigned character; hardwareType is integer
                        iface_ptr->hardwareType = linkInfo->sdl_type;
                        if (linkInfo->sdl_alen > 1) {
                            memcpy(iface_ptr->mac, LLADDR(linkInfo),
                                   linkInfo->sdl_alen);
                            iface_ptr->maclen = linkInfo->sdl_alen;
                        }
                        break;
                    }
                default:
                    break; // ignore other address families
                }
        }
    }

    /* Print out iface_lst data if debug mode */
#ifdef LOWLEVEL_DEBUG
    iface_ptr = iface_lst;
    while (iface_ptr) {
        if_print(iface_ptr);
        iface_ptr = iface_ptr->next;
    }
#endif

    return iface_lst;
} /* end of if_list_get */
Example #27
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);
}
Example #28
0
int
do_interface(const char *ifname,
	     _unused unsigned char *hwaddr, _unused size_t *hwlen,
	     struct in_addr *addr, struct in_addr *net, int get)
{
	int s;
	struct ifconf ifc;
	int retval = 0, found = 0;
	int len = 10 * sizeof(struct ifreq);
	int lastlen = 0;
	char *p;
	union {
		char *buffer;
		struct ifreq *ifr;
	} ifreqs;
	struct sockaddr_in address;
	struct ifreq *ifr;
	struct sockaddr_in netmask;
#ifdef AF_LINK
	struct sockaddr_dl *sdl;
#endif

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		return -1;

	/* Not all implementations return the needed buffer size for
	 * SIOGIFCONF so we loop like so for all until it works */
	memset(&ifc, 0, sizeof(ifc));
	for (;;) {
		ifc.ifc_len = len;
		ifc.ifc_buf = xmalloc((size_t)len);
		if (ioctl(s, SIOCGIFCONF, &ifc) == -1) {
			if (errno != EINVAL || lastlen != 0) {
				close(s);
				free(ifc.ifc_buf);	
				return -1;
			}
		} else {
			if (ifc.ifc_len == lastlen)
				break;
			lastlen = ifc.ifc_len;
		}

		free(ifc.ifc_buf);
		ifc.ifc_buf = NULL;
		len *= 2;
	}

	for (p = (char *)ifc.ifc_buf; p < (char *)ifc.ifc_buf + ifc.ifc_len;) {
		/* Cast the ifc buffer to an ifreq cleanly */
		ifreqs.buffer = p;
		ifr = ifreqs.ifr;

#ifndef __linux__
		if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_ifru))
			p += offsetof(struct ifreq, ifr_ifru) +
				ifr->ifr_addr.sa_len;
		else
#endif
			p += sizeof(*ifr);

		if (strcmp(ifname, ifr->ifr_name) != 0)
			continue;

		found = 1;

#ifdef AF_LINK
		if (hwaddr && hwlen && ifr->ifr_addr.sa_family == AF_LINK) {
			sdl = xmalloc(ifr->ifr_addr.sa_len);
			memcpy(sdl, &ifr->ifr_addr, ifr->ifr_addr.sa_len);
			*hwlen = sdl->sdl_alen;
			memcpy(hwaddr, LLADDR(sdl), *hwlen);
			free(sdl);
			retval = 1;
			break;
		}
#endif

		if (ifr->ifr_addr.sa_family == AF_INET)	{
			memcpy(&address, &ifr->ifr_addr, sizeof(address));
			if (ioctl(s, SIOCGIFNETMASK, ifr) == -1)
				continue;
			memcpy(&netmask, &ifr->ifr_addr, sizeof(netmask));
			if (get) {
				addr->s_addr = address.sin_addr.s_addr;
				net->s_addr = netmask.sin_addr.s_addr;
				retval = 1;
				break;
			} else {
				if (address.sin_addr.s_addr == addr->s_addr &&
				    (!net ||
				     netmask.sin_addr.s_addr == net->s_addr))
				{
					retval = 1;
					break;
				}
			}
		}

	}
Example #29
0
/**
 * Prints interface information for the interface ifa
 */
void printInterfaceInfo(struct ifaddrs *ifa){
	// create a puppet socket to act as a file descriptor for ioctl()
	// I can create it here, since I can reuse it
	int fd=socket(AF_INET,SOCK_DGRAM,0);

	// create the ifr & ifm
	// ifr is more general and more stuff can be retrieved, while
	// ifm is purely for media information
	struct ifreq ifr;
	struct ifmediareq ifm;

	size_t if_name_len=strlen(ifa->ifa_name);
	// ensure the interface name is not too long, since  ifr_name is fixed length buffer
	if (if_name_len < sizeof(ifr.ifr_name) && if_name_len < sizeof(ifm.ifm_name) ) {
		// set name for IFR
		memcpy(ifr.ifr_name, ifa->ifa_name, if_name_len);
		ifr.ifr_name[if_name_len]=0;

		// set name for IFM
		memcpy(ifm.ifm_name, ifa->ifa_name, if_name_len);
		ifm.ifm_name[if_name_len]=0;
	} else {
		puts("Interface name is too long");
		exit(1);
	}

	//output current interface
	printf("Interface: %s", ifa->ifa_name);

	if (fd==-1) {
		puts("Socket could not be created");
		exit(1);
	}

	// print flags
	printHeader("Flags", &printFlags, ifa->ifa_flags);
	// prints the MTU
	if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
			printf("\tMTU: %d", ifr.ifr_metric);

	// prints the options
	if (ioctl(fd, SIOCGIFCAP, &ifr) != -1)
		printHeader("Options", &printCapabilities, ifr.ifr_curcap);

	// prints the MAC address
	if(ifa->ifa_addr->sa_family == AF_LINK){
		struct sockaddr_dl *mac_addr = (struct sockaddr_dl *)ifa->ifa_addr;
		unsigned char mac[6];
		// check if he address length is 6 bytes
		if (6 == mac_addr->sdl_alen) {
		  memcpy(mac, LLADDR(mac_addr), mac_addr->sdl_alen);
		  printf("\tMAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
		}
	}

	// print status
	if (ioctl(fd, SIOCGIFMEDIA, &ifm) != -1)
				printf("\tStatus:%s\n", ifm.ifm_status == 3 ? "Active" : ifm.ifm_status == 1 ?
						"Inactive" : "Unknown"); // 3 is active and 1 is inactive

	/**
	 * I'm not going to handle media because it has way too many flags to implement
	 * in a timely manner
	 */

	// IP
	printIPAddress("IP", IP_ADDR, fd, ifr);

	// Point to point
	printIPAddress("Point-to-Point", P2P_ADDR, fd, ifr);

	// broadcast
	printIPAddress("Broadcast", BCAST_ADDR, fd, ifr);

	//netmask
	printIPAddress("Netmask", MASK_ADDR, fd, ifr);

	//autoconf
	printIPAddress("Autoconf", AUTOCONF_ADDR, fd, ifr);

	//autoconf mask
	printIPAddress("Autoconf mask", AUTOCONF_MASK, fd, ifr);

	//ipv4all
	printIPAddress("IPv4All", IPV4ALL_ADDR, fd, ifr);

	//link level
	printIPAddress("Link level", LINK_LEVEL_ADDR, fd, ifr);

	close(fd);
}
Example #30
0
/* determines hardware address on client machine */
int get_hardware_address(int sock,char *interface_name){

#if defined(__linux__)
	struct ifreq ifr;

	strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)-1);
	ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';

	/* try and grab hardware address of requested interface */
	if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){
                printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name);
		exit(STATE_UNKNOWN);
	        }

	memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6);

#elif defined(__bsd__)
						/* King 2004	see ACKNOWLEDGEMENTS */

        int                     mib[6], len;
        char                    *buf;
        unsigned char           *ptr;
        struct if_msghdr        *ifm;
        struct sockaddr_dl      *sdl;

        mib[0] = CTL_NET;
        mib[1] = AF_ROUTE;
        mib[2] = 0;
        mib[3] = AF_LINK;
        mib[4] = NET_RT_IFLIST;

        if((mib[5] = if_nametoindex(interface_name)) == 0){
                printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno));
                exit(STATE_UNKNOWN);
		}

        if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0){
                printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno));
                exit(STATE_UNKNOWN);
		}

        if((buf = malloc(len)) == NULL){
                printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno));
                exit(4);
		}

        if(sysctl(mib, 6, buf, &len, NULL, 0) < 0){
                printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno));
                exit(STATE_UNKNOWN);
		}

        ifm = (struct if_msghdr *)buf;
        sdl = (struct sockaddr_dl *)(ifm + 1);
        ptr = (unsigned char *)LLADDR(sdl);
        memcpy(&client_hardware_address[0], ptr, 6) ;
						/* King 2004 */

#elif defined(__sun__) || defined(__solaris__)

						/* Kompf 2000-2003	see ACKNOWLEDGEMENTS */
	long stat;
	char dev[20] = "/dev/";
	char *p;
	int unit;

    /* get last number from interfacename, eg lnc0, e1000g0*/
    int i;
    p = interface_name + strlen(interface_name) -1;
	for(i = strlen(interface_name) -1; i > 0; p--) {
		if(isalpha(*p))
            break;
    }
    p++;
	if( p != interface_name ){
		unit = atoi(p) ;
		strncat(dev, interface_name, 6) ;
		}
	else{
		printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name);
		exit(STATE_UNKNOWN);
		}
	stat = mac_addr_dlpi(dev, unit, client_hardware_address);
	if(stat != 0){
		printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
		exit(STATE_UNKNOWN);
		}

#elif defined(__hpux__)

	long stat;
	char dev[20] = "/dev/dlpi" ;
	int unit = 0;

	stat = mac_addr_dlpi(dev, unit, client_hardware_address);
	if(stat != 0){
		printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
		exit(STATE_UNKNOWN);
		}
						/* Kompf 2000-2003 */

#else
	printf(_("Error: can't get MAC address for this architecture.  Use the --mac option.\n"));
	exit(STATE_UNKNOWN);
#endif

	if(verbose)
		print_hardware_address(client_hardware_address);

	return OK;
        }