Ejemplo n.º 1
0
/**
 * \fn struct probe_response probe_icmp(int sockfd, struct sockaddr_in *destination)
 * \brief traite le lancement et la reception d'une sonde sur le réseau
 * \param sockfd, socket a utilisé pour le ping
 * \param destination, pointeur vers la structure sockaddr_in contenant les informations de la destination des paquets
 * \return une structure probe_response contenant les informations necessaire du paquet recu
 */
struct probe_response probe_icmp(int sockfd, struct sockaddr_in *destination) {
    struct packet pkt_r;
    struct icmp_header *pkt_s;
    struct probe_response response;
    struct timeval interval;
    
    response.source_ip = malloc(sizeof(uint32_t)); //

    response.status = PROBE_NO_RESPONSE;
    response.integrity_error = INTEGRITY_OK;
    response.time = TIMEOUT*1000;

    //Envoi le paquet ICMP
    if ((pkt_s = send_echo_request(sockfd, destination)) == NULL)
    {
        perror("Envoi de la sonde échoué ");
        response.status = PROBE_SEND_FAIL;
    }
    //Réinitialisation des valeurs necessaire a select
    interval.tv_sec = TIMEOUT;
    interval.tv_usec = 0;

    if (receive_packet(sockfd, &pkt_r, &interval) > 0) {
        response.status = PROBE_OK; // on a reçu une réponse
    }
    else
        return response;
    
    // Stock l'ip du routeur dans ip_string en format texte
    if(inet_ntop(AF_INET, &(pkt_r.ip.ip_src), response.source_ip,
                 sizeof(char)*16) == NULL) {
        perror("echec inet_ntop");
        response.integrity_error = 1;
        response.source_ip = NULL;
    }

    response.icmp = pkt_r.icmp;
    response.ttl = pkt_r.ip.ttl;

    if(!(pkt_r.icmp.type == 0 &&
         pkt_r.icmp.id == pkt_s->id &&
         pkt_r.icmp.seq_num == pkt_s->seq_num)) {
        response.integrity_error = INTEGRITY_ERROR;
    }
    
    response.time = (1000000 - (long int) interval.tv_usec) / 1000;
    if (TIMEOUT - 1 - interval.tv_sec > 0)
        response.time += (long int) (TIMEOUT - 1 - interval.tv_sec)*1000;

    return response;
}
Ejemplo n.º 2
0
/* Send a set of pings to nodes in order */
void send_npings(nw_skt_t sock, I3ServerList *list, I3ServerListNode **node, int n)
{
    int i;
    static int seq = 1;
    struct in_addr ia;
    
    n = MIN(n, list->num_ping_list);
    for (i = 0; i < n; i++) {
	ia.s_addr = htonl((*node)->addr);
	I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE, 
		"Sending echo request to %s\n", inet_ntoa(ia));
#ifdef ICMP_PING
	send_echo_request(sock, (*node)->addr, seq);
#else
	i3_echo_request(sock, (*node)->addr, (*node)->port, seq);
#endif
	
	*node = (*node)->next_list;
	if (NULL == *node) {
	    *node = list->list;
	    seq++;
	}
    }
}
Ejemplo n.º 3
0
/*
 * Function: main
 * Purpose:  
 * Comments: 
 */
