mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-02 12:52:10 +00:00
UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, create checksum over the complete packet. On RX, if it's < 8 (and not 0), discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both UDP & UDP Lite.
This commit is contained in:
parent
1d7caed340
commit
2f293d53ba
@ -196,6 +196,12 @@ HISTORY
|
|||||||
|
|
||||||
++ Bug fixes:
|
++ Bug fixes:
|
||||||
|
|
||||||
|
2007-06-11 Simon Goldschmidt
|
||||||
|
* udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0,
|
||||||
|
create checksum over the complete packet. On RX, if it's < 8 (and not 0),
|
||||||
|
discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both
|
||||||
|
UDP & UDP Lite.
|
||||||
|
|
||||||
2007-06-11 Srinivas Gollakota & Oleg Tyshev
|
2007-06-11 Srinivas Gollakota & Oleg Tyshev
|
||||||
* tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
|
* tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
|
||||||
where TCP flags wasn't initialized in tcp_keepalive.
|
where TCP flags wasn't initialized in tcp_keepalive.
|
||||||
|
@ -182,9 +182,25 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
||||||
/* Do the UDP Lite checksum */
|
/* Do the UDP Lite checksum */
|
||||||
#if CHECKSUM_CHECK_UDP
|
#if CHECKSUM_CHECK_UDP
|
||||||
|
u16_t chklen = ntohs(udphdr->len);
|
||||||
|
if (chklen < sizeof(struct udp_hdr)) {
|
||||||
|
if (chklen == 0) {
|
||||||
|
/* For UDP-Lite, checksum length of 0 means checksum
|
||||||
|
over the complete packet (See RFC 3828 chap. 3.1) */
|
||||||
|
chklen = p->tot_len;
|
||||||
|
} else {
|
||||||
|
/* At least the UDP-Lite header must be covered by the
|
||||||
|
checksum! (Again, see RFC 3828 chap. 3.1) */
|
||||||
|
UDP_STATS_INC(udp.chkerr);
|
||||||
|
UDP_STATS_INC(udp.drop);
|
||||||
|
snmp_inc_udpinerrors();
|
||||||
|
pbuf_free(p);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
(struct ip_addr *)&(iphdr->dest),
|
||||||
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
|
IP_PROTO_UDPLITE, chklen) != 0) {
|
||||||
LWIP_DEBUGF(UDP_DEBUG | 2,
|
LWIP_DEBUGF(UDP_DEBUG | 2,
|
||||||
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
||||||
UDP_STATS_INC(udp.chkerr);
|
UDP_STATS_INC(udp.chkerr);
|
||||||
@ -395,9 +411,23 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
#if LWIP_UDPLITE
|
#if LWIP_UDPLITE
|
||||||
/* UDP Lite protocol? */
|
/* UDP Lite protocol? */
|
||||||
if (pcb->flags & UDP_FLAGS_UDPLITE) {
|
if (pcb->flags & UDP_FLAGS_UDPLITE) {
|
||||||
|
u16_t chklen;
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
|
||||||
/* set UDP message length in UDP header */
|
/* set UDP message length in UDP header */
|
||||||
udphdr->len = htons(pcb->chksum_len);
|
chklen = pcb->chksum_len;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
/* For UDP-Lite, checksum length of 0 means checksum
|
||||||
|
over the complete packet. (See RFC 3828 chap. 3.1)
|
||||||
|
At least the UDP-Lite header must be covered by the
|
||||||
|
checksum, therefore, if chksum_len has an illegal
|
||||||
|
value, we generate the checksum over the complete
|
||||||
|
packet to be safe. */
|
||||||
|
chklen = p->tot_len;
|
||||||
|
}
|
||||||
|
udphdr->len = htons(chklen);
|
||||||
/* calculate checksum */
|
/* calculate checksum */
|
||||||
#if CHECKSUM_GEN_UDP
|
#if CHECKSUM_GEN_UDP
|
||||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
||||||
@ -405,8 +435,6 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||||
if (udphdr->chksum == 0x0000)
|
if (udphdr->chksum == 0x0000)
|
||||||
udphdr->chksum = 0xffff;
|
udphdr->chksum = 0xffff;
|
||||||
#else /* CHECKSUM_CHECK_UDP */
|
|
||||||
udphdr->chksum = 0x0000;
|
|
||||||
#endif /* CHECKSUM_CHECK_UDP */
|
#endif /* CHECKSUM_CHECK_UDP */
|
||||||
/* output to IP */
|
/* output to IP */
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
|
||||||
@ -423,8 +451,6 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||||
}
|
}
|
||||||
#else /* CHECKSUM_CHECK_UDP */
|
|
||||||
udphdr->chksum = 0x0000;
|
|
||||||
#endif /* CHECKSUM_CHECK_UDP */
|
#endif /* CHECKSUM_CHECK_UDP */
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||||
|
Loading…
Reference in New Issue
Block a user