#define _REENTRANT
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
	char *network=NULL;
	char *netmask=NULL;
	struct in_addr mask;
	struct in_addr net;
	struct sockaddr_in host;
	char addr[INET_ADDRSTRLEN];
	char hostname[NI_MAXHOST];
	int i;
	
	mask.s_addr=0;
	net.s_addr=0;
	host.sin_addr.s_addr=0;
	if(argc==2) {
		char *ptr;
		netmask=argv[1];
		network=strtok_r(argv[1], "/", &ptr);
		netmask=strtok_r(NULL, "/", &ptr);
		if(inet_pton(AF_INET, network, &net)==0) {
			fprintf(stderr, "%s is not a valid ip address\n", network);
			exit(1);
		}
	}
	if(netmask==NULL) {
		inet_pton(AF_INET, "255.255.255.255", &mask);
	} else if(strchr(netmask, '.')==NULL) {
		for(i=0; i<atoi(netmask); i++) {
			mask.s_addr=mask.s_addr >> 1;
			mask.s_addr=mask.s_addr | 0x80000000;
		}
		mask.s_addr=htonl(mask.s_addr);
	} else {
		if(inet_pton(AF_INET, netmask, &mask)==0) {
			fprintf(stderr, "%s is not a valid netmask\n", netmask);
			exit(1);
		}
	}
	net.s_addr=net.s_addr & mask.s_addr;
	inet_ntop(AF_INET, &net, addr, INET_ADDRSTRLEN);
	fprintf(stderr, "Network: %s\n", addr);
	inet_ntop(AF_INET, &mask, addr, INET_ADDRSTRLEN);
	fprintf(stderr, "Netmask: %s\n", addr);
	
	host.sin_addr.s_addr=net.s_addr;
	host.sin_family=AF_INET;
	
	while((host.sin_addr.s_addr & mask.s_addr)==net.s_addr) {
		if(getnameinfo((struct sockaddr *)&host, sizeof(struct sockaddr), hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD)==0) {
			inet_ntop(AF_INET, &host.sin_addr, addr, INET_ADDRSTRLEN);
			fprintf(stdout, "%s %s\n", hostname, addr);
		}
		host.sin_addr.s_addr=htonl(1+ntohl(host.sin_addr.s_addr));
	}
	return 0;
}

