further implemented bootp protocol

This commit is contained in:
Markus Fröschle
2013-12-24 10:41:43 +00:00
parent 8f0ccd2d31
commit 7a33324a83
8 changed files with 427 additions and 524 deletions

View File

@@ -8,12 +8,28 @@
#ifndef _BOOTP_H_ #ifndef _BOOTP_H_
#define _BOOTP_H_ #define _BOOTP_H_
/********************************************************************/ #define BOOTP_SERVER_PORT 67
#define BOOTP_CLIENT_PORT 68
/* protocol header information */
#define BOOTP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE + UDP_HDR_SIZE)
/* timeout in seconds */
#define BOOTP_TIMEOUT 2
/* BOOTP connection status */
struct bootp_connection
{
bool open; /* connection established flag */
NIF *nif; /* pointer to network interface */
IP_ADDR server_ip; /* server IP address */
};
/* /*
* This data definition is defined for Ethernet only! * This data definition is defined for Ethernet only!
*/ */
typedef struct struct bootp_packet
{ {
uint8_t type; /* bootp operation type */ uint8_t type; /* bootp operation type */
uint8_t htype; /* hardware type */ uint8_t htype; /* hardware type */
@@ -29,9 +45,9 @@ typedef struct
uint8_t sname[64]; /* server name */ uint8_t sname[64]; /* server name */
uint8_t file[128]; /* name of bootfile */ uint8_t file[128]; /* name of bootfile */
uint8_t vend[64]; /* vendor specific (see below) */ uint8_t vend[64]; /* vendor specific (see below) */
} bootp_frame_hdr; };
#define BOOTP_HDR_LEN sizeof(bootp_frame_hdr) #define BOOTP_PACKET_LEN (BOOTP_HDR_OFFSET + sizeof(struct bootp_packet))
/* possible values for type field */ /* possible values for type field */
#define BOOTP_TYPE_BOOTREQUEST 1 #define BOOTP_TYPE_BOOTREQUEST 1
@@ -46,11 +62,6 @@ typedef struct
/* values for flags - only broadcast flag in use */ /* values for flags - only broadcast flag in use */
#define BOOTP_FLAGS_BROADCAST 1 #define BOOTP_FLAGS_BROADCAST 1
#define BOOTP_TIMEOUT (1) /* Timeout in seconds */
/* Protocol Header information */
#define BOOTP_HDR_OFFSET ETH_HDR_LEN
extern void bootp_request(NIF *, uint8_t *); extern void bootp_request(NIF *, uint8_t *);
extern void bootp_handler(NIF *, NBUF *); extern void bootp_handler(NIF *, NBUF *);
//extern void bootp_init(BOOTP_INFO *); //extern void bootp_init(BOOTP_INFO *);

View File

@@ -56,30 +56,14 @@ typedef struct
/* /*
* Functions to manipulate the network buffers. * Functions to manipulate the network buffers.
*/ */
int extern int nbuf_init(void);
nbuf_init(void); extern void nbuf_flush(void);
extern NBUF *nbuf_alloc (void);
extern void nbuf_free(NBUF *);
extern NBUF *nbuf_remove(int);
extern void nbuf_add(int, NBUF *);
extern void nbuf_reset(void);
extern void nbuf_debug_dump(void);
void
nbuf_flush(void);
NBUF *
nbuf_alloc (void);
void
nbuf_free(NBUF *);
NBUF *
nbuf_remove(int);
void
nbuf_add(int, NBUF *);
void
nbuf_reset(void);
void
nbuf_debug_dump(void);
/********************************************************************/
#endif /* _NBUF_H_ */ #endif /* _NBUF_H_ */

View File

@@ -1,6 +1,6 @@
/* /*
* File: net.h * File: net.h
* Purpose: Network definitions and prototypes for dBUG. * Purpose: Network definitions and prototypes for BaS.
* *
* Notes: * Notes:
*/ */
@@ -24,7 +24,7 @@
/********************************************************************/ /********************************************************************/
int net_init(void); extern int net_init(void);
/********************************************************************/ /********************************************************************/

View File

@@ -1,9 +1,8 @@
/* /*
* File: net_timer.h * File: net_timer.h
* Purpose: Provide a timer use by the dBUG network as a timeout * Purpose: Provide a timer use by the BaS network as a timeout
* indicator * indicator
* *
* Notes:
*/ */
#ifndef _TIMER_H_ #ifndef _TIMER_H_

View File

