| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_arp.c,v 1.151 2011/05/03 16:00:29 dyoung Exp $ */ | | 1 | /* $NetBSD: if_arp.c,v 1.152 2011/08/27 09:05:54 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Public Access Networks Corporation ("Panix"). It was developed under | | 8 | * by Public Access Networks Corporation ("Panix"). It was developed under |
9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. | | 9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
59 | * SUCH DAMAGE. | | 59 | * SUCH DAMAGE. |
60 | * | | 60 | * |
61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 | | 61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 |
62 | */ | | 62 | */ |
63 | | | 63 | |
64 | /* | | 64 | /* |
65 | * Ethernet address resolution protocol. | | 65 | * Ethernet address resolution protocol. |
66 | * TODO: | | 66 | * TODO: |
67 | * add "inuse/lock" bit (or ref. count) along with valid bit | | 67 | * add "inuse/lock" bit (or ref. count) along with valid bit |
68 | */ | | 68 | */ |
69 | | | 69 | |
70 | #include <sys/cdefs.h> | | 70 | #include <sys/cdefs.h> |
71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.151 2011/05/03 16:00:29 dyoung Exp $"); | | 71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.152 2011/08/27 09:05:54 christos Exp $"); |
72 | | | 72 | |
73 | #include "opt_ddb.h" | | 73 | #include "opt_ddb.h" |
74 | #include "opt_inet.h" | | 74 | #include "opt_inet.h" |
75 | | | 75 | |
76 | #ifdef INET | | 76 | #ifdef INET |
77 | | | 77 | |
78 | #include "bridge.h" | | 78 | #include "bridge.h" |
79 | | | 79 | |
80 | #include <sys/param.h> | | 80 | #include <sys/param.h> |
81 | #include <sys/systm.h> | | 81 | #include <sys/systm.h> |
82 | #include <sys/callout.h> | | 82 | #include <sys/callout.h> |
83 | #include <sys/malloc.h> | | 83 | #include <sys/malloc.h> |
84 | #include <sys/mbuf.h> | | 84 | #include <sys/mbuf.h> |
| @@ -181,26 +181,30 @@ struct in_addr myip, srv_ip; | | | @@ -181,26 +181,30 @@ struct in_addr myip, srv_ip; |
181 | int myip_initialized = 0; | | 181 | int myip_initialized = 0; |
182 | int revarp_in_progress = 0; | | 182 | int revarp_in_progress = 0; |
183 | struct ifnet *myip_ifp = NULL; | | 183 | struct ifnet *myip_ifp = NULL; |
184 | | | 184 | |
185 | #ifdef DDB | | 185 | #ifdef DDB |
186 | static void db_print_sa(const struct sockaddr *); | | 186 | static void db_print_sa(const struct sockaddr *); |
187 | static void db_print_ifa(struct ifaddr *); | | 187 | static void db_print_ifa(struct ifaddr *); |
188 | static void db_print_llinfo(void *); | | 188 | static void db_print_llinfo(void *); |
189 | static int db_show_rtentry(struct rtentry *, void *); | | 189 | static int db_show_rtentry(struct rtentry *, void *); |
190 | #endif | | 190 | #endif |
191 | | | 191 | |
192 | static int arp_drainwanted; | | 192 | static int arp_drainwanted; |
193 | | | 193 | |
| | | 194 | static int log_movements = 1; |
| | | 195 | static int log_permanent_modify = 1; |
| | | 196 | static int log_wrong_iface = 1; |
| | | 197 | |
194 | /* | | 198 | /* |
195 | * this should be elsewhere. | | 199 | * this should be elsewhere. |
196 | */ | | 200 | */ |
197 | | | 201 | |
198 | static char * | | 202 | static char * |
199 | lla_snprintf(u_int8_t *, int); | | 203 | lla_snprintf(u_int8_t *, int); |
200 | | | 204 | |
201 | static char * | | 205 | static char * |
202 | lla_snprintf(u_int8_t *adrp, int len) | | 206 | lla_snprintf(u_int8_t *adrp, int len) |
203 | { | | 207 | { |
204 | #define NUMBUFS 3 | | 208 | #define NUMBUFS 3 |
205 | static char buf[NUMBUFS][16*3]; | | 209 | static char buf[NUMBUFS][16*3]; |
206 | static int bnum = 0; | | 210 | static int bnum = 0; |
| @@ -1075,47 +1079,53 @@ in_arpinput(struct mbuf *m) | | | @@ -1075,47 +1079,53 @@ in_arpinput(struct mbuf *m) |
1075 | ARP_STATINC(ARP_STAT_RCVLOCALSPA); | | 1079 | ARP_STATINC(ARP_STAT_RCVLOCALSPA); |
1076 | log(LOG_ERR, | | 1080 | log(LOG_ERR, |
1077 | "duplicate IP address %s sent from link address %s\n", | | 1081 | "duplicate IP address %s sent from link address %s\n", |
1078 | in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); | | 1082 | in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); |
1079 | itaddr = myaddr; | | 1083 | itaddr = myaddr; |
1080 | goto reply; | | 1084 | goto reply; |
1081 | } | | 1085 | } |
1082 | la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0); | | 1086 | la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0); |
1083 | if (la != NULL && (rt = la->la_rt) && (sdl = satosdl(rt->rt_gateway))) { | | 1087 | if (la != NULL && (rt = la->la_rt) && (sdl = satosdl(rt->rt_gateway))) { |
1084 | if (sdl->sdl_alen && | | 1088 | if (sdl->sdl_alen && |
1085 | memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) { | | 1089 | memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) { |
1086 | if (rt->rt_flags & RTF_STATIC) { | | 1090 | if (rt->rt_flags & RTF_STATIC) { |
1087 | ARP_STATINC(ARP_STAT_RCVOVERPERM); | | 1091 | ARP_STATINC(ARP_STAT_RCVOVERPERM); |
| | | 1092 | if (!log_permanent_modify) |
| | | 1093 | goto out; |
1088 | log(LOG_INFO, | | 1094 | log(LOG_INFO, |
1089 | "%s tried to overwrite permanent arp info" | | 1095 | "%s tried to overwrite permanent arp info" |
1090 | " for %s\n", | | 1096 | " for %s\n", |
1091 | lla_snprintf(ar_sha(ah), ah->ar_hln), | | 1097 | lla_snprintf(ar_sha(ah), ah->ar_hln), |
1092 | in_fmtaddr(isaddr)); | | 1098 | in_fmtaddr(isaddr)); |
1093 | goto out; | | 1099 | goto out; |
1094 | } else if (rt->rt_ifp != ifp) { | | 1100 | } else if (rt->rt_ifp != ifp) { |
1095 | ARP_STATINC(ARP_STAT_RCVOVERINT); | | 1101 | ARP_STATINC(ARP_STAT_RCVOVERINT); |
| | | 1102 | if (!log_wrong_iface) |
| | | 1103 | goto out; |
1096 | log(LOG_INFO, | | 1104 | log(LOG_INFO, |
1097 | "%s on %s tried to overwrite " | | 1105 | "%s on %s tried to overwrite " |
1098 | "arp info for %s on %s\n", | | 1106 | "arp info for %s on %s\n", |
1099 | lla_snprintf(ar_sha(ah), ah->ar_hln), | | 1107 | lla_snprintf(ar_sha(ah), ah->ar_hln), |
1100 | ifp->if_xname, in_fmtaddr(isaddr), | | 1108 | ifp->if_xname, in_fmtaddr(isaddr), |
1101 | rt->rt_ifp->if_xname); | | 1109 | rt->rt_ifp->if_xname); |
1102 | goto out; | | 1110 | goto out; |
1103 | } else { | | 1111 | } else { |
1104 | ARP_STATINC(ARP_STAT_RCVOVER); | | 1112 | ARP_STATINC(ARP_STAT_RCVOVER); |
1105 | log(LOG_INFO, | | 1113 | if (log_movements) |
1106 | "arp info overwritten for %s by %s\n", | | 1114 | log(LOG_INFO, "arp info overwritten " |
1107 | in_fmtaddr(isaddr), | | 1115 | "for %s by %s\n", |
1108 | lla_snprintf(ar_sha(ah), ah->ar_hln)); | | 1116 | in_fmtaddr(isaddr), |
| | | 1117 | lla_snprintf(ar_sha(ah), |
| | | 1118 | ah->ar_hln)); |
1109 | } | | 1119 | } |
1110 | } | | 1120 | } |
1111 | /* | | 1121 | /* |
1112 | * sanity check for the address length. | | 1122 | * sanity check for the address length. |
1113 | * XXX this does not work for protocols with variable address | | 1123 | * XXX this does not work for protocols with variable address |
1114 | * length. -is | | 1124 | * length. -is |
1115 | */ | | 1125 | */ |
1116 | if (sdl->sdl_alen && | | 1126 | if (sdl->sdl_alen && |
1117 | sdl->sdl_alen != ah->ar_hln) { | | 1127 | sdl->sdl_alen != ah->ar_hln) { |
1118 | ARP_STATINC(ARP_STAT_RCVLENCHG); | | 1128 | ARP_STATINC(ARP_STAT_RCVLENCHG); |
1119 | log(LOG_WARNING, | | 1129 | log(LOG_WARNING, |
1120 | "arp from %s: new addr len %d, was %d\n", | | 1130 | "arp from %s: new addr len %d, was %d\n", |
1121 | in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); | | 1131 | in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); |
| @@ -1631,47 +1641,71 @@ sysctl_net_inet_arp_setup(struct sysctll | | | @@ -1631,47 +1641,71 @@ sysctl_net_inet_arp_setup(struct sysctll |
1631 | CTLTYPE_NODE, "inet", NULL, | | 1641 | CTLTYPE_NODE, "inet", NULL, |
1632 | NULL, 0, NULL, 0, | | 1642 | NULL, 0, NULL, 0, |
1633 | CTL_NET, PF_INET, CTL_EOL); | | 1643 | CTL_NET, PF_INET, CTL_EOL); |
1634 | sysctl_createv(clog, 0, NULL, &node, | | 1644 | sysctl_createv(clog, 0, NULL, &node, |
1635 | CTLFLAG_PERMANENT, | | 1645 | CTLFLAG_PERMANENT, |
1636 | CTLTYPE_NODE, "arp", | | 1646 | CTLTYPE_NODE, "arp", |
1637 | SYSCTL_DESCR("Address Resolution Protocol"), | | 1647 | SYSCTL_DESCR("Address Resolution Protocol"), |
1638 | NULL, 0, NULL, 0, | | 1648 | NULL, 0, NULL, 0, |
1639 | CTL_NET, PF_INET, CTL_CREATE, CTL_EOL); | | 1649 | CTL_NET, PF_INET, CTL_CREATE, CTL_EOL); |
1640 | | | 1650 | |
1641 | sysctl_createv(clog, 0, NULL, NULL, | | 1651 | sysctl_createv(clog, 0, NULL, NULL, |
1642 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | | 1652 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1643 | CTLTYPE_INT, "prune", | | 1653 | CTLTYPE_INT, "prune", |
1644 | SYSCTL_DESCR("ARP cache pruning interval"), | | 1654 | SYSCTL_DESCR("ARP cache pruning interval in seconds"), |
1645 | NULL, 0, &arpt_prune, 0, | | 1655 | NULL, 0, &arpt_prune, 0, |
1646 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); | | 1656 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
1647 | | | 1657 | |
1648 | sysctl_createv(clog, 0, NULL, NULL, | | 1658 | sysctl_createv(clog, 0, NULL, NULL, |
1649 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | | 1659 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1650 | CTLTYPE_INT, "keep", | | 1660 | CTLTYPE_INT, "keep", |
1651 | SYSCTL_DESCR("Valid ARP entry lifetime"), | | 1661 | SYSCTL_DESCR("Valid ARP entry lifetime in seconds"), |
1652 | NULL, 0, &arpt_keep, 0, | | 1662 | NULL, 0, &arpt_keep, 0, |
1653 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); | | 1663 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
1654 | | | 1664 | |
1655 | sysctl_createv(clog, 0, NULL, NULL, | | 1665 | sysctl_createv(clog, 0, NULL, NULL, |
1656 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | | 1666 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1657 | CTLTYPE_INT, "down", | | 1667 | CTLTYPE_INT, "down", |
1658 | SYSCTL_DESCR("Failed ARP entry lifetime"), | | 1668 | SYSCTL_DESCR("Failed ARP entry lifetime in seconds"), |
1659 | NULL, 0, &arpt_down, 0, | | 1669 | NULL, 0, &arpt_down, 0, |
1660 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); | | 1670 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
1661 | | | 1671 | |
1662 | sysctl_createv(clog, 0, NULL, NULL, | | 1672 | sysctl_createv(clog, 0, NULL, NULL, |
1663 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, | | 1673 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
1664 | CTLTYPE_INT, "refresh", | | 1674 | CTLTYPE_INT, "refresh", |
1665 | SYSCTL_DESCR("ARP entry refresh interval"), | | 1675 | SYSCTL_DESCR("ARP entry refresh interval"), |
1666 | NULL, 0, &arpt_refresh, 0, | | 1676 | NULL, 0, &arpt_refresh, 0, |
1667 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); | | 1677 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
1668 | | | 1678 | |
1669 | sysctl_createv(clog, 0, NULL, NULL, | | 1679 | sysctl_createv(clog, 0, NULL, NULL, |
1670 | CTLFLAG_PERMANENT, | | 1680 | CTLFLAG_PERMANENT, |
1671 | CTLTYPE_STRUCT, "stats", | | 1681 | CTLTYPE_STRUCT, "stats", |
1672 | SYSCTL_DESCR("ARP statistics"), | | 1682 | SYSCTL_DESCR("ARP statistics"), |
1673 | sysctl_net_inet_arp_stats, 0, NULL, 0, | | 1683 | sysctl_net_inet_arp_stats, 0, NULL, 0, |
1674 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); | | 1684 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
| | | 1685 | |
| | | 1686 | sysctl_createv(clog, 0, NULL, NULL, |
| | | 1687 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
| | | 1688 | CTLTYPE_INT, "log_movements", |
| | | 1689 | SYSCTL_DESCR("log ARP replies from MACs different than" |
| | | 1690 | " the one in the cache"), |
| | | 1691 | NULL, 0, &log_movements, 0, |
| | | 1692 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
| | | 1693 | |
| | | 1694 | sysctl_createv(clog, 0, NULL, NULL, |
| | | 1695 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
| | | 1696 | CTLTYPE_INT, "log_permanent_modify", |
| | | 1697 | SYSCTL_DESCR("log ARP replies from MACs different than" |
| | | 1698 | " the one in the permanent arp entry"), |
| | | 1699 | NULL, 0, &log_permanent_modify, 0, |
| | | 1700 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
| | | 1701 | |
| | | 1702 | sysctl_createv(clog, 0, NULL, NULL, |
| | | 1703 | CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
| | | 1704 | CTLTYPE_INT, "log_wrong_iface", |
| | | 1705 | SYSCTL_DESCR("log ARP packets arriving on the wrong" |
| | | 1706 | " interface"), |
| | | 1707 | NULL, 0, &log_wrong_iface, 0, |
| | | 1708 | CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); |
1675 | } | | 1709 | } |
1676 | | | 1710 | |
1677 | #endif /* INET */ | | 1711 | #endif /* INET */ |