Browse Source

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...
STABLE-2_1_x
fbernon 19 years ago
parent
commit
a24a170b84
  1. 7
      CHANGELOG
  2. 31
      src/api/api_lib.c
  3. 41
      src/api/api_msg.c
  4. 38
      src/api/sockets.c
  5. 4
      src/api/tcpip.c
  6. 72
      src/core/ipv4/ip.c
  7. 14
      src/include/lwip/api.h
  8. 6
      src/include/lwip/api_msg.h
  9. 4
      src/include/lwip/netif.h
  10. 17
      src/include/lwip/opt.h
  11. 20
      src/include/lwip/sockets.h

7
CHANGELOG

@ -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

31
src/api/api_lib.c

@ -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)
{

41
src/api/api_msg.c

@ -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)

38
src/api/sockets.c

@ -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;

4
src/api/tcpip.c

@ -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);

72
src/core/ipv4/ip.c

@ -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) &&

14
src/include/lwip/api.h

@ -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__ */

6
src/include/lwip/api_msg.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
};

4
src/include/lwip/netif.h

@ -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. */

17
src/include/lwip/opt.h

@ -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__ */

20
src/include/lwip/sockets.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…
Cancel
Save