/* return the next IP return NULL if there is no more IP */ char * nutscan_ip_iter_inc(nutscan_ip_iter_t * ip) { char host[SMALLBUF]; if( ip->type == IPv4 ) { /* Check if this is the last address to scan */ if(ip->start.s_addr == ip->stop.s_addr) { return NULL; } /* increment the address (need to pass address in host byte order, then pass back in network byte order */ ip->start.s_addr = htonl((ntohl(ip->start.s_addr)+1)); if( ntop(&ip->start, host, sizeof(host)) != 0 ) { return NULL; } return strdup(host); } else { /* Check if this is the last address to scan */ if( memcmp(&ip->start6.s6_addr, &ip->stop6.s6_addr, sizeof(ip->start6.s6_addr)) == 0 ) { return NULL; } increment_IPv6(&ip->start6); if( ntop6(&ip->start6, host, sizeof(host)) != 0 ) { return NULL; } return strdup(host); } }
Jupiter::StringS Jupiter::Socket::ntop(void *ip, size_t size) { switch (size) { case 4: return ntop4(*reinterpret_cast<uint32_t *>(ip)); case 16: return ntop6(*reinterpret_cast<in_addr6 *>(ip)); default: return Jupiter::StringS::empty; } }
/* Return the first ip or NULL if error */ char * nutscan_ip_iter_init(nutscan_ip_iter_t * ip, const char * startIP, const char * stopIP) { int addr; int i; struct addrinfo hints; struct addrinfo *res; struct sockaddr_in * s_in; struct sockaddr_in6 * s_in6; char host[SMALLBUF]; if( startIP == NULL ) { return NULL; } if(stopIP == NULL ) { stopIP = startIP; } memset(&hints,0,sizeof(struct addrinfo)); hints.ai_family = AF_INET; ip->type = IPv4; /* Detecting IPv4 vs IPv6 */ if(getaddrinfo(startIP,NULL,&hints,&res) != 0) { /*Try IPv6 detection */ ip->type = IPv6; hints.ai_family = AF_INET6; if(getaddrinfo(startIP,NULL,&hints,&res) != 0) { fprintf(stderr,"Invalid address : %s\n",startIP); return NULL; } s_in6 = (struct sockaddr_in6 *)res->ai_addr; memcpy(&ip->start6,&s_in6->sin6_addr,sizeof(struct in6_addr)); freeaddrinfo(res); } else { s_in = (struct sockaddr_in *)res->ai_addr; ip->start = s_in->sin_addr; freeaddrinfo(res); } /* Compute stop IP */ if( ip->type == IPv4 ) { hints.ai_family = AF_INET; if(getaddrinfo(stopIP,NULL,&hints,&res) != 0) { fprintf(stderr,"Invalid address : %s\n",stopIP); return NULL; } s_in = (struct sockaddr_in *)res->ai_addr; ip->stop = s_in->sin_addr; freeaddrinfo(res); } else { hints.ai_family = AF_INET6; if(getaddrinfo(stopIP,NULL,&hints,&res) != 0) { fprintf(stderr,"Invalid address : %s\n",stopIP); return NULL; } s_in6 = (struct sockaddr_in6 *)res->ai_addr; memcpy(&ip->stop6,&s_in6->sin6_addr,sizeof(struct in6_addr)); freeaddrinfo(res); } /* Make sure start IP is lesser than stop IP */ if( ip->type == IPv4 ) { if( ntohl(ip->start.s_addr) > ntohl(ip->stop.s_addr) ) { addr = ip->start.s_addr; ip->start.s_addr = ip->stop.s_addr; ip->stop.s_addr = addr; } if( ntop(&ip->start, host, sizeof(host)) != 0 ) { return NULL; } return strdup(host); } else { /* IPv6 */ for( i=0; i<16; i++ ) { if( ip->start6.s6_addr[i] !=ip->stop6.s6_addr[i] ) { if(ip->start6.s6_addr[i]>ip->stop6.s6_addr[i]){ invert_IPv6(&ip->start6,&ip->stop6); } break; } } if( ntop6(&ip->start6, host, sizeof(host)) != 0 ) { return NULL; } return strdup(host); } }