mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-30 12:32:37 +00:00
Added UDP lite support for sockets
This commit is contained in:
parent
2f293d53ba
commit
046a270156
@ -19,6 +19,9 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2007-06-11 Simon Goldschmidt
|
||||
* sockets.c, sockets.h: Added UDP lite support for sockets
|
||||
|
||||
2007-06-10 Simon Goldschmidt
|
||||
* udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled
|
||||
by default) to switch off UDP-Lite support if not needed (reduces udp.c code
|
||||
|
@ -610,7 +610,8 @@ lwip_socket(int domain, int type, int protocol)
|
||||
domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
conn = netconn_new_with_callback(NETCONN_UDP, event_callback);
|
||||
conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ?
|
||||
NETCONN_UDPLITE : NETCONN_UDP, event_callback);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
|
||||
domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
|
||||
break;
|
||||
@ -1057,6 +1058,7 @@ int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optl
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
|
||||
#if LWIP_TCP
|
||||
/* Level: IPPROTO_TCP */
|
||||
case IPPROTO_TCP:
|
||||
if (*optlen < sizeof(int)) {
|
||||
@ -1082,9 +1084,33 @@ int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optl
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
|
||||
s, optname));
|
||||
err = ENOPROTOOPT;
|
||||
} /* switch (optname */
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
/* Level: IPPROTO_UDPLITE */
|
||||
case IPPROTO_UDPLITE:
|
||||
if (*optlen < sizeof(int)) {
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If this is no UDP lite socket, ignore any options. */
|
||||
if (sock->conn->type != NETCONN_UDPLITE)
|
||||
return 0;
|
||||
|
||||
switch (optname) {
|
||||
case UDPLITE_SEND_CSCOV:
|
||||
case UDPLITE_RECV_CSCOV:
|
||||
break;
|
||||
|
||||
default:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
|
||||
s, optname));
|
||||
err = ENOPROTOOPT;
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_UDP && LWIP_UDPLITE*/
|
||||
/* UNDEFINED LEVEL */
|
||||
default:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
|
||||
@ -1208,6 +1234,7 @@ static void lwip_getsockopt_internal(void *arg)
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
|
||||
#if LWIP_TCP
|
||||
/* Level: IPPROTO_TCP */
|
||||
case IPPROTO_TCP:
|
||||
switch (optname) {
|
||||
@ -1242,6 +1269,24 @@ static void lwip_getsockopt_internal(void *arg)
|
||||
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
/* Level: IPPROTO_UDPLITE */
|
||||
case IPPROTO_UDPLITE:
|
||||
switch (optname) {
|
||||
case UDPLITE_SEND_CSCOV:
|
||||
*(int*)optval = sock->conn->pcb.udp->chksum_len_tx;
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n",
|
||||
s, (*(int*)optval)) );
|
||||
break;
|
||||
case UDPLITE_RECV_CSCOV:
|
||||
*(int*)optval = sock->conn->pcb.udp->chksum_len_rx;
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n",
|
||||
s, (*(int*)optval)) );
|
||||
break;
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
} /* switch (level) */
|
||||
sys_mbox_post(sock->conn->mbox, NULL);
|
||||
}
|
||||
@ -1332,6 +1377,7 @@ int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
|
||||
#if LWIP_TCP
|
||||
/* Level: IPPROTO_TCP */
|
||||
case IPPROTO_TCP:
|
||||
if (optlen < sizeof(int)) {
|
||||
@ -1359,7 +1405,31 @@ int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t
|
||||
err = ENOPROTOOPT;
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
/* Level: IPPROTO_UDPLITE */
|
||||
case IPPROTO_UDPLITE:
|
||||
if (optlen < sizeof(int)) {
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If this is no UDP lite socket, ignore any options. */
|
||||
if (sock->conn->type != NETCONN_UDPLITE)
|
||||
return 0;
|
||||
|
||||
switch (optname) {
|
||||
case UDPLITE_SEND_CSCOV:
|
||||
case UDPLITE_RECV_CSCOV:
|
||||
break;
|
||||
|
||||
default:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
|
||||
s, optname));
|
||||
err = ENOPROTOOPT;
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_UDP && LWIP_UDPLITE */
|
||||
/* UNDEFINED LEVEL */
|
||||
default:
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
|
||||
@ -1481,6 +1551,7 @@ static void lwip_setsockopt_internal(void *arg)
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
|
||||
#if LWIP_TCP
|
||||
/* Level: IPPROTO_TCP */
|
||||
case IPPROTO_TCP:
|
||||
switch (optname) {
|
||||
@ -1519,6 +1590,34 @@ static void lwip_setsockopt_internal(void *arg)
|
||||
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_TCP*/
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
/* Level: IPPROTO_UDPLITE */
|
||||
case IPPROTO_UDPLITE:
|
||||
switch (optname) {
|
||||
case UDPLITE_SEND_CSCOV:
|
||||
if ((*(int*)optval != 0) && (*(int*)optval < 8)) {
|
||||
/* don't allow illegal values! */
|
||||
sock->conn->pcb.udp->chksum_len_tx = 8;
|
||||
} else {
|
||||
sock->conn->pcb.udp->chksum_len_tx = *(int*)optval;
|
||||
}
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %lu\n",
|
||||
s, (*(int*)optval)) );
|
||||
break;
|
||||
case UDPLITE_RECV_CSCOV:
|
||||
if ((*(int*)optval != 0) && (*(int*)optval < 8)) {
|
||||
/* don't allow illegal values! */
|
||||
sock->conn->pcb.udp->chksum_len_rx = 8;
|
||||
} else {
|
||||
sock->conn->pcb.udp->chksum_len_rx = *(int*)optval;
|
||||
}
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %lu\n",
|
||||
s, (*(int*)optval)) );
|
||||
break;
|
||||
} /* switch (optname) */
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
} /* switch (level) */
|
||||
sys_mbox_post(sock->conn->mbox, NULL);
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
u16_t chklen;
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
|
||||
/* set UDP message length in UDP header */
|
||||
chklen = pcb->chksum_len;
|
||||
chklen = pcb->chksum_len_tx;
|
||||
if (chklen < sizeof(struct udp_hdr)) {
|
||||
if (chklen != 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
|
||||
@ -431,7 +431,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* calculate checksum */
|
||||
#if CHECKSUM_GEN_UDP
|
||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
||||
IP_PROTO_UDP, pcb->chksum_len);
|
||||
IP_PROTO_UDP, chklen);
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000)
|
||||
udphdr->chksum = 0xffff;
|
||||
|
@ -118,6 +118,7 @@ struct linger {
|
||||
#define IPPROTO_IP 0
|
||||
#define IPPROTO_TCP 6
|
||||
#define IPPROTO_UDP 17
|
||||
#define IPPROTO_UDPLITE 136
|
||||
|
||||
#define INADDR_ANY 0
|
||||
#define INADDR_BROADCAST 0xffffffff
|
||||
@ -143,6 +144,15 @@ struct linger {
|
||||
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#if LWIP_UDP && LWIP_UDPLITE
|
||||
/*
|
||||
* Options for level IPPROTO_UDPLITE
|
||||
*/
|
||||
#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
|
||||
#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
|
||||
#endif
|
||||
|
||||
|
||||
#if LWIP_IGMP
|
||||
/*
|
||||
* Options and types for UDP multicast traffic handling
|
||||
|
@ -70,7 +70,7 @@ struct udp_pcb {
|
||||
|
||||
#if LWIP_UDPLITE
|
||||
/* used for UDP_LITE only */
|
||||
u16_t chksum_len;
|
||||
u16_t chksum_len_rx, chksum_len_tx;
|
||||
#endif /* LWIP_UDPLITE */
|
||||
|
||||
/* addr and port are in same byte order as in the pcb */
|
||||
|
Loading…
x
Reference in New Issue
Block a user