/**
 * gnome_vfs_address_get_sockaddr:
 * @address: A #GnomeVFSAddress
 * @port: A valid port in host byte order to set in the returned sockaddr
 * structure.
 * @len: A pointer to an int which will contain the length of the
 * return sockaddr structure.
 *
 * This function tanslates @address into a equivalent
 * sockaddr structure. The port specified at @port will
 * be set in the structure and @len will be set to the length
 * of the structure.
 * 
 * 
 * Return value: A newly allocated sockaddr structure the caller must free
 * or %NULL if @address did not point to a valid #GnomeVFSAddress.
 **/
struct sockaddr *
gnome_vfs_address_get_sockaddr (GnomeVFSAddress *address,
				guint16          port,
				int             *len)
{
	struct sockaddr *sa;

	g_return_val_if_fail (address != NULL, NULL);

	sa = g_memdup (address->sa, SA_SIZE (address->sa));

	switch (address->sa->sa_family) {
#ifdef ENABLE_IPV6
	case AF_INET6:
		SIN6 (sa)->sin6_port = g_htons (port);

		if (len != NULL) {
			*len = SIN6_LEN;
		}
		
		break;
#endif
	case AF_INET:
		SIN (sa)->sin_port = g_htons (port);

		if (len != NULL) {
			*len = SIN_LEN;
		}
		break;

	}

	return sa;
}
Exemple #2
0
static void
p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm)
{
	struct sockaddr *sa, *addr[RTAX_MAX];
	char buffer[128];
	char prettyname[128];
	int i, protrusion;

	xo_open_instance(name);
	sa = (struct sockaddr *)(rtm + 1);
	for (i = 0; i < RTAX_MAX; i++) {
		if (rtm->rtm_addrs & (1 << i)) {
			addr[i] = sa;
			sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa));
		}
	}

	protrusion = p_sockaddr("destination", addr[RTAX_DST],
	    addr[RTAX_NETMASK],
	    rtm->rtm_flags, wid_dst);
	protrusion = p_sockaddr("gateway", addr[RTAX_GATEWAY], NULL, RTF_HOST,
	    wid_gw - protrusion);
	snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ",
	    wid_flags - protrusion);
	p_flags(rtm->rtm_flags, buffer);
	if (Wflag) {
		xo_emit("{t:use/%*lu} ", wid_pksent, rtm->rtm_rmx.rmx_pksent);

		if (rtm->rtm_rmx.rmx_mtu != 0)
			xo_emit("{t:mtu/%*lu} ", wid_mtu, rtm->rtm_rmx.rmx_mtu);
		else
			xo_emit("{P:/%*s} ", wid_mtu, "");
	}

	memset(prettyname, 0, sizeof(prettyname));
	if (rtm->rtm_index < ifmap_size) {
		strlcpy(prettyname, ifmap[rtm->rtm_index].ifname,
		    sizeof(prettyname));
		if (*prettyname == '\0')
			strlcpy(prettyname, "---", sizeof(prettyname));
	}

	if (Wflag)
		xo_emit("{t:interface-name/%*s}", wid_if, prettyname);
	else
		xo_emit("{t:interface-name/%*.*s}", wid_if, wid_if,
		    prettyname);
	if (rtm->rtm_rmx.rmx_expire) {
		time_t expire_time;

		if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
			xo_emit(" {:expire-time/%*d}", wid_expire,
			    (int)expire_time);
	}

	xo_emit("\n");
	xo_close_instance(name);
}
Exemple #3
0
int socket_connect(int fd, const char *addr, int port) 
{
    int err = 0;
    sockaddr_x sa;
    if (!sa_build(addr, port, &sa)) {
    	err = EFAULT;
    } else if (connect(fd, (SA*)&sa, SA_SIZE(sa)) < 0) {
    	err = errno;
    }
    return err;
}
/**
 * gnome_vfs_address_dup:
 * @address: A #GnomeVFSAddress.
 * 
 * Duplicates @address.
 * 
 * Return value: Duplicated @address or %NULL if @address was not valid.
 *
 * Since: 2.8
 **/
GnomeVFSAddress *
gnome_vfs_address_dup (GnomeVFSAddress *address)
{
	GnomeVFSAddress *addr;

	g_return_val_if_fail (address != NULL, NULL);
	g_return_val_if_fail (VALID_AF (address->sa), NULL);

	addr = g_new0 (GnomeVFSAddress, 1);
	addr->sa = g_memdup (address->sa, SA_SIZE (address->sa));

	return addr;
}
Exemple #5
0
/*
 * Expand the compacted form of addresses as returned via the
 * configuration read via sysctl().
 */
static void
rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
{
    struct sockaddr *sa;
    int i;

    memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
    for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
        if ((rtinfo->rti_addrs & (1 << i)) == 0)
            continue;
        rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
        cp += SA_SIZE(sa);
    }
}
/**
 * gnome_vfs_address_to_string:
 * @address: A pointer to a #GnomeVFSAddress
 * 
 * Translate @address to a printable string.
 * 
 * Returns: A newly alloced string representation of @address which
 * the caller must free.
 *
 * Since: 2.8
 **/
