mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-09-13 10:15:43 +00:00
bug #52937: raw_input() must tell ip4/6_input() if protocol has been received
This also moves "raw_input" and "raw_netif_ip_addr_changed" to a new file raw_priv.h
This commit is contained in:
parent
ebda5cb04e
commit
fe2c249fb7
@ -50,7 +50,7 @@
|
|||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/icmp.h"
|
#include "lwip/icmp.h"
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
#include "lwip/raw.h"
|
#include "lwip/priv/raw_priv.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
#include "lwip/priv/tcp_priv.h"
|
#include "lwip/priv/tcp_priv.h"
|
||||||
#include "lwip/autoip.h"
|
#include "lwip/autoip.h"
|
||||||
@ -423,6 +423,9 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
|||||||
#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
|
#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
|
||||||
int check_ip_src = 1;
|
int check_ip_src = 1;
|
||||||
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
|
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
|
||||||
|
#if LWIP_RAW
|
||||||
|
raw_input_state_t raw_status;
|
||||||
|
#endif /* LWIP_RAW */
|
||||||
|
|
||||||
LWIP_ASSERT_CORE_LOCKED();
|
LWIP_ASSERT_CORE_LOCKED();
|
||||||
|
|
||||||
@ -675,7 +678,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
/* raw input did not eat the packet? */
|
/* raw input did not eat the packet? */
|
||||||
if (raw_input(p, inp) == 0)
|
raw_status = raw_input(p, inp);
|
||||||
|
if (raw_status != RAW_INPUT_EATEN)
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
{
|
{
|
||||||
pbuf_remove_header(p, iphdr_hlen); /* Move to payload, no check necessary. */
|
pbuf_remove_header(p, iphdr_hlen); /* Move to payload, no check necessary. */
|
||||||
@ -708,21 +712,29 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
|||||||
break;
|
break;
|
||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
default:
|
default:
|
||||||
|
#if LWIP_RAW
|
||||||
|
if (raw_status == RAW_INPUT_DELIVERED) {
|
||||||
|
MIB2_STATS_INC(mib2.ipindelivers);
|
||||||
|
} else
|
||||||
|
#endif /* LWIP_RAW */
|
||||||
|
{
|
||||||
#if LWIP_ICMP
|
#if LWIP_ICMP
|
||||||
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
||||||
if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
|
if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
|
||||||
!ip4_addr_ismulticast(ip4_current_dest_addr())) {
|
!ip4_addr_ismulticast(ip4_current_dest_addr())) {
|
||||||
pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
|
pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
|
||||||
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_ICMP */
|
#endif /* LWIP_ICMP */
|
||||||
|
|
||||||
|
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
|
||||||
|
|
||||||
|
IP_STATS_INC(ip.proterr);
|
||||||
|
IP_STATS_INC(ip.drop);
|
||||||
|
MIB2_STATS_INC(mib2.ipinunknownprotos);
|
||||||
|
}
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
break;
|
||||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
|
|
||||||
|
|
||||||
IP_STATS_INC(ip.proterr);
|
|
||||||
IP_STATS_INC(ip.drop);
|
|
||||||
MIB2_STATS_INC(mib2.ipinunknownprotos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
#include "lwip/ip6_addr.h"
|
#include "lwip/ip6_addr.h"
|
||||||
#include "lwip/ip6_frag.h"
|
#include "lwip/ip6_frag.h"
|
||||||
#include "lwip/icmp6.h"
|
#include "lwip/icmp6.h"
|
||||||
#include "lwip/raw.h"
|
#include "lwip/priv/raw_priv.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
#include "lwip/priv/tcp_priv.h"
|
#include "lwip/priv/tcp_priv.h"
|
||||||
#include "lwip/dhcp6.h"
|
#include "lwip/dhcp6.h"
|
||||||
@ -516,6 +516,9 @@ ip6_input(struct pbuf *p, struct netif *inp)
|
|||||||
@todo
|
@todo
|
||||||
int check_ip_src=1;
|
int check_ip_src=1;
|
||||||
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
|
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
|
||||||
|
#if LWIP_RAW
|
||||||
|
raw_input_state_t raw_status;
|
||||||
|
#endif /* LWIP_RAW */
|
||||||
|
|
||||||
LWIP_ASSERT_CORE_LOCKED();
|
LWIP_ASSERT_CORE_LOCKED();
|
||||||
|
|
||||||
@ -1055,7 +1058,8 @@ options_done:
|
|||||||
/* p points to IPv6 header again for raw_input. */
|
/* p points to IPv6 header again for raw_input. */
|
||||||
pbuf_header_force(p, (s16_t)hlen_tot);
|
pbuf_header_force(p, (s16_t)hlen_tot);
|
||||||
/* raw input did not eat the packet? */
|
/* raw input did not eat the packet? */
|
||||||
if (raw_input(p, inp) == 0)
|
raw_status = raw_input(p, inp);
|
||||||
|
if (raw_status != RAW_INPUT_EATEN)
|
||||||
{
|
{
|
||||||
/* Point to payload. */
|
/* Point to payload. */
|
||||||
pbuf_remove_header(p, hlen_tot);
|
pbuf_remove_header(p, hlen_tot);
|
||||||
@ -1085,19 +1089,26 @@ options_done:
|
|||||||
break;
|
break;
|
||||||
#endif /* LWIP_ICMP */
|
#endif /* LWIP_ICMP */
|
||||||
default:
|
default:
|
||||||
|
#if LWIP_RAW
|
||||||
|
if (raw_status == RAW_INPUT_DELIVERED) {
|
||||||
|
/* @todo: ipv6 mib in-delivers? */
|
||||||
|
} else
|
||||||
|
#endif /* LWIP_RAW */
|
||||||
|
{
|
||||||
#if LWIP_ICMP6
|
#if LWIP_ICMP6
|
||||||
/* p points to IPv6 header again for raw_input. */
|
/* p points to IPv6 header again for raw_input. */
|
||||||
pbuf_header_force(p, (s16_t)hlen_tot);
|
pbuf_header_force(p, (s16_t)hlen_tot);
|
||||||
/* send ICMP parameter problem unless it was a multicast or ICMPv6 */
|
/* send ICMP parameter problem unless it was a multicast or ICMPv6 */
|
||||||
if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
|
if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
|
||||||
(IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
|
(IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
|
||||||
icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
|
icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_ICMP */
|
#endif /* LWIP_ICMP */
|
||||||
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
|
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
|
||||||
|
IP6_STATS_INC(ip6.proterr);
|
||||||
|
IP6_STATS_INC(ip6.drop);
|
||||||
|
}
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
IP6_STATS_INC(ip6.proterr);
|
|
||||||
IP6_STATS_INC(ip6.drop);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/priv/tcp_priv.h"
|
#include "lwip/priv/tcp_priv.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
#include "lwip/raw.h"
|
#include "lwip/priv/raw_priv.h"
|
||||||
#include "lwip/snmp.h"
|
#include "lwip/snmp.h"
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
#include "lwip/etharp.h"
|
#include "lwip/etharp.h"
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/raw.h"
|
#include "lwip/raw.h"
|
||||||
|
#include "lwip/priv/raw_priv.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
#include "lwip/ip6.h"
|
#include "lwip/ip6.h"
|
||||||
#include "lwip/ip6_addr.h"
|
#include "lwip/ip6_addr.h"
|
||||||
@ -130,12 +131,12 @@ raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast)
|
|||||||
* caller).
|
* caller).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
u8_t
|
raw_input_state_t
|
||||||
raw_input(struct pbuf *p, struct netif *inp)
|
raw_input(struct pbuf *p, struct netif *inp)
|
||||||
{
|
{
|
||||||
struct raw_pcb *pcb, *prev;
|
struct raw_pcb *pcb, *prev;
|
||||||
s16_t proto;
|
s16_t proto;
|
||||||
u8_t eaten = 0;
|
raw_input_state_t ret = RAW_INPUT_NONE;
|
||||||
u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
|
u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(inp);
|
LWIP_UNUSED_ARG(inp);
|
||||||
@ -162,21 +163,22 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||||||
pcb = raw_pcbs;
|
pcb = raw_pcbs;
|
||||||
/* loop through all raw pcbs until the packet is eaten by one */
|
/* loop through all raw pcbs until the packet is eaten by one */
|
||||||
/* this allows multiple pcbs to match against the packet by design */
|
/* this allows multiple pcbs to match against the packet by design */
|
||||||
while ((eaten == 0) && (pcb != NULL)) {
|
while (pcb != NULL) {
|
||||||
if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
|
if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
|
||||||
(((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
|
(((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
|
||||||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
|
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
|
||||||
/* receive callback function available? */
|
/* receive callback function available? */
|
||||||
if (pcb->recv != NULL) {
|
if (pcb->recv != NULL) {
|
||||||
|
u8_t eaten;
|
||||||
#ifndef LWIP_NOASSERT
|
#ifndef LWIP_NOASSERT
|
||||||
void *old_payload = p->payload;
|
void *old_payload = p->payload;
|
||||||
#endif
|
#endif
|
||||||
|
ret = RAW_INPUT_DELIVERED;
|
||||||
/* the receive callback function did not eat the packet? */
|
/* the receive callback function did not eat the packet? */
|
||||||
eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
|
eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
|
||||||
if (eaten != 0) {
|
if (eaten != 0) {
|
||||||
/* receive function ate the packet */
|
/* receive function ate the packet */
|
||||||
p = NULL;
|
p = NULL;
|
||||||
eaten = 1;
|
|
||||||
if (prev != NULL) {
|
if (prev != NULL) {
|
||||||
/* move the pcb to the front of raw_pcbs so that is
|
/* move the pcb to the front of raw_pcbs so that is
|
||||||
found faster next time */
|
found faster next time */
|
||||||
@ -184,6 +186,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||||||
pcb->next = raw_pcbs;
|
pcb->next = raw_pcbs;
|
||||||
raw_pcbs = pcb;
|
raw_pcbs = pcb;
|
||||||
}
|
}
|
||||||
|
return RAW_INPUT_EATEN;
|
||||||
} else {
|
} else {
|
||||||
/* sanity-check that the receive callback did not alter the pbuf */
|
/* sanity-check that the receive callback did not alter the pbuf */
|
||||||
LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet",
|
LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet",
|
||||||
@ -196,7 +199,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||||||
prev = pcb;
|
prev = pcb;
|
||||||
pcb = pcb->next;
|
pcb = pcb->next;
|
||||||
}
|
}
|
||||||
return eaten;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
69
src/include/lwip/priv/raw_priv.h
Normal file
69
src/include/lwip/priv/raw_priv.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* raw API internal implementations (do not use in application code)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_RAW_PRIV_H
|
||||||
|
#define LWIP_HDR_RAW_PRIV_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/raw.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** return codes for raw_input */
|
||||||
|
typedef enum raw_input_state
|
||||||
|
{
|
||||||
|
RAW_INPUT_NONE = 0, /* pbuf did not match any pcbs */
|
||||||
|
RAW_INPUT_EATEN, /* pbuf handed off and delivered to pcb */
|
||||||
|
RAW_INPUT_DELIVERED /* pbuf only delivered to pcb (pbuf can still be referenced) */
|
||||||
|
} raw_input_state_t;
|
||||||
|
|
||||||
|
/* The following functions are the lower layer interface to RAW. */
|
||||||
|
raw_input_state_t raw_input(struct pbuf *p, struct netif *inp);
|
||||||
|
|
||||||
|
void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_RAW */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_RAW_PRIV_H */
|
@ -122,12 +122,8 @@ void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *re
|
|||||||
#define raw_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & ~(clr_flags)); } while(0)
|
#define raw_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & ~(clr_flags)); } while(0)
|
||||||
#define raw_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0)
|
#define raw_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0)
|
||||||
|
|
||||||
/* The following functions are the lower layer interface to RAW. */
|
|
||||||
u8_t raw_input (struct pbuf *p, struct netif *inp);
|
|
||||||
#define raw_init() /* Compatibility define, no init needed. */
|
#define raw_init() /* Compatibility define, no init needed. */
|
||||||
|
|
||||||
void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
|
|
||||||
|
|
||||||
/* for compatibility with older implementation */
|
/* for compatibility with older implementation */
|
||||||
#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
|
#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user