int main(int argc, char *argv[])
{
  int                i;
  struct sigaction   si_sa;
  int                euid, ruid;
  struct host_entry *cursor;

  /*
   * first things first
   * if anything goes wrong anywhere, we want to be super careful to release
   * any file descriptor we have on /dev/lkm, and it probably makes sense to
   * shutdown the raw socket we have too.
   */
  atexit(cleanup);

  /*
   * get the effective and the real user id's so we know if we are running
   * with elevated permissions or not
   */
  euid = geteuid();
  ruid = getuid();

  /* check for the command line arguments */
  if(check_options(argc,argv) == 0)
    {
      return -1;
    }

  /*
   * open the raw socket now.  i used to have this further down closer to
   * where it was needed, but because you can't change the euid/uid to and
   * from root (unless you're the superuser) i can only do this once
   */
  if(options & OPT_IPV4)
    {
      if(open_ipmp_sockets4() == 0) return -1; 
    }
  else if(options & OPT_IPV6)
    {
      if(open_ipmp_sockets6() == 0) return -1; 
    }
  else
    {
      if(open_ipmp_sockets4() == 0) return -1;
      if(open_ipmp_sockets6() == 0) return -1;
    }

  /*
   * revoke the permissions we requested as we only need them to open a raw
   * socket.  this is to reduce the impact of any buffer overflow exploits
   * that may be present
   */
  if(ruid != euid)
    {
      setreuid(ruid, ruid);
    }

  /*
   * we get the pid so we can identify incoming ipmp packets destined for
   * this instance of ipmp_ping
   */
  pid = getpid();

  /*
   * need to know about the addresses this host has
   */
  learn_localaddresses();

  /*
   * in FreeBSD, the actual ping is done by a kernel module that has a syscall
   * in it.  the kernel module allows the protocol to get a timestamp as close
   * to when the mbuf is actually sent to ip_output as possible
   */
#if defined(__FreeBSD__)
  if((options & OPT_RAW) == 0)
    {
      i = get_syscall("ipmp_ping", &syscall_num);
      if(i != 0)
        {
          printerror(i, strerror, "could not get the syscall for ipmp_ping");
          return -1;
        }
    }
#endif

  /*
   * the -n option means that the user has supplied a list of hosts to
   * ping, so we read those entries and put them in an list of hosts with
   * details regarding each host.  the task of putting hosts into the list
   * is handled by read_hosts_file
   *
   * if the -n option isnt specified, we create a list containing just the 
   * one host to ping.  this way, all the program logic can be used in a
   * multitude of situations.
   */
  if(options & OPT_NLANR)
    {
      /*
       * if something went wrong parsing the file, we quit.
       */
      if(read_hosts_file() == 0)
	{
	  return -1;
	}
    }
  else
    {
      /*
       * if the user didnt specify a host to ping, we bail, telling them
       * why first...
       */
      if(argc - optind != 1)
	{
	  usage(0);
          return -1;
	}

      /*
       * if we can't add a host entry for the host supplied on the command line
       * tell the user that it couldnt be parse and cleanup
       */
      if(add_host_entry(argv[optind], NULL) == 0)
	{
	  return -1;
	}
    }

  /*
   * we now put some handlers into action so if the user ctrl-c's us we have
   * the opportunity to tell them what we found out first
   * also, if the user specified a timeout, put an alarm in for that so we
   * can bail when they tell us to...
   */
  sigemptyset(&si_sa.sa_mask);
  si_sa.sa_flags = 0;
  si_sa.sa_handler = alarm_bells;
  if(sigaction(SIGINT, &si_sa, 0) == -1)
    {
      printerror(errno, strerror, "could not set sigaction for SIGINT");
      return -1;
    }
  if(options & OPT_TIMEOUT)
    {
      if(sigaction(SIGALRM, &si_sa, 0) == -1)
	{
	  printerror(errno, strerror, "could not set sigaction for SIGALRM");
	  return -1;
	}
    }

  /*
   * we loop for as long as we have not been told to finish up.
   * the finish_up loop will exit when
   *  - there has been an alarm set that goes off
   *  - a SIGINT is received (from e.g. Ctrl-C)
   *  - we have got_all_response()'s
   *
   * this is not an expensive loop in terms of cpu cycles, as the
   * recv_echo_response will sleep if there is nothing to recv until we have
   * told it to stop blocking - typically one second or whatever the between
   * timeout is.
   *
   * the loop does two things:
   *  - sends echo requests
   *  - receives echo responses
   *
   * the loop sends packets, pausing for however long the timeout is set for
   * between packets.  this pause is implemented in the recv_echo_response
   * function in a call to select(2).  if we cannot send a request to one of
   * them, we bail, as this probably means the syscall could not be called.
   *
   * the loop recv's the response and associates the packet with a host_entry
   * we then parse that response for the host entry, and then check if we have
   * now got all the responses we are looking for.  if we have, we exit the
   * loop by setting the finish_up flag
   */

  sent_all_requests = 0;
  i = 0;

  cursor = head;

  while(finish_up == 0)
    {
      while(sent_all_requests == 0)
	{
	  if(send_echo_request(cursor) != 0)
	    {
	      return -1;
	    }
	  cursor->tx++;

	  if(cursor->tx == count)
	    {
	      cursor = cursor->next;
	      if(cursor == NULL)
		{
		  sent_all_requests = 1;
		  alarm(timeout);
		  break;
		}
	    }

	  if(wait_between > 0)
	    {
	      gettimeofday(&wait_between_tv, &tz);
	      timeval_add(&wait_between_tv, wait_between);
	      break;
	    }
	}

      while(time_to_send_request() == 0 && finish_up == 0)
	{
	  if(recv_echo_responses() > 0)
	    {
	      if(got_all_responses() == 1)
		{
		  finish_up = 1;
		}
	    }
	}
    }

  /*
   * if we have been given a list of hosts to ping, we have to print out which
   * hosts did not give us a reply
   */
  if(options & OPT_NLANR)
    {
      show_loss();
    }

  return 0;
}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
	struct {
		struct kdbus_cmd_bus_make head;

		/* name item */
		uint64_t n_size;
		uint64_t n_type;
		char name[64];
	} __attribute__ ((__aligned__(8))) bus_make;
	int fdc, ret;
	char *bus;
	struct conn *conn_a;
	struct conn *conn_b;
	struct pollfd fds[2];
	struct timeval start;
	unsigned int i;

	for (i = 0; i < sizeof(stress_payload); i++)
		stress_payload[i] = i;

	printf("-- opening /dev/kdbus/control\n");
	fdc = open("/dev/kdbus/control", O_RDWR|O_CLOEXEC);
	if (fdc < 0) {
		fprintf(stderr, "--- error %d (%m)\n", fdc);
		return EXIT_FAILURE;
	}

	memset(&bus_make, 0, sizeof(bus_make));
	bus_make.head.bloom_size = 64;

	snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
	bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
	bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;

	bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
			     bus_make.n_size;

	printf("-- creating bus '%s'\n", bus_make.name);
	ret = ioctl(fdc, KDBUS_CMD_BUS_MAKE, &bus_make);
	if (ret) {
		fprintf(stderr, "--- error %d (%m)\n", ret);
		return EXIT_FAILURE;
	}

	if (asprintf(&bus, "/dev/kdbus/%s/bus", bus_make.name) < 0)
		return EXIT_FAILURE;

	conn_a = connect_to_bus(bus);
	if (!conn_a)
		return EXIT_FAILURE;

	conn_b = connect_to_bus(bus);
	if (!conn_b)
		return EXIT_FAILURE;

	upload_policy(conn_a->fd, SERVICE_NAME);

	add_match_empty(conn_a->fd);
	add_match_empty(conn_b->fd);

	fds[0].fd = conn_a->fd;
	fds[1].fd = conn_b->fd;

	name_acquire(conn_a, SERVICE_NAME, 0);

	gettimeofday(&start, NULL);
	reset_stats();

	ret = send_echo_request(conn_b, conn_a->id);
	if (ret)
		return EXIT_FAILURE;

	printf("-- entering poll loop ...\n");

	while (1) {
		struct timeval now;
		unsigned int nfds = sizeof(fds) / sizeof(fds[0]);
		unsigned int i;

		for (i = 0; i < nfds; i++) {
			fds[i].events = POLLIN | POLLPRI | POLLHUP;
			fds[i].revents = 0;
		}

		ret = poll(fds, nfds, 10);
		if (ret < 0)
			break;

		if (fds[0].revents & POLLIN) {
			ret = handle_echo_reply(conn_a);
			if (ret)
				break;

			ret = send_echo_request(conn_b, conn_a->id);
			if (ret)
				break;
		}

		gettimeofday(&now, NULL);
		if (timeval_diff(&now, &start) / 1000ULL > 1000ULL) {
			start.tv_sec = now.tv_sec;
			start.tv_usec = now.tv_usec;
			dump_stats();
			reset_stats();
		}
	}

	printf("-- closing bus connections\n");

	close(conn_a->fd);
	close(conn_b->fd);

	free(conn_a);
	free(conn_b);

	printf("-- closing bus master\n");
	close(fdc);
	free(bus);

	return EXIT_SUCCESS;
}
Ejemplo n.º 5
0
/* To determine the coordinates of the local node initially
 * Ping a subset of nodes and determine coordinates */
