root/netinet/if_ether.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arptimer
  2. arp_rtrequest
  3. arprequest
  4. arpresolve
  5. arpintr
  6. in_arpinput
  7. arptfree
  8. arplookup
  9. arpioctl
  10. arp_ifinit
  11. revarpinput
  12. in_revarpinput
  13. revarprequest
  14. revarpwhoarewe
  15. revarpwhoami
  16. db_print_sa
  17. db_print_ifa
  18. db_print_llinfo
  19. db_show_radix_node
  20. db_show_arptab

    1 /*      $OpenBSD: if_ether.c,v 1.68 2007/03/25 16:43:22 claudio Exp $   */
    2 /*      $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1982, 1986, 1988, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)if_ether.c  8.1 (Berkeley) 6/10/93
   33  */
   34 
   35 /*
   36  * Ethernet address resolution protocol.
   37  * TODO:
   38  *      add "inuse/lock" bit (or ref. count) along with valid bit
   39  */
   40 
   41 #ifdef INET
   42 #include "carp.h"
   43 
   44 #include "bridge.h"
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/socket.h>
   50 #include <sys/kernel.h>
   51 #include <sys/syslog.h>
   52 #include <sys/proc.h>
   53 
   54 #include <net/if.h>
   55 #include <net/if_dl.h>
   56 #include <net/route.h>
   57 #include <net/if_fddi.h>
   58 #include <net/if_types.h>
   59 
   60 #include <netinet/in.h>
   61 #include <netinet/in_var.h>
   62 #include <netinet/if_ether.h>
   63 #if NCARP > 0
   64 #include <netinet/ip_carp.h>
   65 #endif
   66 
   67 #define SIN(s) ((struct sockaddr_in *)s)
   68 #define SDL(s) ((struct sockaddr_dl *)s)
   69 #define SRP(s) ((struct sockaddr_inarp *)s)
   70 
   71 /*
   72  * ARP trailer negotiation.  Trailer protocol is not IP specific,
   73  * but ARP request/response use IP addresses.
   74  */
   75 #define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
   76 
   77 /* timer values */
   78 int     arpt_prune = (5*60*1);  /* walk list every 5 minutes */
   79 int     arpt_keep = (20*60);    /* once resolved, good for 20 more minutes */
   80 int     arpt_down = 20;         /* once declared down, don't send for 20 secs */
   81 #define rt_expire rt_rmx.rmx_expire
   82 
   83 void arptfree(struct llinfo_arp *);
   84 void arptimer(void *);
   85 struct llinfo_arp *arplookup(u_int32_t, int, int);
   86 void in_arpinput(struct mbuf *);
   87 
   88 LIST_HEAD(, llinfo_arp) llinfo_arp;
   89 struct  ifqueue arpintrq = {0, 0, 0, 50};
   90 int     arp_inuse, arp_allocated, arp_intimer;
   91 int     arp_maxtries = 5;
   92 int     useloopback = 1;        /* use loopback interface for local traffic */
   93 int     arpinit_done = 0;
   94 
   95 /* revarp state */
   96 struct in_addr myip, srv_ip;
   97 int myip_initialized = 0;
   98 int revarp_in_progress = 0;
   99 struct ifnet *myip_ifp = NULL;
  100 
  101 #ifdef DDB
  102 #include <uvm/uvm_extern.h>
  103 
  104 void    db_print_sa(struct sockaddr *);
  105 void    db_print_ifa(struct ifaddr *);
  106 void    db_print_llinfo(caddr_t);
  107 int     db_show_radix_node(struct radix_node *, void *);
  108 #endif
  109 
  110 /*
  111  * Timeout routine.  Age arp_tab entries periodically.
  112  */
  113 /* ARGSUSED */
  114 void
  115 arptimer(arg)
  116         void *arg;
  117 {
  118         struct timeout *to = (struct timeout *)arg;
  119         int s;
  120         struct llinfo_arp *la, *nla;
  121 
  122         s = splsoftnet();
  123         timeout_add(to, arpt_prune * hz);
  124         for (la = LIST_FIRST(&llinfo_arp); la != LIST_END(&llinfo_arp);
  125             la = nla) {
  126                 struct rtentry *rt = la->la_rt;
  127 
  128                 nla = LIST_NEXT(la, la_list);
  129                 if (rt->rt_expire && rt->rt_expire <= time_second)
  130                         arptfree(la); /* timer has expired; clear */
  131         }
  132         splx(s);
  133 }
  134 
  135 /*
  136  * Parallel to llc_rtrequest.
  137  */
  138 void
  139 arp_rtrequest(req, rt, info)
  140         int req;
  141         struct rtentry *rt;
  142         struct rt_addrinfo *info;
  143 {
  144         struct sockaddr *gate = rt->rt_gateway;
  145         struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
  146         static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
  147         struct in_ifaddr *ia;
  148         struct ifaddr *ifa;
  149 
  150         if (!arpinit_done) {
  151                 static struct timeout arptimer_to;
  152 
  153                 arpinit_done = 1;
  154                 /*
  155                  * We generate expiration times from time.tv_sec
  156                  * so avoid accidently creating permanent routes.
  157                  */
  158                 if (time_second == 0) {
  159                         time_second++;
  160                 }
  161 
  162                 timeout_set(&arptimer_to, arptimer, &arptimer_to);
  163                 timeout_add(&arptimer_to, hz);
  164         }
  165 
  166         if (rt->rt_flags & RTF_GATEWAY) {
  167                 if (req != RTM_ADD)
  168                         return;
  169 
  170                 /*
  171                  * linklayers with particular link MTU limitation.  it is a bit
  172                  * awkward to have FDDI handling here, we should split ARP from
  173                  * netinet/if_ether.c like NetBSD does.
  174                  */
  175                 switch (rt->rt_ifp->if_type) {
  176                 case IFT_FDDI:
  177                         if (rt->rt_ifp->if_mtu > FDDIIPMTU)
  178                                 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
  179                         break;
  180                 }
  181 
  182                 return;
  183         }
  184 
  185         switch (req) {
  186 
  187         case RTM_ADD:
  188                 /*
  189                  * XXX: If this is a manually added route to interface
  190                  * such as older version of routed or gated might provide,
  191                  * restore cloning bit.
  192                  */
  193                 if ((rt->rt_flags & RTF_HOST) == 0 &&
  194                     SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
  195                         rt->rt_flags |= RTF_CLONING;
  196                 if (rt->rt_flags & RTF_CLONING) {
  197                         /*
  198                          * Case 1: This route should come from a route to iface.
  199                          */
  200                         rt_setgate(rt, rt_key(rt),
  201                             (struct sockaddr *)&null_sdl, 0);
  202                         gate = rt->rt_gateway;
  203                         SDL(gate)->sdl_type = rt->rt_ifp->if_type;
  204                         SDL(gate)->sdl_index = rt->rt_ifp->if_index;
  205                         /*
  206                          * Give this route an expiration time, even though
  207                          * it's a "permanent" route, so that routes cloned
  208                          * from it do not need their expiration time set.
  209                          */
  210                         rt->rt_expire = time_second;
  211                         /*
  212                          * linklayers with particular link MTU limitation.
  213                          */
  214                         switch (rt->rt_ifp->if_type) {
  215                         case IFT_FDDI:
  216                                 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
  217                                     (rt->rt_rmx.rmx_mtu > FDDIIPMTU ||
  218                                      (rt->rt_rmx.rmx_mtu == 0 &&
  219                                       rt->rt_ifp->if_mtu > FDDIIPMTU)))
  220                                         rt->rt_rmx.rmx_mtu = FDDIIPMTU;
  221                                 break;
  222                         }
  223                         break;
  224                 }
  225                 /* Announce a new entry if requested. */
  226                 if (rt->rt_flags & RTF_ANNOUNCE)
  227                         arprequest(rt->rt_ifp,
  228                             &SIN(rt_key(rt))->sin_addr.s_addr,
  229                             &SIN(rt_key(rt))->sin_addr.s_addr,
  230                             (u_char *)LLADDR(SDL(gate)));
  231                 /*FALLTHROUGH*/
  232         case RTM_RESOLVE:
  233                 if (gate->sa_family != AF_LINK ||
  234                     gate->sa_len < sizeof(null_sdl)) {
  235                         log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
  236                         break;
  237                 }
  238                 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
  239                 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
  240                 if (la != 0)
  241                         break; /* This happens on a route change */
  242                 /*
  243                  * Case 2:  This route may come from cloning, or a manual route
  244                  * add with a LL address.
  245                  */
  246                 R_Malloc(la, struct llinfo_arp *, sizeof(*la));
  247                 rt->rt_llinfo = (caddr_t)la;
  248                 if (la == 0) {
  249                         log(LOG_DEBUG, "arp_rtrequest: malloc failed\n");
  250                         break;
  251                 }
  252                 arp_inuse++, arp_allocated++;
  253                 Bzero(la, sizeof(*la));
  254                 la->la_rt = rt;
  255                 rt->rt_flags |= RTF_LLINFO;
  256                 LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
  257 
  258                 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
  259                         if (ia->ia_ifp == rt->rt_ifp &&
  260                             SIN(rt_key(rt))->sin_addr.s_addr ==
  261                             (IA_SIN(ia))->sin_addr.s_addr)
  262                                 break;
  263                 }
  264                 if (ia) {
  265                         /*
  266                          * This test used to be
  267                          *      if (lo0ifp->if_flags & IFF_UP)
  268                          * It allowed local traffic to be forced through
  269                          * the hardware by configuring the loopback down.
  270                          * However, it causes problems during network
  271                          * configuration for boards that can't receive
  272                          * packets they send.  It is now necessary to clear
  273                          * "useloopback" and remove the route to force
  274                          * traffic out to the hardware.
  275                          *
  276                          * In 4.4BSD, the above "if" statement checked
  277                          * rt->rt_ifa against rt_key(rt).  It was changed
  278                          * to the current form so that we can provide a
  279                          * better support for multiple IPv4 addresses on a
  280                          * interface.
  281                          */
  282                         rt->rt_expire = 0;
  283                         Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
  284                             LLADDR(SDL(gate)),
  285                             SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
  286                         if (useloopback)
  287                                 rt->rt_ifp = lo0ifp;
  288                         /*
  289                          * make sure to set rt->rt_ifa to the interface
  290                          * address we are using, otherwise we will have trouble
  291                          * with source address selection.
  292                          */
  293                         ifa = &ia->ia_ifa;
  294                         if (ifa != rt->rt_ifa) {
  295                                 IFAFREE(rt->rt_ifa);
  296                                 ifa->ifa_refcnt++;
  297                                 rt->rt_ifa = ifa;
  298                         }
  299                 }
  300                 break;
  301 
  302         case RTM_DELETE:
  303                 if (la == 0)
  304                         break;
  305                 arp_inuse--;
  306                 LIST_REMOVE(la, la_list);
  307                 rt->rt_llinfo = 0;
  308                 rt->rt_flags &= ~RTF_LLINFO;
  309                 if (la->la_hold)
  310                         m_freem(la->la_hold);
  311                 Free((caddr_t)la);
  312         }
  313 }
  314 
  315 /*
  316  * Broadcast an ARP request. Caller specifies:
  317  *      - arp header source ip address
  318  *      - arp header target ip address
  319  *      - arp header source ethernet address
  320  */
  321 void
  322 arprequest(ifp, sip, tip, enaddr)
  323         struct ifnet *ifp;
  324         u_int32_t *sip, *tip;
  325         u_int8_t *enaddr;
  326 {
  327         struct mbuf *m;
  328         struct ether_header *eh;
  329         struct ether_arp *ea;
  330         struct sockaddr sa;
  331 
  332         if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
  333                 return;
  334         m->m_len = sizeof(*ea);
  335         m->m_pkthdr.len = sizeof(*ea);
  336         MH_ALIGN(m, sizeof(*ea));
  337         ea = mtod(m, struct ether_arp *);
  338         eh = (struct ether_header *)sa.sa_data;
  339         bzero((caddr_t)ea, sizeof (*ea));
  340         bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  341             sizeof(eh->ether_dhost));
  342         eh->ether_type = htons(ETHERTYPE_ARP);  /* if_output will not swap */
  343         ea->arp_hrd = htons(ARPHRD_ETHER);
  344         ea->arp_pro = htons(ETHERTYPE_IP);
  345         ea->arp_hln = sizeof(ea->arp_sha);      /* hardware address length */
  346         ea->arp_pln = sizeof(ea->arp_spa);      /* protocol address length */
  347         ea->arp_op = htons(ARPOP_REQUEST);
  348         bcopy((caddr_t)enaddr, (caddr_t)eh->ether_shost,
  349               sizeof(eh->ether_shost));
  350         bcopy((caddr_t)enaddr, (caddr_t)ea->arp_sha, sizeof(ea->arp_sha));
  351         bcopy((caddr_t)sip, (caddr_t)ea->arp_spa, sizeof(ea->arp_spa));
  352         bcopy((caddr_t)tip, (caddr_t)ea->arp_tpa, sizeof(ea->arp_tpa));
  353         sa.sa_family = pseudo_AF_HDRCMPLT;
  354         sa.sa_len = sizeof(sa);
  355         (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
  356 }
  357 
  358 /*
  359  * Resolve an IP address into an ethernet address.  If success,
  360  * desten is filled in.  If there is no entry in arptab,
  361  * set one up and broadcast a request for the IP address.
  362  * Hold onto this mbuf and resend it once the address
  363  * is finally resolved.  A return value of 1 indicates
  364  * that desten has been filled in and the packet should be sent
  365  * normally; a 0 return indicates that the packet has been
  366  * taken over here, either now or for later transmission.
  367  */
  368 int
  369 arpresolve(ac, rt, m, dst, desten)
  370         struct arpcom *ac;
  371         struct rtentry *rt;
  372         struct mbuf *m;
  373         struct sockaddr *dst;
  374         u_char *desten;
  375 {
  376         struct llinfo_arp *la;
  377         struct sockaddr_dl *sdl;
  378 
  379         if (m->m_flags & M_BCAST) {     /* broadcast */
  380                 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
  381                     sizeof(etherbroadcastaddr));
  382                 return (1);
  383         }
  384         if (m->m_flags & M_MCAST) {     /* multicast */
  385                 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
  386                 return (1);
  387         }
  388         if (rt) {
  389                 la = (struct llinfo_arp *)rt->rt_llinfo;
  390                 if (la == NULL)
  391                         log(LOG_DEBUG, "arpresolve: %s: route without link "
  392                             "local address\n", inet_ntoa(SIN(dst)->sin_addr));
  393         } else {
  394                 if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL)
  395                         rt = la->la_rt;
  396                 else
  397                         log(LOG_DEBUG,
  398                             "arpresolve: %s: can't allocate llinfo\n",
  399                             inet_ntoa(SIN(dst)->sin_addr));
  400         }
  401         if (la == 0 || rt == 0) {
  402                 m_freem(m);
  403                 return (0);
  404         }
  405         sdl = SDL(rt->rt_gateway);
  406         /*
  407          * Check the address family and length is valid, the address
  408          * is resolved; otherwise, try to resolve.
  409          */
  410         if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
  411             sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
  412                 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
  413                 return 1;
  414         }
  415         if (((struct ifnet *)ac)->if_flags & IFF_NOARP)
  416                 return 0;
  417 
  418         /*
  419          * There is an arptab entry, but no ethernet address
  420          * response yet.  Replace the held mbuf with this
  421          * latest one.
  422          */
  423         if (la->la_hold)
  424                 m_freem(la->la_hold);
  425         la->la_hold = m;
  426         /*
  427          * Re-send the ARP request when appropriate.
  428          */
  429 #ifdef  DIAGNOSTIC
  430         if (rt->rt_expire == 0) {
  431                 /* This should never happen. (Should it? -gwr) */
  432                 printf("arpresolve: unresolved and rt_expire == 0\n");
  433                 /* Set expiration time to now (expired). */
  434                 rt->rt_expire = time_second;
  435         }
  436 #endif
  437         if (rt->rt_expire) {
  438                 rt->rt_flags &= ~RTF_REJECT;
  439                 if (la->la_asked == 0 || rt->rt_expire != time_second) {
  440                         rt->rt_expire = time_second;
  441                         if (la->la_asked++ < arp_maxtries)
  442                                 arprequest(&ac->ac_if,
  443                                     &(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
  444                                     &(SIN(dst)->sin_addr.s_addr),
  445 #if NCARP > 0
  446                                     (rt->rt_ifp->if_type == IFT_CARP) ?
  447                                         ((struct arpcom *) rt->rt_ifp->if_softc
  448                                         )->ac_enaddr :
  449 #endif
  450                                     ac->ac_enaddr);
  451                         else {
  452                                 rt->rt_flags |= RTF_REJECT;
  453                                 rt->rt_expire += arpt_down;
  454                                 la->la_asked = 0;
  455                         }
  456                 }
  457         }
  458         return (0);
  459 }
  460 
  461 /*
  462  * Common length and type checks are done here,
  463  * then the protocol-specific routine is called.
  464  */
  465 void
  466 arpintr()
  467 {
  468         struct mbuf *m;
  469         struct arphdr *ar;
  470         int s, len;
  471 
  472         while (arpintrq.ifq_head) {
  473                 s = splnet();
  474                 IF_DEQUEUE(&arpintrq, m);
  475                 splx(s);
  476                 if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
  477                         panic("arpintr");
  478 
  479                 len = sizeof(struct arphdr);
  480                 if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
  481                         continue;
  482 
  483                 ar = mtod(m, struct arphdr *);
  484                 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) {
  485                         m_freem(m);
  486                         continue;
  487                 }
  488 
  489                 len += 2 * (ar->ar_hln + ar->ar_pln);
  490                 if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
  491                         continue;
  492 
  493                 switch (ntohs(ar->ar_pro)) {
  494                 case ETHERTYPE_IP:
  495                 case ETHERTYPE_IPTRAILERS:
  496                         in_arpinput(m);
  497                         continue;
  498                 }
  499                 m_freem(m);
  500         }
  501 }
  502 
  503 /*
  504  * ARP for Internet protocols on Ethernet.
  505  * Algorithm is that given in RFC 826.
  506  * In addition, a sanity check is performed on the sender
  507  * protocol address, to catch impersonators.
  508  * We no longer handle negotiations for use of trailer protocol:
  509  * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
  510  * along with IP replies if we wanted trailers sent to us,
  511  * and also sent them in response to IP replies.
  512  * This allowed either end to announce the desire to receive
  513  * trailer packets.
  514  * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
  515  * but formerly didn't normally send requests.
  516  */
  517 void
  518 in_arpinput(m)
  519         struct mbuf *m;
  520 {
  521         struct ether_arp *ea;
  522         struct arpcom *ac = (struct arpcom *)m->m_pkthdr.rcvif;
  523         struct ether_header *eh;
  524         struct llinfo_arp *la = 0;
  525         struct rtentry *rt;
  526         struct in_ifaddr *ia;
  527 #if NBRIDGE > 0
  528         struct in_ifaddr *bridge_ia = NULL;
  529 #endif
  530 #if NCARP > 0
  531         u_int32_t count = 0, index = 0;
  532 #endif
  533         struct sockaddr_dl *sdl;
  534         struct sockaddr sa;
  535         struct in_addr isaddr, itaddr, myaddr;
  536         u_int8_t *enaddr = NULL;
  537         int op;
  538 
  539         ea = mtod(m, struct ether_arp *);
  540         op = ntohs(ea->arp_op);
  541         if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY))
  542                 goto out;
  543 #if notyet
  544         if ((op == ARPOP_REPLY) && (m->m_flags & (M_BCAST|M_MCAST))) {
  545                 log(LOG_ERR,
  546                     "arp: received reply to broadcast or multicast address\n");
  547                 goto out;
  548         }
  549 #endif
  550 
  551         bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof(itaddr));
  552         bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof(isaddr));
  553 
  554         TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
  555                 if (itaddr.s_addr != ia->ia_addr.sin_addr.s_addr)
  556                         continue;
  557 
  558 #if NCARP > 0
  559                 if (ia->ia_ifp->if_type == IFT_CARP &&
  560                     ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
  561                     (IFF_UP|IFF_RUNNING))) {
  562                         index++;
  563                         if (ia->ia_ifp == m->m_pkthdr.rcvif &&
  564                             carp_iamatch(ia, ea->arp_sha,
  565                             &count, index))
  566                                 break;
  567                 } else
  568 #endif
  569                         if (ia->ia_ifp == m->m_pkthdr.rcvif)
  570                                 break;
  571 #if NBRIDGE > 0
  572                 /*
  573                  * If the interface we received the packet on
  574                  * is part of a bridge, check to see if we need
  575                  * to "bridge" the packet to ourselves at this
  576                  * layer.  Note we still prefer a perfect match,
  577                  * but allow this weaker match if necessary.
  578                  */
  579                 if (m->m_pkthdr.rcvif->if_bridge != NULL) {
  580                         if (m->m_pkthdr.rcvif->if_bridge ==
  581                             ia->ia_ifp->if_bridge)
  582                                 bridge_ia = ia;
  583 #if NCARP > 0
  584                         else if (ia->ia_ifp->if_carpdev != NULL &&
  585                             m->m_pkthdr.rcvif->if_bridge ==
  586                             ia->ia_ifp->if_carpdev->if_bridge &&
  587                             carp_iamatch(ia, ea->arp_sha,
  588                             &count, index))
  589                                 bridge_ia = ia;
  590 #endif
  591                 }
  592 #endif
  593         }
  594 
  595 #if NBRIDGE > 0
  596         if (ia == NULL && bridge_ia != NULL) {
  597                 ia = bridge_ia;
  598                 ac = (struct arpcom *)bridge_ia->ia_ifp;
  599         }
  600 #endif
  601 
  602         if (ia == NULL) {
  603                 TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
  604                         if (isaddr.s_addr != ia->ia_addr.sin_addr.s_addr)
  605                                 continue;
  606                         if (ia->ia_ifp == m->m_pkthdr.rcvif)
  607                                 break;
  608                 }
  609         }
  610 
  611         if (ia == NULL && m->m_pkthdr.rcvif->if_type != IFT_CARP) {
  612                 struct ifaddr *ifa;
  613 
  614                 TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrlist, ifa_list) {
  615                         if (ifa->ifa_addr->sa_family == AF_INET)
  616                                 break;
  617                 }
  618                 if (ifa)
  619                         ia = (struct in_ifaddr *)ifa;
  620         }
  621 
  622         if (ia == NULL)
  623                 goto out;
  624 
  625         if (!enaddr)
  626                 enaddr = ac->ac_enaddr;
  627         myaddr = ia->ia_addr.sin_addr;
  628 
  629         if (!bcmp((caddr_t)ea->arp_sha, enaddr, sizeof (ea->arp_sha)))
  630                 goto out;       /* it's from me, ignore it. */
  631         if (ETHER_IS_MULTICAST (&ea->arp_sha[0]))
  632                 if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr,
  633                     sizeof (ea->arp_sha))) {
  634                         log(LOG_ERR, "arp: ether address is broadcast for "
  635                             "IP address %s!\n", inet_ntoa(isaddr));
  636                         goto out;
  637                 }
  638         if (myaddr.s_addr && isaddr.s_addr == myaddr.s_addr) {
  639                 log(LOG_ERR,
  640                    "duplicate IP address %s sent from ethernet address %s\n",
  641                    inet_ntoa(isaddr), ether_sprintf(ea->arp_sha));
  642                 itaddr = myaddr;
  643                 goto reply;
  644         }
  645         la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
  646         if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
  647                 if (sdl->sdl_alen) {
  648                     if (bcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
  649                         if (rt->rt_flags & RTF_PERMANENT_ARP) {
  650                                 log(LOG_WARNING,
  651                                    "arp: attempt to overwrite permanent "
  652                                    "entry for %s by %s on %s\n",
  653                                    inet_ntoa(isaddr),
  654                                    ether_sprintf(ea->arp_sha),
  655                                    ac->ac_if.if_xname);
  656                                 goto out;
  657                         } else if (rt->rt_ifp != &ac->ac_if) {
  658                                 log(LOG_WARNING,
  659                                    "arp: attempt to overwrite entry for %s "
  660                                    "on %s by %s on %s\n",
  661                                    inet_ntoa(isaddr), rt->rt_ifp->if_xname,
  662                                    ether_sprintf(ea->arp_sha),
  663                                    ac->ac_if.if_xname);
  664                                 goto out;
  665                         } else {
  666                                 log(LOG_INFO,
  667                                    "arp info overwritten for %s by %s on %s\n",
  668                                    inet_ntoa(isaddr),
  669                                    ether_sprintf(ea->arp_sha),
  670                                    ac->ac_if.if_xname);
  671                                 rt->rt_expire = 1; /* no longer static */
  672                         }
  673                     }
  674                 } else if (rt->rt_ifp != &ac->ac_if && !(ac->ac_if.if_bridge &&
  675                     (rt->rt_ifp->if_bridge == ac->ac_if.if_bridge)) &&
  676                     !(rt->rt_ifp->if_type == IFT_CARP &&
  677                     rt->rt_ifp->if_carpdev == &ac->ac_if) &&
  678                     !(ac->ac_if.if_type == IFT_CARP &&
  679                     ac->ac_if.if_carpdev == rt->rt_ifp)) {
  680                     log(LOG_WARNING,
  681                         "arp: attempt to add entry for %s "
  682                         "on %s by %s on %s\n",
  683                         inet_ntoa(isaddr), rt->rt_ifp->if_xname,
  684                         ether_sprintf(ea->arp_sha),
  685                         ac->ac_if.if_xname);
  686                     goto out;
  687                 }
  688                 bcopy(ea->arp_sha, LLADDR(sdl),
  689                     sdl->sdl_alen = sizeof(ea->arp_sha));
  690                 if (rt->rt_expire)
  691                         rt->rt_expire = time_second + arpt_keep;
  692                 rt->rt_flags &= ~RTF_REJECT;
  693                 la->la_asked = 0;
  694                 if (la->la_hold) {
  695                         (*ac->ac_if.if_output)(&ac->ac_if, la->la_hold,
  696                                 rt_key(rt), rt);
  697                         la->la_hold = 0;
  698                 }
  699         }
  700 reply:
  701         if (op != ARPOP_REQUEST) {
  702         out:
  703                 m_freem(m);
  704                 return;
  705         }
  706         if (itaddr.s_addr == myaddr.s_addr) {
  707                 /* I am the target */
  708                 bcopy(ea->arp_sha, ea->arp_tha, sizeof(ea->arp_sha));
  709                 bcopy(enaddr, ea->arp_sha, sizeof(ea->arp_sha));
  710         } else {
  711                 la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
  712                 if (la == 0)
  713                         goto out;
  714                 rt = la->la_rt;
  715                 if (rt->rt_ifp->if_type == IFT_CARP &&
  716                     m->m_pkthdr.rcvif->if_type != IFT_CARP)
  717                         goto out;
  718                 bcopy(ea->arp_sha, ea->arp_tha, sizeof(ea->arp_sha));
  719                 sdl = SDL(rt->rt_gateway);
  720                 bcopy(LLADDR(sdl), ea->arp_sha, sizeof(ea->arp_sha));
  721         }
  722 
  723         bcopy(ea->arp_spa, ea->arp_tpa, sizeof(ea->arp_spa));
  724         bcopy(&itaddr, ea->arp_spa, sizeof(ea->arp_spa));
  725         ea->arp_op = htons(ARPOP_REPLY);
  726         ea->arp_pro = htons(ETHERTYPE_IP); /* let's be sure! */
  727         eh = (struct ether_header *)sa.sa_data;
  728         bcopy(ea->arp_tha, eh->ether_dhost, sizeof(eh->ether_dhost));
  729 #if NCARP > 0
  730         if (ac->ac_if.if_type == IFT_CARP && ac->ac_if.if_flags & IFF_LINK1)
  731                 bcopy(((struct arpcom *)ac->ac_if.if_carpdev)->ac_enaddr,
  732                     eh->ether_shost, sizeof(eh->ether_shost));
  733         else
  734 #endif
  735                 bcopy(enaddr, eh->ether_shost, sizeof(eh->ether_shost));
  736 
  737         eh->ether_type = htons(ETHERTYPE_ARP);
  738         sa.sa_family = pseudo_AF_HDRCMPLT;
  739         sa.sa_len = sizeof(sa);
  740         (*ac->ac_if.if_output)(&ac->ac_if, m, &sa, (struct rtentry *)0);
  741         return;
  742 }
  743 
  744 /*
  745  * Free an arp entry.
  746  */
  747 void
  748 arptfree(la)
  749         struct llinfo_arp *la;
  750 {
  751         struct rtentry *rt = la->la_rt;
  752         struct sockaddr_dl *sdl;
  753 
  754         if (rt == 0)
  755                 panic("arptfree");
  756         if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
  757             sdl->sdl_family == AF_LINK) {
  758                 sdl->sdl_alen = 0;
  759                 la->la_asked = 0;
  760                 rt->rt_flags &= ~RTF_REJECT;
  761                 return;
  762         }
  763         rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0, rt_mask(rt),
  764             0, (struct rtentry **)0, 0);
  765 }
  766 
  767 /*
  768  * Lookup or enter a new address in arptab.
  769  */
  770 struct llinfo_arp *
  771 arplookup(addr, create, proxy)
  772         u_int32_t addr;
  773         int create, proxy;
  774 {
  775         struct rtentry *rt;
  776         static struct sockaddr_inarp sin;
  777 
  778         sin.sin_len = sizeof(sin);
  779         sin.sin_family = AF_INET;
  780         sin.sin_addr.s_addr = addr;
  781         sin.sin_other = proxy ? SIN_PROXY : 0;
  782         rt = rtalloc1(sintosa(&sin), create, 0);
  783         if (rt == 0)
  784                 return (0);
  785         rt->rt_refcnt--;
  786         if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
  787             rt->rt_gateway->sa_family != AF_LINK) {
  788                 if (create) {
  789                         if (rt->rt_refcnt <= 0 &&
  790                             (rt->rt_flags & RTF_CLONED) != 0) {
  791                                 rtrequest(RTM_DELETE,
  792                                     (struct sockaddr *)rt_key(rt),
  793                                     rt->rt_gateway, rt_mask(rt), rt->rt_flags,
  794                                     0, 0);
  795                         }
  796                 }
  797                 return (0);
  798         }
  799         return ((struct llinfo_arp *)rt->rt_llinfo);
  800 }
  801 
  802 int
  803 arpioctl(cmd, data)
  804         u_long cmd;
  805         caddr_t data;
  806 {
  807 
  808         return (EOPNOTSUPP);
  809 }
  810 
  811 void
  812 arp_ifinit(ac, ifa)
  813         struct arpcom *ac;
  814         struct ifaddr *ifa;
  815 {
  816 
  817         /* Warn the user if another station has this IP address. */
  818         arprequest(&ac->ac_if,
  819             &(IA_SIN(ifa)->sin_addr.s_addr),
  820             &(IA_SIN(ifa)->sin_addr.s_addr),
  821             ac->ac_enaddr);
  822         ifa->ifa_rtrequest = arp_rtrequest;
  823         ifa->ifa_flags |= RTF_CLONING;
  824 }
  825 
  826 /*
  827  * Called from Ethernet interrupt handlers
  828  * when ether packet type ETHERTYPE_REVARP
  829  * is received.  Common length and type checks are done here,
  830  * then the protocol-specific routine is called.
  831  */
  832 void
  833 revarpinput(m)
  834         struct mbuf *m;
  835 {
  836         struct arphdr *ar;
  837 
  838         if (m->m_len < sizeof(struct arphdr))
  839                 goto out;
  840         ar = mtod(m, struct arphdr *);
  841         if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
  842                 goto out;
  843         if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
  844                 goto out;
  845         switch (ntohs(ar->ar_pro)) {
  846 
  847         case ETHERTYPE_IP:
  848         case ETHERTYPE_IPTRAILERS:
  849                 in_revarpinput(m);
  850                 return;
  851 
  852         default:
  853                 break;
  854         }
  855 out:
  856         m_freem(m);
  857 }
  858 
  859 /*
  860  * RARP for Internet protocols on Ethernet.
  861  * Algorithm is that given in RFC 903.
  862  * We are only using for bootstrap purposes to get an ip address for one of
  863  * our interfaces.  Thus we support no user-interface.
  864  *
  865  * Since the contents of the RARP reply are specific to the interface that
  866  * sent the request, this code must ensure that they are properly associated.
  867  *
  868  * Note: also supports ARP via RARP packets, per the RFC.
  869  */
  870 void
  871 in_revarpinput(m)
  872         struct mbuf *m;
  873 {
  874         struct ifnet *ifp;
  875         struct ether_arp *ar;
  876         int op;
  877 
  878         ar = mtod(m, struct ether_arp *);
  879         op = ntohs(ar->arp_op);
  880         switch (op) {
  881         case ARPOP_REQUEST:
  882         case ARPOP_REPLY:       /* per RFC */
  883                 in_arpinput(m);
  884                 return;
  885         case ARPOP_REVREPLY:
  886                 break;
  887         case ARPOP_REVREQUEST:  /* handled by rarpd(8) */
  888         default:
  889                 goto out;
  890         }
  891         if (!revarp_in_progress)
  892                 goto out;
  893         ifp = m->m_pkthdr.rcvif;
  894         if (ifp != myip_ifp) /* !same interface */
  895                 goto out;
  896         if (myip_initialized)
  897                 goto wake;
  898         if (bcmp(ar->arp_tha, ((struct arpcom *)ifp)->ac_enaddr,
  899             sizeof(ar->arp_tha)))
  900                 goto out;
  901         bcopy((caddr_t)ar->arp_spa, (caddr_t)&srv_ip, sizeof(srv_ip));
  902         bcopy((caddr_t)ar->arp_tpa, (caddr_t)&myip, sizeof(myip));
  903         myip_initialized = 1;
  904 wake:   /* Do wakeup every time in case it was missed. */
  905         wakeup((caddr_t)&myip);
  906 
  907 out:
  908         m_freem(m);
  909 }
  910 
  911 /*
  912  * Send a RARP request for the ip address of the specified interface.
  913  * The request should be RFC 903-compliant.
  914  */
  915 void
  916 revarprequest(ifp)
  917         struct ifnet *ifp;
  918 {
  919         struct sockaddr sa;
  920         struct mbuf *m;
  921         struct ether_header *eh;
  922         struct ether_arp *ea;
  923         struct arpcom *ac = (struct arpcom *)ifp;
  924 
  925         if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
  926                 return;
  927         m->m_len = sizeof(*ea);
  928         m->m_pkthdr.len = sizeof(*ea);
  929         MH_ALIGN(m, sizeof(*ea));
  930         ea = mtod(m, struct ether_arp *);
  931         eh = (struct ether_header *)sa.sa_data;
  932         bzero((caddr_t)ea, sizeof(*ea));
  933         bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  934             sizeof(eh->ether_dhost));
  935         eh->ether_type = htons(ETHERTYPE_REVARP);
  936         ea->arp_hrd = htons(ARPHRD_ETHER);
  937         ea->arp_pro = htons(ETHERTYPE_IP);
  938         ea->arp_hln = sizeof(ea->arp_sha);      /* hardware address length */
  939         ea->arp_pln = sizeof(ea->arp_spa);      /* protocol address length */
  940         ea->arp_op = htons(ARPOP_REVREQUEST);
  941         bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
  942            sizeof(ea->arp_tha));
  943         bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
  944            sizeof(ea->arp_sha));
  945         bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_tha,
  946            sizeof(ea->arp_tha));
  947         sa.sa_family = pseudo_AF_HDRCMPLT;
  948         sa.sa_len = sizeof(sa);
  949         ifp->if_output(ifp, m, &sa, (struct rtentry *)0);
  950 }
  951 
  952 /*
  953  * RARP for the ip address of the specified interface, but also
  954  * save the ip address of the server that sent the answer.
  955  * Timeout if no response is received.
  956  */
  957 int
  958 revarpwhoarewe(ifp, serv_in, clnt_in)
  959         struct ifnet *ifp;
  960         struct in_addr *serv_in;
  961         struct in_addr *clnt_in;
  962 {
  963         int result, count = 20;
  964 
  965         if (myip_initialized)
  966                 return EIO;
  967 
  968         myip_ifp = ifp;
  969         revarp_in_progress = 1;
  970         while (count--) {
  971                 revarprequest(ifp);
  972                 result = tsleep((caddr_t)&myip, PSOCK, "revarp", hz/2);
  973                 if (result != EWOULDBLOCK)
  974                         break;
  975         }
  976         revarp_in_progress = 0;
  977         if (!myip_initialized)
  978                 return ENETUNREACH;
  979 
  980         bcopy((caddr_t)&srv_ip, serv_in, sizeof(*serv_in));
  981         bcopy((caddr_t)&myip, clnt_in, sizeof(*clnt_in));
  982         return 0;
  983 }
  984 
  985 /* For compatibility: only saves interface address. */
  986 int
  987 revarpwhoami(in, ifp)
  988         struct in_addr *in;
  989         struct ifnet *ifp;
  990 {
  991         struct in_addr server;
  992         return (revarpwhoarewe(ifp, &server, in));
  993 }
  994 
  995 
  996 #ifdef DDB
  997 
  998 #include <machine/db_machdep.h>
  999 #include <ddb/db_interface.h>
 1000 #include <ddb/db_output.h>
 1001 
 1002 void
 1003 db_print_sa(sa)
 1004         struct sockaddr *sa;
 1005 {
 1006         int len;
 1007         u_char *p;
 1008 
 1009         if (sa == 0) {
 1010                 db_printf("[NULL]");
 1011                 return;
 1012         }
 1013 
 1014         p = (u_char *)sa;
 1015         len = sa->sa_len;
 1016         db_printf("[");
 1017         while (len > 0) {
 1018                 db_printf("%d", *p);
 1019                 p++;
 1020                 len--;
 1021                 if (len)
 1022                         db_printf(",");
 1023         }
 1024         db_printf("]\n");
 1025 }
 1026 
 1027 void
 1028 db_print_ifa(ifa)
 1029         struct ifaddr *ifa;
 1030 {
 1031         if (ifa == 0)
 1032                 return;
 1033         db_printf("  ifa_addr=");
 1034         db_print_sa(ifa->ifa_addr);
 1035         db_printf("  ifa_dsta=");
 1036         db_print_sa(ifa->ifa_dstaddr);
 1037         db_printf("  ifa_mask=");
 1038         db_print_sa(ifa->ifa_netmask);
 1039         db_printf("  flags=0x%x, refcnt=%d, metric=%d\n",
 1040             ifa->ifa_flags, ifa->ifa_refcnt, ifa->ifa_metric);
 1041 }
 1042 
 1043 void
 1044 db_print_llinfo(li)
 1045         caddr_t li;
 1046 {
 1047         struct llinfo_arp *la;
 1048 
 1049         if (li == 0)
 1050                 return;
 1051         la = (struct llinfo_arp *)li;
 1052         db_printf("  la_rt=%p la_hold=%p, la_asked=0x%lx\n",
 1053             la->la_rt, la->la_hold, la->la_asked);
 1054 }
 1055 
 1056 /*
 1057  * Function to pass to rn_walktree().
 1058  * Return non-zero error to abort walk.
 1059  */
 1060 int
 1061 db_show_radix_node(rn, w)
 1062         struct radix_node *rn;
 1063         void *w;
 1064 {
 1065         struct rtentry *rt = (struct rtentry *)rn;
 1066 
 1067         db_printf("rtentry=%p", rt);
 1068 
 1069         db_printf(" flags=0x%x refcnt=%d use=%ld expire=%ld\n",
 1070             rt->rt_flags, rt->rt_refcnt, rt->rt_use, rt->rt_expire);
 1071 
 1072         db_printf(" key="); db_print_sa(rt_key(rt));
 1073         db_printf(" mask="); db_print_sa(rt_mask(rt));
 1074         db_printf(" gw="); db_print_sa(rt->rt_gateway);
 1075 
 1076         db_printf(" ifp=%p ", rt->rt_ifp);
 1077         if (rt->rt_ifp)
 1078                 db_printf("(%s)", rt->rt_ifp->if_xname);
 1079         else
 1080                 db_printf("(NULL)");
 1081 
 1082         db_printf(" ifa=%p\n", rt->rt_ifa);
 1083         db_print_ifa(rt->rt_ifa);
 1084 
 1085         db_printf(" genmask="); db_print_sa(rt->rt_genmask);
 1086 
 1087         db_printf(" gwroute=%p llinfo=%p\n", rt->rt_gwroute, rt->rt_llinfo);
 1088         db_print_llinfo(rt->rt_llinfo);
 1089         return (0);
 1090 }
 1091 
 1092 /*
 1093  * Function to print all the route trees.
 1094  * Use this from ddb:  "call db_show_arptab"
 1095  */
 1096 int
 1097 db_show_arptab()
 1098 {
 1099         struct radix_node_head *rnh;
 1100         rnh = rt_gettable(AF_INET, 0);
 1101         db_printf("Route tree for AF_INET\n");
 1102         if (rnh == NULL) {
 1103                 db_printf(" (not initialized)\n");
 1104                 return (0);
 1105         }
 1106         rn_walktree(rnh, db_show_radix_node, NULL);
 1107         return (0);
 1108 }
 1109 #endif
 1110 #endif /* INET */

/* [<][>][^][v][top][bottom][index][help] */