Exemplo n.º 1
0
apr_socket_t *
create_mcast_server(apr_pool_t *context, int32_t family, char *mcast_ip, apr_port_t port, char *bind_addr, char *interface)
{
  apr_status_t status = APR_SUCCESS;
  /* NOTE: If bind is set to mcast_ip in the configuration file, then we will bind the 
   * the multicast address to the socket as well as the port and prevent any 
   * datagrams that might be delivered to this port from being processed. Otherwise,
   * packets destined to the same port (but a different multicast/unicast channel) will be
   * processed. */
  apr_socket_t *socket = create_udp_server(context, family, port, bind_addr);
  if(!socket)
    {
      return NULL;
    }

  /* TODO: We can probe for a list of interfaces and perform multiple join calls for the same
   * socket to have it listen for multicast traffic on all interfaces (important for
   * multihomed machines). */
  if(interface && !apr_strnatcasecmp(interface, "ALL"))
    {
      /* for(each interface)
       * {
       *   join_mcast(...);
       * }
       */
    }
  else
    {
      status = join_mcast(context,  socket, mcast_ip, port, interface );
    }

  return status == APR_SUCCESS? socket: NULL;
}
Exemplo n.º 2
0
void intercom_update_interfaces(intercom_ctx *ctx) {
  for (int i = 0; i < VECTOR_LEN(ctx->interfaces); i++) {
    intercom_if *iface = &VECTOR_INDEX(ctx->interfaces, i);

    iface->ifindex = if_nametoindex(iface->ifname);

    if (!iface->ifindex)
      continue;

    if (join_mcast(ctx->fd, ctx->groupaddr.sin6_addr, iface))
      iface->ok = true;
  }
}
Exemplo n.º 3
0
Arquivo: net.c Projeto: brabander/olsr
void
os_socket_set_olsr_options(struct interface * ifs, int sock, union olsr_sockaddr *mcast) {
  /* Set TOS */
  int data = IPTOS_PREC(olsr_cnf->tos);
  if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (char *)&data, sizeof(data)) < 0) {
    OLSR_WARN(LOG_INTERFACE, "setsockopt(SO_PRIORITY) error %s", strerror(errno));
  }
  data = IPTOS_TOS(olsr_cnf->tos);
  if (setsockopt(sock, SOL_IP, IP_TOS, (char *)&data, sizeof(data)) < 0) {
    OLSR_WARN(LOG_INTERFACE, "setsockopt(IP_TOS) error %s", strerror(errno));
  }

  if (mcast) {
    join_mcast(ifs, sock, mcast);
  }
}
Exemplo n.º 4
0
int servopen(char* host, char* port)
{
    int fd, newfd, i, on, pid;
    const char* protocol;
    struct in_addr inaddr;
    struct servent* sp;

    protocol = udp ? "udp" : "tcp";

    /* Initialize the socket address structure */
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;

    /* Caller normally wildcards the local Internet address, meaning
           a connection will be accepted on any connected interface.
           We only allow an IP address for the "host", not a name. */
    if (host == NULL)
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */
    else {
        if (inet_aton(host, &inaddr) == 0)
            err_quit("invalid host name for server: %s", host);
        servaddr.sin_addr = inaddr;
    }

    /* See if "port" is a service name or number */
    if ((i = atoi(port)) == 0) {
        if ((sp = getservbyname(port, protocol)) == NULL)
            err_ret("getservbyname() error for: %s/%s", port, protocol);

        servaddr.sin_port = sp->s_port;
    } else
        servaddr.sin_port = htons(i);

    if ((fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
        err_sys("socket() error");

    if (reuseaddr) {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
            err_sys("setsockopt of SO_REUSEADDR error");
    }

#ifdef SO_REUSEPORT
    if (reuseport) {
        on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
            err_sys("setsockopt of SO_REUSEPORT error");
    }
#endif

    /* Bind our well-known port so the client can connect to us. */
    if (bind(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        err_sys("can't bind local address");

    join_mcast(fd, &servaddr);

    if (udp) {
        buffers(fd);

        if (foreignip[0] != 0) { /* connect to foreignip/port# */
            bzero(&cliaddr, sizeof(cliaddr));
            if (inet_aton(foreignip, &cliaddr.sin_addr) == 0)
                err_quit("invalid IP address: %s", foreignip);
            cliaddr.sin_family = AF_INET;
            cliaddr.sin_port = htons(foreignport);
            /* connect() for datagram socket doesn't appear to allow
                   wildcarding of either IP address or port number */

            if (connect(fd, (struct sockaddr*)&cliaddr, sizeof(cliaddr)) < 0)
                err_sys("connect() error");
        }

        sockopts(fd, 1);

        return (fd); /* nothing else to do */
    }

    buffers(fd);     /* may set receive buffer size; must do here to get
                               correct window advertised on SYN */
    sockopts(fd, 0); /* only set some socket options for fd */

    listen(fd, listenq);

    if (pauselisten)
        sleep_us(pauselisten * 1000); /* lets connection queue build up */

    if (dofork) TELL_WAIT(); /* initialize synchronization primitives */

    for (;;) {
        i = sizeof(cliaddr);
        if ((newfd = accept(fd, (struct sockaddr*)&cliaddr, &i)) < 0)
            err_sys("accept() error");

        if (dofork) {
            if ((pid = fork()) < 0) err_sys("fork error");

            if (pid > 0) {
                close(newfd); /* parent closes connected socket */
                WAIT_CHILD(); /* wait for child to output to terminal */
                continue;     /* and back to for(;;) for another accept() */
            } else {
                close(fd); /* child closes listening socket */
            }
        }

        /* child (or iterative server) continues here */
        if (verbose) {
            /* Call getsockname() to find local address bound to socket:
                   local internet address is now determined (if multihomed). */
            i = sizeof(servaddr);
            if (getsockname(newfd, (struct sockaddr*)&servaddr, &i) < 0)
                err_sys("getsockname() error");

            /* Can't do one fprintf() since inet_ntoa() stores
                           the result in a static location. */
            fprintf(stderr, "connection on %s.%d ",
                    INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
            fprintf(stderr, "from %s.%d\n", INET_NTOA(cliaddr.sin_addr),
                    ntohs(cliaddr.sin_port));
        }

        buffers(newfd);     /* setsockopt() again, in case it didn't propagate
                                   from listening socket to connected socket */
        sockopts(newfd, 1); /* can set all socket options for this socket */

        if (dofork)
            TELL_PARENT(getppid()); /* tell parent we're done with terminal */

        return (newfd);
    }
}
Exemplo n.º 5
0
int main(int argc, char **argv){
	const int  on = 1;
	unsigned char ttl = 1;
	time_t 	   rawtime;
	time_t 	   lasttime;
	int 	   maxfd;
	fd_set 	   rset;
	ssize_t	   how_much_read;
	char	   msg[MAXLINE];

	rt 			   = Socket(AF_INET, SOCK_RAW, MY_IP_PROTO);
	Setsockopt(rt, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));

	pg			   = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	request_sock   = Socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
	multicast_sock = Socket(AF_INET, SOCK_DGRAM, 0);
	multicast_recv = Socket(AF_INET, SOCK_DGRAM, 0);
	Mcast_set_loop(multicast_sock,0);
	Setsockopt(multicast_sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
	Setsockopt(multicast_recv, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

	gethostname(our_hostname, sizeof(our_hostname));
	//printf("My our_hostname: %s\n", our_hostname);
	get_eth0_stuff();
	if(argc > 1)
	{
		//DEBUG("%s is the start of the tour!\n",our_hostname);

		int   i = 1;		
		tour  tour_pkt;
		
		// separate func
		bzero(&tour_pkt, sizeof(tour_pkt));

		fill_buff_with_ip_of_hostname(our_hostname);
		//printf("fill buff ok\n");
		inet_aton(ip_static_buff, &(tour_pkt.payload[0]));
		join_mcast(MULTICAST_ADDRESS, MULTICAST_PORT);
		#if 0
		// tokenize by ' ' and send each char* to gethostbyname
		char 		*token, *prev_token;
		const char  s[2] = " ";

		/* get the first token */
		token = strtok(argv[1], s);

		/* walk through other tokens */
		while(token != NULL)
		{
			DEBUG("token = %s\n", token );

			fill_buff_with_ip_of_hostname(token);
			inet_aton(ip_static_buff, &tour_pkt.payload[i]);

			prev_token  = token;
			token 		= strtok(NULL, s);
			if(!strcmp(prev_token, token)){
				perror("The same node should not appear consequentively in the tour list – i.e., the next node on the tour cannot be the current node itself");
				exit(0);
			}

			i++;
		}
		// separate func
		#endif
		while(i< argc)
		{
			//printf("argv[%d] is %s\n",i, argv[i]);
			fill_buff_with_ip_of_hostname(argv[i]);
			//printf("fill buff ok\n");
			inet_aton(ip_static_buff, &(tour_pkt.payload[i]));
			i++;
		}
		tour_pkt.index = 0; // We're the origin
		tour_pkt.total = i-1;
		//printf("tour_pkt total %d\n", tour_pkt.total);
		send_raw_tour_packet(&tour_pkt);

	}else{
		//DEBUG("We're NOT the start of the tour!");
		#if 0
		while(1)
		{
			int len = 0;
			len = Recv(rt, msg, sizeof(msg), 0);
			printf("received len %d\n",len);
			int j = 0;
			for(;j<len; j++)
			{
				printf("%.2x ", msg[j]);
				if((i-9) % 10 == 0) printf("\n");
				fflush(stdout);
			}
		}
		#endif
	}
	#if 0
	fill_buff_with_ip_of_hostname("vm2");
	inet_aton(ip_static_buff, (struct in_addr *)&dest_of_echo_req);
	printf("destofechoreq %x\n", dest_of_echo_req.s_addr);
	struct sockaddr_in IPaddr;
	struct hwaddr 	   HWaddr;
	bzero(&IPaddr, sizeof(IPaddr));
	bzero(&HWaddr, sizeof(HWaddr));
	IPaddr.sin_addr = dest_of_echo_req;
	//Areq((struct sockaddr *)&IPaddr, sizeof(struct sockaddr_in), &HWaddr);
	//printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",HWaddr.sll_addr[0],HWaddr.sll_addr[1],HWaddr.sll_addr[2],
	//			HWaddr.sll_addr[3],HWaddr.sll_addr[4],HWaddr.sll_addr[5]);
	void sig_alrm(int signo);
	if(argc > 1){
	Signal(SIGALRM, sig_alrm);
	sig_alrm(SIGALRM);
	}
	//send_icmp_request(HWaddr.sll_addr);
	int n  = 0;
	struct timeval tval;
	
	while(1)
	{
		n = recv(pg, msg, sizeof(msg), 0);
		if(n<0)
		{
			if (errno == EINTR)
				continue;
		}
		printf("receive ping packet\n");
		//int j = 0;
		//for (; j < n; j++)
		//{
		//	printf("%.2x ", msg[j]);
		//	if((j-9) % 10 == 0) printf("\n");
		//	fflush(stdout);
		//}
		Gettimeofday(&tval, NULL);
		proc_v4(msg,n,NULL, &tval);
	}
	#endif
	#if 1
    //act_open.sa_flags = 0;
    //sigemptyset(&act_open.sa_mask);
    //sigaddset(&act_open.sa_mask, SIGALRM);
    //act_open.sa_handler = terminate;
	Signal(SIGALRM, sig_alrm);
	FD_ZERO(&rset);
	maxfd = max(pg, multicast_recv);
	maxfd = max(rt, maxfd);

	while(1){
		FD_SET(multicast_recv, &rset);
		FD_SET(rt, &rset);
		FD_SET(pg, &rset);

		if(select(maxfd+1, &rset, NULL, NULL, NULL)<0)
		{
			if(errno == EINTR)
			{
				continue;
			}
		}

		if(FD_ISSET(rt, &rset)){
			//DEBUG("possibly totally wrong here\n");
			//DEBUG("possibly totally wrong here\n");
			//DEBUG("possibly totally wrong here\n");
			alarm(0);
			bzero(msg, sizeof(msg));
			how_much_read = Recv(rt, msg, sizeof(msg), 0);
		

			//assert(how_much_read == sizeof(sizeof(my_ip_header)+sizeof(tour)));
			//printf("rt receive pkt len %d\n", how_much_read);
			my_ip_header  *head     =  (my_ip_header *)msg;
			tour 		  *tour_pkt =  (tour *)(msg+sizeof(my_ip_header));
			
			if(ntohs(head->id) != MY_IP_ID){
				//DEBUG("head->id != MY_IP_ID\n");
				continue;
			}
			char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&head->saddr));
			time(&rawtime);
			printf("<%s> recieved source routing packet from <%s>\n", ctime (&rawtime), name);
			
			if(!already_here){
				already_here = 1;
				// IP_MULTICAST_TTL - If not otherwise specified, has a default value of 1.
				join_mcast(inet_ntoa(tour_pkt->multicast_addr), ntohs(tour_pkt->multicast_port));
				stop_pinging = 0;
			}
				// start icmp echo reqs
			for(i = 0; i < prev_sender_list.index; i++)
			{
				if(!memcmp(&prev_sender_list.previous_senders[i], &tour_pkt->payload[(tour_pkt->index)], sizeof(struct in_addr)))
					we_dont_need_to_send_echo_req = 1;
				else{
					we_dont_need_to_send_echo_req = 0;
					break;
				}
			}

			if(!we_dont_need_to_send_echo_req){
				//DEBUG("We Need To Send Echo Request\n");

				prev_sender_list.previous_senders[prev_sender_list.index] = tour_pkt->payload[(tour_pkt->index)];
				prev_sender_list.index++;

				dest_of_echo_req = tour_pkt->payload[(tour_pkt->index)];

				char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&tour_pkt->payload[(tour_pkt->index)]));
				printf("PING %s (%s): %d data bytes\n",name,inet_ntoa(dest_of_echo_req), icmpdata);
				sig_alrm(SIGALRM);
			}
			else
			{
				char *name = find_vm_name(inet_ntoa(*(struct in_addr *)&tour_pkt->payload[(tour_pkt->index)]));
				printf("We have ping %s before\n",name);
			}
			

			// INCREMENTING THE INDEX
			tour_pkt->index = (tour_pkt->index)+1;
			if((tour_pkt->index) == MAX_VISITS){
				perror("MAX_VISITS has been reached.");
				exit(0);
			}

			// Now blank
			//bzero(&for_comparisons, sizeof(for_comparisons));
			// ghiTODO this may not work ghiTODO
			//if(!memcmp(&tour_pkt->payload[ntohl(tour_pkt->index)], &for_comparisons, sizeof(for_comparisons))){
			//printf("rt current pkt index %d, total index %d\n",tour_pkt->index, tour_pkt->total);
			if(tour_pkt->index == tour_pkt->total)
			{
				//printf("We're the final destination.\n");
				// ping the saddr
				final_destination = 1;
				char buffer[100];
				snprintf(buffer, 100, "<<<<< This is node %s.  Tour has ended.  Group members please identify yourselves. >>>>>",our_hostname);
				printf("Node %s.  Sending: <%s>.  ",our_hostname, buffer);
				send_multicast_message(buffer,strlen(buffer)+1);
				//printf("send mulitcast msg ok\n");

			}else{
				//printf("We're NOT the final destination, keep touring.\n");
				// pass it along
				send_raw_tour_packet(tour_pkt);
			}


		}else if(FD_ISSET(multicast_recv, &rset)){
			//DEBUG("Receiving multicast message.\n");
			printf("");
			bzero(msg, sizeof(msg));
			how_much_read = Recv(multicast_recv, msg, sizeof(msg), 0);
			//printf("multicast msg len %d\n", how_much_read);
			msg[how_much_read]='\0';
			if(!first_term){
				printf("Node %s.  Received <%s>.  ",our_hostname,msg);
				// then should immediately stop ping 
				//DEBUG("how_much_read is %lu\n", how_much_read);
				stop_pinging = 1;
				alarm(0);
				bzero(msg, sizeof(msg));
				snprintf(msg, sizeof(msg), "<<<<< Node %s I am a member of the group. >>>>>", our_hostname);
				printf("Node %s. Sending <%s>.  ", our_hostname, msg);
				fflush(stdout);
				first_term = 1;
				send_multicast_message(msg,strlen(msg)+1);
			}
			else
			{
				Signal(SIGALRM, terminate);
				alarm(5);
				printf("");
				printf("Node %s.  Received <%s>.  ",our_hostname,msg);
				fflush(stdout);
			}

			//send_multicast_message(msg);
		}else if(FD_ISSET(pg, &rset)){
			//DEBUG("Receiving echo reply message.\n");
			struct timeval tval;
			bzero(msg, sizeof(msg));
			how_much_read = Recv(pg, msg, sizeof(msg), 0);
			Gettimeofday(&tval, NULL);
			proc_v4(msg,how_much_read,NULL, &tval);
			//assert(how_much_read == sizeof(sizeof(my_eth_header)+sizeof(my_ip_header)+sizeof(my_icmp_header)));
			//DEBUG("how_much_read is %lu\n", how_much_read);
			//DEBUG("Node %s recieved %s\n", our_hostname, msg);
			// my_eth_header   *eh    =  (my_eth_header  *)msg;
			// my_ip_header    *iph   =  (my_ip_header   *)msg+sizeof(my_eth_header);
			// my_icmp_header  *icmph =  (my_icmp_header *)msg+sizeof(my_eth_header)+sizeof(my_ip_header);
			//my_ip_header *iph = (my_ip_header *)(msg+sizeof(my_eth_header));
			//if(!memcmp(&iph->saddr, &dest_of_echo_req, sizeof(dest_of_echo_req))){
			//	DEBUG("ghiTODO\n");
			//	count_of_replies++;
			//	DEBUG("ghiTODO\n");
				//DEBUG("ghiTODO\n");
				//DEBUG("ghiTODO\n");
			//	if(final_destination && count_of_replies >= 5){
			//		stop_pinging = 1;
			//		bzero(msg, sizeof(msg));
			///		snprintf(msg, sizeof(msg), "<<<<< This is node %s Tour has ended. Group members please identify yourselves.>>>>>", our_hostname);
			//		printf("Node %s sending %s", our_hostname, msg);
			//		send_multicast_message(msg, strlen(msg)+1);
			//		alarm(5);
			//	}
			//}else{
				//DEBUG("The following is FALSE !memcmp(&iph->saddr, &dest_of_echo_req, sizeof(dest_of_echo_req))");
			//}
		}
		#if 0
		time(&rawtime);
		if(lasttime+1 <= rawtime){
			if(!stop_pinging){	
				struct sockaddr_in IPaddr;
				struct hwaddr 	   HWaddr;
				bzero(&IPaddr, sizeof(IPaddr));
				bzero(&HWaddr, sizeof(HWaddr));
				IPaddr.sin_addr = dest_of_echo_req;
				Areq((struct sockaddr *)&IPaddr, sizeof(struct sockaddr_in), &HWaddr);
				send_raw_echo_request_message(HWaddr.sll_addr);
			}

		}else{
			lasttime = rawtime;
		}
		#endif

	}
	#endif
}
int main(int argc, char **argv) {
  int sock;
  struct sockaddr_in6 server_addr = {};
  char *script = NULL;
  struct in6_addr mgroup_addr;

  sock = socket(PF_INET6, SOCK_DGRAM, 0);

  if (sock < 0) {
    perror("creating socket");
    exit(EXIT_FAILURE);
  }

  server_addr.sin6_family = AF_INET6;
  server_addr.sin6_addr = in6addr_any;

  opterr = 0;

  int group_set = 0;

  int c;
  while ((c = getopt(argc, argv, "p:g:s:i:h")) != -1)
    switch (c) {
      case 'p':
        server_addr.sin6_port = htons(atoi(optarg));
        break;
      case 'g':
        if (!inet_pton(AF_INET6, optarg, &mgroup_addr)) {
          perror("Invalid multicast group. This message will probably confuse you");
          exit(EXIT_FAILURE);
        }

        group_set = 1;
        break;
      case 's':
        free(script); // in case -s is given multiple times

        script = strdup(optarg);

        if (script == NULL) {
          perror("Couldn't duplicate string");
          exit(EXIT_FAILURE);
        }
        break;
      case 'i':
        if (!group_set) {
          fprintf(stderr, "Multicast group must be given before interface.\n");
          exit(EXIT_FAILURE);
        }
        join_mcast(sock, mgroup_addr, optarg);
        break;
      case 'h':
        usage();
        exit(EXIT_SUCCESS);
        break;
      default:
        fprintf(stderr, "Invalid parameter %c ignored.\n", c);
    }

  if (script == NULL) {
    fprintf(stderr, "No script given\n");
    exit(EXIT_FAILURE);
  }

  if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
    perror("bind failed");
    exit(EXIT_FAILURE);
  }

  serve(sock, script);

  free(script);

  return EXIT_FAILURE;
}