void init_coordinates(I3ServerList *list)
{
    int n = MIN(NUM_LANDMARKS_COORDINATE, list->num_newservers + list->num_ping_list);
    I3ServerListNode *node = list->list, *temp_node;
    uint64_t start_time = wall_time();
    Coordinates_RTT coord_rtt[NUM_LANDMARKS_COORDINATE];
    int num_landmarks = 0; int started_full_list = 0;
    struct in_addr ia;
    nw_skt_t tmp_ping_sock;

#ifdef ICMP_PING
    if (init_icmp_socket(&tmp_ping_sock) == -1)
	abort();
#else
    if (init_udp_socket(&tmp_ping_sock) == -1)
	abort();
#endif

    // wait for responses and accumulate
    // cut and pasted from below
    while ((wall_time() - start_time < COORD_INIT_PING_WAIT_TIME) && 
	    (num_landmarks < n)) {
	fd_set rset;
	struct timeval to;
	int ret;

	FD_ZERO(&rset);

	if (!node && !started_full_list) {
	    node = list-> full_list;
	    started_full_list = 1;
	}
	
	if (node) {
	    ia.s_addr = htonl(node->addr);
	    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE,
		    "Sending ICMP echo request to %s\n", inet_ntoa(ia));
#ifdef ICMP_PING
	    send_echo_request(tmp_ping_sock, node->addr, 0);
#else
	    i3_echo_request(tmp_ping_sock, node->addr, node->port, 0);
#endif
	    node = node->next_list;
	}

	FD_SET(tmp_ping_sock, &rset);
        to.tv_sec = 0; to.tv_usec = 200000ULL;
        if ((ret = select(tmp_ping_sock+1, &rset, NULL, NULL, &to)) < 0) {
	    int err = nw_error();
            if (err == EINTR)
                continue;
            else {
                perror("select");
                abort();
            }
        }

	// message received on icmp socket
	if (FD_ISSET(tmp_ping_sock, &rset)) {
	    uint32_t addr; uint16_t port, seq; uint64_t rtt;
#ifdef ICMP_PING
	    if (recv_echo_reply(tmp_ping_sock, &addr, &seq, &rtt)) {
#else
	    if (recv_i3_echo_reply(tmp_ping_sock, &addr, &port, &seq, &rtt)) {
#endif
		temp_node = lookup_i3server(list, addr);
		assert(NULL != temp_node);

		coord_rtt[num_landmarks].coord = temp_node->coord;
		coord_rtt[num_landmarks].rtt = rtt;
		num_landmarks++;

		ia.s_addr = htonl(addr);
		I3_PRINT_DEBUG4(I3_DEBUG_LEVEL_VERBOSE,
			"Node: %s Coordinate: %.1f:%.1f RTT: %Ld\n",
			inet_ntoa(ia), temp_node->coord.latitude,
			temp_node->coord.longitude, rtt);
	    }
	}
    }
    nw_close(tmp_ping_sock);

    // compute own coordinate
    compute_coordinates(num_landmarks, coord_rtt);
}

