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; }
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; }