예제 #1
0
/* Gets IPv6 interface information from the /proc filesystem in linux*/
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
{
    struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
    FILE *fp;
    char addr[8][5];
    int flags, myflags, index, plen, scope;
    char ifname[9], lastname[IFNAMSIZ];
    char addr6[32+7+1]; /* don't forget the seven ':' */
    struct addrinfo hints, *res0;
    struct sockaddr_in6 *sin6;
    struct in6_addr *addrptr;
    int err;
    int sockfd = -1;
    struct ifreq ifr;

    res0=NULL;
    ifihead = NULL;
    ifipnext = &ifihead;
    lastname[0] = 0;

    if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
        sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            goto gotError;
        }
        while (fscanf(fp,
                      "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
                      addr[0],addr[1],addr[2],addr[3],
                      addr[4],addr[5],addr[6],addr[7],
                      &index, &plen, &scope, &flags, ifname) != EOF) {

            myflags = 0;
            if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
                if (doaliases == 0)
                    continue;   /* already processed this interface */
                myflags = IFI_ALIAS;
            }
            memcpy(lastname, ifname, IFNAMSIZ);
            ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
            if (ifi == NULL) {
                goto gotError;
            }

            ifipold   = *ifipnext;       /* need this later */
            ifiptr    = ifipnext;
            *ifipnext = ifi;            /* prev points to this new one */
            ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */

            sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
                    addr[0],addr[1],addr[2],addr[3],
                    addr[4],addr[5],addr[6],addr[7]);

            /* Add address of the interface */
            memset(&hints, 0, sizeof(hints));
            hints.ai_family = AF_INET6;
            hints.ai_flags = AI_NUMERICHOST;
            err = getaddrinfo(addr6, NULL, &hints, &res0);
            if (err) {
                goto gotError;
            }
            ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
            if (ifi->ifi_addr == NULL) {
                goto gotError;
            }
            memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));

            /* Add netmask of the interface */
            char ipv6addr[INET6_ADDRSTRLEN];
            plen_to_mask(plen, ipv6addr);
            ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
            if (ifi->ifi_addr == NULL) {
                goto gotError;
            }
            sin6=calloc(1, sizeof(struct sockaddr_in6));
            addrptr=calloc(1, sizeof(struct in6_addr));
            inet_pton(family, ipv6addr, addrptr);
            sin6->sin6_family=family;
            sin6->sin6_addr=*addrptr;
            sin6->sin6_scope_id=scope;
            memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
            free(sin6);


            /* Add interface name */
            memcpy(ifi->ifi_name, ifname, IFI_NAME);

            /* Add interface index */
            ifi->ifi_index = index;

            /* Add interface flags*/
            memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
            if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
                if (errno == EADDRNOTAVAIL) {
                    /*
                     * If the main interface is configured with no IP address but
                     * an alias interface exists with an IP address, you get
                     * EADDRNOTAVAIL for the main interface
                     */
                    free(ifi->ifi_addr);
                    free(ifi);
                    ifipnext  = ifiptr;
                    *ifipnext = ifipold;
                    continue;
                } else {
                    goto gotError;
                }
            }
            ifi->ifi_flags = ifr.ifr_flags;
            freeaddrinfo(res0);
            res0=NULL;
        }
    }
    goto done;

gotError:
    if (ifihead != NULL) {
        free_ifi_info(ifihead);
        ifihead = NULL;
    }
    if (res0 != NULL) {
        freeaddrinfo(res0);
        res0=NULL;
    }
done:
    if (sockfd != -1) {
        assert(close(sockfd) == 0);
    }
    return(ifihead);    /* pointer to first structure in linked list */
}
예제 #2
0
/* Gets IPv6 interface information from the /proc filesystem in linux*/
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
	{
	struct ifi_info *ifi, *ifihead, **ifipnext;
	FILE *fp;
	char addr[8][5];
	int flags, myflags, index, plen, scope;
	char ifname[9], lastname[IFNAMSIZ];
	char addr6[32+7+1]; /* don't forget the seven ':' */
	struct addrinfo hints, *res0;
	struct sockaddr_in6 *sin6;
	struct in6_addr *addrptr;
	int err;

	res0=NULL;
	ifihead = NULL;
	ifipnext = &ifihead;
	lastname[0] = 0;

	if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
		while (fscanf(fp,
					  "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
					  addr[0],addr[1],addr[2],addr[3],
					  addr[4],addr[5],addr[6],addr[7],
					  &index, &plen, &scope, &flags, ifname) != EOF) {

			myflags = 0;
			if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
				if (doaliases == 0)
					continue;   /* already processed this interface */
				myflags = IFI_ALIAS;
				}
			memcpy(lastname, ifname, IFNAMSIZ);
			ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
			if (ifi == NULL) {
				goto gotError;
				}

			*ifipnext = ifi;            /* prev points to this new one */
			ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */

			sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
					addr[0],addr[1],addr[2],addr[3],
					addr[4],addr[5],addr[6],addr[7]);

			/* Add address of the interface */
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = AF_INET6;
			hints.ai_flags = AI_NUMERICHOST;
			err = getaddrinfo(addr6, NULL, &hints, &res0);
			if (err) {
				goto gotError;
				}
			ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
			if (ifi->ifi_addr == NULL) {
				goto gotError;
				}
			memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));

			/* Add netmask of the interface */
			char ipv6addr[INET6_ADDRSTRLEN];
			plen_to_mask(plen, ipv6addr);
			ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
			if (ifi->ifi_addr == NULL) {
				goto gotError;
				}
			sin6=calloc(1, sizeof(struct sockaddr_in6));
			addrptr=calloc(1, sizeof(struct in6_addr));
			inet_pton(family, ipv6addr, addrptr);
			sin6->sin6_family=family;
			sin6->sin6_addr=*addrptr;
			sin6->sin6_scope_id=scope;
			memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
			free(sin6);


			/* Add interface name */
			memcpy(ifi->ifi_name, ifname, IFI_NAME);

			/* Add interface index */
			ifi->ifi_index = index;

			/* If interface is in /proc then it is up*/
			ifi->ifi_flags = IFF_UP;

			freeaddrinfo(res0);
			res0=NULL;
			}
		}
	goto done;

	gotError:
	if (ifihead != NULL) {
		free_ifi_info(ifihead);
		ifihead = NULL;
		}
	if (res0 != NULL) {
		freeaddrinfo(res0);
		res0=NULL;
		}
	done:
	return(ifihead);    /* pointer to first structure in linked list */
	}