/* Update the coordinates of a node using ping information */
void update_coordinate(I3ServerList *list, I3ServerListNode *next_to_ping)
{
    Coordinates_RTT coord_rtt[NUM_LANDMARKS_COORDINATE];
    int count, num_landmarks = 0;
    I3ServerListNode *node;

    // n1 and n2: number of landmarks from ping_list and rest in
    // proportion to the number of nodes in those lists
    int i, n = MIN(NUM_LANDMARKS_COORDINATE, 
	    list->num_newservers + list->num_ping_list);
    int n1 = ((float)list->num_ping_list/
	    (list->num_newservers + list->num_ping_list)) * n;
    int n2 = n-n1;

    // add from ping list
    count = 0;
    for (i = 0, node = list->list; 
	    i < list->num_ping_list, count < n1;
	    node = node->next_list, ++i) {
	if (node->n > 0) {
	    coord_rtt[count].rtt = get_rtt_node(node);
	    coord_rtt[count].coord = node->coord;
	    count++;
	}
    }
    num_landmarks = count;

    // add from rest
    count = 0;
    for (i = 0, node = list->full_list; 
	    i < list->num_newservers, count < n2; 
	    node = node->next_list, ++i) {
	if (node->n > 0) {
	    coord_rtt[num_landmarks + count].rtt = get_rtt_node(node);
	    coord_rtt[num_landmarks + count].coord = node->coord;
	    count++;
	}
    }
    num_landmarks += count;

    // recompute coordinates
    compute_coordinates(num_landmarks, coord_rtt);

    // repopulate ping list afresh
    change_ping_list(list, &next_to_ping, 1);
}
Ejemplo n.º 6
0
void
snmp_tunnel_ap_run(int tunnelfd,int trapfd)
{
	struct pollfd fds[MAX_SNMP_MANAGERS + 2];
	int num_fds = MAX_SNMP_MANAGERS + 2;
	char buffer[MAX_MSG_SIZE];
	struct sockaddr_in snmpd_addr;
	int n_read,n_write;
	struct snmp_manager managers[MAX_SNMP_MANAGERS];


	/* this is where the local snmpd agent listens */
	bzero((char*)&snmpd_addr, sizeof(snmpd_addr));
	snmpd_addr.sin_family = AF_INET;
	/* TODO : better define localhost here...? */
	snmpd_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	snmpd_addr.sin_port = htons(snmpd_port);

	/* prepare the sockets to be polled */
	/* tunnel-side */
	fds[0].fd = tunnelfd;
	fds[0].events = POLLIN | POLLHUP;


	/* prepare the sockets to be polled */
	/* tunnel-side */
	fds[1].fd = trapfd;
	fds[1].events = POLLIN | POLLHUP;




	/* initialize all manager structs. */
	int i;
	for (i = 0; i < MAX_SNMP_MANAGERS ; i++){
		managers[i].is_active = false;
		managers[i].pfd = &fds[i+2];
		managers[i].pfd->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		managers[i].pfd->events = POLLIN | POLLHUP;
		managers[i].last_active = 0;
	}

	int retval;
	int current_fd;
	tunnel_pkt_header * hdr;
	uint16_t type;
	int last_active = second_now();

	for(;;){

		retval = poll(fds, num_fds, AGENT_KEEPALIVE);

		if (retval == 0){
			printf("sending ECHO_REQUEST\n");
			send_echo_request(fds[0].fd);
		}

		else{
			/* if something came from the tunnel, send it to snmpd */
			if(fds[0].revents & POLLIN) {
				last_active = second_now();
				memset(buffer,'\0', MAX_MSG_SIZE);
				n_read = recv(fds[0].fd, buffer, MAX_MSG_SIZE, 0);
				if(n_read <= 0){
					printf("cannot read from socket - reconnecting...(%s)\n",strerror(errno));
					break;
				}
				else {
					if(process_tunnel_packet(managers, buffer, snmpd_addr) != SUCCESS) {
						printf("failed to process packet from tunnel...");
						// break; - no need to disconnect here...
					}
				}
			}
			
			/* forward snmp traps to the tunnel */
			if(fds[1].revents & POLLIN) {
				if(forward_tunnel_trap_packet(fds[1].fd,fds[0].fd) != SUCCESS) {
					printf("Failed to forward trap to tunnel...\n");
					break;
				}
			}


			/* if something came from snmpd, we need to multiplex and send to the tunnel */
			for (i = 0; i < MAX_SNMP_MANAGERS ; i++) {
				if (managers[i].pfd->revents & POLLIN) {
					if(forward_tunnel_packet(managers[i],fds[0].fd) != SUCCESS) {
						printf("failed to forward to tunnel...\n");
						break;
					}
				}
			}
		}
		
		/* check that the other end is still there... */
		if ( (second_now() - last_active) > AGENT_TIMEOUT ) {
			printf("connection seems broken - reconnecting...\n");
			break;
		}
	}

	printf("Exiting loop...\n");
	/* close all sockets (tunnel + managers) */
	for (i = 0; i < MAX_SNMP_MANAGERS + 1; i++){
		close(fds[i].fd);
	}
}