diff --git a/src/core/ipv4/ip.c b/src/core/ipv4/ip.c index e39334a5..b1d84f6b 100644 --- a/src/core/ipv4/ip.c +++ b/src/core/ipv4/ip.c @@ -209,6 +209,7 @@ ip_input(struct pbuf *p, struct netif *inp) { } /* verify checksum */ +#if CHECKSUM_CHECK_IP if (inet_chksum(iphdr, iphdrlen) != 0) { LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen))); @@ -219,6 +220,7 @@ ip_input(struct pbuf *p, struct netif *inp) { snmp_inc_ipindiscards(); return ERR_OK; } +#endif /* Trim pbuf. This should have been done at the netif layer, but we'll do it anyway just to be sure that its done. */ @@ -415,7 +417,9 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, } IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif } else { iphdr = p->payload; dest = &(iphdr->dest); diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index a522a002..3baae55c 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -136,6 +136,7 @@ tcp_input(struct pbuf *p, struct netif *inp) return; } +#if CHECKSUM_CHECK_TCP /* Verify TCP checksum. */ if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), @@ -152,7 +153,7 @@ tcp_input(struct pbuf *p, struct netif *inp) pbuf_free(p); return; } - +#endif /* Move the payload pointer in the pbuf so that it points to the TCP data instead of the TCP header. */ diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 70838947..a7cdc6be 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -400,9 +400,10 @@ tcp_output(struct tcp_pcb *pcb) TCPH_HDRLEN_SET(tcphdr, 5); tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, p->tot_len); - +#endif ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, IP_PROTO_TCP); @@ -518,10 +519,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) seg->p->payload = seg->tcphdr; seg->tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); +#endif TCP_STATS_INC(tcp.xmit); ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, @@ -552,9 +555,10 @@ tcp_rst(u32_t seqno, u32_t ackno, TCPH_HDRLEN_SET(tcphdr, 5); tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, IP_PROTO_TCP, p->tot_len); - +#endif TCP_STATS_INC(tcp.xmit); /* Send output with hardcoded TTL since we have no access to the pcb */ ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); @@ -621,8 +625,9 @@ tcp_keepalive(struct tcp_pcb *pcb) TCPH_HDRLEN_SET(tcphdr, 5); tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len); - +#endif TCP_STATS_INC(tcp.xmit); /* Send output to IP */ diff --git a/src/core/udp.c b/src/core/udp.c index a95cb770..c9b33b97 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -246,6 +246,7 @@ udp_input(struct pbuf *p, struct netif *inp) if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) { #endif /* IPv4 */ /* Do the UDP Lite checksum */ +#if CHECKSUM_CHECK_UDP if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) { @@ -256,7 +257,9 @@ udp_input(struct pbuf *p, struct netif *inp) pbuf_free(p); goto end; } +#endif } else { +#if CHECKSUM_CHECK_UDP if (udphdr->chksum != 0) { if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), @@ -270,6 +273,7 @@ udp_input(struct pbuf *p, struct netif *inp) goto end; } } +#endif } pbuf_header(p, -UDP_HLEN); if (pcb != NULL) { @@ -408,10 +412,14 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p) /* set UDP message length in UDP header */ udphdr->len = htons(pcb->chksum_len); /* calculate checksum */ +#if CHECKSUM_GEN_UDP udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip), IP_PROTO_UDP, pcb->chksum_len); /* chksum zero must become 0xffff, as zero means 'no checksum' */ if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff; +#else + udphdr->chksum = 0x0000; +#endif /* output to IP */ err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); snmp_inc_udpoutdatagrams(); @@ -419,11 +427,15 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p) LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len)); udphdr->len = htons(q->tot_len); /* calculate checksum */ +#if CHECKSUM_GEN_UDP if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len); /* chksum zero must become 0xffff, as zero means 'no checksum' */ if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff; } +#else + udphdr->chksum = 0x0000; +#endif LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum)); snmp_inc_udpoutdatagrams(); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 343f99a5..297fdcdb 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -495,6 +495,31 @@ a lot of data that needs to be copied, this should be set high. */ #endif /* PPP_SUPPORT */ +/* checksum options - set to zero for hardware checksum support */ + +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif /* Debugging options all default to off */