char *
gnome_vfs_address_to_string (GnomeVFSAddress *address)
{
#ifdef G_OS_WIN32
	char text_addr[100];
	DWORD text_length = sizeof (text_addr);

	if (WSAAddressToString (address->sa, SA_SIZE (address->sa),
				NULL, text_addr, &text_length) == 0)
		return g_strdup (text_addr);

	return NULL;
#else
	const char *text_addr;
#ifdef HAVE_INET_NTOP
	char buf[MAX_ADDRSTRLEN];
#endif	
	g_return_val_if_fail (address != NULL, NULL);

	text_addr = NULL;

	switch (address->sa->sa_family) {
#if defined (ENABLE_IPV6) && defined (HAVE_INET_NTOP)	
	case AF_INET6:
			 
		text_addr = inet_ntop (AF_INET6,
				       &SIN6 (address->sa)->sin6_addr,
				       buf,
				       sizeof (buf));
		break;
#endif
	case AF_INET:
#if HAVE_INET_NTOP
		text_addr = inet_ntop (AF_INET,
				       &SIN (address->sa)->sin_addr,
				       buf,
				       sizeof (buf));
#else
		text_addr = inet_ntoa (SIN (address->sa)->sin_addr);
#endif  /* HAVE_INET_NTOP */
		break;
	}
	   
	  
	return text_addr != NULL ? g_strdup (text_addr) : NULL;
#endif
}
Exemple #7
0
int socket_sendto(int fd, const void *data, size_t count, int flags, const char *addr, int port, size_t *sent) 
{
    ssize_t nsend;
    sockaddr_x sa;
	
    *sent = 0;
    if (!sa_build(addr, port, &sa)) {
		return EFAULT;
    } else {
		nsend = sendto(fd, data, (int)count, flags, (SA*)&sa, (socklen_t)SA_SIZE(sa));
		if (nsend >= 0) {
			*sent = nsend;
			return 0;
		} else {
			return errno;
		}
    }
}
Exemple #8
0
static struct sockaddr *
next_sa(struct sockaddr *sa)
{
        void            *p;
        size_t           sa_size;

#ifdef SA_SIZE
        sa_size = SA_SIZE(sa);
#else
        /* This is not foolproof, kernel may round. */
        sa_size = sa->sa_len;
        if (sa_size < sizeof(u_long))
                sa_size = sizeof(u_long);
#endif

        p = ((char *)sa) + sa_size;

        return (struct sockaddr *)p;
}
Exemple #9
0
static void
np_rtentry(struct rt_msghdr *rtm)
{
	struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
#ifdef notdef
	static int masks_done, banner_printed;
#endif
	static int old_af;
	int af1 = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST;

#ifdef notdef
	/* for the moment, netmasks are skipped over */
	if (!banner_printed) {
		printf("Netmasks:\n");
		banner_printed = 1;
	}
	if (masks_done == 0) {
		if (rtm->rtm_addrs != RTA_DST ) {
			masks_done = 1;
			af1 = sa->sa_family;
		}
	} else
#endif
		af1 = sa->sa_family;
	if (af1 != old_af) {
		pr_family(af1);
		old_af = af1;
	}
	if (rtm->rtm_addrs == RTA_DST)
		p_sockaddr(sa, NULL, 0, 36);
	else {
		p_sockaddr(sa, NULL, rtm->rtm_flags, 16);
		sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);
		p_sockaddr(sa, NULL, 0, 18);
	}
	p_flags(rtm->rtm_flags & interesting, "%-6.6s ");
	putchar('\n');
}
Exemple #10
0
bool
route_table_get_name(ovs_be32 ip, char name[IFNAMSIZ])
{
    struct {
        struct rt_msghdr rtm;
        char space[512];
    } rtmsg;

    struct rt_msghdr *rtm = &rtmsg.rtm;
    struct sockaddr_dl *ifp = NULL;
    struct sockaddr_in *sin;
    struct sockaddr *sa;
    static int seq;
    int i, len, namelen, rtsock;

    rtsock = socket(PF_ROUTE, SOCK_RAW, 0);
    if (rtsock < 0)
        return false;

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

    rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
    rtm->rtm_version = RTM_VERSION;
    rtm->rtm_type = RTM_GET;
    rtm->rtm_addrs = RTA_DST | RTA_IFP;
    rtm->rtm_seq = ++seq;

    sin = (struct sockaddr_in *)(rtm + 1);
    sin->sin_len = len = sizeof(struct sockaddr_in);
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = ip;

    if ((write(rtsock, (char *)&rtmsg, rtm->rtm_msglen)) < 0) {
        close(rtsock);
        return false;
    }

    do {
        len = read(rtsock, (char *)&rtmsg, sizeof(rtmsg));
    } while (len > 0 && (rtmsg.rtm.rtm_seq != seq ||
        rtmsg.rtm.rtm_pid != pid));

    close(rtsock);

    if (len < 0) {
        return false;
    }

    sa = (struct sockaddr *)(rtm + 1);
    for (i = 1; i; i <<= 1) {
        if (rtm->rtm_addrs & i) {
            if (i == RTA_IFP && sa->sa_family == AF_LINK &&
              ((struct sockaddr_dl *)sa)->sdl_nlen) {
                ifp = (struct sockaddr_dl *)sa;
                namelen = ifp->sdl_nlen;
                if (namelen > IFNAMSIZ - 1)
                    namelen = IFNAMSIZ - 1;
                memcpy(name, ifp->sdl_data, namelen);
                name[namelen] = '\0';
                return true;
            }
            sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa));
        }
    }
    return false;
}
static int do_route (const char *ifname,
					 struct in_addr destination,
					 struct in_addr netmask,
					 struct in_addr gateway,
					 int metric,
					 int change, int del)
{
	int s;
	struct rtm 
	{
		struct rt_msghdr hdr;
		char buffer[sizeof (struct sockaddr_storage) * 3];
	} rtm;
	char *bp = rtm.buffer;
	static int seq;
	union sockunion {
		struct sockaddr sa;
		struct sockaddr_in sin;
#ifdef INET6
		struct sockaddr_in6 sin6;
#endif
		struct sockaddr_dl sdl;
		struct sockaddr_storage ss;
	} su;
	
	int l;

	if (! ifname)
		return -1;

	log_route (destination, netmask, gateway, metric, change, del);

	if ((s = socket (PF_ROUTE, SOCK_RAW, 0)) == -1) {
		logger (LOG_ERR, "socket: %s", strerror (errno));
		return -1;
	}

	memset (&rtm, 0, sizeof (struct rtm));

	rtm.hdr.rtm_version = RTM_VERSION;
	rtm.hdr.rtm_seq = ++seq;
	rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
	rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC;

	/* This order is important */
	rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;

#define ADDADDR(_addr) \
	memset (&su, 0, sizeof (struct sockaddr_storage)); \
	su.sin.sin_family = AF_INET; \
	su.sin.sin_len = sizeof (struct sockaddr_in); \
	memcpy (&su.sin.sin_addr, &_addr, sizeof (struct in_addr)); \
	l = SA_SIZE (&(su.sa)); \
	memcpy (bp, &(su), l); \
	bp += l;

	ADDADDR (destination);

	if (netmask.s_addr == INADDR_BROADCAST ||
		gateway.s_addr == INADDR_ANY)
	{
		/* Make us a link layer socket */
		unsigned char *hwaddr;
		int hwlen = 0;

		if (netmask.s_addr == INADDR_BROADCAST) 
			rtm.hdr.rtm_flags |= RTF_HOST;

		hwaddr = xmalloc (sizeof (unsigned char) * HWADDR_LEN);
		_do_interface (ifname, hwaddr, &hwlen, NULL, false, false);
		memset (&su, 0, sizeof (struct sockaddr_storage));
		su.sdl.sdl_len = sizeof (struct sockaddr_dl);
		su.sdl.sdl_family = AF_LINK;
		su.sdl.sdl_nlen = strlen (ifname);
		memcpy (&su.sdl.sdl_data, ifname, su.sdl.sdl_nlen);
		su.sdl.sdl_alen = hwlen;
		memcpy (((unsigned char *) &su.sdl.sdl_data) + su.sdl.sdl_nlen,
				hwaddr, su.sdl.sdl_alen);

		l = SA_SIZE (&(su.sa));
		memcpy (bp, &su, l);
		bp += l;
		free (hwaddr);
	} else {
		rtm.hdr.rtm_flags |= RTF_GATEWAY;
		ADDADDR (gateway);
	}

	ADDADDR (netmask);
#undef ADDADDR

	rtm.hdr.rtm_msglen = sizeof (rtm);
	if (write (s, &rtm, sizeof (rtm)) == -1) {
		/* Don't report error about routes already existing */
		if (errno != EEXIST)
			logger (LOG_ERR, "write: %s", strerror (errno));
		close (s);
		return -1;
	}

	close (s);
	return 0;
}
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load_defaultrouter_from_sysctl(netsnmp_container *container, int family)
{
    netsnmp_defaultrouter_entry *entry;
    struct rt_msghdr *rtm;
    struct sockaddr *dst_sa, *gw_sa;
    char *buf, *lim, *newbuf, *next;
    char address[NETSNMP_ACCESS_DEFAULTROUTER_BUF_SIZE + 1];
    int mib[6];
    size_t address_len, needed;
    int address_type, err, preference, st;

    netsnmp_assert(NULL != container);

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = family;
    mib[4] = NET_RT_DUMP;
    mib[5] = 0;

    err = 0;

    buf = newbuf = NULL;

    if (family == AF_INET) {
        address_len = 4;
        address_type = INETADDRESSTYPE_IPV4;
#ifdef NETSNMP_ENABLE_IPV6
    } else if (family == AF_INET6) {
        address_len = 16;
        address_type = INETADDRESSTYPE_IPV6;
#endif
    } else {
        err = EINVAL;
        goto out;
    }

    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
        err = errno;
        goto out;
    }

    /* Empty arp table. */
    if (needed == 0)
        goto out;

    for (;;) {
        newbuf = realloc(buf, needed);
        if (newbuf == NULL) {
            err = ENOMEM;
            goto out;
        }
        buf = newbuf;
        st = sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0);
        if (st == 0 || errno != ENOMEM)
            break;
        else
            needed += needed / 8; /* XXX: why 8? */
    }
    if (st == -1) {
        err = errno;
        goto out;
    }

    lim = buf + needed;
    for (next = buf; next < lim; next += rtm->rtm_msglen) {
#ifdef NETSNMP_ENABLE_IPV6
	struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif

        rtm = (struct rt_msghdr *)next;

        if (!(rtm->rtm_addrs & RTA_GATEWAY))
            continue;

        dst_sa = (struct sockaddr*)(rtm + 1);
#ifdef SA_SIZE
        gw_sa = (struct sockaddr*)(SA_SIZE(dst_sa) + (char*)dst_sa);
#else
        gw_sa = (struct sockaddr*)(RT_ROUNDUP(dst_sa->sa_len) + (char*)dst_sa);
#endif

        switch (family) {
        case AF_INET:
            if (((struct sockaddr_in*)dst_sa)->sin_addr.s_addr != INADDR_ANY)
                continue;
	    memcpy(address, &((struct sockaddr_in*)gw_sa)->sin_addr.s_addr,
	           address_len);
            break;
#ifdef NETSNMP_ENABLE_IPV6
        case AF_INET6:
            if (memcmp(((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
			&in6addr_any, sizeof in6addr_any) != 0)
		continue; /* XXX: need to determine qualifying criteria for
                       * default gateways in IPv6. */
            memcpy(address, &((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
		   address_len);
            break;
#endif
        default:
            break;
        }

        entry = netsnmp_access_defaultrouter_entry_create();
        if (NULL == entry) {
            err = ENOMEM;
            break;
        }

        /* XXX: this is wrong (hardcoding the router preference to medium). */
        preference = 0;

        entry->ns_dr_index    = ++idx_offset;
        entry->dr_addresstype = address_type;
        entry->dr_address_len = address_len;
        memcpy(entry->dr_address, address, sizeof(address));
        entry->dr_if_index = rtm->rtm_index;
        entry->dr_lifetime    = rtm->rtm_rmx.rmx_expire;
        entry->dr_preference  = preference;

        if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:arp:container",
                        "error with defaultrouter_entry: "
                        "insert into container failed.\n"));
            netsnmp_access_defaultrouter_entry_free(entry);
            goto out;
        }
    }

out:
    free(buf);
    return err;
}
Exemple #13
0
static int
_load_ndp_table_from_sysctl(netsnmp_arp_access *access)
{
#if 1
    netsnmp_arp_entry *entry;
    struct rt_msghdr *rtm;
    struct sockaddr_in6 *sin2;
    struct sockaddr_dl *sdl;
    size_t needed;
    int err, mib[6], st;
    char *buf, *lim, *newbuf, *next;

    netsnmp_assert(NULL != access);

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_INET6;
    mib[4] = NET_RT_FLAGS;
    mib[5] = RTF_LLINFO;

    err = 0;
    buf = newbuf = NULL;

    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
        err = errno;
        goto out;
    }

    /* Empty arp table. */
    if (needed == 0)
        goto out;

    for (;;) {
        newbuf = realloc(buf, needed);
        if (newbuf == NULL) {
            err = ENOMEM;
            goto out;
        }
        buf = newbuf;
        st = sysctl(mib, 6, buf, &needed, NULL, 0);
        if (st == 0 || errno != ENOMEM)
            break;
        else
            needed += needed / 8; /* XXX: why 8? */
    }
    if (st == -1) {
        err = errno;
        goto out;
    }

    lim = buf + needed;
    for (next = buf; next < lim; next += rtm->rtm_msglen) {

        rtm = (struct rt_msghdr *)next;
        sin2 = (struct sockaddr_in6*)(rtm + 1);
#ifdef SA_SIZE
        sdl = (struct sockaddr_dl*)((char *)sin2 + SA_SIZE(sin2));
#else
	sdl = (struct sockaddr_dl*)(void *)(RT_ROUNDUP(sin2->sin6_len) + (char *)(void *)sin2);
#endif

        if (!(rtm->rtm_flags & RTF_HOST) ||
            IN6_IS_ADDR_MULTICAST(&sin2->sin6_addr))
            continue;

        entry = netsnmp_access_arp_entry_create();
        if (NULL == entry) {
            err = ENOMEM;
            break;
        }

        entry->generation = access->generation;
        entry->if_index = rtm->rtm_index;

        entry->arp_ipaddress_len = 16;

        memcpy(entry->arp_ipaddress, &sin2->sin6_addr.s6_addr,
            entry->arp_ipaddress_len);

        /* HW Address */
        entry->arp_physaddress_len = sdl->sdl_alen;
        if (0 < sdl->sdl_alen &&
            sdl->sdl_alen <= NETSNMP_ACCESS_ARP_PHYSADDR_BUF_SIZE) {
            memcpy(entry->arp_physaddress, LLADDR(sdl), sdl->sdl_alen);
            /* Process status */
            /* XXX: setting this value for all states is wrong. */
            entry->arp_state = INETNETTOMEDIASTATE_REACHABLE;
        } else {
            entry->arp_physaddress[0] = '\0';
            entry->arp_state = INETNETTOMEDIASTATE_INCOMPLETE;
        }

        /* Process type */
        /* XXX: more states should be handled here, probably.. */
        if (rtm->rtm_rmx.rmx_expire == 0)
            entry->arp_type = INETNETTOMEDIATYPE_STATIC;
        else
            entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC;

        access->update_hook(access, entry);

    }

