mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-17 13:46:56 +08: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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user