From owner-freebsd-net@FreeBSD.ORG Tue Dec 7 19:19:21 2010 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 155791065694 for ; Tue, 7 Dec 2010 19:19:21 +0000 (UTC) (envelope-from rozhuk.im@gmail.com) Received: from mail-ww0-f50.google.com (mail-ww0-f50.google.com [74.125.82.50]) by mx1.freebsd.org (Postfix) with ESMTP id 730C18FC12 for ; Tue, 7 Dec 2010 19:19:20 +0000 (UTC) Received: by wwf26 with SMTP id 26so249686wwf.31 for ; Tue, 07 Dec 2010 11:19:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:reply-to:from:to:subject:date :message-id:mime-version:content-type:x-mailer:thread-index :content-language; bh=CRk/RYF4ThG7DdXI9esG6R7hTeYBSczhPTzRqbfLZSE=; b=KptIj/8z+44nO4ZYkqTZsU/HZ4/kb/a4/teAbzqpi9OKsHeWu0AHMpreLiSDAwh2Xs IahYhgLqsq33maFIQpcZI9U0K6yFf2JZSRBZ2XuB4URafnY4f7wOHCYKFIR2AOzshtpA 0BxfvS6ICauLjHRs6+7qBOcI3gJx2w6q+R3MI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=reply-to:from:to:subject:date:message-id:mime-version:content-type :x-mailer:thread-index:content-language; b=kFLCwb/TMfxbzw1k5JIsvdxSpsVFn7GOdTir+Nm/TqDp+pd51CKE5XFnRQmhzIaBRK nPkocWuW5fyYBv6CeHCihDJ/AJYOoXkdmiQCbKgpuXEsCtL2d98pjdqhFFSxxTgzY/z6 l7TcXlqNAMGf6JCcH5PRZ5y6Gb3wVymxdBucY= Received: by 10.216.50.147 with SMTP id z19mr821936web.38.1291749559280; Tue, 07 Dec 2010 11:19:19 -0800 (PST) Received: from rimwks1x64 ([92.124.16.65]) by mx.google.com with ESMTPS id x28sm3130518weq.40.2010.12.07.11.19.16 (version=SSLv3 cipher=RC4-MD5); Tue, 07 Dec 2010 11:19:18 -0800 (PST) From: rozhuk.im@gmail.com To: Date: Wed, 8 Dec 2010 03:19:14 +0800 Message-ID: <4cfe88b6.1cedd80a.33f5.119d@mx.google.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0065_01CB9686.B27BE840" X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: AcuWQ6KYRrLlJ7k9SVKlpuvD9hTEkQ== Content-Language: ru Subject: [arp] possible DoS, fixes and improvements X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Rozhuk.IM@gmail.com List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Dec 2010 19:19:21 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_0065_01CB9686.B27BE840 Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: quoted-printable Hi! 1. ah->ar_hln - is depend from ar_hrd? Yes, and for ARPHRD_ETHER is 6 (ETHER_ADDR_LEN) For ARPHRD_IEEE1394 - sizeof(struct fw_hwaddr) ah->ar_hln ignored in ether_output: bcopy(ar_tha(ah), edst, = ETHER_ADDR_LEN); check in in_arpinput: if (ifp->if_addrlen !=3D ah->ar_hln) { LLE_WUNLOCK(la); log(LOG_WARNING, "arp from %*D: addr len: new %d, i/f %d (ignored)", ifp->if_addrlen, (u_char *) ar_sha(ah), ":", ah->ar_hln, ifp->if_addrlen); goto reply; } NO DROP!!!! In reply we get: (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln); Or=20 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); How to use it see below. 2. ah->ar_pln - does not checked! We can make big arp request (512 nulls after struct arphdr + 2*6 + 2*4) = , valid for host, set ar_plt =3D 255 And in reply will receive part of stack or core panic: in_arpinput: (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln); ... m->m_len =3D sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); ( eq arphdr_len(ah) ) 3. ar_sha(ah) - does not checked for multicast! Answers to request my be send to multicast addrs Only broadcast and host addr are checked. No check is ar_sha(ah) equal to Ethernet.ether_shost As result: arp -an ? (172.16.0.2) at 01:80:c2:00:00:01 on em0 expires in 118 seconds = [ethernet] 4. holded packet my be sended without any locks Current: if (la->la_hold !=3D NULL) { struct mbuf *m_hold, *m_hold_next; bcopy(L3_ADDR(la), &sa, sizeof(sa)); LLE_WUNLOCK(la); for (m_hold =3D la->la_hold, la->la_hold =3D NULL; m_hold !=3D NULL; m_hold =3D m_hold_next) { m_hold_next =3D m_hold->m_nextpkt; m_hold->m_nextpkt =3D NULL; (*ifp->if_output)(ifp, m_hold, &sa, NULL); } } else LLE_WUNLOCK(la); la->la_hold =3D NULL; la->la_numheld =3D 0; Here we unlock la and then modify them - this is bad idea! Patched - see in attached patch. This sample will work only for Ethernet without locks if_output -> call arplookup again for every packet for sa_family =3D = AF_INET AF_UNSPEC - just copy ether_type/arc_type/... and L2 addr from = dst->sa_data struct mbuf *m_hold, *m_hold_next; struct sockaddr dst; m_hold =3D la->la_hold; if (m_hold !=3D NULL) { dst.sa_len =3D sizeof(dst); dst.sa_family =3D AF_UNSPEC; /* prevent call arpresolve, we know L2 addr dst */ switch (ntohs(ah->ar_hrd)){ case ARPHRD_ETHER: ((struct ether_header*)&dst.sa_data)->ether_type =3D ah->ar_pro; bcopy(ar_sha(ah), ((struct ether_header*)&dst.sa_data)->ether_dhost, ah->ar_hln); break; //case ARPHRD_IEEE802: // break; //case ARPHRD_ARCNET: // ((struct arc_header *)&dst.sa_data)->arc_type =3D ah->ar_pro; // bcopy(ar_sha(ah), ((struct arc_header *)&dst.sa_data)->arc_dhost, ah->ar_hln); // break; //case ARPHRD_FRELAY: // break; //case ARPHRD_IEEE1394: // break; default: bcopy(L3_ADDR(la), &dst, sizeof(dst)); } } la->la_hold =3D NULL; la->la_numheld =3D 0; LLE_WUNLOCK(la); for (; m_hold !=3D NULL; m_hold =3D m_hold_next) { m_hold_next =3D m_hold->m_nextpkt; m_hold->m_nextpkt =3D NULL; (*ifp->if_output)(ifp, m_hold, &dst, NULL); } Do I need include this improvement in next patch? Will attached patch included in mainstream code? PS: patch contain fixes and some code cleanup and improvements. Only basics tests done, not tested in production. PPS: tests for 1 and 2 Part of code to generate arp packet struct arphdr *ah; u_char buff[2048]; u_int32_t src, dst; bzero(buff, sizeof(buff)); ah =3D (struct arphdr *)buff; src =3D INET_ADDR(172,16,0,2); dst =3D INET_ADDR(172,16,0,254);// - target! ah->ar_hrd =3D htons(ARPHRD_ETHER); ah->ar_pro =3D htons(ETHERTYPE_IP); ah->ar_op =3D htons(ARPOP_REQUEST); ah->ar_hln =3D 255;//ETHER_ADDR_LEN; ah->ar_pln =3D 255;//INET_ADDR_LEN; ETHER_ADDR_COPY(ar_sha(ah), ether_shost); INET_ADDR_COPY(ar_spa(ah), &src); INET_ADDR_COPY(ar_tpa(ah), &dst); send_ether(bpf, ether_dhost, ether_shost, ETHERTYPE_ARP, (u_char*)ah, = 1200); returned answer is 1042 bytes size, no core panic tested on my home freebsd box (i386, 8.2 @ E5300), with custom kernel 0x0030 x 0000 0000 0018 0000 0000 0000 00ff ffff x ................ 0x0040 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0050 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0060 x 0000 0000 0000 0000 0000 0000 0000 6a2f x ..............j/ 0x0070 x c5a0 522f c580 552f c500 412f c500 0008 x ..R/..U/..A/.... 0x0080 x f100 0000 f101 b000 0000 000a f100 0000 x ................ 0x0090 x 0000 0000 0000 0000 0086 801f a086 80d3 x ................ 0x00A0 x 1007 0010 0002 0000 0000 0801 1100 0000 x ................ 0x00B0 x 0006 0000 0000 0000 0002 0000 0022 c8cc x .............".. 0x00C0 x cecf 0000 0000 0000 0000 0000 0000 0000 x ................ 0x00D0 x 0000 0000 0000 0000 0000 0000 0080 00d0 x ................ 0x00E0 x 0100 0000 0000 0000 0000 0000 0000 0000 x ................ 0x00F0 x 0000 0000 0004 8005 00a0 1c1c 0000 0000 x ................ 0x0100 x 0000 2000 0003 00ac 1000 feac 1000 0210 x ................ 0x0110 x 0200 00ac 1000 0200 0000 0000 0000 00a0 x ................ 0x0120 x 3520 c570 3820 c5a0 3520 c5a0 3520 c502 x 5..p8...5...5... 0x0130 x e249 fb00 0000 0000 8121 c900 58c2 c07c x .I.......!..X..| 0x0140 x 7cdb c4ea 6856 c000 8121 c9c0 066c c001 x |...hV...!...l.. 0x0150 x 0000 0002 0000 0060 7cdb c4a0 3520 c5a0 x .......`|...5... 0x0160 x 3520 c5c4 0000 007f ffff ff80 0000 00cc x 5............... 0x0170 x 59c2 c001 0000 0007 0000 00c0 c31e c500 x Y............... 0x0180 x 5e1c c5a0 3520 c5ac 7cdb c49e 0d49 c000 x ^...5...|....I.. 0x0190 x 58c2 c0ec e64b c000 0000 0009 0100 0047 x X....K.........G 0x01A0 x d152 e8a0 3520 c500 0000 0000 5e1c c530 x .R..5.......^..0 0x01B0 x d11e c5a0 3520 c5dc 7cdb c43e 2649 c0a0 x ....5...|..>&I.. 0x01C0 x 1a20 c500 5e1c c57d c565 c02d 0500 0070 x ....^..}.e.-...p 0x01D0 x 5e1c c56c 5e1c c5a0 1a20 c530 d11e c5a0 x ^..l^......0.... 0x01E0 x 3520 c500 0000 0014 7ddb c4fd e948 c030 x 5.......}....H.0 0x01F0 x d11e c528 7ddb c400 0000 0000 0000 0000 x ...(}........... 0x0200 x 0000 0000 0000 001d 0ff2 4b4a 0000 0000 x ..........KJ.... 0x0210 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0220 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0230 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0240 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0250 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0260 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0270 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0280 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0290 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x02F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0300 x 0000 0000 00ac 1000 0200 0000 0000 0000 x ................ 0x0310 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0320 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0330 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0340 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0350 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0360 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0370 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0380 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0390 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x03F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0400 x 0000 0000 x .... ah->ar_hln =3D ETHER_ADDR_LEN; // =3D 6 ah->ar_pln =3D 255;//INET_ADDR_LEN; 0x0000 x 0001 0800 06ff 0002 001b 214f f5b3 ac10 x ..........!O.... 0x0010 x 00fe ac10 0002 1002 0000 ac10 0002 0000 x ................ 0x0020 x 0000 0000 0000 a035 20c5 0000 0000 a035 x .......5.......5 0x0030 x 20c5 a035 20c5 02e2 49fb 0000 0000 00c4 x ...5....I....... 0x0040 x 26c9 0058 c2c0 7c7c dbc4 ea68 56c0 00c4 x &..X..||...hV... 0x0050 x 26c9 c006 6cc0 0100 0000 0200 0000 607c x &...l.........`| 0x0060 x dbc4 a035 20c5 a035 20c5 c400 0000 7fff x ...5...5........ 0x0070 x ffff 8000 0000 cc59 c2c0 0100 0000 0700 x .......Y........ 0x0080 x 0000 c0c3 1ec5 005e 1cc5 a035 20c5 ac7c x .......^...5...| 0x0090 x dbc4 9e0d 49c0 0058 c2c0 ece6 4bc0 0000 x ....I..X....K... 0x00A0 x 0000 0901 0000 dedc 6b6f a035 20c5 0000 x ........ko.5.... 0x00B0 x 0000 005e 1cc5 30d1 1ec5 a035 20c5 dc7c x ...^..0....5...| 0x00C0 x dbc4 3e26 49c0 a01a 20c5 005e 1cc5 7dc5 x ..>&I......^..}. 0x00D0 x 65c0 2d05 0000 705e 1cc5 6c5e 1cc5 a01a x e.-...p^..l^.... 0x00E0 x 20c5 30d1 1ec5 a035 20c5 0000 0000 147d x ..0....5.......} 0x00F0 x dbc4 fde9 48c0 30d1 1ec5 287d dbc4 0000 x ....H.0...(}.... 0x0100 x 0000 0000 0000 0000 0000 0000 0000 1d0f x ................ 0x0110 x f24b 4aac 1000 0200 0000 0000 0000 0000 x .KJ............. 0x0120 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0130 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0140 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0150 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0160 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0170 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0180 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0190 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x01F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0200 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................ 0x0210 x 0000 x .. =A0 -- Rozhuk Ivan =A0=20 ------=_NextPart_000_0065_01CB9686.B27BE840 Content-Type: application/octet-stream; name="if_ether.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="if_ether.patch" --- /usr/src/sys/netinet/if_ether.orig 2010-12-02 16:52:06.000000000 = +0800=0A= +++ /usr/src/sys/netinet/if_ether.c 2010-12-08 02:49:07.000000000 +0800=0A= @@ -57,6 +57,9 @@=0A= #include =0A= #include =0A= #include =0A= +#include =0A= +#include =0A= +#include =0A= #include =0A= #include =0A= =0A= @@ -246,7 +249,7 @@=0A= m->m_pkthdr.len =3D m->m_len;=0A= MH_ALIGN(m, m->m_len);=0A= ah =3D mtod(m, struct arphdr *);=0A= - bzero((caddr_t)ah, m->m_len);=0A= + bzero(ah, m->m_len);=0A= #ifdef MAC=0A= mac_netinet_arp_send(ifp, m);=0A= #endif=0A= @@ -254,9 +257,9 @@=0A= ah->ar_hln =3D ifp->if_addrlen; /* hardware address length */=0A= ah->ar_pln =3D sizeof(struct in_addr); /* protocol address length */=0A= ah->ar_op =3D htons(ARPOP_REQUEST);=0A= - bcopy((caddr_t)enaddr, (caddr_t)ar_sha(ah), ah->ar_hln);=0A= - bcopy((caddr_t)sip, (caddr_t)ar_spa(ah), ah->ar_pln);=0A= - bcopy((caddr_t)tip, (caddr_t)ar_tpa(ah), ah->ar_pln);=0A= + bcopy(enaddr, ar_sha(ah), ah->ar_hln);=0A= + bcopy(sip, ar_spa(ah), ah->ar_pln);=0A= + bcopy(tip, ar_tpa(ah), ah->ar_pln);=0A= sa.sa_family =3D AF_ARP;=0A= sa.sa_len =3D 2;=0A= m->m_flags |=3D M_BCAST;=0A= @@ -292,8 +295,7 @@=0A= if (m !=3D NULL) {=0A= if (m->m_flags & M_BCAST) {=0A= /* broadcast */=0A= - (void)memcpy(desten,=0A= - ifp->if_broadcastaddr, ifp->if_addrlen);=0A= + bcopy(ifp->if_broadcastaddr, desten, ifp->if_addrlen);=0A= return (0);=0A= }=0A= if (m->m_flags & M_MCAST && ifp->if_type !=3D IFT_ARCNET) {=0A= @@ -429,42 +431,68 @@=0A= static void=0A= arpintr(struct mbuf *m)=0A= {=0A= - struct arphdr *ar;=0A= + struct arphdr *ah;=0A= =0A= if (m->m_len < sizeof(struct arphdr) &&=0A= ((m =3D m_pullup(m, sizeof(struct arphdr))) =3D=3D NULL)) {=0A= log(LOG_ERR, "arp: runt packet -- m_pullup failed\n");=0A= return;=0A= }=0A= - ar =3D mtod(m, struct arphdr *);=0A= + ah =3D mtod(m, struct arphdr *);=0A= =0A= - if (ntohs(ar->ar_hrd) !=3D ARPHRD_ETHER &&=0A= - ntohs(ar->ar_hrd) !=3D ARPHRD_IEEE802 &&=0A= - ntohs(ar->ar_hrd) !=3D ARPHRD_ARCNET &&=0A= - ntohs(ar->ar_hrd) !=3D ARPHRD_IEEE1394) {=0A= - log(LOG_ERR, "arp: unknown hardware address format (0x%2D)\n",=0A= - (unsigned char *)&ar->ar_hrd, "");=0A= - m_freem(m);=0A= - return;=0A= + /* check hw addr len and hw addr */=0A= + switch (ntohs(ah->ar_hrd)){=0A= + case ARPHRD_ETHER:=0A= + if (ah->ar_hln !=3D ETHER_ADDR_LEN) {=0A= + log(LOG_ERR, "arp: invalid length of hardware address\n");=0A= + goto drop;=0A= + }=0A= + /* is from [multi/broad]cast? - sender cant be [multi/broad]cast! */=0A= + if (ETHER_IS_MULTICAST(ar_sha(ah)) !=3D 0) {=0A= + log(LOG_ERR, "arp: link address is multicast\n");=0A= + goto drop;=0A= + }=0A= + break;=0A= + case ARPHRD_IEEE802:=0A= + if (ah->ar_hln !=3D ISO88025_ADDR_LEN)=0A= + goto drop;=0A= + break;=0A= + case ARPHRD_ARCNET:=0A= + if (ah->ar_hln !=3D ARC_ADDR_LEN)=0A= + goto drop;=0A= + break;=0A= + case ARPHRD_FRELAY:=0A= + if (ah->ar_hln !=3D 2)=0A= + goto drop;=0A= + break;=0A= + case ARPHRD_IEEE1394:=0A= + if (ah->ar_hln !=3D sizeof(struct fw_hwaddr)) /* XXX 8? */=0A= + goto drop;=0A= + break;=0A= + default:=0A= + log(LOG_ERR, "arp: unknown hardware address format\n");=0A= + goto drop;=0A= }=0A= =0A= - if (m->m_len < arphdr_len(ar)) {=0A= - if ((m =3D m_pullup(m, arphdr_len(ar))) =3D=3D NULL) {=0A= + if (m->m_len < arphdr_len(ah)) {=0A= + if ((m =3D m_pullup(m, arphdr_len(ah))) =3D=3D NULL) {=0A= log(LOG_ERR, "arp: runt packet\n");=0A= - m_freem(m);=0A= return;=0A= }=0A= - ar =3D mtod(m, struct arphdr *);=0A= + ah =3D mtod(m, struct arphdr *);=0A= }=0A= =0A= ARPSTAT_INC(received);=0A= - switch (ntohs(ar->ar_pro)) {=0A= + switch (ntohs(ah->ar_pro)) {=0A= #ifdef INET=0A= case ETHERTYPE_IP:=0A= in_arpinput(m);=0A= return;=0A= #endif=0A= }=0A= +=0A= + log(LOG_ERR, "arp: unknown format of protocol address\n");=0A= +drop:=0A= m_freem(m);=0A= }=0A= =0A= @@ -507,11 +535,10 @@=0A= struct rtentry *rt;=0A= struct ifaddr *ifa;=0A= struct in_ifaddr *ia;=0A= - struct sockaddr sa;=0A= + struct sockaddr dst;=0A= struct in_addr isaddr, itaddr, myaddr;=0A= u_int8_t *enaddr =3D NULL;=0A= int op, flags;=0A= - int req_len;=0A= int bridged =3D 0, is_bridge =3D 0;=0A= int carp_match =3D 0;=0A= struct sockaddr_in sin;=0A= @@ -519,25 +546,25 @@=0A= sin.sin_family =3D AF_INET;=0A= sin.sin_addr.s_addr =3D 0;=0A= =0A= - if (ifp->if_bridge)=0A= - bridged =3D 1;=0A= - if (ifp->if_type =3D=3D IFT_BRIDGE)=0A= - is_bridge =3D 1;=0A= =0A= - req_len =3D arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr));=0A= - if (m->m_len < req_len && (m =3D m_pullup(m, req_len)) =3D=3D NULL) {=0A= - log(LOG_ERR, "in_arp: runt packet -- m_pullup failed\n");=0A= - return;=0A= + ah =3D mtod(m, struct arphdr *);=0A= + if (ah->ar_pln !=3D sizeof(struct in_addr)) {=0A= + log(LOG_ERR, "arp: invalid length of protocol address\n");=0A= + goto drop;=0A= }=0A= =0A= - ah =3D mtod(m, struct arphdr *);=0A= op =3D ntohs(ah->ar_op);=0A= - (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));=0A= - (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));=0A= + bcopy(ar_spa(ah), &isaddr, sizeof (isaddr));=0A= + bcopy(ar_tpa(ah), &itaddr, sizeof (itaddr));=0A= =0A= if (op =3D=3D ARPOP_REPLY)=0A= ARPSTAT_INC(rxreplies);=0A= =0A= + if (ifp->if_bridge)=0A= + bridged =3D 1;=0A= + if (ifp->if_type =3D=3D IFT_BRIDGE)=0A= + is_bridge =3D 1;=0A= +=0A= /*=0A= * For a bridge, we want to check the address irrespective=0A= * of the receive interface. (This will change slightly=0A= @@ -626,6 +653,15 @@=0A= enaddr =3D (u_int8_t *)IF_LLADDR(ifp);=0A= myaddr =3D ia->ia_addr.sin_addr;=0A= ifa_free(&ia->ia_ifa);=0A= +=0A= + /* XXX length of hardware address (ar_hln) already checked in arpintr = */=0A= + if (ifp->if_addrlen !=3D ah->ar_hln) {=0A= + log(LOG_WARNING,=0A= + "arp from %*D: addr len: new %d, i/f %d (ignored)",=0A= + ifp->if_addrlen, (u_char *) ar_sha(ah), ":",=0A= + ah->ar_hln, ifp->if_addrlen);=0A= + goto drop;=0A= + }=0A= if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen))=0A= goto drop; /* it's from me, ignore it. */=0A= if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {=0A= @@ -695,16 +731,8 @@=0A= ifp->if_xname);=0A= }=0A= }=0A= - =0A= - if (ifp->if_addrlen !=3D ah->ar_hln) {=0A= - LLE_WUNLOCK(la);=0A= - log(LOG_WARNING,=0A= - "arp from %*D: addr len: new %d, i/f %d (ignored)",=0A= - ifp->if_addrlen, (u_char *) ar_sha(ah), ":",=0A= - ah->ar_hln, ifp->if_addrlen);=0A= - goto reply;=0A= - }=0A= - (void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);=0A= +=0A= + bcopy(ar_sha(ah), &la->ll_addr, ifp->if_addrlen);=0A= la->la_flags |=3D LLE_VALID;=0A= =0A= EVENTHANDLER_INVOKE(arp_update_event, la);=0A= @@ -728,31 +756,31 @@=0A= * NB: The lock MUST be released before the call to the=0A= * output routine.=0A= */=0A= - if (la->la_hold !=3D NULL) {=0A= - struct mbuf *m_hold, *m_hold_next;=0A= + struct mbuf *m_hold, *m_hold_next;=0A= =0A= - memcpy(&sa, L3_ADDR(la), sizeof(sa));=0A= - LLE_WUNLOCK(la);=0A= - for (m_hold =3D la->la_hold, la->la_hold =3D NULL;=0A= - m_hold !=3D NULL; m_hold =3D m_hold_next) {=0A= - m_hold_next =3D m_hold->m_nextpkt;=0A= - m_hold->m_nextpkt =3D NULL;=0A= - (*ifp->if_output)(ifp, m_hold, &sa, NULL);=0A= - }=0A= - } else=0A= - LLE_WUNLOCK(la);=0A= + m_hold =3D la->la_hold;=0A= + if (m_hold !=3D NULL)=0A= + bcopy(L3_ADDR(la), &dst, sizeof(dst));=0A= la->la_hold =3D NULL;=0A= la->la_numheld =3D 0;=0A= - } /* end of FIB loop */=0A= + LLE_WUNLOCK(la);=0A= +=0A= + /* send packets to output */=0A= + for (; m_hold !=3D NULL; m_hold =3D m_hold_next) {=0A= + m_hold_next =3D m_hold->m_nextpkt;=0A= + m_hold->m_nextpkt =3D NULL;=0A= + (*ifp->if_output)(ifp, m_hold, &dst, NULL);=0A= + }=0A= + }=0A= reply:=0A= if (op !=3D ARPOP_REQUEST)=0A= goto drop;=0A= ARPSTAT_INC(rxrequests);=0A= =0A= + bcopy(ar_sha(ah), ar_tha(ah), ah->ar_hln);=0A= if (itaddr.s_addr =3D=3D myaddr.s_addr) {=0A= /* Shortcut.. the receiving interface is the target. */=0A= - (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);=0A= - (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);=0A= + bcopy(enaddr, ar_sha(ah), ah->ar_hln);=0A= } else {=0A= struct llentry *lle =3D NULL;=0A= =0A= @@ -762,8 +790,7 @@=0A= IF_AFDATA_UNLOCK(ifp);=0A= =0A= if ((lle !=3D NULL) && (lle->la_flags & LLE_PUB)) {=0A= - (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);=0A= - (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);=0A= + bcopy(&lle->ll_addr, ar_sha(ah), ah->ar_hln);=0A= LLE_RUNLOCK(lle);=0A= } else {=0A= =0A= @@ -790,9 +817,6 @@=0A= }=0A= RTFREE_LOCKED(rt);=0A= =0A= - (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);=0A= - (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);=0A= -=0A= /*=0A= * Also check that the node which sent the ARP packet=0A= * is on the the interface we expect it to be on. This=0A= @@ -815,6 +839,8 @@=0A= }=0A= RTFREE_LOCKED(rt);=0A= =0A= + bcopy(enaddr, ar_sha(ah), ah->ar_hln);=0A= +=0A= #ifdef DEBUG_PROXY=0A= printf("arp: proxying for %s\n",=0A= inet_ntoa(itaddr));=0A= @@ -835,15 +861,15 @@=0A= /* default behaviour; never reply by broadcast. */=0A= m->m_flags &=3D ~(M_BCAST|M_MCAST);=0A= }=0A= - (void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);=0A= - (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);=0A= + bcopy(ar_spa(ah), ar_tpa(ah), ah->ar_pln);=0A= + bcopy(&itaddr, ar_spa(ah), ah->ar_pln);=0A= ah->ar_op =3D htons(ARPOP_REPLY);=0A= ah->ar_pro =3D htons(ETHERTYPE_IP); /* let's be sure! */=0A= - m->m_len =3D sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); =0A= + m->m_len =3D arphdr_len(ah); =0A= m->m_pkthdr.len =3D m->m_len; =0A= - sa.sa_family =3D AF_ARP;=0A= - sa.sa_len =3D 2;=0A= - (*ifp->if_output)(ifp, m, &sa, NULL);=0A= + dst.sa_family =3D AF_ARP;=0A= + dst.sa_len =3D 2;=0A= + (*ifp->if_output)(ifp, m, &dst, NULL);=0A= ARPSTAT_INC(txreplies);=0A= return;=0A= =0A= ------=_NextPart_000_0065_01CB9686.B27BE840--