if_types.h 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
#ifndef IF_TYPES_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IF_TYPES_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define IFT_OTHER 0x01 /*!< \brief Neither Ethernet and PPP, nor loopback. */
#define IFT_ETHER 0x06 /*!< \brief Ethernet interface. */
#define IFT_PPP 0x17 /*!< \brief PPP interface. */
#define IFT_LOOP 0x18 /*!< \brief Loopback interface */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
if_var.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef IF_VAR_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IF_VAR_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "XNutOS.h"
#include "netbuf.h"
#include "if_types.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define ATF_REM 0x01 /*!< \brief Entry marked for removal. */
#define ATF_COM 0x02 /*!< \brief Completed entry. */
#define ATF_PERM 0x04 /*!< \brief Permanent entry. */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief ARP entry type.
*/
typedef struct _ARPENTRY ARPENTRY;
/*!
* \struct _ARPENTRY if_var.h net/if_var.h
* \brief ARP entry structure.
*
* Each network interface maintains its own ARP table.
*/
struct _ARPENTRY {
ARPENTRY *ae_next; /*!< \brief Linked list chain. */
u_long ae_ip; /*!< \brief IP address. */
u_char ae_ha[6]; /*!< \brief Hardware address. */
u_char ae_flags; /*!< \brief Status flags, permanent and completed. */
u_char ae_outdated; /*!< \brief Minutes since last use. */
NUTHANDLE ae_tq; /*!< \brief Threads waiting for entry to be completed. */
};
/*!
* \brief Multicast address entry type.
*/
typedef struct _MCASTENTRY MCASTENTRY;
/*!
* \struct _MCASTENTRY if_var.h net/if_var.h
* \brief Multicast entry structure.
*/
struct _MCASTENTRY {
MCASTENTRY *mca_next;
u_char mca_ha[6];
u_long mca_ip;
};
/*!
* \brief Network interface type.
*/
typedef struct ifnet IFNET;
/*!
* \struct ifnet if_var.h net/if_var.h
* \brief Network interface structure.
*
* Contains information about the network interface.
*/
struct ifnet {
u_char if_type; /*!< \brief Interface type.
* Either IFT_ETHER or IFT_PPP.
*/
u_char if_mac[6]; /*!< \brief Hardware net address. */
u_long if_local_ip; /*!< \brief IP address. */
u_long if_remote_ip; /*!< \brief Remote IP address for point to point. */
u_long if_mask; /*!< \brief IP network mask. */
u_short if_mtu; /*!< \brief Maximum size of a transmission unit. */
u_short if_pkt_id; /*!< \brief Packet identifier. */
ARPENTRY *arpTable; /*!< \brief Linked list of arp entries. */
MCASTENTRY *if_mcast; /*!< \brief Linked list of multicast address entries. */
void (*if_recv) (NUTDEVICE *, NETBUF *); /*!< \brief Receive routine. */
int (*if_send) (NUTDEVICE *, NETBUF *); /*!< \brief Send routine. */
int (*if_output) (NUTDEVICE *, u_short, u_char *, NETBUF *); /*!< \brief Media output routine. */
int (*if_ioctl) (NUTDEVICE *, int, void *); /*!< \brief Interface specific control function. */
};
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
int NutNetIfConfig2(CONST char *name, void *mac_dev, u_long ip_addr, u_long ip_mask, u_long gateway);
int NutNetIfConfig(CONST char *name, void *mac_dev, u_long ip_addr, u_long ip_mask);
int NutNetIfSetup(NUTDEVICE * dev, u_long ip_addr, u_long ip_mask, u_long gateway);
int NutNetLoadConfig(CONST char *name);
int NutNetSaveConfig(void);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ifconfig.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IFCONFIG_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "XLib.h"
#include "ether.h"
#include "route.h"
#include "inet.h"
#include "if_ether.h"
#include "confnet.h"
#include "..\pro\dhcp.h"
#ifdef NUTDEBUG
#include "netdebug.h"
#endif
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Network interface setup.
*
* \param dev Identifies the network device to setup.
* \param ip_addr Specified IP address in network byte order.
* \param ip_mask Specified IP network mask in network byte order.
* \param gateway Optional default gateway.
*
* \return 0 on success, -1 otherwise.
*
* \note Typical applications do not use this function, but call
* NutDhcpIfConfig() or NutNetIfConfig().
*/
int NutNetIfSetup(NUTDEVICE * dev, u_long ip_addr, u_long ip_mask, u_long gateway)
{
IFNET *nif;
nif = dev->dev_icb;
/*
* Use specified or previously used IP address.
*/
if (ip_addr == 0 && (ip_addr = confnet.cdn_ip_addr) == 0)
return -1;
nif->if_local_ip = ip_addr;
/*
* Use specified or default mask.
*/
if (ip_mask == 0)
ip_mask = inet_addr("255.255.255.0");
nif->if_mask = ip_mask;
/*
* Add routing entries.
*/
NutIpRouteAdd(ip_addr & ip_mask, ip_mask, 0, dev);
if (gateway)
NutIpRouteAdd(0, 0, gateway, dev);
/*
* Save configuration in EEPROM.
*/
memcpy(confnet.cd_name, dev->dev_name, sizeof(confnet.cd_name));
/* Never save an invalid MAC address. */
if (ETHER_IS_UNICAST(nif->if_mac)) {
memcpy(confnet.cdn_mac, nif->if_mac, sizeof(nif->if_mac));
}
confnet.cdn_ip_addr = ip_addr;
confnet.cdn_ip_mask = ip_mask;
/*
* Set gateway, if one was provided by the caller. Remove
* gateway, if it's outside of our network.
*/
if (gateway || (confnet.cdn_gateway & ip_mask) != (ip_addr & ip_mask))
confnet.cdn_gateway = gateway;
return NutNetSaveConfig();
}
/*!
* \brief Configure a network interface.
*
* Devices must have been registered by NutRegisterDevice() before
* calling this function.
*
* For Ethernet devices applications may alternatively call
* NutDhcpIfConfig(), which allows automatic configuration by DHCP or
* the so called ARP method.
*
* \param name Name of the device to configure.
* \param params Pointer to interface specific parameters. For Ethernet
* interfaces this parameter may be a pointer to a buffer
* containing the 6 byte long MAC address. This will
* override the MAC address stored in the non-volatile
* configuration memory. If this memory is uninitialized
* or not available, the MAC address must be specified.
* For PPP interfaces this parameter is ignored and should
* be set to zero.
* \param ip_addr Specified IP address in network byte order. This must
* be a unique address within the Internet. If you do not
* directly communicate with other Internet hosts, you can
* use a locally assigned address. With PPP interfaces this
* may be set to 0.0.0.0, in which case the remote peer
* will be queried for an IP address.
* \param ip_mask Specified IP network mask in network byte order.
* Typical Ethernet networks use 255.255.255.0, which
* allows upto 254 hosts. For PPP interfaces 255.255.255.255
* is the default.
*
* \return 0 on success, -1 otherwise.
*
* \note The whole interface configuration has become a mess over
* the years and need a major redesign.
*/
int NutNetIfConfig(CONST char *name, void *params, u_long ip_addr, u_long ip_mask)
{
return NutNetIfConfig2(name, params, ip_addr, ip_mask, 0);
}
/*!
* \brief Configure a network interface including the default gateway.
*
* Devices must have been registered by NutRegisterDevice() before
* calling this function.
*
* For Ethernet devices applications may alternatively call
* NutDhcpIfConfig(), which allows automatic configuration by DHCP or
* the so called ARP method.
*
* \param name Name of the device to configure.
* \param params Pointer to interface specific parameters.
* \param ip_addr Specified IP address in network byte order. This must
* be a unique address within the Internet. If you do not
* directly communicate with other Internet hosts, you can
* use a locally assigned address. With PPP interfaces this
* may be set to 0.0.0.0, in which case the remote peer
* will be queried for an IP address.
* \param ip_mask Specified IP network mask in network byte order.
* Typical Ethernet networks use 255.255.255.0, which
* allows upto 254 hosts. For PPP interfaces 255.255.255.255
* is the default.
* \param gateway Specified IP address of gateway or next router in LAN.
*
* \return 0 on success, -1 otherwise.
*
* \note I do not like this function, because setting a gateway should
* be handled by NutIpRouteAdd(). It's not yet deprecated, but I
* recommend not to use it in application code.
*/
int NutNetIfConfig2(CONST char *name, void *params, u_long ip_addr, u_long ip_mask, u_long gateway)
{
NUTDEVICE *dev;
IFNET *nif;
/*
* Check if this is a registered network device.
*/
if ((dev = NutDeviceLookup(name)) == 0 || dev->dev_type != IFTYP_NET)
return -1;
/*
* Setup Ethernet interfaces.
*/
nif = dev->dev_icb;
if (nif->if_type == IFT_ETHER) {
memcpy(nif->if_mac, params, sizeof(nif->if_mac));
return NutNetIfSetup(dev, ip_addr, ip_mask, gateway);
}
/*
* Setup PPP interfaces.
*/
// else if (nif->if_type == IFT_PPP) {
// PPPDCB *dcb = dev->dev_dcb;
//
// /*
// * Set the interface's IP address, make sure that the state
// * change queue is empty and switch hardware driver into
// * network mode.
// */
// dcb->dcb_local_ip = ip_addr;
// dcb->dcb_ip_mask = ip_mask ? ip_mask : 0xffffffff;
// NutEventBroadcast(&dcb->dcb_state_chg);
// _ioctl(dcb->dcb_fd, HDLC_SETIFNET, &dev);
//
// /*
// * Wait for network layer up and configure the interface on
// * success.
// */
// if (NutEventWait(&dcb->dcb_state_chg, 60000) == 0 && dcb->dcb_ipcp_state == PPPS_OPENED) {
// return NutNetIfSetup(dev, dcb->dcb_local_ip, dcb->dcb_ip_mask, dcb->dcb_remote_ip);
// }
// }
return -1;
}
#endif
in.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef IN_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IN_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*
* Protocols
*/
#define IPPROTO_IP 0 /*!< \brief Dummy for IP. */
#define IPPROTO_ICMP 1 /*!< \brief Control message protocol. */
#define IPPROTO_IGMP 2 /*!< \brief Group management protocol. */
#define IPPROTO_TCP 6 /*!< \brief Transmission control protocol. */
#define IPPROTO_UDP 17 /*!< \brief User datagram protocol. */
#define IPPROTO_RAW 255 /*!< \brief Raw IP packet. */
#define IPPROTO_MAX 256 /*!< \brief Maximum protocol identifier. */
#define IPPORT_RESERVED 1024 /*!< \brief Last reserved port number. */
#define IPPORT_USERRESERVED 5000 /*!< \brief User reserved port number. */
/*!
* \brief Any IP address.
*/
#define INADDR_ANY (u_long)0x00000000
/*!
* \brief Broadcast IP address.
*/
#define INADDR_BROADCAST (u_long)0xffffffff
/*
* Definitions of bits in internet address integers.
*/
#ifdef BIG_ENDIAN
#define IN_CLASSA(i) (((u_long)(i) & 0x80000000) == 0)
#define IN_CLASSA_NET 0xff000000
#define IN_CLASSB(i) (((u_long)(i) & 0xc0000000) == 0x80000000)
#define IN_CLASSB_NET 0xffff0000
#define IN_CLASSC(i) (((u_long)(i) & 0xe0000000) == 0xc0000000)
#define IN_CLASSC_NET 0xffffff00
#define IN_CLASSD(i) (((u_long)(i) & 0xf0000000) == 0xe0000000)
#define IN_CLASSD_NET 0xf0000000
#else /* BIG_ENDIAN */
#define IN_CLASSA(i) (((u_long)(i) & 0x00000080) == 0)
#define IN_CLASSA_NET 0x000000ff
#define IN_CLASSB(i) (((u_long)(i) & 0x000000c0) == 0x00000080)
#define IN_CLASSB_NET 0x0000ffff
#define IN_CLASSC(i) (((u_long)(i) & 0x000000e0) == 0x000000c0)
#define IN_CLASSC_NET 0x00ffffff
#define IN_CLASSD(i) (((u_long)(i) & 0x000000f0) == 0x000000e0)
#define IN_CLASSD_NET 0x0000000f
#endif /* BIG_ENDIAN */
#define IN_MULTICAST(i) IN_CLASSD(i)
#ifdef BIG_ENDIAN
#define INADDR_UNSPEC_GROUP (u_long)0xe0000000 /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */
#define INADDR_ALLRTRS_GROUP (u_long)0xe0000002 /* 224.0.0.2 */
#define INADDR_ALLRPTS_GROUP (u_long)0xe0000016 /* 224.0.0.22, IGMPv3 */
#define INADDR_CARP_GROUP (u_long)0xe0000012 /* 224.0.0.18 */
#define INADDR_PFSYNC_GROUP (u_long)0xe00000f0 /* 224.0.0.240 */
#define INADDR_ALLMDNS_GROUP (u_long)0xe00000fb /* 224.0.0.251 */
#define INADDR_MAX_LOCAL_GROUP (u_long)0xe00000ff /* 224.0.0.255 */
#else /* BIG_ENDIAN */
#define INADDR_UNSPEC_GROUP (u_long)0x000000e0 /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP (u_long)0x010000e0 /* 224.0.0.1 */
#define INADDR_ALLRTRS_GROUP (u_long)0x020000e0 /* 224.0.0.2 */
#define INADDR_ALLRPTS_GROUP (u_long)0x160000e0 /* 224.0.0.22, IGMPv3 */
#define INADDR_CARP_GROUP (u_long)0x120000e0 /* 224.0.0.18 */
#define INADDR_PFSYNC_GROUP (u_long)0xf00000e0 /* 224.0.0.240 */
#define INADDR_ALLMDNS_GROUP (u_long)0xfb0000e0 /* 224.0.0.251 */
#define INADDR_MAX_LOCAL_GROUP (u_long)0xff0000e0 /* 224.0.0.255 */
#endif /* BIG_ENDIAN */
#ifdef BIG_ENDIAN
#define INADDR_LOOPBACK (u_long)0x7f000001
#else /* BIG_ENDIAN */
#define INADDR_LOOPBACK (u_long)0x0100007f
#endif /* BIG_ENDIAN */
/*!
* \brief Official loopback net address.
*/
#define IN_LOOPBACKNET 127
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
inet.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define INET_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "inet.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Convert decimal dotted ASCII representation into numeric IP address.
*
* \param str String containing the ASCII representation.
*
* \return IP address in network byte order.
*/
u_long inet_addr(CONST char * str)
{
u_short num;
u_long addr = 0;
u_char parts = 0;
u_char *ap;
ap = (u_char *) & addr;
while (parts < 4) {
if (*str < '0' || *str > '9')
break;
for (num = 0; num <= 255;) {
num = (num * 10) + (*str - '0');
if (*++str < '0' || *str > '9')
break;
}
if (num > 255)
break;
parts++;
*ap++ = (u_char) num;
if (*str != '.') {
if (parts == 4)
return addr;
break;
}
str++;
}
return (u_long) -1;
}
/*!
* \brief Convert numeric IP address into decimal dotted
* ASCII representation.
*
* \note This function is not thread safe. Each subsequent
* call will destroy the previous result. Applications
* should locally store the result before calling the
* function again or allowing other threads to call it.
*
* \param addr IP address in network byte order.
*
* \return Pointer to a static buffer containing the
* ASCII representation.
*/
char *inet_ntoa(u_long addr)
{
static char str[16];
char inv[3];
char *rp;
u_char *ap;
u_char rem;
u_char n;
u_char i;
rp = str;
ap = (u_char *) & addr;
for (n = 0; n < 4; n++) {
i = 0;
do {
rem = *ap % (u_char) 10;
*ap /= (u_char) 10;
inv[i++] = '0' + rem;
} while (*ap);
while (i--)
*rp++ = inv[i];
*rp++ = '.';
ap++;
}
*--rp = 0;
return str;
}
#endif
inet.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef INET_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define INET_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
u_long inet_addr(CONST char *str);
char *inet_ntoa(u_long addr);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ip.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef IP_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IP_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "if_arp.h"
#include "netbuf.h"
#include "if_var.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define IPVERSION 4 /*!< \brief IP protocol version. */
#define IP_DF 0x4000 /*!< \brief Don't fragment flag. */
#define IP_MF 0x2000 /*!< \brief More fragments flag. */
#define IP_OFFMASK 0x1fff /*!< \brief Mask for fragmenting bits. */
#define IPOPT_EOL 0 /*!< \brief End of option list. */
#define IPOPT_NOP 1 /*!< \brief No operation. */
#define IPOPT_RR 7 /*!< \brief Record packet route. */
#define IPOPT_TS 68 /*!< \brief Timestamp. */
#define IPOPT_SECURITY 130 /*!< \brief Provide s,c,h,tcc. */
#define IPOPT_LSRR 131 /*!< \brief Loose source route. */
#define IPOPT_SATID 136 /*!< \brief Satnet id. */
#define IPOPT_SSRR 137 /*!< \brief Strict source route. */
#define IPOPT_OPTVAL 0 /*!< \brief Option identifier offset. */
#define IPOPT_OLEN 1 /*!< \brief Option length offset. */
#define IPOPT_OFFSET 2 /*!< \brief Offset within option. */
#define IPOPT_MINOFF 4 /*!< \brief Minimum offset within option. */
#define MAXTTL 255 /*!< \brief Maximum time to live (seconds). */
#define IPDEFTTL 64 /*!< \brief Default time to live. */
#define IPFRAGTTL 60 /*!< \brief Time to live for fragments. */
#define IPTTLDEC 1 /*!< \brief Subtracted from time to live when forwarding. */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Internet header type.
*/
typedef struct ip IPHDR;
/*!
* \brief Structure of an internet header.
*/
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039 // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif
struct ip {
#ifndef BIG_ENDIAN
u_char ip_hl:4, /*!< \brief Header length. */
ip_v:4; /*!< \brief Version. */
#else /* #ifndef BIG_ENDIAN */
u_char ip_v:4, /*!< \brief Version. */
ip_hl:4; /*!< \brief Header length. */
#endif /* #ifndef BIG_ENDIAN */
u_char ip_tos; /*!< \brief Type of service. */
short ip_len; /*!< \brief Total length. */
u_short ip_id; /*!< \brief Identification. */
short ip_off; /*!< \brief Fragment offset field. */
u_char ip_ttl; /*!< \brief Time to live. */
u_char ip_p; /*!< \brief Protocol. */
u_short ip_sum; /*!< \brief Checksum. */
u_long ip_src; /*!< \brief Source IP address. */
u_long ip_dst; /*!< \brief Destination IP address. */
};
#if defined(__ICCARM__)
#pragma pack ( )
#endif
typedef int (*NutIpFilterFunc) (u_long);
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/*
* API declarations.
*/
int NutIpOutput(u_char proto, u_long dest, NETBUF * nb);
/*
* Kernel declarations.
*/
void NutIpInput(NUTDEVICE * dev, NETBUF * nb);
/*
* Ip Filter declarations.
*/
void NutIpSetInputFilter(NutIpFilterFunc callbackFunc);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ip_icmp.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef IP_ICMP_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IP_ICMP_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "if_arp.h"
#include "ip.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*
* Definition of type and code field values.
*/
#define ICMP_ECHOREPLY 0 /*!< \brief Echo reply type. */
#define ICMP_UNREACH 3 /*!< \brief Destination unreachable type. */
#define ICMP_UNREACH_NET 0 /*!< \brief Destination unreachable: Bad net code. */
#define ICMP_UNREACH_HOST 1 /*!< \brief Destination unreachable: Bad host. */
#define ICMP_UNREACH_PROTOCOL 2 /*!< \brief Destination unreachable: Bad protocol. */
#define ICMP_UNREACH_PORT 3 /*!< \brief Destination unreachable: Bad port. */
#define ICMP_UNREACH_NEEDFRAG 4 /*!< \brief Destination unreachable: Fragmentation needed. */
#define ICMP_UNREACH_SRCFAIL 5 /*!< \brief Destination unreachable: Source route failed. */
#define ICMP_UNREACH_NET_UNKNOWN 6 /*!< \brief Destination unreachable: Unknown net. */
#define ICMP_UNREACH_HOST_UNKNOWN 7 /*!< \brief Destination unreachable: Unknown host. */
#define ICMP_UNREACH_ISOLATED 8 /*!< \brief Destination unreachable: Source host isolated. */
#define ICMP_UNREACH_NET_PROHIB 9 /*!< \brief Destination unreachable: Net access prohibited. */
#define ICMP_UNREACH_HOST_PROHIB 10 /*!< \brief Destination unreachable: Host access prohibited. */
#define ICMP_UNREACH_TOSNET 11 /*!< \brief Destination unreachable: Bad tos for net. */
#define ICMP_UNREACH_TOSHOST 12 /*!< \brief Destination unreachable: Bad tos for host. */
#define ICMP_SOURCEQUENCH 4 /*!< \brief Packet lost type. */
#define ICMP_REDIRECT 5 /*!< \brief Shorter route type. */
#define ICMP_REDIRECT_NET 0 /*!< \brief Shorter route for network. */
#define ICMP_REDIRECT_HOST 1 /*!< \brief Shorter route for host. */
#define ICMP_REDIRECT_TOSNET 2 /*!< \brief Shorter route for tos and net. */
#define ICMP_REDIRECT_TOSHOST 3 /*!< \brief Shorter route for tos and host. */
#define ICMP_ECHO 8 /*!< \brief Echo reply type. */
#define ICMP_ROUTERADVERT 9 /*!< \brief Router advertisement type. */
#define ICMP_ROUTERSOLICIT 10 /*!< \brief Router solicitation type. */
#define ICMP_TIMXCEED 11 /*!< \brief Time exceeded type. */
#define ICMP_TIMXCEED_INTRANS 0 /*!< \brief Time exceeded in transit. */
#define ICMP_TIMXCEED_REASS 1 /*!< \brief Time exceeded in reassembly. */
#define ICMP_PARAMPROB 12 /*!< \brief Bad IP header type. */
#define ICMP_PARAMPROB_OPTABSENT 1 /*!< \brief Bad IP header: Required option missing. */
#define ICMP_TSTAMP 13 /*!< \brief Timestamp request type. */
#define ICMP_TSTAMPREPLY 14 /*!< \brief Timestamp reply type. */
#define ICMP_IREQ 15 /*!< \brief Information request type. */
#define ICMP_IREQREPLY 16 /*!< \brief Information reply type. */
#define ICMP_MASKREQ 17 /*!< \brief Address mask request type. */
#define ICMP_MASKREPLY 18 /*!< \brief Address mask reply type. */
#define ICMP_MAXTYPE 18 /*!< \brief Maximum ICMP type number. */
#define ICMP_MINLEN 8 /*!< \brief Lower bounds on packet length. */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \typedef ICMPHDR
* \brief ICMP protocol header type.
*/
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039 // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif
typedef struct icmp {
u_char icmp_type; /*!< \brief Type of message. */
u_char icmp_code; /*!< \brief Type sub code. */
u_short icmp_cksum; /*!< \brief Ones complement header checksum. */
u_long icmp_spec; /*!< \brief Type specific information. */
} ICMPHDR;
#if defined(__ICCARM__)
#pragma pack ( )
#endif
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ipcsum.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IPCSUM_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "ipcsum.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/*
* Details of the pseudo header used as part of the
* calculation of UDP and TCP header checksums.
*/
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039 // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif
struct pseudo_hdr {
u_long ph_src_addr;
u_long ph_dest_addr;
u_char ph_zero;
u_char ph_protocol;
u_short ph_len;
};
#if defined(__ICCARM__)
#pragma pack ( )
#endif
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Calculate a partial IP checksum of a buffer.
*
* The caller must create the one's complement of the final result.
*
* \param ics Initial checksum from previous parts.
* \param buf Pointer to the buffer.
* \param len Number of bytes in the buffer.
*
* \return Partial checksum in network byte order.
*/
u_short NutIpChkSumPartial(u_short ics, CONST void *buf, int len)
{
register u_long sum = ics;
register u_char *cp = (u_char *) buf;
/* Sum up 16 bit values. */
while (len > 1) {
#ifdef BIG_ENDIAN
sum += ((u_short)*cp << 8) | *(cp + 1);
#else
sum += ((u_short)*(cp + 1) << 8) | *cp;
#endif
cp += 2;
len -= 2;
}
/* Add remaining byte on odd lengths. */
if (len) {
#ifdef BIG_ENDIAN
sum += (u_short)*cp << 8;
#else
sum += *cp;
#endif
}
/* Fold upper 16 bits to lower ones. */
while (sum >> 16) {
sum = (u_short)sum + (sum >> 16);
}
return (u_short) sum;
}
/*!
* \brief Calculates an the final IP checksum over a block of data.
*
* Unlike the partial checksum in NutIpChkSumPartial(), this function takes
* the one's complement of the final result, thus making it the full checksum.
*/
u_short NutIpChkSum(u_short ics, CONST void *buf, int len)
{
return ~NutIpChkSumPartial(ics, buf, len);
}
/*!
* \brief Calculates the partial IP pseudo checksum.
*
*/
u_long NutIpPseudoChkSumPartial(u_long src_addr, u_long dest_addr, u_char protocol, int len)
{
struct pseudo_hdr ph;
ph.ph_src_addr = src_addr;
ph.ph_dest_addr = dest_addr;
ph.ph_zero = 0;
ph.ph_protocol = protocol;
ph.ph_len = len;
return NutIpChkSumPartial(0, &ph, sizeof(struct pseudo_hdr));
}
#endif
ipcsum.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef IPCSUM_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IPCSUM_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <stdio.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
u_short NutIpChkSumPartial(u_short ics, CONST void *buf, int len);
u_short NutIpChkSum(u_short ics, CONST void *buf, int len);
u_long NutIpPseudoChkSumPartial(u_long src_addr, u_long dest_addr, u_char protocol, int len);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ipin.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IPIN_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "route.h"
#include "in.h"
#include "ip.h"
#include "icmp.h"
#include "ip_icmp.h"
#include "udp.h"
#include "socket.h"
#include "inet.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static NutIpFilterFunc NutIpFilter;
/*!
* \brief Set filter function for incoming IP datagrams.
*
* The callbackFunc is called by the IP layer on every incoming IP
* datagram. Thus it must not block. The implementer returns 0 for
* allow, -1 for deny.
*
* It is recommended to set the filer after DHCP has done its thing,
* just in case your DHCP server is on a different subnet for example.
*
* \param callbackFunc Pointer to callback function to filter IP packets.
* Set to 0 to disable the filter again.
*/
void NutIpSetInputFilter(NutIpFilterFunc callbackFunc)
{
NutIpFilter = callbackFunc;
}
/*!
* \brief Process incoming IP datagrams.
*
* Datagrams addressed to other destinations and datagrams
* whose version number is not 4 are silently discarded.
*
* \note This routine is called by the Ethernet layer on
* incoming IP datagrams. Applications typically do
* not call this function.
*
* \param dev Identifies the device that received this datagram.
* \param nb The network buffer received.
*/
void NutIpInput(NUTDEVICE * dev, NETBUF * nb)
{
IPHDR *ip;
u_short hdrlen;
u_long dst;
u_char bcast;
IFNET *nif;
ip = nb->nb_nw.vp;
/*
* Silently discard datagrams of different IP version as well as
* fragmented or filtered datagrams.
*/
if (ip->ip_v != IPVERSION || /* Version check. */
(ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) != 0 || /* Fragmentation. */
(NutIpFilter && NutIpFilter(ip->ip_src))) { /* Filter. */
NutNetBufFree(nb);
return;
}
/*
** IP header length is given in 32-bit fields. Calculate the size in
** bytes and make sure that the header we know will fit in. Check
** further, that the header length is not larger than the bytes we
** received.
*/
hdrlen = ip->ip_hl * 4;
if (hdrlen < sizeof(IPHDR) || hdrlen > nb->nb_nw.sz) {
NutNetBufFree(nb);
return;
}
#if NUT_IP_INCHKSUM
/* Optional checksum calculation on incoming datagrams. */
#endif
/*
* Check for broadcast.
*/
dst = ip->ip_dst;
nif = dev->dev_icb;
if (dst == INADDR_BROADCAST ||
(nif->if_local_ip && nif->if_mask != INADDR_BROADCAST && (dst | nif->if_mask) == INADDR_BROADCAST)) {
bcast = 1;
}
/*
* Check for multicast.
*/
else if (IN_MULTICAST(dst)) {
MCASTENTRY *mca;
for (mca = nif->if_mcast; mca; mca = mca->mca_next) {
if (dst == mca->mca_ip) {
break;
}
}
if (mca == NULL) {
NutNetBufFree(nb);
return;
}
bcast = 2;
}
/*
* Packet is unicast.
*/
else {
bcast = 0;
nb->nb_flags |= NBAF_UNICAST;
#ifdef NUTIPCONF_ICMP_ARPMETHOD
/*
* Silently discard datagrams for other destinations.
* However, if we haven't got an IP address yet, we
* allow ICMP datagrams to support dynamic IP ARP method,
* if this option had been enabled.
*/
if (nif->if_local_ip == 0 && ip->ip_p == IPPROTO_ICMP && (dst & 0xff000000) != 0xff000000 && (dst & 0xff000000) != 0) {
NutNetIfSetup(dev, dst, 0, 0);
}
#endif
if (nif->if_local_ip && (dst == 0 || dst != nif->if_local_ip)) {
NutNetBufFree(nb);
return;
}
}
/* Check the IP data length. */
nb->nb_tp.sz = htons(ip->ip_len);
if (nb->nb_tp.sz < hdrlen || nb->nb_tp.sz > nb->nb_nw.sz) {
NutNetBufFree(nb);
return;
}
nb->nb_nw.sz = hdrlen;
nb->nb_tp.sz -= hdrlen;
if (nb->nb_tp.sz) {
nb->nb_tp.vp = ((char *) ip) + hdrlen;
}
switch (ip->ip_p) {
case IPPROTO_ICMP:
NutIcmpInput(dev, nb);
break;
case IPPROTO_UDP:
NutUdpInput(dev, nb);
break;
case IPPROTO_TCP:
NutTcpInput(dev, nb);
break;
#if 0
case IPPROTO_IGMP:
NutIgmpInput(dev, nb);
break;
#endif
default:
/* Unkown protocol, send ICMP destination (protocol)
* unreachable message.
*/
if (bcast || !NutIcmpResponse(ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 0, nb))
NutNetBufFree(nb);
break;
}
}
#endif
ipout.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define IPOUT_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "ether.h"
#include "route.h"
#include "if_ether.h"
#include "ipcsum.h"
#include "ip.h"
#include "in.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Send IP datagram.
*
* Route an IP datagram to the proper interface.
*
* The function will not return until the data has been stored
* in the network device hardware for transmission. If the
* device is not ready for transmitting a new packet, the
* calling thread will be suspended until the device becomes
* ready again. If the hardware address of the target host needs
* to be resolved the function will be suspended too.
*
* \param proto Protocol type.
* \param dest Destination IP address. The function will determine
* the proper network interface by checking the routing
* table. It will also perform any neccessary hardware
* address resolution.
* \param nb Network buffer structure containing the datagram.
* This buffer will be released if the function returns
* an error.
*
* \return 0 on success, -1 otherwise.
*
* \bug Broadcasts to multiple network devices will fail after the
* first device returns an error.
*/
int NutIpOutput(u_char proto, u_long dest, NETBUF * nb)
{
u_char ha[6];
IPHDR *ip;
NUTDEVICE *dev;
IFNET *nif;
u_long gate;
int rc;
if ((nb = NutNetBufAlloc(nb, NBAF_NETWORK, sizeof(IPHDR))) == 0)
return -1;
/*
* Set those items in the IP header, which are common for
* all interfaces.
*/
ip = nb->nb_nw.vp;
ip->ip_v = 4;
ip->ip_hl = sizeof(IPHDR) / 4;
ip->ip_tos = 0;
ip->ip_len = htons(nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz);
ip->ip_off = 0;
if (proto == IPPROTO_IGMP) {
ip->ip_ttl = 1;
} else {
ip->ip_ttl = 0x40;
}
ip->ip_p = proto;
ip->ip_dst = dest;
/*
* Broadcasts are sent on all network interfaces.
*/
if (dest == 0xffffffff) {
memset(ha, 0xff, sizeof(ha));
for (dev = nutDeviceList, rc = 0; dev && rc == 0; dev = dev->dev_next) {
if (dev->dev_type == IFTYP_NET) {
/*
* Set remaining IP header items and calculate the checksum.
*/
nif = dev->dev_icb;
//ip->ip_id = htons(nif->if_pkt_id++);
ip->ip_id = htons(nif->if_pkt_id); nif->if_pkt_id++;
ip->ip_src = nif->if_local_ip;
ip->ip_sum = 0;
ip->ip_sum = NutIpChkSum(0, nb->nb_nw.vp, nb->nb_nw.sz);
/*
* TODO: We must clone the NETBUF!!!
*/
if (nif->if_type == IFT_ETHER)
rc = (*nif->if_output) (dev, ETHERTYPE_IP, ha, nb);
// else
// rc = (*nif->if_output) (dev, PPP_IP, 0, nb);
}
}
return rc;
}
/*
* Get destination's route. This will also return the proper
* interface.
*/
if ((dev = NutIpRouteQuery(dest, &gate)) == 0) {
NutNetBufFree(nb);
return -1;
}
/*
* Set remaining IP header items and calculate the checksum.
*/
nif = dev->dev_icb;
//ip->ip_id = htons(nif->if_pkt_id++);
ip->ip_id = htons(nif->if_pkt_id); nif->if_pkt_id++;
ip->ip_src = nif->if_local_ip;
ip->ip_sum = 0;
ip->ip_sum = NutIpChkSum(0, nb->nb_nw.vp, nb->nb_nw.sz);
/*
* On Ethernet we query the MAC address of our next hop,
* which might be the destination or the gateway to this
* destination.
*/
if (nif->if_type == IFT_ETHER) {
/*
* Detect directed broadcasts for the local network. In this
* case don't send ARP queries, but send directly to MAC broadcast
* address.
*/
if ((gate == 0) && ((dest | nif->if_mask) == 0xffffffff)) {
memset(ha, 0xff, sizeof(ha));
} else if (NutArpCacheQuery(dev, gate ? gate : dest, ha)) {
/* Note, that a failed ARP request is not considered a
transmission error. It might be caused by a simple
packet loss. */
return 0;
}
return (*nif->if_output) (dev, ETHERTYPE_IP, ha, nb);
}
// else if (nif->if_type == IFT_PPP)
// return (*nif->if_output) (dev, PPP_IP, 0, nb);
NutNetBufFree(nb);
return -1;
}
#endif
netbuf.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NETBUF_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOs.h"
#include "netbuf.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static int NutNetBufAllocData(NBDATA * nbd, int size)
{
nbd->vp = NutHeapAlloc(size);
if (nbd->vp) {
nbd->sz = size;
return 0;
}
return -1;
}
/*!
* \brief Allocate or re-allocate a network buffer part.
*
* \param nb Points to an existing network buffer structure or NULL,
* if a new structure should be created. An existing buffer
* must not be used any further if this function returns
* a null pointer.
* \param type Part of the buffer to be allocated. This can be any of
* the following:
* - NBAF_DATALINK
* - NBAF_NETWORK
* - NBAF_TRANSPORT
* - NBAF_APPLICATION
* \param size Size of the part to be allocated.
*
* \return Pointer to the allocated network buffer structure. A null
* pointer is returned if not enough memory is available and
* the whole structure is released.
*/
NETBUF *NutNetBufAlloc(NETBUF * nb, u_char type, int size)
{
NBDATA * nbd;
/* Allocate a new buffer, if the caller don't provide one. */
if (nb == NULL) {
nb = NutHeapAllocClear(sizeof(NETBUF));
}
/* Make sure, that the allocation above was successful. */
if (nb) {
/* Determine the data type. */
switch(type) {
case NBAF_DATALINK:
nbd = &nb->nb_dl;
break;
case NBAF_NETWORK:
nbd = &nb->nb_nw;
break;
case NBAF_TRANSPORT:
nbd = &nb->nb_tp;
break;
default:
nbd = &nb->nb_ap;
break;
}
/* Check previously allocated buffer. */
if (nb->nb_flags & type) {
if (nbd->sz < size) {
/* Existing buffer is too small. */
NutHeapFree(nbd->vp);
nbd->sz = 0;
} else {
/*
* Reduce the size. This is actually a bad idea, because
* we may waste too much memory. One option would be to
* use the new NutHeapRealloc, but not sure if it will
* work for 32-bit CPUs after some crashes after its
* introduction. Further, I'm not fully sure, if our
* network routines actually re-use network buffers.
*/
nbd->sz = size;
}
} else {
/* Buffer was not allocated from heap. */
nbd->sz = 0;
}
/* If the size is zero at this point,
we need to allocate a new buffer. */
if (nbd->sz == 0) {
if (NutNetBufAllocData(nbd, size)) {
/* Out of memory, release the complete net buffer. */
NutNetBufFree(nb);
nb = NULL;
} else {
/* Success, mark the buffer allocated. */
nb->nb_flags |= type;
}
}
}
return nb;
}
/*!
* \brief Create a copy of an existing network buffer
* structure.
*
* \param nb Points to an existing network buffer
* structure, previously allocated by
* NutNetBufAlloc().
*
* \return Pointer to a newly allocated copy.
*/
NETBUF *NutNetBufClone(NETBUF * nb)
{
NETBUF *cb = NutHeapAllocClear(sizeof(NETBUF));
if (cb) {
register int e = 0;
register int s;
s = nb->nb_dl.sz;
if (s && (e = NutNetBufAllocData(&cb->nb_dl, s)) == 0) {
memcpy(cb->nb_dl.vp, nb->nb_dl.vp, s);
cb->nb_flags |= NBAF_DATALINK;
}
s = nb->nb_nw.sz;
if (s && e == 0 && (e = NutNetBufAllocData(&cb->nb_nw, s)) == 0) {
memcpy(cb->nb_nw.vp, nb->nb_nw.vp, s);
cb->nb_flags |= NBAF_NETWORK;
}
s = nb->nb_tp.sz;
if (s && e == 0 && (e = NutNetBufAllocData(&cb->nb_tp, s)) == 0) {
memcpy(cb->nb_tp.vp, nb->nb_tp.vp, s);
cb->nb_flags |= NBAF_TRANSPORT;
}
s = nb->nb_ap.sz;
if (s && e == 0 && (e = NutNetBufAllocData(&cb->nb_ap, s)) == 0) {
memcpy(cb->nb_ap.vp, nb->nb_ap.vp, s);
cb->nb_flags |= NBAF_APPLICATION;
}
if (e) {
NutNetBufFree(cb);
cb = NULL;
}
}
return cb;
}
/*!
* \brief Release a network buffer structure.
*
* Returns all memory previously allocated by a
* network buffer to the available heap space.
*
* \param nb Points to an existing network buffer
* structure, previously allocated by
* NutNetBufAlloc().
*/
void NutNetBufFree(NETBUF * nb)
{
if (nb->nb_flags & NBAF_DATALINK) {
NutHeapFree(nb->nb_dl.vp);
}
if (nb->nb_flags & NBAF_NETWORK) {
NutHeapFree(nb->nb_nw.vp);
}
if (nb->nb_flags & NBAF_TRANSPORT) {
NutHeapFree(nb->nb_tp.vp);
}
if (nb->nb_flags & NBAF_APPLICATION) {
NutHeapFree(nb->nb_ap.vp);
}
NutHeapFree(nb);
}
/*!
* \brief Collect linked list of network buffers.
*
* \param nbq Points to an existing network buffer queue.
*
* \return Number of released network buffers.
*/
int NutNetBufCollect(NETBUF * nbq, int total)
{
int rc = 0;
NETBUF *nb;
NETBUF *nbx;
NBDATA nbd;
u_char *ap;
if (NutNetBufAllocData(&nbd, total) == 0) {
ap = (u_char *) nbd.vp;
memcpy(nbd.vp, nbq->nb_ap.vp, nbq->nb_ap.sz);
nbd.sz = nbq->nb_ap.sz;
nb = nbq->nb_next;
while (nb && total >= nbd.sz + nb->nb_ap.sz) {
nbx = nb->nb_next;
memcpy(ap + nbd.sz, nb->nb_ap.vp, nb->nb_ap.sz);
nbd.sz += nb->nb_ap.sz;
NutNetBufFree(nb);
nb = nbx;
rc++;
}
nbq->nb_next = nb;
if (nbq->nb_flags & NBAF_APPLICATION) {
NutHeapFree(nbq->nb_ap.vp);
} else {
nbq->nb_flags |= NBAF_APPLICATION;
}
nbq->nb_ap.vp = nbd.vp;
nbq->nb_ap.sz = nbd.sz;
}
return rc;
}
#endif
netbuf.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NETBUF_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NETBUF_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* lower bits may be used as ref-count, if ever needed */
#define NBAF_UNICAST 0x08 /*!< \brief Unicast address. */
#define NBAF_DATALINK 0x10 /*!< \brief Datalink buffer allocated flag. */
#define NBAF_NETWORK 0x20 /*!< \brief Network buffer allocated flag. */
#define NBAF_TRANSPORT 0x40 /*!< \brief Transport buffer allocated flag. */
#define NBAF_APPLICATION 0x80 /*!< \brief Application buffer allocated flag. */
#define NBAF_ALL 0xf0 /*!< \brief Masks allocated buffer flags flag. */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Network buffer type.
*/
typedef struct _NETBUF NETBUF;
/*!
* \brief Network buffer data type.
*/
typedef struct _NBDATA NBDATA;
/*!
* \struct _NBDATA netbuf.h dev/netbuf.h
* \brief Data part of a network buffer structure.
*/
struct _NBDATA {
void *vp; /*!< \brief Pointer to data buffer. */
int sz; /*!< \brief Size of data buffer. */
};
/*!
* \struct _NETBUF netbuf.h dev/netbuf.h
* \brief Network buffer structure.
*/
struct _NETBUF {
NETBUF *nb_next; /*!< \brief Link to next structure. */
u_char nb_flags; /*!< \brief NBAF_ flags. */
NBDATA nb_dl; /*!< \brief Datalink buffer. */
NBDATA nb_nw; /*!< \brief Network buffer. */
NBDATA nb_tp; /*!< \brief Transport buffer. */
NBDATA nb_ap; /*!< \brief Application buffer. */
};
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
NETBUF *NutNetBufAlloc(NETBUF *nb, u_char type, int size);
NETBUF *NutNetBufClone(NETBUF *nb);
void NutNetBufFree(NETBUF * nb);
int NutNetBufCollect(NETBUF * nbq, int total);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
netdb.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NETDB_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NETDB_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*
* Error return codes.
*/
#define NETDB_INTERNAL -1 /* see errno */
#define NETDB_SUCCESS 0 /* no problem */
#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */
#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
#define NO_DATA 4 /* Valid name, no data record of requested type */
#define NO_ADDRESS NO_DATA /* no address, look for MX record */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
void NutDnsConfig2(u_char * hostname, u_char * domain, u_long pdnsip, u_long sdnsip);
void NutDnsGetConfig2(char ** hostname, char ** domain, u_long *pdnsip, u_long *sdnsip);
void NutDnsConfig(CONST u_char *hostname, CONST u_char *domain, u_long dnsip);
u_long NutDnsGetHostByName(CONST u_char *hostname);
u_long NutDnsGetMxByDomain(CONST u_char * hostname);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
netdebug.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NETDEBUG_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "inet.h"
#include "in.h"
#include "ip.h"
#include "icmp.h"
#include "ip_icmp.h"
#include "ipcsum.h"
#include "netdebug.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
extern TCPSOCKET *tcpSocketList;
extern UDPSOCKET *udpSocketList;
void NutDumpTcpHeader(FILE * stream, char * ds, TCPSOCKET * sock, NETBUF * nb)
{
static const char fmt[] = "%s%p[%u]-SEQ(%lx)";
TCPHDR *th = (TCPHDR *) nb->nb_tp.vp;
fprintf(stream, fmt, ds, sock, (u_int)nb->nb_ap.sz, ntohl(th->th_seq));
if (th->th_flags & TH_ACK)
fprintf(stream, "-ACK(%lx)", ntohl(th->th_ack));
if (th->th_flags & TH_FIN)
fputs("-FIN", stream);
if (th->th_flags & TH_SYN)
fputs("-SYN", stream);
if (th->th_flags & TH_RST)
fputs("-RST", stream);
if (th->th_flags & TH_PUSH)
fputs("-PSH", stream);
if (th->th_flags & TH_URG)
fputs("-URG", stream);
fputs("\r\n", stream);
}
void NutDumpSockState(FILE * stream, u_char state, char * lead, char * trail)
{
if (lead)
fputs(lead, stream);
switch (state) {
case TCPS_LISTEN:
fputs("LISTEN", stream);
break;
case TCPS_SYN_SENT:
fputs("SYNSENT", stream);
break;
case TCPS_SYN_RECEIVED:
fputs("SYNRCVD", stream);
break;
case TCPS_ESTABLISHED:
fputs("ESTABL", stream);
break;
case TCPS_FIN_WAIT_1:
fputs("FINWAIT1", stream);
break;
case TCPS_FIN_WAIT_2:
fputs("FINWAIT2", stream);
break;
case TCPS_CLOSE_WAIT:
fputs("CLOSEWAIT", stream);
break;
case TCPS_CLOSING:
fputs("CLOSING", stream);
break;
case TCPS_LAST_ACK:
fputs("LASTACK", stream);
break;
case TCPS_TIME_WAIT:
fputs("TIMEWAIT", stream);
break;
case TCPS_CLOSED:
fputs("CLOSED", stream);
break;
default:
fputs("?UNK?", stream);
break;
}
if (trail)
fputs(trail, stream);
}
void NutDumpSocketList(FILE * stream)
{
TCPSOCKET *ts;
UDPSOCKET *us;
static const char fmt1[] = "%08lX TCP %-15s:%-5u ";
static const char fmt2[] = "%08lX UDP %-5u\r\n";
fputs("Socket Typ Local Remote State\r\n", stream);
/* 12345678 123 123456789012345:12345 123456789012345:12345 */
for (ts = tcpSocketList; ts; ts = ts->so_next) {
fprintf(stream, fmt1, (uptr_t) ts, inet_ntoa(ts->so_local_addr), ntohs(ts->so_local_port));
fprintf(stream, "%-15s:%-5u ", inet_ntoa(ts->so_remote_addr), ntohs(ts->so_remote_port));
NutDumpSockState(stream, ts->so_state, 0, "\r\n");
}
for (us = udpSocketList; us; us = us->so_next) {
fprintf(stream, fmt2, (uptr_t) us, ntohs(us->so_local_port));
}
}
/*!
* \brief Control TCP tracing.
*
* \param stream Pointer to a previously opened stream or null to leave
* it unchanged.
* \param flags Flags to enable specific traces.
*/
void NutTraceTcp(FILE * stream, u_char flags)
{
if (stream)
__tcp_trs = stream;
if (__tcp_trs)
__tcp_trf = flags;
else
__tcp_trf = 0;
}
#endif
netdebug.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NETDEBUG_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NETDEBUG_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <stdio.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "socket.h"
#include "tcp.h"
#include "errno.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
#ifdef NETDEBUG_C
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN FILE *__tcp_trs; /*!< \brief TCP trace output stream. */
EXTERN u_char __tcp_trf; /*!< \brief TCP trace flags. */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
void NutTraceTcp(FILE *stream, u_char flags);
void NutDumpTcpHeader(FILE *stream, char *ds, TCPSOCKET *sock, NETBUF *nb);
void NutDumpSockState(FILE *stream, u_char state, char *lead, char *trail);
void NutDumpSocketList(FILE *stream);
#undef EXTERN
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
route.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define ROUTE_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "if_var.h"
#include "route.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
RTENTRY *rteList; /*!< Linked list of routing entries. */
/*!
* \brief Add a new entry to the IP routing table.
*
* Note, that there is currently no support for detecting duplicates.
* Anyway, newer entries will be found first, because they are inserted
* in front of older entries. However, this works only for equal masks,
* i.e. new network routes will never overwrite old host routes.
*
* \param ip Network or host IP address to be routed.
* Set 0 for default route.
* \param mask Mask for this entry. -1 for host routes,
* 0 for default or net mask for net routes.
* \param gate Route through this gateway, otherwise 0.
* \param dev Network interface to use.
*
* \return 0 on success, -1 otherwise.
*/
int NutIpRouteAdd(u_long ip, u_long mask, u_long gate, NUTDEVICE * dev)
{
int rc = -1;
RTENTRY *rte;
RTENTRY *rtp;
RTENTRY **rtpp;
/*
* Insert a new entry into the list, which is
* sorted based on the mask. Host routes are
* in front, default routes at the end and
* networks in between.
*/
rtp = rteList;
rtpp = &rteList;
while (rtp && rtp->rt_mask > mask) {
rtpp = &rtp->rt_next;
rtp = rtp->rt_next;
}
if ((rte = NutHeapAlloc(sizeof(RTENTRY))) != 0) {
rte->rt_ip = ip & mask;
rte->rt_mask = mask;
rte->rt_gateway = gate;
rte->rt_dev = dev;
rte->rt_next = rtp;
*rtpp = rte;
rc = 0;
}
return rc;
}
/*!
* \brief Delete all route table entries for the given device.
*
* \param dev Pointer to the device. If NULL, it deletes all route table entries.
*
* \return 0 on success, -1 otherwise.
*/
int NutIpRouteDelAll(NUTDEVICE * dev)
{
RTENTRY **rtpp;
RTENTRY *rte;
rtpp = &rteList;
while (*rtpp) {
rte = *rtpp;
if (rte->rt_dev == dev || dev == 0) {
*rtpp = rte->rt_next;
NutHeapFree(rte);
} else
*rtpp = (*rtpp)->rt_next;
}
return 0;
}
/*!
* \brief Delete the specified route table entry.
*
* All fields must exactly match an existing entry.
*
* \param ip Network or host IP address of the route entry.
* \param mask Mask for this entry. -1 for host routes,
* 0 for default or net mask for net routes.
* \param gate Route through this gateway, 0 for default gate.
* \param dev Network interface to use.
*
* \return 0 on success, -1 otherwise.
*/
int NutIpRouteDel(u_long ip, u_long mask, u_long gate, NUTDEVICE * dev)
{
int rc = -1;
RTENTRY **rtpp;
RTENTRY *rte;
for (rtpp = &rteList; *rtpp; *rtpp = (*rtpp)->rt_next) {
rte = *rtpp;
if (rte->rt_ip == ip && rte->rt_mask == mask && rte->rt_gateway == gate && rte->rt_dev == dev) {
*rtpp = rte->rt_next;
NutHeapFree(rte);
rc = 0;
}
}
return rc;
}
/*!
* \brief Return an array of RTENTRY structures which contain all the current route table entries.
*
* The calling function is responsible for deleting the array.
*
* \param numEntries Points to an integer, which receives the length of the array.
*
* \return Pointer to the array. Will be NULL in case of an error.
*/
RTENTRY *NutIpRouteList(int *numEntries)
{
RTENTRY *rc;
RTENTRY *rte;
/* First count the number of entries. */
*numEntries = 0;
for (rte = rteList; rte; rte = rte->rt_next) {
(*numEntries)++;
}
/* Allocate space for the result. */
rc = (RTENTRY *) NutHeapAlloc(sizeof(RTENTRY) * (*numEntries));
/* Fill in the result. */
if (rc) {
for (rte = rteList; rte; rc++, rte = rte->rt_next) {
memcpy(rc, rte, sizeof(RTENTRY));
}
}
else {
*numEntries = 0;
}
return rc;
}
/*!
* \brief Used to limit route lookup recursion for gateways.
*
* The returned pointer points directly into the linked
* list of all route entries, which is safe, as entries
* are never removed or modified.
*
* \param ip IP address in network byte order.
* \param gate Points to a buffer which optionally
* receives the IP address of a gateway.
* The pointer may be NULL, if the caller
* is not interested in this information.
* \param level Recursion level.
*/
static RTENTRY *NutIpRouteRecQuery(u_long ip, u_long * gate, u_char level)
{
RTENTRY *rte = 0;
if (level < 4) {
for (rte = rteList; rte; rte = rte->rt_next) {
if ((ip & rte->rt_mask) == rte->rt_ip)
break;
}
if (rte) {
if (gate && rte->rt_gateway)
*gate = rte->rt_gateway;
if (rte->rt_dev == 0)
rte = NutIpRouteRecQuery(rte->rt_gateway, gate, level + 1);
}
}
return rte;
}
/*!
* \brief Find a device associated with a particular IP route.
*
* Gateway routes will be automatically resolved up to
* four levels of redirection.
*
* \param ip IP address to find a route for, given in
* network byte order.
* \param gate Points to a buffer which optionally
* receives the IP address of a gateway.
* The pointer may be NULL, if the caller
* is not interested in this information.
*
* \return Pointer to the interface structure or NULL
* if no route was found.
*/
NUTDEVICE *NutIpRouteQuery(u_long ip, u_long * gate)
{
RTENTRY *rte;
if (gate)
*gate = 0;
/* Return the first interface if the IP is broadcast. This solves the
long existing problem with bad checksums on UDP broadcasts. Many
thanks to Nicolas Moreau for this patch. */
if (ip == 0xFFFFFFFF)
rte = rteList;
else
rte = NutIpRouteRecQuery(ip, gate, 0);
return rte ? rte->rt_dev : 0;
}
#endif
route.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef ROUTE_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define ROUTE_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "if_var.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Route entry type.
*/
typedef struct _RTENTRY RTENTRY;
/*!
* \struct _RTENTRY route.h net/route.h
* \brief Route entry structure.
*/
struct _RTENTRY {
RTENTRY *rt_next; //!< \brief Link to next entry.
u_long rt_ip; //!< \brief Destination ip address.
u_long rt_mask; //!< \brief IP address mask, -1 on host routes.
u_long rt_gateway; //!< \brief Gateway ip address.
NUTDEVICE *rt_dev; //!< \brief Device to use.
};
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
int NutIpRouteAdd(u_long ip, u_long mask, u_long gate, NUTDEVICE * dev);
NUTDEVICE *NutIpRouteQuery(u_long ip, u_long * gate);
int NutIpRouteDelAll(NUTDEVICE * dev);
int NutIpRouteDel(u_long ip, u_long mask, u_long gate, NUTDEVICE * dev);
RTENTRY *NutIpRouteList(int *numEntries);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif