/* * File: arp.c * Purpose: Address Resolution Protocol routines. * * Notes: */ #include "net.h" #include "bootp.h" #include #include #include "bas_printf.h" #define TIMER_NETWORK 0 static struct bootp_connection connection; #define XID 0x1234 /* this is arbitrary */ #define MAX_TRIES 5 /* since UDP can fail */ void bootp_request(NIF *nif, uint8_t *pa) { /* * This function broadcasts a BOOTP request for the protocol * address "pa" */ uint8_t *addr; IP_ADDR broadcast = {255, 255, 255, 255}; NBUF *nbuf; struct bootp_packet *p; int i, result; nbuf = nbuf_alloc(); if (nbuf == NULL) { xprintf("%s: couldn't allocate Tx buffer\r\n", __FUNCTION__); return; } p = (struct bootp_packet *) &nbuf->data[BOOTP_HDR_OFFSET]; /* Build the BOOTP request packet */ p->type = BOOTP_TYPE_BOOTREQUEST; p->htype = BOOTP_HTYPE_ETHERNET; p->hlen = BOOTP_HLEN_ETHERNET; p->hops = 0; p->xid = XID; p->secs = 1; p->flags = BOOTP_FLAGS_BROADCAST; p->cl_addr = 0x0; p->yi_addr = 0x0; p->gi_addr = 0x0; connection.nif = nif; addr = &nif->hwa[0]; for (i = 0; i < 6; i++) p->ch_addr[i] = addr[i]; nbuf->length = BOOTP_PACKET_LEN; /* setup reply handler */ udp_bind_port(BOOTP_CLIENT_PORT, bootp_handler); for (i = 0; i < MAX_TRIES; i++) { /* Send the BOOTP request */ result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT, BOOTP_SERVER_PORT, nbuf); xprintf("sent bootp request\r\n"); if (result == true) break; } /* release handler */ udp_free_port(BOOTP_CLIENT_PORT); if (result == 0) nbuf_free(nbuf); } void bootp_handler(NIF *nif, NBUF *nbuf) { /* * BOOTP protocol handler */ uint8_t *addr; struct bootp_packet *rx_p; udp_frame_hdr *udpframe; rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset]; udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE]; /* check packet if it is valid and if it is really intended for us */ if (rx_p->type == BOOTP_TYPE_BOOTREPLY && rx_p->xid == XID) { xprintf("received bootp reply\r\n"); /* seems to be valid */ } else { /* not valid */ return; } return; }