out:
    free(buf);
    return err;
#else
    return 0;
#endif
}
Exemple #14
0
std::string CNetworkInterfaceLinux::GetCurrentDefaultGateway(void)
{
   std::string result;

#if defined(TARGET_DARWIN)
  FILE* pipe = popen("echo \"show State:/Network/Global/IPv4\" | scutil | grep Router", "r");
  usleep(100000);
  if (pipe)
  {
    std::string tmpStr;
    char buffer[256] = {'\0'};
    if (fread(buffer, sizeof(char), sizeof(buffer), pipe) > 0 && !ferror(pipe))
    {
      tmpStr = buffer;
      if (tmpStr.length() >= 11)
        result = tmpStr.substr(11);
    }
    pclose(pipe);
  }
  if (result.empty())
    CLog::Log(LOGWARNING, "Unable to determine gateway");
#elif defined(TARGET_FREEBSD)
   size_t needed;
   int mib[6];
   char *buf, *next, *lim;
   char line[16];
   struct rt_msghdr *rtm;
   struct sockaddr *sa;
   struct sockaddr_in *sockin;

   mib[0] = CTL_NET;
   mib[1] = PF_ROUTE;
   mib[2] = 0;
   mib[3] = 0;
   mib[4] = NET_RT_DUMP;
   mib[5] = 0;
   if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
      return result;

   if ((buf = (char *)malloc(needed)) == NULL)
      return result;

   if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
      free(buf);
      return result;
   }

   lim  = buf + needed;
   for (next = buf; next < lim; next += rtm->rtm_msglen) {
      rtm = (struct rt_msghdr *)next;
      sa = (struct sockaddr *)(rtm + 1);
      sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);	
      sockin = (struct sockaddr_in *)sa;
      if (inet_ntop(AF_INET, &sockin->sin_addr.s_addr,
         line, sizeof(line)) == NULL) {
            free(buf);
            return result;
	  }
	  result = line;
      break;
   }
   free(buf);
