further implemented bootp protocol
This commit is contained in:
190
net/bootp.c
190
net/bootp.c
@@ -9,9 +9,14 @@
|
||||
#include "bootp.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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)
|
||||
{
|
||||
/*
|
||||
@@ -19,172 +24,75 @@ void bootp_request(NIF *nif, uint8_t *pa)
|
||||
* address "pa"
|
||||
*/
|
||||
uint8_t *addr;
|
||||
NBUF *pNbuf;
|
||||
bootp_frame_hdr *bootpframe;
|
||||
IP_ADDR broadcast = {255, 255, 255, 255};
|
||||
NBUF *nbuf;
|
||||
struct bootp_packet *p;
|
||||
int i, result;
|
||||
|
||||
pNbuf = nbuf_alloc();
|
||||
if (pNbuf == NULL)
|
||||
nbuf = nbuf_alloc();
|
||||
if (nbuf == NULL)
|
||||
{
|
||||
#if defined(DEBUG_PRINT)
|
||||
xprintf("%s: arp_request couldn't allocate Tx buffer\r\n", __FUNCTION__);
|
||||
#endif
|
||||
return;
|
||||
xprintf("%s: couldn't allocate Tx buffer\r\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
bootpframe = (bootp_frame_hdr *) &pNbuf->data[BOOTP_HDR_OFFSET];
|
||||
p = (struct bootp_packet *) &nbuf->data[BOOTP_HDR_OFFSET];
|
||||
|
||||
/* Build the BOOTP request packet */
|
||||
bootpframe->type = BOOTP_TYPE_BOOTREQUEST;
|
||||
bootpframe->htype = BOOTP_HTYPE_ETHERNET;
|
||||
bootpframe->hlen = BOOTP_HLEN_ETHERNET;
|
||||
bootpframe->hops = 0;
|
||||
bootpframe->xid = 0x1234;
|
||||
bootpframe->secs = 1;
|
||||
bootpframe->flags = BOOTP_FLAGS_BROADCAST;
|
||||
bootpframe->cl_addr = 0x0;
|
||||
bootpframe->yi_addr = 0x0;
|
||||
bootpframe->gi_addr = 0x0;
|
||||
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;
|
||||
|
||||
addr = &nif->hwa[0];
|
||||
for (i = 0; i < 6; i++)
|
||||
bootpframe->ch_addr[i] = addr[i];
|
||||
p->ch_addr[i] = addr[i];
|
||||
|
||||
pNbuf->length = BOOTP_HDR_LEN;
|
||||
nbuf->length = BOOTP_PACKET_LEN;
|
||||
|
||||
/* Send the BOOTP request */
|
||||
result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_IP, pNbuf);
|
||||
for (i = 0; i < MAX_TRIES; i++)
|
||||
{
|
||||
/* Send the BOOTP request */
|
||||
result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT,
|
||||
BOOTP_SERVER_PORT, nbuf);
|
||||
if (result == true)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
nbuf_free(pNbuf);
|
||||
nbuf_free(nbuf);
|
||||
}
|
||||
|
||||
void bootp_handler(NIF *nif, NBUF *pNbuf)
|
||||
void bootp_handler(NIF *nif, NBUF *nbuf)
|
||||
{
|
||||
/*
|
||||
* ARP protocol handler
|
||||
* BOOTP protocol handler
|
||||
*/
|
||||
uint8_t *addr;
|
||||
bootp_frame_hdr *rx_bootpframe, *tx_bootpframe;
|
||||
struct bootp_packet *rx_p;
|
||||
udp_frame_hdr *udpframe;
|
||||
|
||||
rx_bootpframe = (bootp_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||
rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset];
|
||||
udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE];
|
||||
|
||||
#ifdef _NOT_USED_
|
||||
/*
|
||||
* Check for an appropriate ARP packet
|
||||
*/
|
||||
if ((pNbuf->length < ARP_HDR_LEN) ||
|
||||
(rx_arpframe->ar_hrd != ETHERNET) ||
|
||||
(rx_arpframe->ar_hln != 6) ||
|
||||
(rx_arpframe->ar_pro != ETH_FRM_IP) ||
|
||||
(rx_arpframe->ar_pln != 4))
|
||||
/* 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)
|
||||
{
|
||||
nbuf_free(pNbuf);
|
||||
return;
|
||||
/* seems to be valid */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if it was addressed to me - if it was, keep this
|
||||
* ARP entry in the table permanently; if not, mark it so that it
|
||||
* can be displaced later if necessary
|
||||
*/
|
||||
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
|
||||
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
|
||||
(rx_arpframe->ar_tpa[1] == addr[1]) &&
|
||||
(rx_arpframe->ar_tpa[2] == addr[2]) &&
|
||||
(rx_arpframe->ar_tpa[3] == addr[3]) )
|
||||
else
|
||||
{
|
||||
longevity = ARP_ENTRY_PERM;
|
||||
}
|
||||
else
|
||||
longevity = ARP_ENTRY_TEMP;
|
||||
/* not valid */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add ARP info into the table
|
||||
*/
|
||||
arp_merge(arptab,
|
||||
rx_arpframe->ar_pro,
|
||||
rx_arpframe->ar_hln,
|
||||
&rx_arpframe->ar_sha[0],
|
||||
rx_arpframe->ar_pln,
|
||||
&rx_arpframe->ar_spa[0],
|
||||
longevity
|
||||
);
|
||||
|
||||
switch (rx_arpframe->opcode)
|
||||
{
|
||||
case ARP_REQUEST:
|
||||
/*
|
||||
* Check to see if request is directed to me
|
||||
*/
|
||||
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
|
||||
(rx_arpframe->ar_tpa[1] == addr[1]) &&
|
||||
(rx_arpframe->ar_tpa[2] == addr[2]) &&
|
||||
(rx_arpframe->ar_tpa[3] == addr[3]) )
|
||||
{
|
||||
/*
|
||||
* Reuse the current network buffer to assemble an ARP reply
|
||||
*/
|
||||
tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET];
|
||||
|
||||
/*
|
||||
* Build new ARP frame from the received data
|
||||
*/
|
||||
tx_arpframe->ar_hrd = ETHERNET;
|
||||
tx_arpframe->ar_pro = ETH_FRM_IP;
|
||||
tx_arpframe->ar_hln = 6;
|
||||
tx_arpframe->ar_pln = 4;
|
||||
tx_arpframe->opcode = ARP_REPLY;
|
||||
tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0];
|
||||
tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1];
|
||||
tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2];
|
||||
tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3];
|
||||
tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4];
|
||||
tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5];
|
||||
tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0];
|
||||
tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1];
|
||||
tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2];
|
||||
tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3];
|
||||
|
||||
/*
|
||||
* Now copy in the new information
|
||||
*/
|
||||
addr = &nif->hwa[0];
|
||||
tx_arpframe->ar_sha[0] = addr[0];
|
||||
tx_arpframe->ar_sha[1] = addr[1];
|
||||
tx_arpframe->ar_sha[2] = addr[2];
|
||||
tx_arpframe->ar_sha[3] = addr[3];
|
||||
tx_arpframe->ar_sha[4] = addr[4];
|
||||
tx_arpframe->ar_sha[5] = addr[5];
|
||||
|
||||
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
|
||||
tx_arpframe->ar_spa[0] = addr[0];
|
||||
tx_arpframe->ar_spa[1] = addr[1];
|
||||
tx_arpframe->ar_spa[2] = addr[2];
|
||||
tx_arpframe->ar_spa[3] = addr[3];
|
||||
|
||||
/*
|
||||
* Save the length of my packet in the buffer structure
|
||||
*/
|
||||
pNbuf->length = ARP_HDR_LEN;
|
||||
|
||||
nif->send(nif,
|
||||
&tx_arpframe->ar_tha[0],
|
||||
&tx_arpframe->ar_sha[0],
|
||||
ETH_FRM_ARP,
|
||||
pNbuf);
|
||||
}
|
||||
else
|
||||
nbuf_free(pNbuf);
|
||||
break;
|
||||
case ARP_REPLY:
|
||||
/*
|
||||
* The ARP Reply case is already taken care of
|
||||
*/
|
||||
default:
|
||||
nbuf_free(pNbuf);
|
||||
break;
|
||||
}
|
||||
#endif /* _NOT_USED_ */
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user