Esempio n. 1
0
int
__bootp_find_local_ip(bootp_header_t *info)
{
    udp_socket_t    udp_skt;
    int             retry;
    unsigned long   start;
    ip_addr_t       saved_ip_addr;

    bp_info = info;

    diag_printf("\nRequesting IP conf via BOOTP/DHCP...\n");

    memcpy(&xid, __local_enet_addr, sizeof xid);
    xid ^= (__local_enet_addr[4]<<16) + __local_enet_addr[5];
    xid ^= (unsigned)&retry + (unsigned)&__bootp_find_local_ip;

    debug_printf("XID: %08x\n",xid);

    memcpy(saved_ip_addr, __local_ip_addr, sizeof __local_ip_addr);    // save our IP in case of failure

    NewDhcpState(DHCP_NONE);

    __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler);

    retry = MAX_RETRIES;

    while (retry > 0) {
        start = MS_TICKS();
        memset(__local_ip_addr, 0, sizeof(__local_ip_addr));

        // send bootp REQUEST or dhcp DISCOVER
        bootp_start();

        // wait for timeout, user-abort, or for receive packet handler to fail/succeed
        while ((MS_TICKS_DELAY() - start) < RETRY_TIME_MS) {
            __enet_poll();
            if (dhcpState == DHCP_FAILED)
                break;
            if (dhcpState == DHCP_DONE)
                goto done;
            if (_rb_break(1))          // did user hit ^C?
                goto failed;
            MS_TICKS_DELAY();
        }
        --retry;
        ++xid;
        diag_printf("TIMEOUT%s\n", retry ? ", retrying..." : "");
    }

failed:
    diag_printf("FAIL\n");
    __udp_remove_listener(IPPORT_BOOTPC);
    memcpy(__local_ip_addr, saved_ip_addr, sizeof __local_ip_addr);    // restore prev IP
    return -1;

done:
    diag_printf("OK\n");
    __udp_remove_listener(IPPORT_BOOTPC);
    return 0;
}
Esempio n. 2
0
/*
 * Poll timer list for timer expirations.
 */
void
__timer_poll(void)
{
    timer_t *prev, *t;

    prev = NULL;
    t = tmr_list;
    while (t) {
	if ((MS_TICKS_DELAY() - t->start) >= t->delay) {

	    /* remove it before calling handler */
	    if (prev)
		prev->next = t->next;
	    else
		tmr_list = t->next;
	    /* now, call the handler */
	    t->handler(t->user_data);
	    
	    /*
	     * handler may be time consuming, so start
	     * from beginning of list.
	     */
	    prev = NULL;
	    t = tmr_list;
	} else {
	    prev = t;
	    t = t->next;
	}
    }
}
Esempio n. 3
0
int
__udp_recvfrom(char *data, int len, struct sockaddr_in *server, 
               struct sockaddr_in *local, struct timeval *timo)
{
    int res, my_port, total_ms;
    udp_socket_t skt;
    unsigned long start;