#else
   FILE* fp = fopen("/proc/net/route", "r");
   if (!fp)
   {
     // TBD: Error
     return result;
   }

   char* line = NULL;
   char iface[16];
   char dst[128];
   char gateway[128];
   size_t linel = 0;
   int n;
   int linenum = 0;
   while (getdelim(&line, &linel, '\n', fp) > 0)
   {
      // skip first two lines
      if (linenum++ < 1)
         continue;

      // search where the word begins
      n = sscanf(line,  "%15s %127s %127s",
         iface, dst, gateway);

      if (n < 3)
         continue;

      if (strcmp(iface, m_interfaceName.c_str()) == 0 &&
          strcmp(dst, "00000000") == 0 &&
          strcmp(gateway, "00000000") != 0)
      {
         unsigned char gatewayAddr[4];
         int len = CNetwork::ParseHex(gateway, gatewayAddr);
         if (len == 4)
         {
            struct in_addr in;
            in.s_addr = (gatewayAddr[0] << 24) | (gatewayAddr[1] << 16) |
                        (gatewayAddr[2] << 8) | (gatewayAddr[3]);
            result = inet_ntoa(in);
            break;
         }
      }
   }
   free(line);
   fclose(fp);
#endif

   return result;
}
Exemple #15
0
std::string CNetworkInterfaceLinux::GetCurrentDefaultGateway(void)
{
   std::string result;

#if defined(TARGET_FREEBSD) || defined(TARGET_DARWIN)
   size_t needed;
   int mib[6];
   char *buf, *next, *lim;
   char line[16];
   struct rt_msghdr *rtm;
   struct sockaddr *sa;
   struct sockaddr_in *sockin;

   mib[0] = CTL_NET;
   mib[1] = PF_ROUTE;
   mib[2] = 0;
   mib[3] = 0;
   mib[4] = NET_RT_DUMP;
   mib[5] = 0;
   if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
      return result;

   if ((buf = (char *)malloc(needed)) == NULL)
      return result;

   if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
      free(buf);
      return result;
   }

   lim  = buf + needed;
   for (next = buf; next < lim; next += rtm->rtm_msglen) {
      rtm = (struct rt_msghdr *)next;
      sa = (struct sockaddr *)(rtm + 1);
      sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);	
      sockin = (struct sockaddr_in *)sa;
      if (inet_ntop(AF_INET, &sockin->sin_addr.s_addr,
         line, sizeof(line)) == NULL) {
            free(buf);
            return result;
	  }
	  result = line;
      break;
   }
   free(buf);
#else
   FILE* fp = fopen("/proc/net/route", "r");
   if (!fp)
   {
     // TBD: Error
     return result;
   }

   char* line = NULL;
   char iface[16];
   char dst[128];
   char gateway[128];
   size_t linel = 0;
   int n;
   int linenum = 0;
   while (getdelim(&line, &linel, '\n', fp) > 0)
   {
      // skip first two lines
      if (linenum++ < 1)
         continue;

      // search where the word begins
      n = sscanf(line,  "%16s %128s %128s",
         iface, dst, gateway);

      if (n < 3)
         continue;

      if (strcmp(iface, m_interfaceName.c_str()) == 0 &&
          strcmp(dst, "00000000") == 0 &&
          strcmp(gateway, "00000000") != 0)
      {
         unsigned char gatewayAddr[4];
         int len = CNetwork::ParseHex(gateway, gatewayAddr);
         if (len == 4)
         {
            struct in_addr in;
            in.s_addr = (gatewayAddr[0] << 24) | (gatewayAddr[1] << 16) |
                        (gatewayAddr[2] << 8) | (gatewayAddr[3]);
            result = inet_ntoa(in);
            break;
         }
      }
   }
   free(line);
   fclose(fp);
#endif

   return result;
}
Exemple #16
0
/*
 * Set an individual arp entry
 */
static int
set(int argc, char **argv)
{
	struct sockaddr_in *addr;
	struct sockaddr_in *dst;	/* what are we looking for */
	struct sockaddr_dl *sdl;
	struct rt_msghdr *rtm;
	struct ether_addr *ea;
	char *host = argv[0], *eaddr = argv[1];
	struct sockaddr_dl sdl_m;

	argc -= 2;
	argv += 2;

	bzero(&sdl_m, sizeof(sdl_m));
	sdl_m.sdl_len = sizeof(sdl_m);
	sdl_m.sdl_family = AF_LINK;

	dst = getaddr(host);
	if (dst == NULL)
		return (1);
	doing_proxy = flags = expire_time = 0;
	while (argc-- > 0) {
		if (strncmp(argv[0], "temp", 4) == 0) {
			struct timespec tp;
			int max_age;
			size_t len = sizeof(max_age);

			clock_gettime(CLOCK_MONOTONIC, &tp);
			if (sysctlbyname("net.link.ether.inet.max_age",
			    &max_age, &len, NULL, 0) != 0)
				err(1, "sysctlbyname");
			expire_time = tp.tv_sec + max_age;
		} else if (strncmp(argv[0], "pub", 3) == 0) {
			flags |= RTF_ANNOUNCE;
			doing_proxy = 1;
			if (argc && strncmp(argv[1], "only", 3) == 0) {
				/*
				 * Compatibility: in pre FreeBSD 8 times
				 * the "only" keyword used to mean that
				 * an ARP entry should be announced, but
				 * not installed into routing table.
				 */
				argc--; argv++;
			}
		} else if (strncmp(argv[0], "blackhole", 9) == 0) {
			if (flags & RTF_REJECT) {
				printf("Choose one of blackhole or reject, not both.\n");
			}
			flags |= RTF_BLACKHOLE;
		} else if (strncmp(argv[0], "reject", 6) == 0) {
			if (flags & RTF_BLACKHOLE) {
				printf("Choose one of blackhole or reject, not both.\n");
			}
			flags |= RTF_REJECT;
		} else if (strncmp(argv[0], "trail", 5) == 0) {
			/* XXX deprecated and undocumented feature */
			printf("%s: Sending trailers is no longer supported\n",
				host);
		}
		argv++;
	}
	ea = (struct ether_addr *)LLADDR(&sdl_m);
	if (doing_proxy && !strcmp(eaddr, "auto")) {
		if (!get_ether_addr(dst->sin_addr.s_addr, ea)) {
			printf("no interface found for %s\n",
			       inet_ntoa(dst->sin_addr));
			return (1);
		}
		sdl_m.sdl_alen = ETHER_ADDR_LEN;
	} else {
		struct ether_addr *ea1 = ether_aton(eaddr);

		if (ea1 == NULL) {
			warnx("invalid Ethernet address '%s'", eaddr);
			return (1);
		} else {
			*ea = *ea1;
			sdl_m.sdl_alen = ETHER_ADDR_LEN;
		}
	}

	/*
	 * In the case a proxy-arp entry is being added for
	 * a remote end point, the RTF_ANNOUNCE flag in the 
	 * RTM_GET command is an indication to the kernel
	 * routing code that the interface associated with
	 * the prefix route covering the local end of the
	 * PPP link should be returned, on which ARP applies.
	 */
	rtm = rtmsg(RTM_GET, dst, &sdl_m);
	if (rtm == NULL) {
		warn("%s", host);
		return (1);
	}
	addr = (struct sockaddr_in *)(rtm + 1);
	sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);

	if ((sdl->sdl_family != AF_LINK) ||
	    (rtm->rtm_flags & RTF_GATEWAY) ||
	    !valid_type(sdl->sdl_type)) {
		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, dst, &sdl_m) == NULL);
}
Exemple #17
0
/*
 * Search for interface with name "ifn", and fill n accordingly:
 *
 * n->ip	ip address of interface "ifn"
 * n->if_name   copy of interface name "ifn"
 */
