mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-20 19:21:05 +00:00
bug #33634 ip_forward() have a faulty behaviour: Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. Also added code to allow ip_forward() to forward non-broadcast packets to the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1).
This commit is contained in:
parent
1ebd914cdc
commit
3306641708
@ -6,6 +6,12 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2011-07-21: Simon Goldschmidt (patch by hanhui)
|
||||||
|
* ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour:
|
||||||
|
Added pbuf flags to mark incoming packets as link-layer broadcast/multicast.
|
||||||
|
Also added code to allow ip_forward() to forward non-broadcast packets to
|
||||||
|
the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1).
|
||||||
|
|
||||||
2011-09-27: Simon Goldschmidt
|
2011-09-27: Simon Goldschmidt
|
||||||
* opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
|
* opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
|
||||||
(define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)
|
(define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)
|
||||||
|
@ -125,6 +125,13 @@ ip_route(ip_addr_t *dest)
|
|||||||
{
|
{
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
|
||||||
|
#ifdef LWIP_HOOK_IP4_ROUTE
|
||||||
|
netif = LWIP_HOOK_IP4_ROUTE(dest);
|
||||||
|
if (netif != NULL) {
|
||||||
|
return netif;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* iterate through netifs */
|
/* iterate through netifs */
|
||||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
/* network mask matches? */
|
/* network mask matches? */
|
||||||
@ -147,6 +154,41 @@ ip_route(ip_addr_t *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if IP_FORWARD
|
#if IP_FORWARD
|
||||||
|
/**
|
||||||
|
* Determine whether an IP address is in a reserved set of addresses
|
||||||
|
* that may not be forwarded, or whether datagrams to that destination
|
||||||
|
* may be forwarded.
|
||||||
|
* @param p the packet to forward
|
||||||
|
* @param dest the destination IP address
|
||||||
|
* @return 1: can forward 0: discard
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ip_canforward(struct pbuf *p)
|
||||||
|
{
|
||||||
|
u32_t addr = ip4_addr_get_u32(ip_current_dest_addr());
|
||||||
|
|
||||||
|
if (p->flags & PBUF_FLAG_LLBCAST) {
|
||||||
|
/* don't route link-layer broadcasts */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
|
||||||
|
/* don't route link-layer multicasts unless the destination address is an IP
|
||||||
|
multicast address */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (IP_EXPERIMENTAL(addr)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (IP_CLASSA(addr)) {
|
||||||
|
u32_t net = addr & IP_CLASSA_NET;
|
||||||
|
if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
|
||||||
|
/* don't route loopback packets */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards an IP packet. It finds an appropriate route for the
|
* Forwards an IP packet. It finds an appropriate route for the
|
||||||
* packet, decrements the TTL value of the packet, adjusts the
|
* packet, decrements the TTL value of the packet, adjusts the
|
||||||
@ -163,6 +205,10 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
|
|
||||||
PERF_START;
|
PERF_START;
|
||||||
|
|
||||||
|
if (!ip_canforward(p)) {
|
||||||
|
goto return_noroute;
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC3927 2.7: do not forward link-local addresses */
|
/* RFC3927 2.7: do not forward link-local addresses */
|
||||||
if (ip_addr_islinklocal(¤t_iphdr_dest)) {
|
if (ip_addr_islinklocal(¤t_iphdr_dest)) {
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||||
@ -179,12 +225,14 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
|
||||||
goto return_noroute;
|
goto return_noroute;
|
||||||
}
|
}
|
||||||
|
#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
|
||||||
/* Do not forward packets onto the same network interface on which
|
/* Do not forward packets onto the same network interface on which
|
||||||
* they arrived. */
|
* they arrived. */
|
||||||
if (netif == inp) {
|
if (netif == inp) {
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
|
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
|
||||||
goto return_noroute;
|
goto return_noroute;
|
||||||
}
|
}
|
||||||
|
#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
|
||||||
|
|
||||||
/* decrement TTL */
|
/* decrement TTL */
|
||||||
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
|
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
|
||||||
@ -264,6 +312,13 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LWIP_HOOK_IP4_INPUT
|
||||||
|
if (LWIP_HOOK_IP4_INPUT(p, inp)) {
|
||||||
|
/* the packet has been eaten */
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* obtain IP header length in number of 32-bit words */
|
/* obtain IP header length in number of 32-bit words */
|
||||||
iphdr_hlen = IPH_HL(iphdr);
|
iphdr_hlen = IPH_HL(iphdr);
|
||||||
/* calculate IP header length in bytes */
|
/* calculate IP header length in bytes */
|
||||||
|
@ -595,6 +595,17 @@
|
|||||||
#define IP_SOF_BROADCAST_RECV 0
|
#define IP_SOF_BROADCAST_RECV 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back
|
||||||
|
* out on the netif where it was received. This should only be used for
|
||||||
|
* wireless networks.
|
||||||
|
* ATTENTION: When this is 1, make sure your netif driver correctly marks incoming
|
||||||
|
* link-layer-broadcast/multicast packets as such using the corresponding pbuf flags!
|
||||||
|
*/
|
||||||
|
#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF
|
||||||
|
#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first
|
* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first
|
||||||
* local TCP/UDP pcb (default==0). This can prevent creating predictable port
|
* local TCP/UDP pcb (default==0). This can prevent creating predictable port
|
||||||
@ -1821,6 +1832,34 @@
|
|||||||
#define LWIP_CHECKSUM_ON_COPY 0
|
#define LWIP_CHECKSUM_ON_COPY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
---------------------------------------
|
||||||
|
---------- Hook options ---------------
|
||||||
|
---------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Hooks are undefined by default, define them to a function if you need them. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_HOOK_IP4_INPUT(pbuf, input_netif):
|
||||||
|
* - called from ip_input() (IPv4)
|
||||||
|
* - pbuf: received struct pbuf passed to ip_input()
|
||||||
|
* - input_netif: struct netif on which the packet has been received
|
||||||
|
* Return values:
|
||||||
|
* - 0: Hook has not consumed the packet, packet is processed as normal
|
||||||
|
* - != 0: Hook has consumed the packet.
|
||||||
|
* If the hook consumed the packet, 'pbuf' is in the responsibility of the hook
|
||||||
|
* (i.e. free it when done).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_HOOK_IP4_ROUTE(dest):
|
||||||
|
* - called from ip_route() (IPv4)
|
||||||
|
* - dest: destination IPv4 address
|
||||||
|
* Returns the destination netif or NULL if no destination netif is found. In
|
||||||
|
* that case, ip_route() continues as normal.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
---------- Debugging options ----------
|
---------- Debugging options ----------
|
||||||
|
@ -69,6 +69,10 @@ typedef enum {
|
|||||||
#define PBUF_FLAG_IS_CUSTOM 0x02U
|
#define PBUF_FLAG_IS_CUSTOM 0x02U
|
||||||
/** indicates this pbuf is UDP multicast to be looped back */
|
/** indicates this pbuf is UDP multicast to be looped back */
|
||||||
#define PBUF_FLAG_MCASTLOOP 0x04U
|
#define PBUF_FLAG_MCASTLOOP 0x04U
|
||||||
|
/** indicates this pbuf was received as link-level broadcast */
|
||||||
|
#define PBUF_FLAG_LLBCAST 0x08U
|
||||||
|
/** indicates this pbuf was received as link-level multicast */
|
||||||
|
#define PBUF_FLAG_LLMCAST 0x10U
|
||||||
/** indicates this pbuf includes a TCP FIN flag */
|
/** indicates this pbuf includes a TCP FIN flag */
|
||||||
#define PBUF_FLAG_TCP_FIN 0x20U
|
#define PBUF_FLAG_TCP_FIN 0x20U
|
||||||
|
|
||||||
|
@ -65,6 +65,11 @@
|
|||||||
const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||||
const struct eth_addr ethzero = {{0,0,0,0,0,0}};
|
const struct eth_addr ethzero = {{0,0,0,0,0,0}};
|
||||||
|
|
||||||
|
/** The 24-bit IANA multicast OUI is 01-00-5e: */
|
||||||
|
#define LL_MULTICAST_ADDR_0 0x01
|
||||||
|
#define LL_MULTICAST_ADDR_1 0x00
|
||||||
|
#define LL_MULTICAST_ADDR_2 0x5e
|
||||||
|
|
||||||
#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
|
#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
/** the time an ARP entry stays valid after its last update,
|
/** the time an ARP entry stays valid after its last update,
|
||||||
@ -942,9 +947,9 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
|
|||||||
/* multicast destination IP address? */
|
/* multicast destination IP address? */
|
||||||
} else if (ip_addr_ismulticast(ipaddr)) {
|
} else if (ip_addr_ismulticast(ipaddr)) {
|
||||||
/* Hash IP multicast address to MAC address.*/
|
/* Hash IP multicast address to MAC address.*/
|
||||||
mcastaddr.addr[0] = 0x01;
|
mcastaddr.addr[0] = LL_MULTICAST_ADDR_0;
|
||||||
mcastaddr.addr[1] = 0x00;
|
mcastaddr.addr[1] = LL_MULTICAST_ADDR_1;
|
||||||
mcastaddr.addr[2] = 0x5e;
|
mcastaddr.addr[2] = LL_MULTICAST_ADDR_2;
|
||||||
mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
|
mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
|
||||||
mcastaddr.addr[4] = ip4_addr3(ipaddr);
|
mcastaddr.addr[4] = ip4_addr3(ipaddr);
|
||||||
mcastaddr.addr[5] = ip4_addr4(ipaddr);
|
mcastaddr.addr[5] = ip4_addr4(ipaddr);
|
||||||
@ -1322,6 +1327,20 @@ ethernet_input(struct pbuf *p, struct netif *netif)
|
|||||||
netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
|
netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type));
|
||||||
#endif /* LWIP_ARP_FILTER_NETIF*/
|
#endif /* LWIP_ARP_FILTER_NETIF*/
|
||||||
|
|
||||||
|
if (ethhdr->dest.addr[0] & 1) {
|
||||||
|
/* this might be a multicast or broadcast packet */
|
||||||
|
if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) {
|
||||||
|
if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) &&
|
||||||
|
(ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) {
|
||||||
|
/* mark the pbuf as link-layer multicast */
|
||||||
|
p->flags |= PBUF_FLAG_LLMCAST;
|
||||||
|
}
|
||||||
|
} else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) {
|
||||||
|
/* mark the pbuf as link-layer broadcast */
|
||||||
|
p->flags |= PBUF_FLAG_LLBCAST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#if LWIP_ARP
|
#if LWIP_ARP
|
||||||
/* IP packet? */
|
/* IP packet? */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user