示例#1
0
static void create()
{
    ::create();
    set_short_desc("Entrance");
    set_long_desc("A small, cramped room, roughly hewn from rock with little " +
		  "eye for detail.\n");
    add_neighbour("workroom",
		  "east", 0,
		  1, 1,
		  "A small room is visible through a doorway to the west.",
		  "to the west");
}
示例#2
0
文件: simu.c 项目: 12019/smews
int main(int argc, char **argv) {

	/* command line arguments variables */
	char *smewsBinaryPath = NULL;
	int nNodes = DEFAULT_NNODES;
	double nodeRange = DEFAULT_NODE_RANGE;
	double lossRate = DEFAULT_LOSS_RATE;

	/* misc. locals... */
	int i;
	int j;
	int ret;
	int nRead;
	int nfds;
	int tun_fd;
	int socket_fd;
	fd_set fdset;
	char tmpstr[64];
	char *cptr;
	struct sockaddr_in sockaddr;

	/* arguments parsing */
	if(argc == 1)
		usage();
	opterr = 0;
	while ((j = getopt (argc, argv, "hb:n:r:l:")) != -1) {
		switch (j) {
			case 'h':
				usage();
				break;
			case 'b':
				smewsBinaryPath = optarg;
				break;
			case 'n':
				nNodes = strtol(optarg, &cptr, 10);
				ensure(!*cptr && nNodes > 0,"Option -n requires a positive integer as argument.\n");
				break;
			case 'r':
				nodeRange = strtod(optarg, &cptr);
				ensure(!*cptr && nodeRange > 0 && nodeRange <=1,"Option -r requires a float in ]0-1] as argument.\n");
				break;
			case 'l':
				lossRate = strtod(optarg, &cptr);
				ensure(!*cptr && lossRate >= 0 && lossRate <=1,"Option -r requires a float in [0-1] as argument.\n");
				break;
			case '?':
				if(isprint (optopt))
					sprintf(tmpstr,"Unknown option `-%c'.\n", optopt);
				else
					sprintf(tmpstr,"Unknown option character `0x%x'.\n",optopt);
				ensure(0,tmpstr);
			default:
				ensure(0,"An error occured when parsing the arguments.\n");
		}
	}
	if(optind != argc) {
		sprintf(tmpstr,"Invalid argument `%s'\n", argv[optind]);
		ensure(0,tmpstr);
	}
	ensure(smewsBinaryPath != NULL,"Option -b is required.\n");

	/* print the current configuration */
	printf("Configuring the simulator...\n");
	printf("Smews binary path: %s\n",smewsBinaryPath);
	printf("Amount of nodes: %d\n",nNodes);
	printf("Nodes range: %f\n",nodeRange);
	printf("Loss rate: %f\n",lossRate);
	
	/* catch the 16 first signals signals */
	for(i=1; i<16; i++)
		signal(i, &cleanup);

	/* host socket creation */
	socket_fd = socket(AF_INET,SOCK_DGRAM,0);
	check(socket_fd != -1,"socket() error");
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(1024);
	sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	memset(&sockaddr.sin_zero,0,8);
	ret=bind(socket_fd,(struct sockaddr*)&sockaddr,sizeof(sockaddr));
	check(ret != -1,"bind() error");

	/* Smews processes and nodes creation */
	nodes = (struct node_s *)malloc(nNodes*sizeof(struct node_s));
	check(nodes != NULL,"malloc() error");
	srand(time(NULL));
	for(i=0; i<nNodes; i++) {
		nodes[i].first_neighbour = NULL;
		nodes[i].nodeN = i;
		/* set coordinates for the node i */
		do {
			nodes[i].x = rand()/(float)RAND_MAX;
			nodes[i].y = rand()/(float)RAND_MAX;
			for(j=0; j<i; j++) {
				/* set neighbourhoud */
				if(ABS_DIST(nodes[i],nodes[j]) <= nodeRange) {
					add_neighbour(&nodes[i],&nodes[j]);
					add_neighbour(&nodes[j],&nodes[i]);
				}
			}
		/* ensures that the graph is connected */
		} while (i!=0 && !nodes[i].first_neighbour);
		/* new Smews process creation */
		sprintf(tmpstr,"%d",i);
		setenv("SMEWS_ID",tmpstr,1);
		if(!vfork()) { 
			execl(smewsBinaryPath,"",NULL);
			perror("execl() error");
			cleanup(2);
		}
	}

	/* TUN interface creation */
	struct ifreq ifr;
	tun_fd = open(DEVTUN, O_RDWR);
	check(tun_fd != -1,"tun open() error");
	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_flags = IFF_TUN;
	ret = ioctl(tun_fd, TUNSETIFF, (void *) &ifr);
	check(ret >= 0,"tun ioctl error");
	/* TUN attachement to an IP address */
	snprintf((char*)tmpstr, BUFSIZE, "ifconfig %s 192.168.0.0 pointopoint 192.168.1.0 mtu 1500",ifr.ifr_name);
	ret = system((char*)tmpstr);
	check(ret != -1,"system() error when setting ifconfig");
	
	/* main loop */
	printf("Simulation is launched...\n");
	nfds = MAX(tun_fd,socket_fd)+1;
	FD_ZERO(&fdset);
	while(1) {
		FD_SET(tun_fd, &fdset);
		FD_SET(socket_fd, &fdset);
		ret = select(nfds, &fdset, NULL, NULL, NULL);
		check(ret != -1,"select() error");
		/* wait for something to read on tun_fd or socket_fd */
		if(ret) {
			if(FD_ISSET(tun_fd, &fdset)) {
				/* something has been received on tun_fd, we forward it to the reachable node */
				nRead = read(tun_fd, (void *)buffer, BUFSIZE);
				check(nRead != -1,"read() error");
				if(!loss_occurs(0,1,lossRate)) {
					sockaddr.sin_port = htons(1025);
					ret = sendto(socket_fd,buffer,nRead,0,(struct sockaddr*)&sockaddr,sizeof(sockaddr));
					check(ret != -1,"sendto() error");
				}
			}
			if(FD_ISSET(socket_fd, &fdset)) {
				/* something has been received on socket_fd */
				int addrLen;
				int emitterN;
				nRead = recvfrom(socket_fd,buffer,BUFSIZE,0,(struct sockaddr*)&sockaddr,&addrLen);
				check(nRead != -1,"recvfrom() error");
				emitterN = ntohs(sockaddr.sin_port) - (1025);
				if(emitterN >= 0 && emitterN < nNodes) {
					/* send the datagram to all the neighbours of the emitter */
					struct neighbour_s *curr_neighbour = nodes[emitterN].first_neighbour;
					while(curr_neighbour) {
						if(!loss_occurs(emitterN,curr_neighbour->node->nodeN,lossRate)) {
							sockaddr.sin_port = htons(1025 + curr_neighbour->node->nodeN);
							ret = sendto(socket_fd,buffer,nRead,0,(struct sockaddr*)&sockaddr,sizeof(sockaddr));
							check(ret != -1,"sendto() error");
						}
						curr_neighbour = curr_neighbour->next;
					}
					/* if the emitter is the reachable node, send the datagram on the TUN interface */
					if(emitterN == 0) {
						if(!loss_occurs(emitterN,0,lossRate)) {
							ret = write(tun_fd, buffer_shadow, nRead+4);
							check(ret != -1,"write() error");
						}
					}
				}
			}
		}
	}
	return 0;
}