    my_port = ntohs(local->sin_port);
    if (__udp_install_listener(&skt, my_port, __udp_recvfrom_handler) < 0) {
        return -1;
    }
    recvfrom_buf = data;
    recvfrom_len = len;
    recvfrom_server = server;
    total_ms = (timo->tv_sec * 1000) + (timo->tv_usec / 1000);
    start = MS_TICKS();
    res = -1;
    do {
        __enet_poll();  // Handle the hardware
        if (!recvfrom_buf) {
            // Data have arrived
            res = recvfrom_len;
            break;
        }
    } while ((MS_TICKS_DELAY() - start) < total_ms);
    __udp_remove_listener(my_port);
    return res;
}
Esempio n. 4
0
static void do_ping(int argc, char *argv[])
{
	struct option_info opts[7];
	long count, timeout, length, rate, start_time, end_time, timer,
	    received, tries;
	char *local_ip_addr, *host_ip_addr;
	bool local_ip_addr_set, host_ip_addr_set, count_set,
	    timeout_set, length_set, rate_set, verbose;
	struct sockaddr_in local_addr, host_addr;
	ip_addr_t hold_addr;
	icmp_header_t *icmp;
	pktbuf_t *pkt;
	ip_header_t *ip;
	unsigned short cksum;
	ip_route_t dest_ip;

	init_opts(&opts[0], 'n', true, OPTION_ARG_TYPE_NUM,
		  (void *)&count, (bool *) & count_set,
		  "<count> - number of packets to test");
	init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_NUM, (void *)&timeout,
		  (bool *) & timeout_set,
		  "<timeout> - max #ms per packet [rount trip]");
	init_opts(&opts[2], 'i', true, OPTION_ARG_TYPE_STR,
		  (void *)&local_ip_addr, (bool *) & local_ip_addr_set,
		  "local IP address");
	init_opts(&opts[3], 'h', true, OPTION_ARG_TYPE_STR,
		  (void *)&host_ip_addr, (bool *) & host_ip_addr_set,
		  "host name or IP address");
	init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, (void *)&length,
		  (bool *) & length_set, "<length> - size of payload");
	init_opts(&opts[5], 'v', false, OPTION_ARG_TYPE_FLG, (void *)&verbose,
		  (bool *) 0, "verbose operation");
	init_opts(&opts[6], 'r', true, OPTION_ARG_TYPE_NUM, (void *)&rate,
		  (bool *) & rate_set, "<rate> - time between packets");
	if (!scan_opts(argc, argv, 1, opts, 7, (void **)0, 0, "")) {
		diag_printf("PING - Invalid option specified\n");
		return;
	}
	// Set defaults; this has to be done _after_ the scan, since it will
	// have destroyed all values not explicitly set.
	if (local_ip_addr_set) {
		if (!_gethostbyname(local_ip_addr, (in_addr_t *) & local_addr)) {
			diag_printf("PING - Invalid local name: %s\n",
				    local_ip_addr);
			return;
		}
	} else {
		memcpy((in_addr_t *) & local_addr, __local_ip_addr,
		       sizeof(__local_ip_addr));
	}
	if (host_ip_addr_set) {
		if (!_gethostbyname(host_ip_addr, (in_addr_t *) & host_addr)) {
			diag_printf("PING - Invalid host name: %s\n",
				    host_ip_addr);
			return;
		}
		if (__arp_lookup((ip_addr_t *) & host_addr.sin_addr, &dest_ip) <
		    0) {
			diag_printf("PING: Cannot reach server '%s' (%s)\n",
				    host_ip_addr,
				    inet_ntoa((in_addr_t *) & host_addr));
			return;
		}
	} else {
		diag_printf("PING - host name or IP address required\n");
		return;
	}
#define DEFAULT_LENGTH   64
#define DEFAULT_COUNT    10
#define DEFAULT_TIMEOUT  1000
#define DEFAULT_RATE     1000
	if (!rate_set) {
		rate = DEFAULT_RATE;
	}
	if (!length_set) {
		length = DEFAULT_LENGTH;
	}
	if ((length < 64) || (length > 1400)) {
		diag_printf("Invalid length specified: %ld\n", length);
		return;
	}
	if (!count_set) {
		count = DEFAULT_COUNT;
	}
	if (!timeout_set) {
		timeout = DEFAULT_TIMEOUT;
	}
	// Note: two prints here because 'inet_ntoa' returns a static pointer
	diag_printf("Network PING - from %s",
		    inet_ntoa((in_addr_t *) & local_addr));
	diag_printf(" to %s\n", inet_ntoa((in_addr_t *) & host_addr));
	received = 0;
	__icmp_install_listener(handle_icmp);
	// Save default "local" address
	memcpy(hold_addr, __local_ip_addr, sizeof(hold_addr));
	for (tries = 0; tries < count; tries++) {
		// The network stack uses the global variable '__local_ip_addr'
		memcpy(__local_ip_addr, &local_addr, sizeof(__local_ip_addr));
		// Build 'ping' request
		if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) {
			// Give up if no packets - something is wrong
			break;
		}

		icmp = pkt->icmp_hdr;
		ip = pkt->ip_hdr;
		pkt->pkt_bytes = length + sizeof(icmp_header_t);

		icmp->type = ICMP_TYPE_ECHOREQUEST;
		icmp->code = 0;
		icmp->checksum = 0;
		icmp->seqnum = htons(tries + 1);
		cksum = __sum((word *) icmp, pkt->pkt_bytes, 0);
		icmp->checksum = htons(cksum);

		memcpy(ip->source, (in_addr_t *) & local_addr,
		       sizeof(ip_addr_t));
		memcpy(ip->destination, (in_addr_t *) & host_addr,
		       sizeof(ip_addr_t));
		ip->protocol = IP_PROTO_ICMP;
		ip->length = htons(pkt->pkt_bytes);

		__ip_send(pkt, IP_PROTO_ICMP, &dest_ip);
		__pktbuf_free(pkt);

		start_time = MS_TICKS();
		timer = start_time + timeout;
		icmp_received = false;
		while (!icmp_received && (MS_TICKS_DELAY() < timer)) {
			if (_rb_break(1)) {
				goto abort;
			}
			MS_TICKS_DELAY();
			__enet_poll();
		}
		end_time = MS_TICKS();

		timer = MS_TICKS() + rate;
		while (MS_TICKS_DELAY() < timer) {
			if (_rb_break(1)) {
				goto abort;
			}
			MS_TICKS_DELAY();
			__enet_poll();
		}

		if (icmp_received) {
			received++;
			if (verbose) {
				diag_printf(" seq: %ld, time: %ld (ticks)\n",
					    ntohs(hold_hdr.seqnum),
					    end_time - start_time);
			}
		}
	}
