if_ether.c (237263) | if_ether.c (238945) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 22 unchanged lines hidden (view full) --- 31 32/* 33 * Ethernet address resolution protocol. 34 * TODO: 35 * add "inuse/lock" bit (or ref. count) along with valid bit 36 */ 37 38#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 22 unchanged lines hidden (view full) --- 31 32/* 33 * Ethernet address resolution protocol. 34 * TODO: 35 * add "inuse/lock" bit (or ref. count) along with valid bit 36 */ 37 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/sys/netinet/if_ether.c 237263 2012-06-19 07:34:13Z np $"); | 39__FBSDID("$FreeBSD: head/sys/netinet/if_ether.c 238945 2012-07-31 11:31:12Z glebius $"); |
40 41#include "opt_inet.h" 42 43#include <sys/param.h> 44#include <sys/kernel.h> 45#include <sys/queue.h> 46#include <sys/sysctl.h> 47#include <sys/systm.h> --- 34 unchanged lines hidden (view full) --- 82 83/* timer values */ 84static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20 85 * minutes */ 86static VNET_DEFINE(int, arp_maxtries) = 5; 87VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for 88 * local traffic */ 89static VNET_DEFINE(int, arp_proxyall) = 0; | 40 41#include "opt_inet.h" 42 43#include <sys/param.h> 44#include <sys/kernel.h> 45#include <sys/queue.h> 46#include <sys/sysctl.h> 47#include <sys/systm.h> --- 34 unchanged lines hidden (view full) --- 82 83/* timer values */ 84static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20 85 * minutes */ 86static VNET_DEFINE(int, arp_maxtries) = 5; 87VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for 88 * local traffic */ 89static VNET_DEFINE(int, arp_proxyall) = 0; |
90static VNET_DEFINE(int, arpt_down) = 20; /* keep incomplete entries for 91 * 20 seconds */ | 90static VNET_DEFINE(int, arpt_down) = 20; /* keep incomplete entries for 91 * 20 seconds */ |
92VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */ 93 94static VNET_DEFINE(int, arp_maxhold) = 1; 95 96#define V_arpt_keep VNET(arpt_keep) 97#define V_arpt_down VNET(arpt_down) 98#define V_arp_maxtries VNET(arp_maxtries) 99#define V_arp_proxyall VNET(arp_proxyall) --- 14 unchanged lines hidden (view full) --- 114 "Enable proxy ARP for all suitable requests"); 115SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, wait, CTLFLAG_RW, 116 &VNET_NAME(arpt_down), 0, 117 "Incomplete ARP entry lifetime in seconds"); 118SYSCTL_VNET_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW, 119 &VNET_NAME(arpstat), arpstat, 120 "ARP statistics (struct arpstat, net/if_arp.h)"); 121SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, maxhold, CTLFLAG_RW, | 92VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */ 93 94static VNET_DEFINE(int, arp_maxhold) = 1; 95 96#define V_arpt_keep VNET(arpt_keep) 97#define V_arpt_down VNET(arpt_down) 98#define V_arp_maxtries VNET(arp_maxtries) 99#define V_arp_proxyall VNET(arp_proxyall) --- 14 unchanged lines hidden (view full) --- 114 "Enable proxy ARP for all suitable requests"); 115SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, wait, CTLFLAG_RW, 116 &VNET_NAME(arpt_down), 0, 117 "Incomplete ARP entry lifetime in seconds"); 118SYSCTL_VNET_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW, 119 &VNET_NAME(arpstat), arpstat, 120 "ARP statistics (struct arpstat, net/if_arp.h)"); 121SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, maxhold, CTLFLAG_RW, |
122 &VNET_NAME(arp_maxhold), 0, | 122 &VNET_NAME(arp_maxhold), 0, |
123 "Number of packets to hold per ARP entry"); 124 125static void arp_init(void); 126static void arpintr(struct mbuf *); 127static void arptimer(void *); 128#ifdef INET 129static void in_arpinput(struct mbuf *); 130#endif --- 61 unchanged lines hidden (view full) --- 192 } 193 194 pkts_dropped = llentry_free(lle); 195 ARPSTAT_ADD(dropped, pkts_dropped); 196 ARPSTAT_INC(timeouts); 197 } else { 198#ifdef DIAGNOSTIC 199 struct sockaddr *l3addr = L3_ADDR(lle); | 123 "Number of packets to hold per ARP entry"); 124 125static void arp_init(void); 126static void arpintr(struct mbuf *); 127static void arptimer(void *); 128#ifdef INET 129static void in_arpinput(struct mbuf *); 130#endif --- 61 unchanged lines hidden (view full) --- 192 } 193 194 pkts_dropped = llentry_free(lle); 195 ARPSTAT_ADD(dropped, pkts_dropped); 196 ARPSTAT_INC(timeouts); 197 } else { 198#ifdef DIAGNOSTIC 199 struct sockaddr *l3addr = L3_ADDR(lle); |
200 log(LOG_INFO, | 200 log(LOG_INFO, |
201 "arptimer issue: %p, IPv4 address: \"%s\"\n", lle, 202 inet_ntoa( 203 ((const struct sockaddr_in *)l3addr)->sin_addr)); 204#endif 205 LLE_WUNLOCK(lle); 206 } 207 } 208 IF_AFDATA_UNLOCK(ifp); --- 36 unchanged lines hidden (view full) --- 245 sip = &IA_SIN(ifa)->sin_addr; 246 } 247 248 if (0 == ((sip->s_addr ^ tip->s_addr) & 249 IA_MASKSIN(ifa)->sin_addr.s_addr)) 250 break; /* found it. */ 251 } 252 IF_ADDR_RUNLOCK(ifp); | 201 "arptimer issue: %p, IPv4 address: \"%s\"\n", lle, 202 inet_ntoa( 203 ((const struct sockaddr_in *)l3addr)->sin_addr)); 204#endif 205 LLE_WUNLOCK(lle); 206 } 207 } 208 IF_AFDATA_UNLOCK(ifp); --- 36 unchanged lines hidden (view full) --- 245 sip = &IA_SIN(ifa)->sin_addr; 246 } 247 248 if (0 == ((sip->s_addr ^ tip->s_addr) & 249 IA_MASKSIN(ifa)->sin_addr.s_addr)) 250 break; /* found it. */ 251 } 252 IF_ADDR_RUNLOCK(ifp); |
253 if (sip == NULL) { | 253 if (sip == NULL) { |
254 printf("%s: cannot find matching address\n", __func__); 255 return; 256 } 257 } 258 if (enaddr == NULL) 259 enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp); 260 261 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) --- 72 unchanged lines hidden (view full) --- 334 } 335 if (la == NULL) { 336 if (flags & LLE_CREATE) 337 log(LOG_DEBUG, 338 "arpresolve: can't allocate llinfo for %s\n", 339 inet_ntoa(SIN(dst)->sin_addr)); 340 m_freem(m); 341 return (EINVAL); | 254 printf("%s: cannot find matching address\n", __func__); 255 return; 256 } 257 } 258 if (enaddr == NULL) 259 enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp); 260 261 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) --- 72 unchanged lines hidden (view full) --- 334 } 335 if (la == NULL) { 336 if (flags & LLE_CREATE) 337 log(LOG_DEBUG, 338 "arpresolve: can't allocate llinfo for %s\n", 339 inet_ntoa(SIN(dst)->sin_addr)); 340 m_freem(m); 341 return (EINVAL); |
342 } | 342 } |
343 344 if ((la->la_flags & LLE_VALID) && 345 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { 346 bcopy(&la->ll_addr, desten, ifp->if_addrlen); 347 /* 348 * If entry has an expiry time and it is approaching, 349 * see if we need to send an ARP request within this 350 * arpt_down interval. 351 */ 352 if (!(la->la_flags & LLE_STATIC) && 353 time_uptime + la->la_preempt > la->la_expire) { 354 arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL); 355 la->la_preempt--; 356 } 357 358 *lle = la; 359 error = 0; 360 goto done; | 343 344 if ((la->la_flags & LLE_VALID) && 345 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { 346 bcopy(&la->ll_addr, desten, ifp->if_addrlen); 347 /* 348 * If entry has an expiry time and it is approaching, 349 * see if we need to send an ARP request within this 350 * arpt_down interval. 351 */ 352 if (!(la->la_flags & LLE_STATIC) && 353 time_uptime + la->la_preempt > la->la_expire) { 354 arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL); 355 la->la_preempt--; 356 } 357 358 *lle = la; 359 error = 0; 360 goto done; |
361 } 362 | 361 } 362 |
363 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 364 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n", 365 inet_ntoa(SIN(dst)->sin_addr)); 366 m_freem(m); 367 error = EINVAL; 368 goto done; 369 } 370 --- 13 unchanged lines hidden (view full) --- 384 if (la->la_numheld >= V_arp_maxhold) { 385 if (la->la_hold != NULL) { 386 next = la->la_hold->m_nextpkt; 387 m_freem(la->la_hold); 388 la->la_hold = next; 389 la->la_numheld--; 390 ARPSTAT_INC(dropped); 391 } | 363 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 364 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n", 365 inet_ntoa(SIN(dst)->sin_addr)); 366 m_freem(m); 367 error = EINVAL; 368 goto done; 369 } 370 --- 13 unchanged lines hidden (view full) --- 384 if (la->la_numheld >= V_arp_maxhold) { 385 if (la->la_hold != NULL) { 386 next = la->la_hold->m_nextpkt; 387 m_freem(la->la_hold); 388 la->la_hold = next; 389 la->la_numheld--; 390 ARPSTAT_INC(dropped); 391 } |
392 } | 392 } |
393 if (la->la_hold != NULL) { 394 curr = la->la_hold; 395 while (curr->m_nextpkt != NULL) 396 curr = curr->m_nextpkt; 397 curr->m_nextpkt = m; | 393 if (la->la_hold != NULL) { 394 curr = la->la_hold; 395 while (curr->m_nextpkt != NULL) 396 curr = curr->m_nextpkt; 397 curr->m_nextpkt = m; |
398 } else | 398 } else |
399 la->la_hold = m; 400 la->la_numheld++; 401 if (renew == 0 && (flags & LLE_EXCLUSIVE)) { 402 flags &= ~LLE_EXCLUSIVE; 403 LLE_DOWNGRADE(la); 404 } 405 406 } --- 98 unchanged lines hidden (view full) --- 505static int log_arp_wrong_iface = 1; 506static int log_arp_movements = 1; 507static int log_arp_permanent_modify = 1; 508 509SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW, 510 &log_arp_wrong_iface, 0, 511 "log arp packets arriving on the wrong interface"); 512SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_movements, CTLFLAG_RW, | 399 la->la_hold = m; 400 la->la_numheld++; 401 if (renew == 0 && (flags & LLE_EXCLUSIVE)) { 402 flags &= ~LLE_EXCLUSIVE; 403 LLE_DOWNGRADE(la); 404 } 405 406 } --- 98 unchanged lines hidden (view full) --- 505static int log_arp_wrong_iface = 1; 506static int log_arp_movements = 1; 507static int log_arp_permanent_modify = 1; 508 509SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_wrong_iface, CTLFLAG_RW, 510 &log_arp_wrong_iface, 0, 511 "log arp packets arriving on the wrong interface"); 512SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_movements, CTLFLAG_RW, |
513 &log_arp_movements, 0, 514 "log arp replies from MACs different than the one in the cache"); | 513 &log_arp_movements, 0, 514 "log arp replies from MACs different than the one in the cache"); |
515SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_permanent_modify, CTLFLAG_RW, | 515SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_permanent_modify, CTLFLAG_RW, |
516 &log_arp_permanent_modify, 0, 517 "log arp replies from MACs different than the one in the permanent arp entry"); | 516 &log_arp_permanent_modify, 0, 517 "log arp replies from MACs different than the one in the permanent arp entry"); |
518 519 520static void 521in_arpinput(struct mbuf *m) 522{ 523 struct arphdr *ah; 524 struct ifnet *ifp = m->m_pkthdr.rcvif; 525 struct llentry *la = NULL; --- 19 unchanged lines hidden (view full) --- 545 546 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr)); 547 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) { 548 log(LOG_NOTICE, "in_arp: runt packet -- m_pullup failed\n"); 549 return; 550 } 551 552 ah = mtod(m, struct arphdr *); | 518 519 520static void 521in_arpinput(struct mbuf *m) 522{ 523 struct arphdr *ah; 524 struct ifnet *ifp = m->m_pkthdr.rcvif; 525 struct llentry *la = NULL; --- 19 unchanged lines hidden (view full) --- 545 546 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr)); 547 if (m->m_len < req_len && (m = m_pullup(m, req_len)) == NULL) { 548 log(LOG_NOTICE, "in_arp: runt packet -- m_pullup failed\n"); 549 return; 550 } 551 552 ah = mtod(m, struct arphdr *); |
553 /* | 553 /* |
554 * ARP is only for IPv4 so we can reject packets with 555 * a protocol length not equal to an IPv4 address. 556 */ 557 if (ah->ar_pln != sizeof(struct in_addr)) { 558 log(LOG_NOTICE, "in_arp: requested protocol length != %zu\n", 559 sizeof(struct in_addr)); 560 return; 561 } --- 119 unchanged lines hidden (view full) --- 681 goto reply; 682 683 bzero(&sin, sizeof(sin)); 684 sin.sin_len = sizeof(struct sockaddr_in); 685 sin.sin_family = AF_INET; 686 sin.sin_addr = isaddr; 687 flags = (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0; 688 flags |= LLE_EXCLUSIVE; | 554 * ARP is only for IPv4 so we can reject packets with 555 * a protocol length not equal to an IPv4 address. 556 */ 557 if (ah->ar_pln != sizeof(struct in_addr)) { 558 log(LOG_NOTICE, "in_arp: requested protocol length != %zu\n", 559 sizeof(struct in_addr)); 560 return; 561 } --- 119 unchanged lines hidden (view full) --- 681 goto reply; 682 683 bzero(&sin, sizeof(sin)); 684 sin.sin_len = sizeof(struct sockaddr_in); 685 sin.sin_family = AF_INET; 686 sin.sin_addr = isaddr; 687 flags = (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0; 688 flags |= LLE_EXCLUSIVE; |
689 IF_AFDATA_LOCK(ifp); | 689 IF_AFDATA_LOCK(ifp); |
690 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin); 691 IF_AFDATA_UNLOCK(ifp); 692 if (la != NULL) { 693 /* the following is not an error when doing bridging */ 694 if (!bridged && la->lle_tbl->llt_ifp != ifp) { 695 if (log_arp_wrong_iface) 696 log(LOG_WARNING, "arp: %s is on %s " 697 "but got reply from %*D on %s\n", --- 13 unchanged lines hidden (view full) --- 711 "arp: %*D attempts to modify " 712 "permanent entry for %s on %s\n", 713 ifp->if_addrlen, 714 (u_char *)ar_sha(ah), ":", 715 inet_ntoa(isaddr), ifp->if_xname); 716 goto reply; 717 } 718 if (log_arp_movements) { | 690 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin); 691 IF_AFDATA_UNLOCK(ifp); 692 if (la != NULL) { 693 /* the following is not an error when doing bridging */ 694 if (!bridged && la->lle_tbl->llt_ifp != ifp) { 695 if (log_arp_wrong_iface) 696 log(LOG_WARNING, "arp: %s is on %s " 697 "but got reply from %*D on %s\n", --- 13 unchanged lines hidden (view full) --- 711 "arp: %*D attempts to modify " 712 "permanent entry for %s on %s\n", 713 ifp->if_addrlen, 714 (u_char *)ar_sha(ah), ":", 715 inet_ntoa(isaddr), ifp->if_xname); 716 goto reply; 717 } 718 if (log_arp_movements) { |
719 log(LOG_INFO, "arp: %s moved from %*D " | 719 log(LOG_INFO, "arp: %s moved from %*D " |
720 "to %*D on %s\n", 721 inet_ntoa(isaddr), 722 ifp->if_addrlen, 723 (u_char *)&la->ll_addr, ":", 724 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 725 ifp->if_xname); 726 } 727 } | 720 "to %*D on %s\n", 721 inet_ntoa(isaddr), 722 ifp->if_addrlen, 723 (u_char *)&la->ll_addr, ":", 724 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 725 ifp->if_xname); 726 } 727 } |
728 | 728 |
729 if (ifp->if_addrlen != ah->ar_hln) { 730 LLE_WUNLOCK(la); 731 log(LOG_WARNING, "arp from %*D: addr len: new %d, " 732 "i/f %d (ignored)\n", ifp->if_addrlen, 733 (u_char *) ar_sha(ah), ":", ah->ar_hln, 734 ifp->if_addrlen); 735 goto drop; 736 } --- 9 unchanged lines hidden (view full) --- 746 la->la_expire = time_uptime + V_arpt_keep; 747 canceled = callout_reset(&la->la_timer, 748 hz * V_arpt_keep, arptimer, la); 749 if (canceled) 750 LLE_REMREF(la); 751 } 752 la->la_asked = 0; 753 la->la_preempt = V_arp_maxtries; | 729 if (ifp->if_addrlen != ah->ar_hln) { 730 LLE_WUNLOCK(la); 731 log(LOG_WARNING, "arp from %*D: addr len: new %d, " 732 "i/f %d (ignored)\n", ifp->if_addrlen, 733 (u_char *) ar_sha(ah), ":", ah->ar_hln, 734 ifp->if_addrlen); 735 goto drop; 736 } --- 9 unchanged lines hidden (view full) --- 746 la->la_expire = time_uptime + V_arpt_keep; 747 canceled = callout_reset(&la->la_timer, 748 hz * V_arpt_keep, arptimer, la); 749 if (canceled) 750 LLE_REMREF(la); 751 } 752 la->la_asked = 0; 753 la->la_preempt = V_arp_maxtries; |
754 /* | 754 /* |
755 * The packets are all freed within the call to the output 756 * routine. 757 * 758 * NB: The lock MUST be released before the call to the 759 * output routine. 760 */ 761 if (la->la_hold != NULL) { 762 struct mbuf *m_hold, *m_hold_next; --- 19 unchanged lines hidden (view full) --- 782 if (itaddr.s_addr == myaddr.s_addr) { 783 /* Shortcut.. the receiving interface is the target. */ 784 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); 785 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln); 786 } else { 787 struct llentry *lle = NULL; 788 789 sin.sin_addr = itaddr; | 755 * The packets are all freed within the call to the output 756 * routine. 757 * 758 * NB: The lock MUST be released before the call to the 759 * output routine. 760 */ 761 if (la->la_hold != NULL) { 762 struct mbuf *m_hold, *m_hold_next; --- 19 unchanged lines hidden (view full) --- 782 if (itaddr.s_addr == myaddr.s_addr) { 783 /* Shortcut.. the receiving interface is the target. */ 784 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); 785 (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln); 786 } else { 787 struct llentry *lle = NULL; 788 789 sin.sin_addr = itaddr; |
790 IF_AFDATA_LOCK(ifp); | 790 IF_AFDATA_LOCK(ifp); |
791 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin); 792 IF_AFDATA_UNLOCK(ifp); 793 794 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) { 795 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); 796 (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); 797 LLE_RUNLOCK(lle); 798 } else { --- 42 unchanged lines hidden (view full) --- 841 inet_ntoa(isaddr), ifp->if_xname, 842 rt->rt_ifp->if_xname); 843 RTFREE_LOCKED(rt); 844 goto drop; 845 } 846 RTFREE_LOCKED(rt); 847 848#ifdef DEBUG_PROXY | 791 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin); 792 IF_AFDATA_UNLOCK(ifp); 793 794 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) { 795 (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); 796 (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); 797 LLE_RUNLOCK(lle); 798 } else { --- 42 unchanged lines hidden (view full) --- 841 inet_ntoa(isaddr), ifp->if_xname, 842 rt->rt_ifp->if_xname); 843 RTFREE_LOCKED(rt); 844 goto drop; 845 } 846 RTFREE_LOCKED(rt); 847 848#ifdef DEBUG_PROXY |
849 printf("arp: proxying for %s\n", 850 inet_ntoa(itaddr)); | 849 printf("arp: proxying for %s\n", inet_ntoa(itaddr)); |
851#endif 852 } 853 } 854 855 if (itaddr.s_addr == myaddr.s_addr && 856 IN_LINKLOCAL(ntohl(itaddr.s_addr))) { 857 /* RFC 3927 link-local IPv4; always reply by broadcast. */ 858#ifdef DEBUG_LINKLOCAL --- 5 unchanged lines hidden (view full) --- 864 } else { 865 /* default behaviour; never reply by broadcast. */ 866 m->m_flags &= ~(M_BCAST|M_MCAST); 867 } 868 (void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln); 869 (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln); 870 ah->ar_op = htons(ARPOP_REPLY); 871 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */ | 850#endif 851 } 852 } 853 854 if (itaddr.s_addr == myaddr.s_addr && 855 IN_LINKLOCAL(ntohl(itaddr.s_addr))) { 856 /* RFC 3927 link-local IPv4; always reply by broadcast. */ 857#ifdef DEBUG_LINKLOCAL --- 5 unchanged lines hidden (view full) --- 863 } else { 864 /* default behaviour; never reply by broadcast. */ 865 m->m_flags &= ~(M_BCAST|M_MCAST); 866 } 867 (void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln); 868 (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln); 869 ah->ar_op = htons(ARPOP_REPLY); 870 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */ |
872 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); 873 m->m_pkthdr.len = m->m_len; | 871 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); 872 m->m_pkthdr.len = m->m_len; |
874 m->m_pkthdr.rcvif = NULL; 875 sa.sa_family = AF_ARP; 876 sa.sa_len = 2; 877 (*ifp->if_output)(ifp, m, &sa, NULL); 878 ARPSTAT_INC(txreplies); 879 return; 880 881drop: --- 7 unchanged lines hidden (view full) --- 889 struct llentry *lle; 890 891 if (ifa->ifa_carp != NULL) 892 return; 893 894 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY) { 895 arprequest(ifp, &IA_SIN(ifa)->sin_addr, 896 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp)); | 873 m->m_pkthdr.rcvif = NULL; 874 sa.sa_family = AF_ARP; 875 sa.sa_len = 2; 876 (*ifp->if_output)(ifp, m, &sa, NULL); 877 ARPSTAT_INC(txreplies); 878 return; 879 880drop: --- 7 unchanged lines hidden (view full) --- 888 struct llentry *lle; 889 890 if (ifa->ifa_carp != NULL) 891 return; 892 893 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY) { 894 arprequest(ifp, &IA_SIN(ifa)->sin_addr, 895 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp)); |
897 /* | 896 /* |
898 * interface address is considered static entry 899 * because the output of the arp utility shows 900 * that L2 entry as permanent 901 */ 902 IF_AFDATA_LOCK(ifp); 903 lle = lla_lookup(LLTABLE(ifp), (LLE_CREATE | LLE_IFADDR | LLE_STATIC), 904 (struct sockaddr *)IA_SIN(ifa)); 905 IF_AFDATA_UNLOCK(ifp); --- 25 unchanged lines hidden --- | 897 * interface address is considered static entry 898 * because the output of the arp utility shows 899 * that L2 entry as permanent 900 */ 901 IF_AFDATA_LOCK(ifp); 902 lle = lla_lookup(LLTABLE(ifp), (LLE_CREATE | LLE_IFADDR | LLE_STATIC), 903 (struct sockaddr *)IA_SIN(ifa)); 904 IF_AFDATA_UNLOCK(ifp); --- 25 unchanged lines hidden --- |