mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-29 00:32:51 +00:00
New configuration option LWIP_IGMP to enable IGMP processing. Based on only one filter per all network interfaces. Declare a new function in netif to enable to control the MAC filter (to reduce lwIP traffic processing).
Mace Gael for the upper layers, Steve Reynolds for lower ones...
This commit is contained in:
parent
bc4b3764fc
commit
a24a170b84
@ -23,6 +23,13 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds
|
||||
* sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c,
|
||||
ip.c, netif.h, tcpip.c, opt.h:
|
||||
New configuration option LWIP_IGMP to enable IGMP processing. Based on only one
|
||||
filter per all network interfaces. Declare a new function in netif to enable to
|
||||
control the MAC filter (to reduce lwIP traffic processing).
|
||||
|
||||
2007-03-11 Frédéric Bernon
|
||||
* tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
|
||||
be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
|
||||
|
@ -682,6 +682,37 @@ netconn_close(struct netconn *conn)
|
||||
return conn->err;
|
||||
}
|
||||
|
||||
#if LWIP_IGMP
|
||||
err_t
|
||||
netconn_join_leave_group (struct netconn *conn,
|
||||
struct ip_addr *multiaddr,
|
||||
struct ip_addr *interface,
|
||||
u16_t join_or_leave)
|
||||
{
|
||||
struct api_msg msg;
|
||||
struct ip_addr *ipaddr[2];
|
||||
|
||||
if (conn == NULL) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
if (conn->err != ERR_OK) {
|
||||
return conn->err;
|
||||
}
|
||||
|
||||
msg.type = API_MSG_JOIN_LEAVE;
|
||||
msg.msg.conn = conn;
|
||||
ipaddr[0] = multiaddr;
|
||||
ipaddr[1] = interface;
|
||||
msg.msg.msg.bc.ipaddr = (struct ip_addr *)ipaddr;
|
||||
msg.msg.msg.bc.port = join_or_leave;
|
||||
api_msg_post(&msg);
|
||||
|
||||
sys_mbox_fetch(conn->mbox, NULL);
|
||||
return conn->err;
|
||||
}
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
err_t
|
||||
netconn_err(struct netconn *conn)
|
||||
{
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/igmp.h"
|
||||
|
||||
#if LWIP_RAW
|
||||
static u8_t
|
||||
@ -788,6 +789,41 @@ do_close(struct api_msg_msg *msg)
|
||||
}
|
||||
sys_mbox_post(msg->conn->mbox, NULL);
|
||||
}
|
||||
|
||||
#if LWIP_IGMP
|
||||
static void
|
||||
do_join_leave_group(struct api_msg_msg *msg)
|
||||
{
|
||||
err_t err = ERR_OK;
|
||||
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
switch (msg->conn->type) {
|
||||
#if LWIP_RAW
|
||||
case NETCONN_RAW:
|
||||
break;
|
||||
#endif
|
||||
#if LWIP_UDP
|
||||
case NETCONN_UDPLITE:
|
||||
case NETCONN_UDPNOCHKSUM:
|
||||
case NETCONN_UDP:
|
||||
switch(msg->msg.bc.port){
|
||||
case NETCONN_JOIN: err = igmp_joingroup (netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
|
||||
case NETCONN_LEAVE: err = igmp_leavegroup(netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
#if LWIP_TCP
|
||||
case NETCONN_TCP:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg->conn->err = err;
|
||||
sys_mbox_post(msg->conn->mbox, NULL);
|
||||
}
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
typedef void (* api_msg_decode)(struct api_msg_msg *msg);
|
||||
static api_msg_decode decode[API_MSG_MAX] = {
|
||||
@ -801,7 +837,10 @@ static api_msg_decode decode[API_MSG_MAX] = {
|
||||
do_send,
|
||||
do_recv,
|
||||
do_write,
|
||||
do_close
|
||||
do_close,
|
||||
#if LWIP_IGMP
|
||||
do_join_leave_group
|
||||
#endif /* LWIP_IGMP */
|
||||
};
|
||||
void
|
||||
api_msg_input(struct api_msg *msg)
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/arch.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#define NUM_SOCKETS MEMP_NUM_NETCONN
|
||||
@ -1237,6 +1237,21 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
|
||||
err = EINVAL;
|
||||
}
|
||||
break;
|
||||
#if LWIP_IGMP
|
||||
case IP_MULTICAST_TTL:
|
||||
{ if(( optlen != sizeof(char) ) && ( optlen != sizeof(int) )) //NOTE, some BSD implementation use "int", some others "char"
|
||||
{ err = EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IP_ADD_MEMBERSHIP:
|
||||
case IP_DROP_MEMBERSHIP:
|
||||
{ if( optlen < sizeof(struct ip_mreq) )
|
||||
{ err = EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* LWIP_IGMP */
|
||||
default:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
|
||||
err = ENOPROTOOPT;
|
||||
@ -1328,6 +1343,27 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
|
||||
sock->conn->pcb.tcp->tos = (u8_t)(*(int*)optval);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));
|
||||
break;
|
||||
#if LWIP_IGMP
|
||||
case IP_MULTICAST_TTL:
|
||||
{ if (optlen==sizeof(int)) sock->conn->pcb.tcp->ttl = (u8_t)(*(int*) optval);
|
||||
if (optlen==sizeof(u8_t)) sock->conn->pcb.tcp->ttl = (u8_t)(*(u8_t*)optval);
|
||||
break;
|
||||
}
|
||||
case IP_ADD_MEMBERSHIP:
|
||||
case IP_DROP_MEMBERSHIP:
|
||||
{ /* If this is a TCP or a RAW socket, ignore these options. */
|
||||
if ((sock->conn->type == NETCONN_TCP) || (sock->conn->type == NETCONN_RAW))
|
||||
{ err = EAFNOSUPPORT;
|
||||
}
|
||||
else
|
||||
{ struct ip_mreq *imr = (struct ip_mreq *)optval;
|
||||
if (netconn_join_leave_group( sock->conn, (struct ip_addr *)&(imr->imr_multiaddr.s_addr), (struct ip_addr *)&(imr->imr_interface.s_addr), ((optname==IP_ADD_MEMBERSHIP)?NETCONN_JOIN:NETCONN_LEAVE)) < 0)
|
||||
{ err = EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* LWIP_IGMP */
|
||||
} /* switch */
|
||||
break;
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "lwip/tcp.h"
|
||||
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/igmp.h"
|
||||
|
||||
static void (* tcpip_init_done)(void *arg) = NULL;
|
||||
static void *tcpip_init_done_arg;
|
||||
@ -168,6 +169,9 @@ tcpip_thread(void *arg)
|
||||
sys_timeout(DHCP_COARSE_TIMER_SECS*1000, dhcp_timer_coarse, NULL);
|
||||
sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
|
||||
#endif
|
||||
#if LWIP_IGMP
|
||||
igmp_init();
|
||||
#endif
|
||||
|
||||
if (tcpip_init_done != NULL) {
|
||||
tcpip_init_done(tcpip_init_done_arg);
|
||||
|
@ -59,6 +59,9 @@
|
||||
# include "lwip/dhcp.h"
|
||||
#endif /* LWIP_DHCP */
|
||||
|
||||
#if LWIP_IGMP
|
||||
# include "lwip/igmp.h"
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
/**
|
||||
* Initializes the IP layer.
|
||||
@ -227,28 +230,44 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
|
||||
|
||||
/* match packet against an interface, i.e. is this packet for us? */
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
|
||||
iphdr->dest.addr, netif->ip_addr.addr,
|
||||
iphdr->dest.addr & netif->netmask.addr,
|
||||
netif->ip_addr.addr & netif->netmask.addr,
|
||||
iphdr->dest.addr & ~(netif->netmask.addr)));
|
||||
|
||||
/* interface is up and configured? */
|
||||
if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
|
||||
{
|
||||
/* unicast to this interface address? */
|
||||
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
|
||||
/* or broadcast on this interface network address? */
|
||||
ip_addr_isbroadcast(&(iphdr->dest), netif)) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
/* break out of for loop */
|
||||
break;
|
||||
#if LWIP_IGMP
|
||||
if (ip_addr_ismulticast(&(iphdr->dest)))
|
||||
{ if (lookfor_group( inp, &(iphdr->dest)))
|
||||
{ netif = inp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ netif = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
|
||||
iphdr->dest.addr, netif->ip_addr.addr,
|
||||
iphdr->dest.addr & netif->netmask.addr,
|
||||
netif->ip_addr.addr & netif->netmask.addr,
|
||||
iphdr->dest.addr & ~(netif->netmask.addr)));
|
||||
|
||||
/* interface is up and configured? */
|
||||
if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
|
||||
{
|
||||
/* unicast to this interface address? */
|
||||
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
|
||||
/* or broadcast on this interface network address? */
|
||||
ip_addr_isbroadcast(&(iphdr->dest), netif)) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
/* break out of for loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LWIP_IGMP
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_DHCP
|
||||
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
|
||||
* using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
|
||||
@ -310,7 +329,13 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
}
|
||||
|
||||
#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
|
||||
|
||||
#if LWIP_IGMP
|
||||
/* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
|
||||
if((iphdrlen > IP_HLEN && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
|
||||
#else
|
||||
if (iphdrlen > IP_HLEN) {
|
||||
#endif
|
||||
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
||||
pbuf_free(p);
|
||||
IP_STATS_INC(ip.opterr);
|
||||
@ -349,6 +374,11 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
snmp_inc_ipindelivers();
|
||||
icmp_input(p, inp);
|
||||
break;
|
||||
#if LWIP_IGMP
|
||||
case IP_PROTO_IGMP:
|
||||
igmp_input(p,inp,&(iphdr->dest));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
||||
if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
|
||||
|
@ -71,6 +71,13 @@ enum netconn_evt {
|
||||
NETCONN_EVT_SENDMINUS
|
||||
};
|
||||
|
||||
#if LWIP_IGMP
|
||||
enum netconn_igmp {
|
||||
NETCONN_JOIN,
|
||||
NETCONN_LEAVE
|
||||
};
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
struct netbuf {
|
||||
struct pbuf *p, *ptr;
|
||||
struct ip_addr *fromaddr;
|
||||
@ -155,6 +162,13 @@ err_t netconn_write (struct netconn *conn,
|
||||
u8_t copy);
|
||||
err_t netconn_close (struct netconn *conn);
|
||||
|
||||
#if LWIP_IGMP
|
||||
err_t netconn_join_leave_group (struct netconn *conn,
|
||||
struct ip_addr *multiaddr,
|
||||
struct ip_addr *interface,
|
||||
u16_t join_or_leave);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
err_t netconn_err (struct netconn *conn);
|
||||
|
||||
#endif /* __LWIP_API_H__ */
|
||||
|
@ -59,7 +59,11 @@ enum api_msg_type {
|
||||
API_MSG_WRITE,
|
||||
|
||||
API_MSG_CLOSE,
|
||||
|
||||
|
||||
#if LWIP_IGMP
|
||||
API_MSG_JOIN_LEAVE,
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
API_MSG_MAX
|
||||
};
|
||||
|
||||
|
@ -126,6 +126,10 @@ struct netif {
|
||||
u32_t ifoutnucastpkts;
|
||||
u32_t ifoutdiscards;
|
||||
#endif
|
||||
#if LWIP_IGMP
|
||||
/* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
|
||||
err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
|
||||
#endif
|
||||
};
|
||||
|
||||
/** The list of network interfaces. */
|
||||
|
@ -52,6 +52,7 @@
|
||||
#ifndef NO_SYS
|
||||
#define NO_SYS 0
|
||||
#endif
|
||||
|
||||
/* ---------- Memory options ---------- */
|
||||
#ifndef MEM_LIBC_MALLOC
|
||||
#define MEM_LIBC_MALLOC 0
|
||||
@ -162,10 +163,7 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#define PBUF_LINK_HLEN 14
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* ---------- ARP options ---------- */
|
||||
|
||||
/** Number of active hardware address, IP address pairs cached */
|
||||
#ifndef ARP_TABLE_SIZE
|
||||
#define ARP_TABLE_SIZE 10
|
||||
@ -270,13 +268,11 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#endif
|
||||
|
||||
/* ---------- ICMP options ---------- */
|
||||
|
||||
#ifndef ICMP_TTL
|
||||
#define ICMP_TTL (IP_DEFAULT_TTL)
|
||||
#endif
|
||||
|
||||
/* ---------- RAW options ---------- */
|
||||
|
||||
/* ---------- RAW options ----------- */
|
||||
#ifndef LWIP_RAW
|
||||
#define LWIP_RAW 1
|
||||
#endif
|
||||
@ -286,7 +282,6 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#endif
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
|
||||
#ifndef LWIP_DHCP
|
||||
#define LWIP_DHCP 0
|
||||
#endif
|
||||
@ -317,6 +312,11 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#define SNMP_PRIVATE_MIB 0
|
||||
#endif
|
||||
|
||||
/* ---------- IGMP options ---------- */
|
||||
#ifndef LWIP_IGMP
|
||||
#define LWIP_IGMP 0
|
||||
#endif
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#ifndef LWIP_UDP
|
||||
#define LWIP_UDP 1
|
||||
@ -516,7 +516,6 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
/* ---------- PPP options ---------- */
|
||||
|
||||
#ifndef PPP_SUPPORT
|
||||
#define PPP_SUPPORT 0 /* Set for PPP */
|
||||
#endif
|
||||
@ -764,5 +763,3 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
|
||||
#endif /* __LWIP_OPT_H__ */
|
||||
|
||||
|
||||
|
||||
|
@ -123,10 +123,26 @@ struct linger {
|
||||
/*
|
||||
* Options for level IPPROTO_IP
|
||||
*/
|
||||
#define IP_TOS 1
|
||||
#define IP_TTL 2
|
||||
#define IP_TOS 1
|
||||
#define IP_TTL 2
|
||||
|
||||
|
||||
#ifdef LWIP_IGMP
|
||||
/*
|
||||
* Options and types for UDP multicast traffic handling
|
||||
*/
|
||||
#define IP_ADD_MEMBERSHIP 3
|
||||
#define IP_DROP_MEMBERSHIP 4
|
||||
#define IP_MULTICAST_TTL 5
|
||||
#define IP_MULTICAST_IF 6
|
||||
#define IP_MULTICAST_LOOP 7
|
||||
|
||||
typedef struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
} ip_mreq;
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#define IPTOS_TOS_MASK 0x1E
|
||||
#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
|
||||
#define IPTOS_LOWDELAY 0x10
|
||||
|
Loading…
x
Reference in New Issue
Block a user