abort:
	__icmp_remove_listener();
	// Clean up
	memcpy(__local_ip_addr, &hold_addr, sizeof(__local_ip_addr));
	// Report
	diag_printf("PING - received %ld of %ld expected\n", received, count);
}
Esempio n. 5
0
/* 
 * Find the ethernet address of the machine with the given
 * ip address.
 * Return 0 and fills in 'eth_addr' if successful,
 *       -1 if unsuccessful.
 */
int
__arp_request(ip_addr_t *ip_addr, enet_addr_t *eth_addr, int allow_self)
{
    pktbuf_t *pkt;
    arp_header_t *arp;
    unsigned long retry_start;
    enet_addr_t   bcast_addr;
    int           retry;

    if (!allow_self) {
        // Special case request for self
        if (!memcmp(ip_addr, __local_ip_addr, 4)) {
            memcpy(eth_addr, __local_enet_addr, sizeof(enet_addr_t));
            return 0;
        }
    }

    /* just fail if can't get a buffer */
    if ((pkt = __pktbuf_alloc(ARP_PKT_SIZE)) == NULL)
	return -1;

    arp = pkt->arp_hdr;
    arp->opcode = htons(ARP_REQUEST);
    arp->hw_type = htons(ARP_HW_ETHER);
    arp->protocol = htons(0x800);
    arp->hw_len = sizeof(enet_addr_t);
    arp->proto_len = sizeof(ip_addr_t);

    memcpy(arp->sender_ip, __local_ip_addr, sizeof(ip_addr_t));
    memcpy(arp->sender_enet, __local_enet_addr, sizeof(enet_addr_t));
    memcpy(arp->target_ip, ip_addr, sizeof(ip_addr_t));

    bcast_addr[0] = 255;
    bcast_addr[1] = 255;
    bcast_addr[2] = 255;
    bcast_addr[3] = 255;
    bcast_addr[4] = 255;
    bcast_addr[5] = 255;

    arp_req.eth = (char *)eth_addr;
    arp_req.ip = (char *)ip_addr;
    arp_req.waiting = 1;

    retry = 8;
    while (retry-- > 0) {

        /* send the packet */
	pkt->pkt_bytes = sizeof(arp_header_t);
        __enet_send(pkt, &bcast_addr, ETH_TYPE_ARP);

        retry_start = MS_TICKS();
	while ((MS_TICKS_DELAY() - retry_start) < 250) {
	    __enet_poll();
	    if (!arp_req.waiting) {
		__pktbuf_free(pkt);
		return 0;
	    }
	}
    }
    __pktbuf_free(pkt);
    return -1;
}