From owner-freebsd-net Thu Nov 16 2: 9:48 2000 Delivered-To: freebsd-net@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id E273837B479; Thu, 16 Nov 2000 02:09:40 -0800 (PST) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.0/8.11.0) id eAGA9bU47477; Thu, 16 Nov 2000 12:09:37 +0200 (EET) (envelope-from ru) Date: Thu, 16 Nov 2000 12:09:36 +0200 From: Ruslan Ermilov To: Jonathan Lemon Cc: net@FreeBSD.org Subject: Delayed checksums commit broke UDP checksum calculation Message-ID: <20001116120936.A45755@sunbay.com> Mail-Followup-To: Jonathan Lemon , net@FreeBSD.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="mP3DRpeJDSE+ciuQ" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --mP3DRpeJDSE+ciuQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! RFC768> If the computed checksum is zero, it is transmitted as all ones RFC768> (the equivalent in one's complement arithmetic). An all zero RFC768> transmitted checksum value means that the transmitter generated RFC768> no checksum. This (0x0000 -> 0xFFFF) apparently got broken in udp_usrreq.c,v 1.65. --- udp_usrreq.c 1999/12/22 19:13:24 1.64 +++ udp_usrreq.c 2000/03/27 19:14:23 1.65 @@ -688,11 +700,14 @@ udp_output(inp, m, addr, control, p) ui->ui_dport = inp->inp_fport; - ui->ui_ulen = ui->ui_len; + ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); /* - * Stuff checksum and output datagram. + * Set up checksum and output datagram. */ - ui->ui_sum = 0; if (udpcksum) { - if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0) - ui->ui_sum = 0xffff; + ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr, + htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); + m->m_pkthdr.csum_flags = CSUM_UDP; + m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); + } else { + ui->ui_sum = 0; } The attached patch should fix this. Comments? -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --mP3DRpeJDSE+ciuQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p Index: ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.116 diff -u -p -r1.116 ip_output.c --- ip_output.c 2000/11/01 01:59:28 1.116 +++ ip_output.c 2000/11/16 10:05:06 @@ -974,6 +974,8 @@ in_delayed_cksum(struct mbuf *m) ip = mtod(m, struct ip *); offset = IP_VHL_HL(ip->ip_vhl) << 2 ; csum = in_cksum_skip(m, ip->ip_len, offset); + if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0) + csum = 0xffff; /* per RFC768 */ offset += m->m_pkthdr.csum_data; /* checksum offset */ if (offset + sizeof(u_short) > m->m_len) { --mP3DRpeJDSE+ciuQ-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message