added debug output
This commit is contained in:
183
include/ip.h
183
include/ip.h
@@ -1,100 +1,83 @@
|
|||||||
/*
|
/*
|
||||||
* File: ip.h
|
* File: ip.h
|
||||||
* Purpose: Definitions for the Internet Protocol, IP.
|
* Purpose: Definitions for the Internet Protocol, IP.
|
||||||
*
|
*
|
||||||
* Notes: See RFC 791 "DARPA Internet Program Protocol
|
* Notes: See RFC 791 "DARPA Internet Program Protocol
|
||||||
* Specification" for more details.
|
* Specification" for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _IP_H
|
#ifndef _IP_H
|
||||||
#define _IP_H
|
#define _IP_H
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
/* 32-bit IP Addresses */
|
/* 32-bit IP Addresses */
|
||||||
typedef uint8_t IP_ADDR[4];
|
typedef uint8_t IP_ADDR[4];
|
||||||
|
|
||||||
/* Pointer to an IP Address */
|
/* Pointer to an IP Address */
|
||||||
typedef uint8_t IP_ADDR_P[];
|
typedef uint8_t IP_ADDR_P[];
|
||||||
|
|
||||||
/* Definition of an IP packet header */
|
/* Definition of an IP packet header */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t version_ihl;
|
uint8_t version_ihl;
|
||||||
uint8_t service_type;
|
uint8_t service_type;
|
||||||
uint16_t total_length;
|
uint16_t total_length;
|
||||||
uint16_t identification;
|
uint16_t identification;
|
||||||
uint16_t flags_frag_offset;
|
uint16_t flags_frag_offset;
|
||||||
uint8_t ttl;
|
uint8_t ttl;
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
IP_ADDR source_addr;
|
IP_ADDR source_addr;
|
||||||
IP_ADDR dest_addr;
|
IP_ADDR dest_addr;
|
||||||
uint8_t options; /* actually an array of undetermined length */
|
uint8_t options; /* actually an array of undetermined length */
|
||||||
} ip_frame_hdr;
|
} ip_frame_hdr;
|
||||||
|
|
||||||
/* Macros for accessing an IP datagram. */
|
/* Macros for accessing an IP datagram. */
|
||||||
#define IP_VERSION(a) ((a->version_ihl & 0x00F0) >> 4)
|
#define IP_VERSION(a) ((a->version_ihl & 0x00F0) >> 4)
|
||||||
#define IP_IHL(a) ((a->version_ihl & 0x000F))
|
#define IP_IHL(a) ((a->version_ihl & 0x000F))
|
||||||
#define IP_SERVICE(a) (a->service_type)
|
#define IP_SERVICE(a) (a->service_type)
|
||||||
#define IP_LENGTH(a) (a->total_length)
|
#define IP_LENGTH(a) (a->total_length)
|
||||||
#define IP_IDENT(a) (a->identification)
|
#define IP_IDENT(a) (a->identification)
|
||||||
#define IP_FLAGS(a) ((a->flags_frag_offset & 0x0000E000) >> 13)
|
#define IP_FLAGS(a) ((a->flags_frag_offset & 0x0000E000) >> 13)
|
||||||
#define IP_FRAGMENT(a) ((a->flags_frag_offset & 0x00001FFF))
|
#define IP_FRAGMENT(a) ((a->flags_frag_offset & 0x00001FFF))
|
||||||
#define IP_TTL(a) (a->ttl)
|
#define IP_TTL(a) (a->ttl)
|
||||||
#define IP_PROTOCOL(a) (a->protocol)
|
#define IP_PROTOCOL(a) (a->protocol)
|
||||||
#define IP_CHKSUM(a) (a->checksum)
|
#define IP_CHKSUM(a) (a->checksum)
|
||||||
#define IP_SRC(a) (&a->source_addr[0])
|
#define IP_SRC(a) (&a->source_addr[0])
|
||||||
#define IP_DEST(a) (&a->dest_addr[0])
|
#define IP_DEST(a) (&a->dest_addr[0])
|
||||||
#define IP_OPTIONS(a) (&a->options)
|
#define IP_OPTIONS(a) (&a->options)
|
||||||
#define IP_DATA(a) (&((uint8_t *)a)[IP_IHL(a) * 4])
|
#define IP_DATA(a) (&((uint8_t *)a)[IP_IHL(a) * 4])
|
||||||
|
|
||||||
/* Defined IP protocols */
|
/* Defined IP protocols */
|
||||||
#define IP_PROTO_ICMP (1)
|
#define IP_PROTO_ICMP (1)
|
||||||
#define IP_PROTO_UDP (17)
|
#define IP_PROTO_UDP (17)
|
||||||
|
|
||||||
/* Protocol Header information */
|
/* Protocol Header information */
|
||||||
#define IP_HDR_OFFSET ETH_HDR_LEN
|
#define IP_HDR_OFFSET ETH_HDR_LEN
|
||||||
#define IP_HDR_SIZE 20 /* no options */
|
#define IP_HDR_SIZE 20 /* no options */
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IP_ADDR myip;
|
IP_ADDR myip;
|
||||||
IP_ADDR gateway;
|
IP_ADDR gateway;
|
||||||
IP_ADDR netmask;
|
IP_ADDR netmask;
|
||||||
IP_ADDR broadcast;
|
IP_ADDR broadcast;
|
||||||
unsigned int rx;
|
unsigned int rx;
|
||||||
unsigned int rx_unsup;
|
unsigned int rx_unsup;
|
||||||
unsigned int tx;
|
unsigned int tx;
|
||||||
unsigned int err;
|
unsigned int err;
|
||||||
} IP_INFO;
|
} IP_INFO;
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
void
|
extern void ip_handler(NIF *nif, NBUF *nbf);
|
||||||
ip_handler (NIF *, NBUF *);
|
uint16_t ip_chksum(uint16_t *data, int num);
|
||||||
|
extern int ip_send(NIF *nif, uint8_t *dest_addr, uint8_t *src_addr, uint8_t protocol, NBUF *nbf);
|
||||||
uint16_t
|
extern void ip_init(IP_INFO *, IP_ADDR_P, IP_ADDR_P, IP_ADDR_P);
|
||||||
ip_chksum (uint16_t *, int);
|
extern uint8_t *ip_get_myip(IP_INFO *);
|
||||||
|
extern uint8_t *ip_resolve_route(NIF *, IP_ADDR_P);
|
||||||
int
|
|
||||||
ip_send (NIF *,
|
#endif /* _IP_H */
|
||||||
uint8_t *, /* destination IP */
|
|
||||||
uint8_t *, /* source IP */
|
|
||||||
uint8_t, /* protocol */
|
|
||||||
NBUF * /* buffer descriptor */);
|
|
||||||
|
|
||||||
void
|
|
||||||
ip_init (IP_INFO *, IP_ADDR_P, IP_ADDR_P, IP_ADDR_P);
|
|
||||||
|
|
||||||
uint8_t *
|
|
||||||
ip_get_myip (IP_INFO *);
|
|
||||||
|
|
||||||
uint8_t *
|
|
||||||
ip_resolve_route (NIF *, IP_ADDR_P);
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
#endif /* _IP_H */
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ void bootp_request(NIF *nif, uint8_t *pa)
|
|||||||
p->yi_addr = 0x0;
|
p->yi_addr = 0x0;
|
||||||
p->gi_addr = 0x0;
|
p->gi_addr = 0x0;
|
||||||
|
|
||||||
|
connection.nif = nif;
|
||||||
addr = &nif->hwa[0];
|
addr = &nif->hwa[0];
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
p->ch_addr[i] = addr[i];
|
p->ch_addr[i] = addr[i];
|
||||||
|
|||||||
417
net/ip.c
417
net/ip.c
@@ -11,284 +11,303 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define IP_DEBUG
|
||||||
|
#if defined(IP_DEBUG)
|
||||||
|
#define dbg(format, arg...) do { xprintf("DEBUG: " format "\r\n", ##arg); } while (0)
|
||||||
|
#else
|
||||||
|
#define dbg(format, arg...) do { ; } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void ip_init(IP_INFO *info, IP_ADDR_P myip, IP_ADDR_P gateway, IP_ADDR_P netmask)
|
void ip_init(IP_INFO *info, IP_ADDR_P myip, IP_ADDR_P gateway, IP_ADDR_P netmask)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||||
{
|
{
|
||||||
info->myip[index] = myip[index];
|
info->myip[index] = myip[index];
|
||||||
info->gateway[index] = gateway[index];
|
info->gateway[index] = gateway[index];
|
||||||
info->netmask[index] = netmask[index];
|
info->netmask[index] = netmask[index];
|
||||||
info->broadcast[index] = 0xFF;
|
info->broadcast[index] = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->rx = 0;
|
info->rx = 0;
|
||||||
info->rx_unsup = 0;
|
info->rx_unsup = 0;
|
||||||
info->tx = 0;
|
info->tx = 0;
|
||||||
info->err = 0;
|
info->err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ip_get_myip(IP_INFO *info)
|
uint8_t *ip_get_myip(IP_INFO *info)
|
||||||
{
|
{
|
||||||
if (info != 0)
|
if (info != 0)
|
||||||
{
|
{
|
||||||
return (uint8_t *) &info->myip[0];
|
return (uint8_t *) &info->myip[0];
|
||||||
}
|
}
|
||||||
return 0;
|
dbg("%s: info is NULL!\n\t", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2)
|
int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||||
{
|
{
|
||||||
if (addr1[i] != addr2[i])
|
if (addr1[i] != addr2[i])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip)
|
uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This function determines whether or not an outgoing IP
|
* This function determines whether or not an outgoing IP
|
||||||
* packet needs to be transmitted on the local net or sent
|
* packet needs to be transmitted on the local net or sent
|
||||||
* to the router for transmission.
|
* to the router for transmission.
|
||||||
*/
|
*/
|
||||||
IP_INFO *info;
|
IP_INFO *info;
|
||||||
IP_ADDR mask, result;
|
IP_ADDR mask, result;
|
||||||
int i;
|
IP_ADDR bc = { 255, 255, 255, 255 };
|
||||||
|
int i;
|
||||||
|
|
||||||
info = nif_get_protocol_info(nif, ETH_FRM_IP);
|
info = nif_get_protocol_info(nif, ETH_FRM_IP);
|
||||||
|
|
||||||
/* create mask for local IP */
|
if (memcmp(destip, bc) == 0)
|
||||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
{
|
||||||
{
|
dbg("%s: destip is broadcast address, no gateway needed\r\n", __FUNCTION__);
|
||||||
mask[i] = info->myip[i] & info->netmask[i];
|
return destip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply mask to the destination IP */
|
/* create mask for local IP */
|
||||||
for (i = 0; i < sizeof(IP_ADDR); i++)
|
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||||
{
|
{
|
||||||
result[i] = mask[i] & destip[i];
|
mask[i] = info->myip[i] & info->netmask[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if destination IP is local or not */
|
/* apply mask to the destination IP */
|
||||||
if (ip_addr_compare(mask, result))
|
for (i = 0; i < sizeof(IP_ADDR); i++)
|
||||||
{
|
{
|
||||||
/* The destination IP is on the local net */
|
result[i] = mask[i] & destip[i];
|
||||||
return arp_resolve(nif, ETH_FRM_IP, destip);
|
}
|
||||||
}
|
|
||||||
else
|
/* See if destination IP is local or not */
|
||||||
{
|
if (ip_addr_compare(mask, result))
|
||||||
/* The destination IP is not on the local net */
|
{
|
||||||
return arp_resolve(nif, ETH_FRM_IP, info->gateway);
|
/* The destination IP is on the local net */
|
||||||
}
|
return arp_resolve(nif, ETH_FRM_IP, destip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The destination IP is not on the local net */
|
||||||
|
return arp_resolve(nif, ETH_FRM_IP, info->gateway);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf)
|
int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This function assembles an IP datagram and passes it
|
* This function assembles an IP datagram and passes it
|
||||||
* onto the hardware to be sent over the network.
|
* onto the hardware to be sent over the network.
|
||||||
*/
|
*/
|
||||||
uint8_t *route;
|
uint8_t *route;
|
||||||
ip_frame_hdr *ipframe;
|
ip_frame_hdr *ipframe;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct the IP header
|
* Construct the IP header
|
||||||
*/
|
*/
|
||||||
ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET];
|
ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET];
|
||||||
|
|
||||||
/* IP version 4, Internet Header Length of 5 32-bit words */
|
/* IP version 4, Internet Header Length of 5 32-bit words */
|
||||||
ipframe->version_ihl = 0x45;
|
ipframe->version_ihl = 0x45;
|
||||||
|
|
||||||
/* Type of Service == 0, normal and routine */
|
/* Type of Service == 0, normal and routine */
|
||||||
ipframe->service_type = 0x00;
|
ipframe->service_type = 0x00;
|
||||||
|
|
||||||
/* Total length of data */
|
/* Total length of data */
|
||||||
ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE);
|
ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE);
|
||||||
|
|
||||||
/* User defined identification */
|
/* User defined identification */
|
||||||
ipframe->identification = 0x0000;
|
ipframe->identification = 0x0000;
|
||||||
|
|
||||||
/* Fragment Flags and Offset -- Don't fragment, last frag */
|
/* Fragment Flags and Offset -- Don't fragment, last frag */
|
||||||
ipframe->flags_frag_offset = 0x0000;
|
ipframe->flags_frag_offset = 0x0000;
|
||||||
|
|
||||||
/* Time To Live */
|
/* Time To Live */
|
||||||
ipframe->ttl = 0xFF;
|
ipframe->ttl = 0xFF;
|
||||||
|
|
||||||
/* Protocol */
|
/* Protocol */
|
||||||
ipframe->protocol = protocol;
|
ipframe->protocol = protocol;
|
||||||
|
|
||||||
/* Checksum, computed later, zeroed for computation */
|
/* Checksum, computed later, zeroed for computation */
|
||||||
ipframe->checksum = 0x0000;
|
ipframe->checksum = 0x0000;
|
||||||
|
|
||||||
/* source IP address */
|
/* source IP address */
|
||||||
ipframe->source_addr[0] = src[0];
|
ipframe->source_addr[0] = src[0];
|
||||||
ipframe->source_addr[1] = src[1];
|
ipframe->source_addr[1] = src[1];
|
||||||
ipframe->source_addr[2] = src[2];
|
ipframe->source_addr[2] = src[2];
|
||||||
ipframe->source_addr[3] = src[3];
|
ipframe->source_addr[3] = src[3];
|
||||||
|
|
||||||
/* dest IP address */
|
/* dest IP address */
|
||||||
ipframe->dest_addr[0] = dest[0];
|
ipframe->dest_addr[0] = dest[0];
|
||||||
ipframe->dest_addr[1] = dest[1];
|
ipframe->dest_addr[1] = dest[1];
|
||||||
ipframe->dest_addr[2] = dest[2];
|
ipframe->dest_addr[2] = dest[2];
|
||||||
ipframe->dest_addr[3] = dest[3];
|
ipframe->dest_addr[3] = dest[3];
|
||||||
|
|
||||||
/* Compute checksum */
|
/* Compute checksum */
|
||||||
ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE);
|
ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE);
|
||||||
|
|
||||||
/* Increment the packet length by the size of the IP header */
|
/* Increment the packet length by the size of the IP header */
|
||||||
pNbuf->length += IP_HDR_SIZE;
|
pNbuf->length += IP_HDR_SIZE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the hardware address of the recipient
|
* Determine the hardware address of the recipient
|
||||||
*/
|
*/
|
||||||
IP_ADDR bc = { 255, 255, 255, 255};
|
IP_ADDR bc = { 255, 255, 255, 255};
|
||||||
if (memcmp(bc, dest, 4) != 0)
|
if (memcmp(bc, dest, 4) != 0)
|
||||||
{
|
{
|
||||||
route = ip_resolve_route(nif, dest);
|
route = ip_resolve_route(nif, dest);
|
||||||
if (route == NULL)
|
if (route == NULL)
|
||||||
{
|
{
|
||||||
xprintf("Unable to locate %d.%d.%d.%d\n",
|
dbg("Unable to locate %d.%d.%d.%d\n",
|
||||||
dest[0], dest[1], dest[2], dest[3]);
|
dest[0], dest[1], dest[2], dest[3]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
route = bc;
|
route = bc;
|
||||||
|
dbg("%s: route = broadcast\r\n", __FUNCTION__);
|
||||||
|
dbg("%s: nif = %p\r\n", __FUNCTION__, nif);
|
||||||
|
dbg("%s: nif->send = %p\n\t", __FUNCTION__, nif->send);
|
||||||
|
}
|
||||||
|
|
||||||
return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf);
|
return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_PRINT)
|
#if defined(DEBUG_PRINT)
|
||||||
void
|
void dump_ip_frame(ip_frame_hdr *ipframe)
|
||||||
dump_ip_frame (ip_frame_hdr *ipframe)
|
|
||||||
{
|
{
|
||||||
printf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4));
|
xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4));
|
||||||
printf("IHL: %02X\n", ipframe->version_ihl & 0x000f);
|
xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f);
|
||||||
printf("Service: %02X\n", ipframe->service_type);
|
xprintf("Service: %02X\n", ipframe->service_type);
|
||||||
printf("Length: %04X\n", ipframe->total_length);
|
xprintf("Length: %04X\n", ipframe->total_length);
|
||||||
printf("Ident: %04X\n", ipframe->identification);
|
xprintf("Ident: %04X\n", ipframe->identification);
|
||||||
printf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14));
|
xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14));
|
||||||
printf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF);
|
xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF);
|
||||||
printf("TTL: %02X\n", ipframe->ttl);
|
xprintf("TTL: %02X\n", ipframe->ttl);
|
||||||
printf("Protocol: %02X\n", ipframe->protocol);
|
xprintf("Protocol: %02X\n", ipframe->protocol);
|
||||||
printf("Chksum: %04X\n", ipframe->checksum);
|
xprintf("Chksum: %04X\n", ipframe->checksum);
|
||||||
printf("Source : %d.%d.%d.%d\n",
|
xprintf("Source : %d.%d.%d.%d\n",
|
||||||
ipframe->source_addr[0],
|
ipframe->source_addr[0],
|
||||||
ipframe->source_addr[1],
|
ipframe->source_addr[1],
|
||||||
ipframe->source_addr[2],
|
ipframe->source_addr[2],
|
||||||
ipframe->source_addr[3]);
|
ipframe->source_addr[3]);
|
||||||
printf("Dest : %d.%d.%d.%d\n",
|
xprintf("Dest : %d.%d.%d.%d\n",
|
||||||
ipframe->dest_addr[0],
|
ipframe->dest_addr[0],
|
||||||
ipframe->dest_addr[1],
|
ipframe->dest_addr[1],
|
||||||
ipframe->dest_addr[2],
|
ipframe->dest_addr[2],
|
||||||
ipframe->dest_addr[3]);
|
ipframe->dest_addr[3]);
|
||||||
printf("Options: %08X\n", ipframe->options);
|
xprintf("Options: %08X\n", ipframe->options);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint16_t ip_chksum(uint16_t *data, int num)
|
uint16_t ip_chksum(uint16_t *data, int num)
|
||||||
{
|
{
|
||||||
int chksum, ichksum;
|
int chksum, ichksum;
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
|
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
num = num >> 1; /* from bytes to words */
|
num = num >> 1; /* from bytes to words */
|
||||||
for (; num; num--, data++)
|
for (; num; num--, data++)
|
||||||
{
|
{
|
||||||
temp = *data;
|
temp = *data;
|
||||||
ichksum = chksum + temp;
|
ichksum = chksum + temp;
|
||||||
ichksum = ichksum & 0x0000FFFF;
|
ichksum = ichksum & 0x0000FFFF;
|
||||||
if ((ichksum < temp) || (ichksum < chksum))
|
if ((ichksum < temp) || (ichksum < chksum))
|
||||||
{
|
{
|
||||||
ichksum += 1;
|
ichksum += 1;
|
||||||
ichksum = ichksum & 0x0000FFFF;
|
ichksum = ichksum & 0x0000FFFF;
|
||||||
}
|
}
|
||||||
chksum = ichksum;
|
chksum = ichksum;
|
||||||
}
|
}
|
||||||
return (uint16_t) ~chksum;
|
return (uint16_t) ~chksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe)
|
static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe)
|
||||||
{
|
{
|
||||||
int index, chksum;
|
int index, chksum;
|
||||||
IP_INFO *info;
|
IP_INFO *info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the IP Version
|
* Check the IP Version
|
||||||
*/
|
*/
|
||||||
if (IP_VERSION(ipframe) != 4)
|
if (IP_VERSION(ipframe) != 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check Internet Header Length
|
* Check Internet Header Length
|
||||||
*/
|
*/
|
||||||
if (IP_IHL(ipframe) < 5)
|
if (IP_IHL(ipframe) < 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the destination IP address
|
* Check the destination IP address
|
||||||
*/
|
*/
|
||||||
info = nif_get_protocol_info(nif,ETH_FRM_IP);
|
info = nif_get_protocol_info(nif,ETH_FRM_IP);
|
||||||
for (index = 0; index < sizeof(IP_ADDR); index++)
|
for (index = 0; index < sizeof(IP_ADDR); index++)
|
||||||
if (info->myip[index] != ipframe->dest_addr[index])
|
if (info->myip[index] != ipframe->dest_addr[index])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the checksum
|
* Check the checksum
|
||||||
*/
|
*/
|
||||||
chksum = (int)((uint16_t) IP_CHKSUM(ipframe));
|
chksum = (int)((uint16_t) IP_CHKSUM(ipframe));
|
||||||
IP_CHKSUM(ipframe) = 0;
|
IP_CHKSUM(ipframe) = 0;
|
||||||
|
|
||||||
if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum)
|
if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
IP_CHKSUM(ipframe) = (uint16_t) chksum;
|
IP_CHKSUM(ipframe) = (uint16_t) chksum;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip_handler(NIF *nif, NBUF *pNbuf)
|
void ip_handler(NIF *nif, NBUF *pNbuf)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* IP packet handler
|
* IP packet handler
|
||||||
*/
|
*/
|
||||||
ip_frame_hdr *ipframe;
|
ip_frame_hdr *ipframe;
|
||||||
|
|
||||||
ipframe = (ip_frame_hdr *)&pNbuf->data[pNbuf->offset];
|
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify valid IP header and destination IP
|
* Verify valid IP header and destination IP
|
||||||
*/
|
*/
|
||||||
if (!validate_ip_hdr(nif, ipframe))
|
if (!validate_ip_hdr(nif, ipframe))
|
||||||
{
|
{
|
||||||
nbuf_free(pNbuf);
|
nbuf_free(pNbuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNbuf->offset += (IP_IHL(ipframe) * 4);
|
pNbuf->offset += (IP_IHL(ipframe) * 4);
|
||||||
pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4));
|
pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call the appriopriate handler
|
* Call the appriopriate handler
|
||||||
*/
|
*/
|
||||||
switch (IP_PROTOCOL(ipframe))
|
switch (IP_PROTOCOL(ipframe))
|
||||||
{
|
{
|
||||||
case IP_PROTO_ICMP:
|
case IP_PROTO_ICMP:
|
||||||
// FIXME: icmp_handler(nif,pNbuf);
|
// FIXME: icmp_handler(nif,pNbuf);
|
||||||
break;
|
break;
|
||||||
case IP_PROTO_UDP:
|
case IP_PROTO_UDP:
|
||||||
udp_handler(nif,pNbuf);
|
udp_handler(nif,pNbuf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nbuf_free(pNbuf);
|
nbuf_free(pNbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
13
net/udp.c
13
net/udp.c
@@ -11,6 +11,13 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define UDP_DEBUG
|
||||||
|
#if defined(UDP_DEBUG)
|
||||||
|
#define dbg(format, arg...) do { xprintf("DEBUG: " format "\r\n", ##arg); } while (0)
|
||||||
|
#else
|
||||||
|
#define dbg(format, arg...) do { ; } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
@@ -99,6 +106,12 @@ uint16_t udp_obtain_free_port(void)
|
|||||||
|
|
||||||
int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
|
int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
|
||||||
{
|
{
|
||||||
|
if (nif == NULL)
|
||||||
|
{
|
||||||
|
dbg("%s: nif is NULL\r\n", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function takes data and creates a UDP frame and
|
* This function takes data and creates a UDP frame and
|
||||||
* passes it onto the IP layer
|
* passes it onto the IP layer
|
||||||
|
|||||||
Reference in New Issue
Block a user