static void
set_addr_dynamic(const char *ifn, struct cfg_nat *n)
{
	size_t needed;
	int mib[6];
	char *buf, *lim, *next;
	struct if_msghdr *ifm;
	struct ifa_msghdr *ifam;
	struct sockaddr_dl *sdl;
	struct sockaddr_in *sin;
	int ifIndex, ifMTU;

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = AF_INET;
	mib[4] = NET_RT_IFLIST;
	mib[5] = 0;
/*
 * Get interface data.
 */
	if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
		err(1, "iflist-sysctl-estimate");
	buf = safe_calloc(1, needed);
	if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
		err(1, "iflist-sysctl-get");
	lim = buf + needed;
/*
 * Loop through interfaces until one with
 * given name is found. This is done to
 * find correct interface index for routing
 * message processing.
 */
	ifIndex	= 0;
	next = buf;
	while (next < lim) {
		ifm = (struct if_msghdr *)next;
		next += ifm->ifm_msglen;
		if (ifm->ifm_version != RTM_VERSION) {
			if (co.verbose)
				warnx("routing message version %d "
				    "not understood", ifm->ifm_version);
			continue;
		}
		if (ifm->ifm_type == RTM_IFINFO) {
			sdl = (struct sockaddr_dl *)(ifm + 1);
			if (strlen(ifn) == sdl->sdl_nlen &&
			    strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) {
				ifIndex = ifm->ifm_index;
				ifMTU = ifm->ifm_data.ifi_mtu;
				break;
			}
		}
	}
	if (!ifIndex)
		errx(1, "unknown interface name %s", ifn);
/*
 * Get interface address.
 */
	sin = NULL;
	while (next < lim) {
		ifam = (struct ifa_msghdr *)next;
		next += ifam->ifam_msglen;
		if (ifam->ifam_version != RTM_VERSION) {
			if (co.verbose)
				warnx("routing message version %d "
				    "not understood", ifam->ifam_version);
			continue;
		}
		if (ifam->ifam_type != RTM_NEWADDR)
			break;
		if (ifam->ifam_addrs & RTA_IFA) {
			int i;
			char *cp = (char *)(ifam + 1);

			for (i = 1; i < RTA_IFA; i <<= 1) {
				if (ifam->ifam_addrs & i)
					cp += SA_SIZE((struct sockaddr *)cp);
			}
			if (((struct sockaddr *)cp)->sa_family == AF_INET) {
				sin = (struct sockaddr_in *)cp;
				break;
			}
		}
	}
	if (sin == NULL)
		n->ip.s_addr = htonl(INADDR_ANY);
	else
		n->ip = sin->sin_addr;
	strncpy(n->if_name, ifn, IF_NAMESIZE);

	free(buf);
}
Exemple #18
0
static int
_load_routing_table_from_sysctl(netsnmp_container* container, int *index,
    int family)
{
    char *buf, *lim, *next;
    int mib[6];
    size_t needed;
    int err;
    u_char dest_len, dest_type;
    struct rt_msghdr *rtm;

    buf = NULL;
    err = 0;

    if (family == AF_INET) {
        dest_len = 4;
        dest_type = INETADDRESSTYPE_IPV4;
    } else if (family == AF_INET6) {
        dest_len = 16;
        dest_type = INETADDRESSTYPE_IPV6;
    } else {
        err = EINVAL;
        goto out;
    }

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = family;
    mib[4] = NET_RT_DUMP;
    mib[5] = 0;

    if (sysctl(mib, (sizeof(mib) / sizeof(mib[0])), NULL, &needed, NULL,
        0) == -1) {
        err = errno;
        goto out;
    }

    if ((buf = malloc(needed)) == NULL) {
        err = ENOMEM;
        goto out;
    }

    if (sysctl(mib, (sizeof(mib) / sizeof(mib[0])), buf, &needed, NULL,
        0) == -1) {
        err = errno;
        goto out;
    }

    lim = buf + needed;

    for (next = buf; next < lim; next += rtm->rtm_msglen) {    
	struct sockaddr *if_name = NULL, *if_addr = NULL;
	struct sockaddr *dest_sa = NULL, *gateway_sa = NULL, *netmask_sa = NULL;
	netsnmp_route_entry *entry;
	char *addr_ptr;

        rtm = (struct rt_msghdr*)next;

        /* 
         * Some code in netstat checks for this ("netmasks done" case).
         * Filter this out (I don't know why it should exist).
         */
        if (rtm->rtm_addrs == RTA_DST)
            continue;

        entry = netsnmp_access_route_entry_create();
        if (entry == NULL)
            return -3;
        memset(entry->rt_dest, 0, dest_len);
        entry->rt_mask = 0;
        memset(entry->rt_nexthop, 0, dest_len);

        addr_ptr = (char *)(rtm + 1);

	if (rtm->rtm_addrs &  RTA_DST) {
	    dest_sa = (struct sockaddr *)addr_ptr;
	    addr_ptr += SA_SIZE(dest_sa);
	}
	if (rtm->rtm_addrs &  RTA_GATEWAY) {
	    gateway_sa = (struct sockaddr *)addr_ptr;
	    addr_ptr += SA_SIZE(gateway_sa);
	}
	if (rtm->rtm_addrs &  RTA_NETMASK) {
	    netmask_sa = (struct sockaddr *)addr_ptr;
	    addr_ptr += SA_SIZE(netmask_sa);
	}
	if (rtm->rtm_addrs &  RTA_IFP) {
	    if_name = (struct sockaddr *)addr_ptr;
	    addr_ptr += SA_SIZE(if_name);
	}
	if (rtm->rtm_addrs &  RTA_IFA) {
	    if_addr = (struct sockaddr *)addr_ptr;
	    addr_ptr += SA_SIZE(if_addr);
	}

        entry->if_index = rtm->rtm_index;

        /* arbitrary index */
        entry->ns_rt_index = ++(*index);

        /* copy dest & next hop */
        entry->rt_dest_type = dest_type;
        entry->rt_dest_len = dest_len;
        if (rtm->rtm_addrs & RTA_DST) {
            if (family == AF_INET)
                memcpy(entry->rt_dest,
                    &((struct sockaddr_in*)dest_sa)->sin_addr, dest_len);
#ifdef NETSNMP_ENABLE_IPV6
            if (family == AF_INET6)
                memcpy(entry->rt_dest,
                    &((struct sockaddr_in6*)dest_sa)->sin6_addr, dest_len);
#endif
        }

        entry->rt_nexthop_type = dest_type;
        entry->rt_nexthop_len = dest_len;
        if (rtm->rtm_addrs & RTA_GATEWAY) {
            if (family == AF_INET)
                memcpy(entry->rt_nexthop,
                    &((struct sockaddr_in*)gateway_sa)->sin_addr, dest_len);
#ifdef NETSNMP_ENABLE_IPV6
            if (family == AF_INET6)
                memcpy(entry->rt_nexthop,
                    &((struct sockaddr_in6*)gateway_sa)->sin6_addr, dest_len);
#endif
        }
        else {
            if (family == AF_INET)
                memcpy(entry->rt_nexthop,
                    &((struct sockaddr_in*)if_addr)->sin_addr, dest_len);
#ifdef NETSNMP_ENABLE_IPV6
            if (family == AF_INET6)
                memcpy(entry->rt_nexthop,
                    &((struct sockaddr_in6*)if_addr)->sin6_addr, dest_len);
#endif
        }

        if (family == AF_INET) {
	    if (netmask_sa) {
            /* count bits in mask */
		entry->rt_pfx_len = netsnmp_ipaddress_ipv4_prefix_len(
			((struct sockaddr_in *)netmask_sa)->sin_addr.s_addr);
		memcpy(&entry->rt_mask, &((struct sockaddr_in *)netmask_sa)->sin_addr, 4);
	    }
	    else {
		entry->rt_pfx_len = 32;
	    }
        }
#ifdef NETSNMP_ENABLE_IPV6
        if (family == AF_INET6) {
	    if (netmask_sa) {
            /* count bits in mask */
		entry->rt_pfx_len = netsnmp_ipaddress_ipv6_prefix_len(
			((struct sockaddr_in6 *)netmask_sa)->sin6_addr);
		memcpy(&entry->rt_mask, &((struct sockaddr_in6 *)netmask_sa)->sin6_addr, 16);
	    }
	    else {
		entry->rt_pfx_len = 128;
	    }
        }
#endif

#ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE
        /*
    inetCidrRoutePolicy OBJECT-TYPE 
        SYNTAX     OBJECT IDENTIFIER 
        MAX-ACCESS not-accessible 
        STATUS     current 
        DESCRIPTION 
               "This object is an opaque object without any defined 
                semantics.  Its purpose is to serve as an additional 
                index which may delineate between multiple entries to 
                the same destination.  The value { 0 0 } shall be used 
                as the default value for this object."
        */
	entry->rt_policy = calloc(3, sizeof(oid));
	entry->rt_policy[2] = entry->if_index;
	entry->rt_policy_len = sizeof(oid)*3;
#endif

        entry->rt_type = _type_from_flags(rtm->rtm_flags);
	entry->rt_age = rtm->rtm_rmx.rmx_expire;
	entry->rt_nexthop_as = 0;
	/* entry->rt_metric1 = rtm->rtm_rmx.rmx_hopcount; */

        if (rtm->rtm_flags & RTF_DYNAMIC)
            entry->rt_proto = IANAIPROUTEPROTOCOL_ICMP;
        else if (rtm->rtm_flags & RTF_STATIC)
            entry->rt_proto = IANAIPROUTEPROTOCOL_NETMGMT;
#ifdef RTF_LOCAL
        else if (rtm->rtm_flags & RTF_LOCAL)
            entry->rt_proto = IANAIPROUTEPROTOCOL_LOCAL;
#endif
        else
            entry->rt_proto = IANAIPROUTEPROTOCOL_OTHER;

        if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:route:container",
                "error with route_entry: insert into container failed.\n"));
            netsnmp_access_route_entry_free(entry);
            continue;
        }
    }