@@ -8,8 +8,6 @@
#ifndef _TFTP_H_ #ifndef _TFTP_H_
#define _TFTP_H_ #define _TFTP_H_
/********************************************************************/
#define TFTP_RRQ (1) #define TFTP_RRQ (1)
#define TFTP_WRQ (2) #define TFTP_WRQ (2)
#define TFTP_DATA (3) #define TFTP_DATA (3)

View File

@@ -9,9 +9,14 @@
#include "bootp.h" #include "bootp.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include "bas_printf.h"
#define TIMER_NETWORK 0 #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) void bootp_request(NIF *nif, uint8_t *pa)
{ {
/* /*
@@ -19,172 +24,75 @@ void bootp_request(NIF *nif, uint8_t *pa)
* address "pa" * address "pa"
*/ */
uint8_t *addr; uint8_t *addr;
NBUF *pNbuf; IP_ADDR broadcast = {255, 255, 255, 255};
bootp_frame_hdr *bootpframe; NBUF *nbuf;
struct bootp_packet *p;
int i, result; int i, result;
pNbuf = nbuf_alloc(); nbuf = nbuf_alloc();
if (pNbuf == NULL) if (nbuf == NULL)
{ {
#if defined(DEBUG_PRINT) xprintf("%s: couldn't allocate Tx buffer\r\n", __FUNCTION__);
xprintf("%s: arp_request couldn't allocate Tx buffer\r\n", __FUNCTION__);
#endif
return; return;
} }
bootpframe = (bootp_frame_hdr *) &pNbuf->data[BOOTP_HDR_OFFSET]; p = (struct bootp_packet *) &nbuf->data[BOOTP_HDR_OFFSET];
/* Build the BOOTP request packet */ /* Build the BOOTP request packet */
bootpframe->type = BOOTP_TYPE_BOOTREQUEST; p->type = BOOTP_TYPE_BOOTREQUEST;
bootpframe->htype = BOOTP_HTYPE_ETHERNET; p->htype = BOOTP_HTYPE_ETHERNET;
bootpframe->hlen = BOOTP_HLEN_ETHERNET; p->hlen = BOOTP_HLEN_ETHERNET;
bootpframe->hops = 0; p->hops = 0;
bootpframe->xid = 0x1234; p->xid = XID;
bootpframe->secs = 1; p->secs = 1;
bootpframe->flags = BOOTP_FLAGS_BROADCAST; p->flags = BOOTP_FLAGS_BROADCAST;
bootpframe->cl_addr = 0x0; p->cl_addr = 0x0;
bootpframe->yi_addr = 0x0; p->yi_addr = 0x0;
bootpframe->gi_addr = 0x0; p->gi_addr = 0x0;
addr = &nif->hwa[0]; addr = &nif->hwa[0];
for (i = 0; i < 6; i++) 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;
for (i = 0; i < MAX_TRIES; i++)
{
/* Send the BOOTP request */ /* Send the BOOTP request */
result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_IP, pNbuf); result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT,
BOOTP_SERVER_PORT, nbuf);
if (result == true)
break;
}
if (result == 0) 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; 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 packet if it is valid and if it is really intended for us */
/*
* Check for an appropriate ARP packet if (rx_p->type == BOOTP_TYPE_BOOTREPLY && rx_p->xid == XID)
*/
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))
{ {
nbuf_free(pNbuf); /* seems to be valid */
}
else
{
/* not valid */
return; return;
} }
/*
* 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]) )
{
longevity = ARP_ENTRY_PERM;
}
else
longevity = ARP_ENTRY_TEMP;
/*
* 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; return;
} }

View File

@@ -1,6 +1,6 @@
/* /*
* File: net_timer.c * File: net_timer.c
* Purpose: Provide a timer use by the dBUG network as a timeout * Purpose: Provide a timer use by the BaS network as a timeout
* indicator * indicator
* *
* Notes: * Notes:
@@ -19,10 +19,13 @@
#error unknown machine! #error unknown machine!
#endif #endif
static NET_TIMER net_timer[4] = {{0, 0, 0, 0, 0, 0, 0}, static NET_TIMER net_timer[4] =
{
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}}; {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
int timer_default_isr(void *not_used, NET_TIMER *t) int timer_default_isr(void *not_used, NET_TIMER *t)

View File

@@ -189,7 +189,7 @@ bool isr_execute_handler(int vector)
bool retval = false; bool retval = false;
/* /*
* First locate a dBUG Interrupt Service Routine handler. * First locate a BaS Interrupt Service Routine handler.
*/ */
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {