int main() { udpsock s1 = udplisten(iplocal(NULL, 5555, 0)); udpsock s2 = udplisten(iplocal(NULL, 5556, 0)); ipaddr addr = ipremote("127.0.0.1", 5556, 0, -1); while(1) { udpsend(s1, addr, "ABC", 3); assert(errno == 0); char buf[3]; size_t sz = udprecv(s2, &addr, buf, sizeof(buf), now() + 100); if(errno == ETIMEDOUT) continue; assert(errno == 0); assert(sz == 3); break; } while(1) { udpsend(s2, addr, "DEF", 3); assert(errno == 0); char buf[3]; size_t sz = udprecv(s1, &addr, buf, sizeof(buf), now() + 100); if(errno == ETIMEDOUT) continue; assert(errno == 0); assert(sz == 3); break; } udpclose(s2); udpclose(s1); return 0; }
//////////////////////////////////////////////////////////////////////////////// // listenbootp // PURPOSE: Listens for bootp response, returns status after one packet // received. // PARAMS: (IN) u32 xid - xid from the bootp request we sent. // (OUT) u32 *ciaddr - Clients (our) IP address. // (OUT) u32 *siaddr - Servers IP address. // RETURNS: int - 0 for failure, 1 for success. //////////////////////////////////////////////////////////////////////////////// static int listenbootp(u32 xid, u32 *ciaddr, u32 *siaddr, u32 *giaddr, u32 *smask, char *bootfile) { u8 packet[MAX_PACKET_SIZE]; u16 size = MAX_PACKET_SIZE; u8 *bootppacket = packet + UDPIP_HEADER_SIZE; u32 rxid; u32 iaddr; u32 time = get_time_timer() + NET_TIMEOUT; u32 client_iaddr; u32 server_iaddr; //scratch variables for parse_options_dhcp; we don't care about these u8 msg_type; u32 sid; while(1) { u8 bootp_type; if (time < get_time_timer()) { // We timed out receiving reply // We can't rely on the udplisten timeout because we could // theoretically receive a steady supply of miscellaneous packets // so it will never time out. return 0; } if(udplisten(packet, &size, &iaddr, 1)) { bootp_type = *bootppacket; bootppacket += 4; rxid = (*(bootppacket++) << 24); rxid |= (*(bootppacket++) << 16); rxid |= (*(bootppacket++) << 8); rxid |= *(bootppacket++); bootppacket += sizeof(u32) * 2; if(rxid == xid && bootp_type == BOOTP_REPLY) { client_iaddr = *bootppacket++ << 24; client_iaddr |= *bootppacket++ << 16; client_iaddr |= *bootppacket++ << 8; client_iaddr |= *bootppacket++; server_iaddr = *bootppacket++ << 24; server_iaddr |= *bootppacket++ << 16; server_iaddr |= *bootppacket++ << 8; server_iaddr |= *bootppacket++; break; } } } //skip the relay agent ip field bootppacket += sizeof(u32); //skip the hardware address field bootppacket += 16; //skip the servername field bootppacket += 64; //skip the bootfile field itc_strcpy(bootfile, (char *)bootppacket); DEBUG_3("Bootfile: %s\r\n", bootfile); bootppacket += 128; //skip the magic cookie bootppacket += sizeof(u32); parse_options_dhcp(bootppacket, giaddr, smask, &sid, &msg_type); *ciaddr = client_iaddr; *siaddr = server_iaddr; return 1; }