out:
    free(buf);

    return err;
}
Exemple #19
0
int
get_src_for_route_to(const struct sockaddr * dst,
                     void * src, size_t * src_len,
                     int * index)
{
	int found = 0;
	int s;
	int l, i;
	char * p;
	struct sockaddr * sa;
	struct {
	  struct rt_msghdr m_rtm;
	  char       m_space[512];
	} m_rtmsg;
#define rtm m_rtmsg.m_rtm

	if(dst == NULL)
		return -1;
	if(dst->sa_len > 0) {
		l = dst->sa_len;
	} else {
		if(dst->sa_family == AF_INET)
			l = sizeof(struct sockaddr_in);
		else if(dst->sa_family == AF_INET6)
			l = sizeof(struct sockaddr_in6);
		else {
			syslog(LOG_ERR, "unknown address family %d", dst->sa_family);
			return -1;
		}
	}
	s = socket(PF_ROUTE, SOCK_RAW, dst->sa_family);
	if(s < 0) {
		syslog(LOG_ERR, "socket(PF_ROUTE) failed : %m");
		return -1;
	}
	memset(&rtm, 0, sizeof(rtm));
	rtm.rtm_type = RTM_GET;
	rtm.rtm_flags = RTF_UP;
	rtm.rtm_version = RTM_VERSION;
	rtm.rtm_seq = 1;
	rtm.rtm_addrs = RTA_DST | RTA_IFA | RTA_IFP;	/* pass destination address, request source address & interface */
	memcpy(m_rtmsg.m_space, dst, l);
	((struct sockaddr *)m_rtmsg.m_space)->sa_len = l;
	rtm.rtm_msglen = sizeof(struct rt_msghdr) + l;
	if(write(s, &m_rtmsg, rtm.rtm_msglen) < 0) {
		syslog(LOG_ERR, "write: %m");
		close(s);
		return -1;
	}

	do {
		l = read(s, &m_rtmsg, sizeof(m_rtmsg));
		if(l<0) {
			syslog(LOG_ERR, "read: %m");
			close(s);
			return -1;
		}
		syslog(LOG_DEBUG, "read l=%d seq=%d pid=%d   sizeof(struct rt_msghdr)=%d",
		       l, rtm.rtm_seq, rtm.rtm_pid, (int)sizeof(struct rt_msghdr));
	} while(l > 0 && (rtm.rtm_pid != getpid() || rtm.rtm_seq != 1));
	close(s);
	if(l <= 0) {
		syslog(LOG_WARNING, "no matching ROUTE response message");
		return -1;
	}
	p = m_rtmsg.m_space;
	if(rtm.rtm_addrs) {
		for(i=1; i<0x8000; i <<= 1) {
			if(i & rtm.rtm_addrs) {
				char tmp[256] = { 0 };
				if(p >= (char *)&m_rtmsg + l) {
					syslog(LOG_ERR, "error parsing ROUTE response message");
					break;
				}
				sa = (struct sockaddr *)p;
				sockaddr_to_string(sa, tmp, sizeof(tmp));
				syslog(LOG_DEBUG, "type=%d sa_len=%d sa_family=%d %s",
				       i, sa->sa_len, sa->sa_family, tmp);
				if(i == RTA_IFA) {
					size_t len = 0;
					void * paddr = NULL;
					if(sa->sa_family == AF_INET) {
						paddr = &((struct sockaddr_in *)sa)->sin_addr;
						len = sizeof(struct in_addr);
					} else if(sa->sa_family == AF_INET6) {
						paddr = &((struct sockaddr_in6 *)sa)->sin6_addr;
						len = sizeof(struct in6_addr);
					}
					if(paddr) {
						if(src && src_len) {
							if(*src_len < len) {
								syslog(LOG_WARNING, "cannot copy src. %u<%u",
								       (unsigned)*src_len, (unsigned)len);
								return -1;
							}
							memcpy(src, paddr, len);
							*src_len = len;
						}
						found = 1;
					}
				}
#ifdef AF_LINK
				else if((i == RTA_IFP) && (sa->sa_family == AF_LINK)) {
					struct sockaddr_dl * sdl = (struct sockaddr_dl *)sa;
					if(index)
						*index = sdl->sdl_index;
				}
#endif
				/* at least 4 bytes per address are reserved,
				 * that is true with OpenBSD 4.3 */
				if(SA_SIZE(sa) > 0)
					p += SA_SIZE(sa);
				else
					p += 4;
			}
		}
	}
	return found ? 0 : -1;
}