Ejemplo n.º 1
0
/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
static char *INET6_sprint(struct sockaddr *sap, int numeric)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
    if (INET6_rresolve(buff, (struct sockaddr_in6 *) sap, numeric) != 0)
	return (NULL);
    return (buff);
}
Ejemplo n.º 2
0
/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
static char *INET6_sprint(struct sockaddr *sap, int numeric)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
    if (INET6_rresolve(buff, (struct sockaddr_in6 *) sap, numeric) != 0)
	return safe_strncpy(buff, _("[UNKNOWN]"), sizeof(buff));
    return (fix_v4_address(buff, &((struct sockaddr_in6 *)sap)->sin6_addr));
}
Ejemplo n.º 3
0
static void snprint_ip_port(char *ip_port, int size, struct sockaddr *addr, int port, const char *proto, int numeric)
{
	const char *port_name;

#if ENABLE_FEATURE_IPV6
	if (addr->sa_family == AF_INET6) {
		INET6_rresolve(ip_port, size, (struct sockaddr_in6 *)addr,
			(numeric & NETSTAT_NUMERIC) ? 0x0fff : 0);
	} else
#endif
	{
		INET_rresolve(ip_port, size, (struct sockaddr_in *)addr,
			0x4000 | ((numeric & NETSTAT_NUMERIC) ? 0x0fff : 0),
			0xffffffff);
	}
	port_name = get_sname(htons(port), proto, numeric);
	if ((strlen(ip_port) + strlen(port_name)) > 22)
		ip_port[22 - strlen(port_name)] = '\0';
	ip_port += strlen(ip_port);
	strcat(ip_port, ":");
	strcat(ip_port, port_name);
}
Ejemplo n.º 4
0
static void INET6_displayroutes(int noresolve)
{
	char addr6[128], naddr6[128];
	/* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses.
	 * We read the non-delimited strings into the tail of the buffer
	 * using fscanf and then modify the buffer by shifting forward
	 * while inserting ':'s and the nul terminator for the first string.
	 * Hence the strings are at addr6x and addr6x+40.  This generates
	 * _much_ less code than the previous (upstream) approach. */
	char addr6x[80];
	char iface[16], flags[16];
	int iflags, metric, refcnt, use, prefix_len, slen;
	struct sockaddr_in6 snaddr6;

	FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r");

	bb_printf("Kernel IPv6 routing table\n%-44s%-40s"
			  "Flags Metric Ref    Use Iface\n",
			  "Destination", "Next Hop");

	while (1) {
		int r;
		r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n",
				   addr6x+14, &prefix_len, &slen, addr6x+40+7,
				   &metric, &use, &refcnt, &iflags, iface);
		if (r != 9) {
			if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */
				break;
			}
		ERROR:
			bb_error_msg_and_die("fscanf");
		}

		/* Do the addr6x shift-and-insert changes to ':'-delimit addresses.
		 * For now, always do this to validate the proc route format, even
		 * if the interface is down. */
		{
			int i = 0;
			char *p = addr6x+14;

			do {
				if (!*p) {
					if (i==40) { /* nul terminator for 1st address? */
						addr6x[39] = 0;	/* Fixup... need 0 instead of ':'. */
						++p;	/* Skip and continue. */
						continue;
					}
					goto ERROR;
				}
				addr6x[i++] = *p++;
				if (!((i+1)%5)) {
					addr6x[i++] = ':';
				}
			} while (i < 40+28+7);
		}

		if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */
			continue;
		}

		set_flags(flags, (iflags & IPV6_MASK));

		r = 0;
		do {
			inet_pton(AF_INET6, addr6x + r,
					  (struct sockaddr *) &snaddr6.sin6_addr);
			snaddr6.sin6_family = AF_INET6;
			INET6_rresolve(naddr6, sizeof(naddr6),
						   (struct sockaddr_in6 *) &snaddr6,
#if 0
						   (noresolve | 0x8000) /* Default instead of *. */
#else
						   0x0fff /* Apparently, upstream never resolves. */
#endif
						   );

			if (!r) {			/* 1st pass */
				snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len);
				r += 40;
			} else {			/* 2nd pass */
				/* Print the info. */
				bb_printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n",
						  addr6, naddr6, flags, metric, refcnt, use, iface);
				break;
			}
		} while (1);
	}
}
Ejemplo n.º 5
0
static void INET6_displayroutes(int noresolve)
{
	char buff[256];
	char iface[16], flags[16];
	char addr6[128], naddr6[128];
	struct sockaddr_in6 saddr6, snaddr6;
	int iflags, metric, refcnt, use, prefix_len, slen;
	int numeric;

	char addr6p[8][5], saddr6p[8][5], naddr6p[8][5];

	FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r");

	flags[0] = 'U';

	if (noresolve)
		noresolve = 0x0fff;
	numeric = noresolve | 0x8000;	/* default instead of * */

	printf("Kernel IPv6 routing table\n"
		   "Destination                                 "
		   "Next Hop                                "
		   "Flags Metric Ref    Use Iface\n");

	while (fgets(buff, sizeof(buff), fp) != NULL) {
		int ifl;

		if (sscanf(buff, "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
				   "%4s%4s%4s%4s%4s%4s%4s%4s %02x "
				   "%4s%4s%4s%4s%4s%4s%4s%4s %08x %08x %08x %08x %s\n",
				   addr6p[0], addr6p[1], addr6p[2], addr6p[3],
				   addr6p[4], addr6p[5], addr6p[6], addr6p[7],
				   &prefix_len,
				   saddr6p[0], saddr6p[1], saddr6p[2], saddr6p[3],
				   saddr6p[4], saddr6p[5], saddr6p[6], saddr6p[7],
				   &slen,
				   naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3],
				   naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7],
				   &metric, &use, &refcnt, &iflags, iface) != 31) {
			bb_error_msg_and_die("Unsuported kernel route format\n");
		}

		ifl = 1;		/* parse flags */
		if (!(iflags & RTF_UP))
			continue;
		if (iflags & RTF_GATEWAY)
			flags[ifl++] = 'G';
		if (iflags & RTF_HOST)
			flags[ifl++] = 'H';
		if (iflags & RTF_DEFAULT)
			flags[ifl++] = 'D';
		if (iflags & RTF_ADDRCONF)
			flags[ifl++] = 'A';
		if (iflags & RTF_CACHE)
			flags[ifl++] = 'C';
		flags[ifl] = 0;

		/* Fetch and resolve the target address. */
		snprintf(addr6, sizeof(addr6), "%s:%s:%s:%s:%s:%s:%s:%s",
				 addr6p[0], addr6p[1], addr6p[2], addr6p[3],
				 addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
		inet_pton(AF_INET6, addr6, (struct sockaddr *) &saddr6.sin6_addr);
		saddr6.sin6_family = AF_INET6;

		INET6_rresolve(addr6, sizeof(addr6), (struct sockaddr_in6 *) &saddr6,
					   numeric);
		snprintf(addr6, sizeof(addr6), "%s/%d", addr6, prefix_len);

		/* Fetch and resolve the nexthop address. */
		snprintf(naddr6, sizeof(naddr6), "%s:%s:%s:%s:%s:%s:%s:%s",
				 naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3],
				 naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7]);
		inet_pton(AF_INET6, naddr6, (struct sockaddr *) &snaddr6.sin6_addr);
		snaddr6.sin6_family = AF_INET6;

		INET6_rresolve(naddr6, sizeof(naddr6),
					   (struct sockaddr_in6 *) &snaddr6, numeric);

		/* Print the info. */
		printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n",
			   addr6, naddr6, flags, metric, refcnt, use, iface);
	}
}
Ejemplo n.º 6
0
int
INET6_displayroutes_array(webs_t wp)
{
    char addr6[128], *naddr6;
    /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses.
     * We read the non-delimited strings into the tail of the buffer
     * using fscanf and then modify the buffer by shifting forward
     * while inserting ':'s and the nul terminator for the first string.
     * Hence the strings are at addr6x and addr6x+40.  This generates
     * _much_ less code than the previous (upstream) approach. */
    char addr6x[80];
    char iface[16], flags[16];
    int iflags, metric, refcnt, use, prefix_len, slen;
    struct sockaddr_in6 snaddr6;
    int ret = 0;

    FILE *fp = fopen("/proc/net/ipv6_route", "r");

    while (1) {
        int r;
        r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n",
                   addr6x+14, &prefix_len, &slen, addr6x+40+7,
                   &metric, &use, &refcnt, &iflags, iface);
        if (r != 9) {
            if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */
                break;
            }
ERROR:
            perror("fscanf");
            return ret;
        }

        /* Do the addr6x shift-and-insert changes to ':'-delimit addresses.
         * For now, always do this to validate the proc route format, even
         * if the interface is down. */
        {
            int i = 0;
            char *p = addr6x+14;

            do {
                if (!*p) {
                    if (i == 40) { /* nul terminator for 1st address? */
                        addr6x[39] = 0;	/* Fixup... need 0 instead of ':'. */
                        ++p;	/* Skip and continue. */
                        continue;
                    }
                    goto ERROR;
                }
                addr6x[i++] = *p++;
                if (!((i+1) % 5)) {
                    addr6x[i++] = ':';
                }
            } while (i < 40+28+7);
        }

        if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */
            continue;
        }

        ipv6_set_flags(flags, (iflags & IPV6_MASK));

        r = 0;
        do {
            inet_pton(AF_INET6, addr6x + r,
                      (struct sockaddr *) &snaddr6.sin6_addr);
            snaddr6.sin6_family = AF_INET6;
            naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6,
                                    0x0fff /* Apparently, upstream never resolves. */
                                   );

            if (!r) {			/* 1st pass */
                snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len);
                r += 40;
                free(naddr6);
            } else {			/* 2nd pass */
                /* Print the info. */
                ret += websWrite(wp, "[\"%3s\", \"%s\", \"%s\", \"%d\", \"%d\", \"%d\", \"%s\"],\n",
                                 addr6, naddr6, flags, metric, refcnt, use, iface);
                free(naddr6);
                break;
            }
        } while (1);
    }

    return ret;;
}