ifLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:46k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ifLib.c - network interface library */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 03h,10may02,kbw  making man page edits
  8. 03g,09may02,wsl  fix doc formatting error
  9. 03f,08jan02,vvv  fixed ifRouteDelete to use correct netmask (SPR #33381)
  10. 03e,07dec01,rae  merge from synth ver 03r (SPR #70269)
  11. 03d,05nov01,vvv  fixed compilation warning
  12. 03c,15oct01,rae  merge from truestack ver 03p, base 03b (ROUTER_STACK)
  13. 03b,12mar99,c_c  Doc: updated ifAddrGet, ifFlagSet() and ifDeleRoute 
  14. (SPRs #21401, 9146 and 21076).
  15. 03a,06oct98,ham  changed API for ifAddrAdd() (SPR22267)
  16. 02a,19mar98,spm  fixed byte ordering in ifRouteDelete() routine; changed to 
  17.                  use mRouteDelete() to support classless routing (SPR #20548)
  18. 01z,16apr97,vin  changed SOCK_DGRAM to SOCK_RAW as udp can be scaled out.
  19.  fixed ifRouteDelete().
  20. 01y,16oct96,dgp  doc: add explanations to ifFlagsSet per SPR 7337
  21. 01x,11jul94,dzb  Fixed setting of errno in ifIoctlCall() (SPR #3188).
  22.                  Fixed ntohl transfer in ifMaskGet() (SPR #3334).
  23. 01w,19oct92,jmm  added ntohl () to ifMaskGet() to make it symetrical w/ifMaskSet
  24. 01v,02sep93,elh  changed ifunit back to berkeley orig to fix spr (1516).
  25. 01u,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h
  26. 01t,05feb93,jag  Changed call to inet_ntoa to inet_ntoa_b in ifInetAddrToStr,
  27.  changed ifRouteDelete accordingly SPR# 1814
  28. 01s,20jan93,jdi  documentation cleanup for 5.1.
  29. 01r,18jul92,smb  Changed errno.h to errnoLib.h.
  30. 01q,26may92,rrr  the tree shuffle
  31.   -changed includes to have absolute path from h/
  32. 01p,10dec91,gae  added includes for ANSI.
  33. 01o,04oct91,rrr  passed through the ansification filter
  34.                   -changed functions to ansi style
  35.   -changed includes to have absolute path from h/
  36.   -fixed #else and #endif
  37.   -changed copyright notice
  38. 01n,01may91,elh  added htonl to ifMaskSet because network wants mask
  39.                  to be in network byte order.
  40. 01m,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  41.    +elh  added ifunit() from if.c (elh); doc review by dnw.
  42. 01l,18jan91,jaa  documentation.
  43. 01k,26jun90,hjb  moved ifShow, etc. to netShow.c.
  44. 01j,18mar90,hjb  de-linted.  minor syntax cleanup.
  45. 01i,14mar90,jdi  documentation cleanup.
  46. 01h,07aug89,gae  undid 01e -- fixed if_bp.c.
  47. 01g,03aug89,hjb  fixed ifShow to work with "bp" interfaces which
  48.                  use incompatible "ifp->if_name" convention (unit number is
  49.                  for some reason appended to the if_name itself?).
  50. 01f,30jul89,gae  removed varargs stuff; internal name changes.
  51.  documentation tweaks.  lint.
  52. 01e,28jul89,hjb  added routines ifAddrGet, ifBroadcastGet, ifDstAddrGet,
  53.                  ifAddrParamGet, ifMaskGet, ifFlagChange, ifFlagGet,
  54.  ifMetricSet, ifMetricGet, ifIoctl, ifSetIoctl, ifGetIoctl,
  55.  ifIoctlCall, and modified ifEtherPrint.
  56. 01d,27jul89,hjb  added routines ifShow, ifFlagSet, ifDstAddrSet, ifAddrPrint,
  57.  ifFlagPrint, ifEtherPrint, ifRouteDelete.
  58. 01c,18aug88,gae  documentation.
  59. 01b,30may88,dnw  changed to v4 names.
  60. 01a,28may88,dnw  extracted from netLib.
  61. */
  62. /*
  63. DESCRIPTION
  64. This library contains routines to configure the network interface parameters.
  65. Generally, each routine corresponds to one of the functions of the UNIX
  66. command f3ifconfigfP.
  67. To use this feature, include the following component:
  68. INCLUDE_NETWRS_IFLIB
  69. INCLUDE FILES: ifLib.h
  70. SEE ALSO: hostLib
  71. */
  72. #include "vxWorks.h"
  73. #include "stdio.h"
  74. #include "netinet/in.h"
  75. #include "net/if.h"
  76. #include "netinet/if_ether.h"
  77. #include "sys/ioctl.h"
  78. #include "ioLib.h"
  79. #include "inetLib.h"
  80. #include "string.h"
  81. #include "netinet/in_var.h"
  82. #include "errnoLib.h"
  83. #include "sockLib.h"
  84. #include "hostLib.h"
  85. #include "routeLib.h"
  86. #include "unistd.h"
  87. #include "ifLib.h"
  88. #include "m2Lib.h"
  89. #include "arpLib.h"
  90. #include "routeEnhLib.h"
  91. #ifdef DEBUG
  92. #include "logLib.h"
  93. #endif
  94. #ifdef VIRTUAL_STACK
  95. #include "netinet/vsLib.h"
  96. #include "netinet/vsRadix.h"  /* for rt_tables definition */
  97. #include "netinet/vsIp.h"  /* for _in_ifaddr definition */
  98. #endif /* VIRTUAL_STACK */
  99. /*
  100.  * macro to convert interface address into character string representation.
  101.  * The return value is a_ip_addr.
  102.  */
  103. #define ifInetAddrToStr(ifAddr,a_ip_addr) 
  104. ((inet_ntoa_b(((struct sockaddr_in *)(ifAddr))->sin_addr,a_ip_addr)),a_ip_addr)
  105. #define RT_ARP          0x100                   /* arp route entry */
  106. /*
  107.  * Imported global variables
  108.  */
  109. #ifndef VIRTUAL_STACK
  110. IMPORT struct ifnet  *ifnet; /* global pointer to all interfaces */
  111. IMPORT struct in_ifaddr  *in_ifaddr; /* global pointer to addresses */
  112. #endif /* VIRTUAL_STACK */
  113. IMPORT STATUS _arpCmd (int, struct in_addr *, u_char *, int *);
  114. /* forward static functions */
  115. static STATUS ifAddrParamGet (char *interfaceName, int code, char *address);
  116. static STATUS ifIoctl (char *interfaceName, int code, int arg);
  117. static STATUS ifIoctlSet (char *interfaceName, int code, int val);
  118. static STATUS ifIoctlGet (char *interfaceName, int code, int *val);
  119. static STATUS ifIoctlCall (int code, struct ifreq *ifrp);
  120. LOCAL int routeNodeDelete ();
  121. LOCAL int _routeNodeDelete (struct rtentry * pRt, int * pDeleted);
  122. /*******************************************************************************
  123. *
  124. * ifUnnumberedSet - configure an interface to be unnumbered
  125. *
  126. * This API sets an interface unnumbered. It sets the IFF_POINTOPOINT flags
  127. * and creates a routing entry through the interface using a user-specified
  128. * destination IP address. The unnumbered link can then be uniquely referred
  129. * to by the destination IP address, <pDstIp>, when adding routes. The
  130. * interface is assigned a "borrowed" IP address--borrowed from another
  131. * interface on the machine. In RFC 1812 it is also called the router ID.
  132. * This address will be used to generate any needed ICMP messages or the like.
  133. * Note that ARP is not able to run on an unnumbered link.
  134. * The initialization of the unnumbered device is similar to other
  135. * network devices, but it does have a few additional steps and concerns.
  136. * ifUnnumberedSet() must come next after ipAttach(). Please note that
  137. * the interface using the IP address that the unnumbered interface will
  138. * borrow must be brought up first and configured with <ifAddrSet> or 
  139. * equivalent. This is required to ensure normal network operation for
  140. * that IP address/interface.  After ifUnnumberedSet(), one must create
  141. * additional routing entries (using mRouteAdd(), routeNetAdd(), etc)
  142. * in order to reach other networks, including the network to which
  143. * the destination IP address belongs. 
  144. * The <pDstMac> field in ifUnnumberedSet() is used to specify the
  145. * destination's MAC address. It should be left NULL if the destination
  146. * is not an Ethernet device. If the MAC address is not known, then
  147. * supply an artificial address. We recommend using "00:00:00:00:00:01"
  148. * The destination interface can then be set promiscuous to accept
  149. * this artificial address. This is accomplished using the <ifpromisc>
  150. * command.
  151. *
  152. * Example:
  153. * ss
  154. * ipAttach (1, "fei")
  155. * ifUnnumberedSet ("fei1", "120.12.12.12", "140.34.78.94", "00:a0:d0:d8:c8:14")
  156. * routeNetAdd ("120.12.0.0","120.12.12.12") <One possible network>
  157. * routeNetAdd ("178.45.0.0","120.12.12.12") <Another possible network>
  158. * se
  159. * RETURNS: OK, or ERROR if the interface cannot be set.
  160. *
  161. */
  162. #ifdef ROUTER_STACK
  163. STATUS ifUnnumberedSet
  164.     (
  165.     char *pIfName, /* Name of interface to configure */ 
  166.     char *pDstIp,  /* Destination address of the point to point link */
  167.     char *pBorrowedIp, /* The borrowed IP address/router ID */
  168.     char *pDstMac /* Destination MAC address */
  169.     )
  170.     {
  171.     int s, ret;
  172.     struct ifnet *ifp;
  173.     struct sockaddr_in sock;
  174.     if(!(ifp = ifunit (pIfName)))
  175. return (ERROR);
  176.     /*
  177.      * Make sure that the interface with the "real"
  178.      * pBorrowedIp is already brought up.
  179.      */
  180.     bzero ((char *)&sock, sizeof (struct sockaddr_in));
  181.     sock.sin_family = AF_INET;
  182.     sock.sin_len = sizeof (struct sockaddr_in);
  183.     sock.sin_addr.s_addr = inet_addr (pBorrowedIp);
  184.     if (!ifa_ifwithaddr ((struct sockaddr *)&sock))
  185.         return (EINVAL); 
  186.     /* We manually configure the interface to be IFF_UNNUMBERED */
  187.     s = splnet ();
  188.     ifp->if_flags &= ~IFF_BROADCAST;
  189.     ifp->if_flags |= IFF_UNNUMBERED; /* It's defined as IFF_POINTOPOINT */
  190.     splx (s);
  191.     ret = ifAddrAdd (pIfName, pBorrowedIp, pDstIp, 0);
  192.     if (ret != OK)
  193. return (ret);
  194.     /*
  195.      * For ethernet devices, we need to complete the route entry
  196.      * just created by the above operation. The ATF_INCOMPLETE flag
  197.      * will change the routing entry to contain the MAC address
  198.      * of the destination's ethernet device.
  199.      */
  200.     if (pDstMac != (char *)NULL)
  201.         ret = arpAdd (pDstIp, pDstMac, ATF_PERM | ATF_INCOMPLETE);
  202.     return (ret);
  203.     }
  204. #endif /* ROUTER_STACK */
  205. /*******************************************************************************
  206. *
  207. * ifAddrAdd - add an interface address for a network interface
  208. *
  209. * This routine assigns an Internet address to a specified network interface.
  210. * The Internet address can be a host name or a standard Internet address
  211. * format (e.g., 90.0.0.4).  If a host name is specified, it should already
  212. * have been added to the host table with hostAdd().
  213. *
  214. * You must specify both an <interfaceName> and an <interfaceAddress>. A 
  215. * <broadcastAddress> is optional. If <broadcastAddress> is NULL, in_ifinit() 
  216. * generates a <broadcastAddress> value based on the <interfaceAddress> value
  217. * and the netmask.  A <subnetMask> value is optional.  If <subnetMask> is 0, 
  218. * in_ifinit() uses a <subnetMask> the same as the netmask that is generated 
  219. * by the <interfaceAddress>.  The <broadcastAddress> is also <destAddress> in 
  220. * case of IFF_POINTOPOINT.
  221. *
  222. * RETURNS: OK, or ERROR if the interface cannot be set.
  223. *
  224. * SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet()
  225. */
  226. STATUS ifAddrAdd
  227.     (
  228.     char *interfaceName,     /* name of interface to configure */
  229.     char *interfaceAddress,  /* Internet address to assign to interface */
  230.     char *broadcastAddress,  /* broadcast address to assign to interface */
  231.     int   subnetMask         /* subnetMask */
  232.     )
  233.     {
  234.     struct ifaliasreq   ifa;
  235.     struct sockaddr_in *pSin_iaddr = (struct sockaddr_in *)&ifa.ifra_addr;
  236.     struct sockaddr_in *pSin_baddr = (struct sockaddr_in *)&ifa.ifra_broadaddr;
  237.     struct sockaddr_in *pSin_snmsk = (struct sockaddr_in *)&ifa.ifra_mask;
  238.     int                 so;
  239.     int                 status = 0;
  240.     bzero ((caddr_t) &ifa, sizeof (ifa));
  241.     /* verify Internet address is in correct format */
  242.     if ((pSin_iaddr->sin_addr.s_addr =
  243.              inet_addr (interfaceAddress)) == ERROR &&
  244.         (pSin_iaddr->sin_addr.s_addr =
  245.              hostGetByName (interfaceAddress) == ERROR))
  246.         {
  247.         return (ERROR);
  248.         }
  249.     /* verify Boradcast address is in correct format */
  250.     if (broadcastAddress != NULL &&
  251.         (pSin_baddr->sin_addr.s_addr =
  252.              inet_addr (broadcastAddress)) == ERROR &&
  253.         (pSin_baddr->sin_addr.s_addr =
  254.              hostGetByName (broadcastAddress) == ERROR))
  255.         {
  256.         return (ERROR);
  257.         }
  258.     strncpy (ifa.ifra_name, interfaceName, sizeof (ifa.ifra_name));
  259.     /* for interfaceAddress */
  260.     ifa.ifra_addr.sa_len = sizeof (struct sockaddr_in);
  261.     ifa.ifra_addr.sa_family = AF_INET;
  262.     /* for broadcastAddress */
  263.     if (broadcastAddress != NULL)
  264.         {
  265.         ifa.ifra_broadaddr.sa_len = sizeof (struct sockaddr_in);
  266.         ifa.ifra_broadaddr.sa_family = AF_INET;
  267.         }
  268.     /* for subnetmask */
  269.     if (subnetMask != 0)
  270.        {
  271.        ifa.ifra_mask.sa_len = sizeof (struct sockaddr_in);
  272.        ifa.ifra_mask.sa_family = AF_INET;
  273.        pSin_snmsk->sin_addr.s_addr = htonl (subnetMask);
  274.        }
  275.     if ((so = socket (AF_INET, SOCK_RAW, 0)) < 0)
  276.         return (ERROR);
  277.     status = ioctl (so, SIOCAIFADDR, (int)&ifa);
  278.     (void)close (so);
  279.     if (status != 0)
  280.         {
  281.         if (status != ERROR)    /* iosIoctl() can return ERROR */
  282.             (void)errnoSet (status);
  283.         return (ERROR);
  284.         }
  285.     return (OK);
  286.     }
  287. /*******************************************************************************
  288. *
  289. * ifAddrSet - set an interface address for a network interface
  290. *
  291. * This routine assigns an Internet address to a specified network interface.
  292. * The Internet address can be a host name or a standard Internet address
  293. * format (e.g., 90.0.0.4).  If a host name is specified, it should already
  294. * have been added to the host table with hostAdd().
  295. *
  296. * A successful call to ifAddrSet() results in the addition of a new route.
  297. *
  298. * The subnet mask used in determining the network portion of the address will
  299. * be that set by ifMaskSet(), or the default class mask if ifMaskSet() has not
  300. * been called.  It is standard practice to call ifMaskSet() prior to calling
  301. * ifAddrSet().
  302. *
  303. * RETURNS: OK, or ERROR if the interface cannot be set.
  304. *
  305. * SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet()
  306. */
  307. STATUS ifAddrSet
  308.     (
  309.     char *interfaceName,        /* name of interface to configure, i.e. ei0 */
  310.     char *interfaceAddress      /* Internet address to assign to interface */
  311.     )
  312.     {
  313.     return (ifIoctl (interfaceName, SIOCSIFADDR, (int)interfaceAddress));
  314.     }
  315. /*******************************************************************************
  316. *
  317. * ifAddrDelete - delete an interface address for a network interface
  318. *
  319. * This routine deletes an Internet address from a specified network interface.
  320. * The Internet address can be a host name or a standard Internet address
  321. * format (e.g., 90.0.0.4).  If a host name is specified, it should already
  322. * have been added to the host table with hostAdd().
  323. *
  324. * RETURNS: OK, or ERROR if the interface cannot be deleted.
  325. *
  326. * SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet()
  327. */
  328. STATUS ifAddrDelete
  329.     (
  330.     char *interfaceName,        /* name of interface to delete addr from */
  331.     char *interfaceAddress      /* Internet address to delete from interface */
  332.     )
  333.     {
  334.     return (ifIoctl (interfaceName, SIOCDIFADDR, (int) interfaceAddress));
  335.     }
  336. /*******************************************************************************
  337. *
  338. * ifAddrGet - get the Internet address of a network interface
  339. *
  340. * This routine gets the Internet address of a specified network interface and
  341. * copies it to <interfaceAddress>. This pointer should point to a buffer
  342. * large enough to contain INET_ADDR_LEN bytes.
  343. *
  344. * RETURNS: OK or ERROR.
  345. *
  346. * SEE ALSO: ifAddrSet(), ifDstAddrSet(), ifDstAddrGet()
  347. */
  348. STATUS ifAddrGet
  349.     (
  350.     char *interfaceName,        /* name of interface, i.e. ei0 */
  351.     char *interfaceAddress      /* buffer for Internet address */
  352.     )
  353.     {
  354.     return (ifAddrParamGet (interfaceName, SIOCGIFADDR, interfaceAddress));
  355.     }
  356. /*******************************************************************************
  357. *
  358. * ifBroadcastSet - set the broadcast address for a network interface
  359. *
  360. * This routine assigns a broadcast address for the specified network interface.
  361. * The broadcast address must be a string in standard Internet address format
  362. * (e.g., 90.0.0.0).
  363. *
  364. * An interface's default broadcast address is its Internet address with a
  365. * host part of all ones (e.g., 90.255.255.255).  This conforms to current
  366. * ARPA specifications.  However, some older systems use an Internet address
  367. * with a host part of all zeros as the broadcast address.
  368. *
  369. * NOTE
  370. * VxWorks automatically accepts a host part of all zeros as a broadcast
  371. * address, in addition to the default or specified broadcast address.  But
  372. * if VxWorks is to broadcast to older systems using a host part of all zeros
  373. * as the broadcast address, this routine should be used to change the
  374. * broadcast address of the interface.
  375. *
  376. * RETURNS: OK or ERROR.
  377. */
  378. STATUS ifBroadcastSet
  379.     (
  380.     char *interfaceName,        /* name of interface to assign, i.e. ei0 */
  381.     char *broadcastAddress      /* broadcast address to assign to interface */
  382.     )
  383.     {
  384.     return (ifIoctl (interfaceName, SIOCSIFBRDADDR, (int)broadcastAddress));
  385.     }
  386. /*******************************************************************************
  387. *
  388. * ifBroadcastGet - get the broadcast address for a network interface
  389. *
  390. * This routine gets the broadcast address for a specified network interface.
  391. * The broadcast address is copied to the buffer <broadcastAddress>.
  392. *
  393. * RETURNS: OK or ERROR.
  394. *
  395. * SEE ALSO: ifBroadcastSet()
  396. */
  397. STATUS ifBroadcastGet
  398.     (
  399.     char *interfaceName,        /* name of interface, i.e. ei0 */
  400.     char *broadcastAddress      /* buffer for broadcast address */
  401.     )
  402.     {
  403.     return (ifAddrParamGet (interfaceName, SIOCGIFBRDADDR, broadcastAddress));
  404.     }
  405. /*******************************************************************************
  406. *
  407. * ifDstAddrSet - define an address for the other end of a point-to-point link
  408. *
  409. * This routine assigns the Internet address of a machine connected to the
  410. * opposite end of a point-to-point network connection, such as a SLIP
  411. * connection.  Inherently, point-to-point connection-oriented protocols such as
  412. * SLIP require that addresses for both ends of a connection be specified.
  413. *
  414. * RETURNS: OK or ERROR.
  415. *
  416. * SEE ALSO: ifAddrSet(), ifDstAddrGet()
  417. */
  418. STATUS ifDstAddrSet
  419.     (
  420.     char *interfaceName,        /* name of interface to configure, i.e. ei0 */
  421.     char *dstAddress            /* Internet address to assign to destination */
  422.     )
  423.     {
  424.     return (ifIoctl (interfaceName, SIOCSIFDSTADDR, (int)dstAddress));
  425.     }
  426. /*******************************************************************************
  427. *
  428. * ifDstAddrGet - get the Internet address of a point-to-point peer
  429. *
  430. * This routine gets the Internet address of a machine connected to the
  431. * opposite end of a point-to-point network connection.  The Internet address is
  432. * copied to the buffer <dstAddress>.
  433. *
  434. * RETURNS: OK or ERROR.
  435. *
  436. * SEE ALSO: ifDstAddrSet(), ifAddrGet()
  437. */
  438. STATUS ifDstAddrGet
  439.     (
  440.     char *interfaceName,        /* name of interface, i.e. ei0 */
  441.     char *dstAddress            /* buffer for destination address */
  442.     )
  443.     {
  444.     return (ifAddrParamGet (interfaceName, SIOCGIFDSTADDR, dstAddress));
  445.     }
  446. /*******************************************************************************
  447. *
  448. * ifAddrParamGet - call ifIoctl to get the Internet address of the interface
  449. *
  450. * ifAddrParamGet may be used to retrieve Internet address of the network
  451. * interface in ASCII character string representation (dot-notation
  452. * like "192.0.0.3").
  453. *
  454. * RETURNS: OK or ERROR
  455. *
  456. * ERRNO: EINVAL
  457. *
  458. * SEE ALSO: ifAddrGet (), ifDstAddrGet (), ifBroadcastGet ()
  459. */
  460. LOCAL STATUS ifAddrParamGet
  461.     (
  462.     char *interfaceName,        /* name of interface to configure, i.e. ei0 */
  463.     int   code,                 /* SIOCG ioctl code */
  464.     char *address               /* address retrieved here */
  465.     )
  466.     {
  467.     struct in_addr inetAddrBuf; /* result */
  468.     char netString [INET_ADDR_LEN];
  469.     if (address == NULL)
  470. {
  471. (void)errnoSet (EINVAL);
  472. return (ERROR);
  473. }
  474.     if (ifIoctl (interfaceName, code, (int)&inetAddrBuf) == OK)
  475. {
  476. inet_ntoa_b (inetAddrBuf, netString);
  477. strncpy (address, netString, INET_ADDR_LEN);
  478. return (OK);
  479. }
  480.     return (ERROR);
  481.     }
  482. /*******************************************************************************
  483. *
  484. * ifMaskSet - define a subnet for a network interface
  485. *
  486. * This routine allocates additional bits to the network portion of an
  487. * Internet address.  The network portion is specified with a mask that must
  488. * contain ones in all positions that are to be interpreted as the network
  489. * portion.  This includes all the bits that are normally interpreted as the
  490. * network portion for the given class of address, plus the bits to be added.
  491. * Note that all bits must be contiguous.  The mask is specified in host byte
  492. * order.
  493. *
  494. * In order to correctly interpret the address, a subnet mask should be set
  495. * for an interface prior to setting the Internet address of the interface
  496. * with the routine ifAddrSet().
  497. *
  498. * RETURNS: OK or ERROR.
  499. *
  500. * SEE ALSO: ifAddrSet()
  501. */
  502. STATUS ifMaskSet
  503.     (
  504.     char *interfaceName,   /* name of interface to set mask for, i.e. ei0 */
  505.     int netMask            /* subnet mask (e.g. 0xff000000) */
  506.     )
  507.     {
  508.     return (ifIoctl (interfaceName, SIOCSIFNETMASK, htonl (netMask)));
  509.     }
  510. /*******************************************************************************
  511. *
  512. * ifMaskGet - get the subnet mask for a network interface
  513. *
  514. * This routine gets the subnet mask for a specified network interface.
  515. * The subnet mask is copied to the buffer <netMask>.  The subnet mask is
  516. * returned in host byte order.
  517. *
  518. * RETURNS: OK or ERROR.
  519. *
  520. * SEE ALSO: ifAddrGet(), ifFlagGet()
  521. */
  522. STATUS ifMaskGet
  523.     (
  524.     char *interfaceName,        /* name of interface, i.e. ei0 */
  525.     int  *netMask               /* buffer for subnet mask */
  526.     )
  527.     {
  528.     int status = ifIoctl (interfaceName, SIOCGIFNETMASK, (u_long) netMask);
  529.     if (status != ERROR)
  530. *netMask = ntohl (*netMask);
  531.     return (status);
  532.     }
  533. /*******************************************************************************
  534. *
  535. * ifFlagChange - change the network interface flags
  536. *
  537. * This routine changes the flags for the specified network interfaces.  If
  538. * the parameter <on> is TRUE, the specified flags are turned on; otherwise,
  539. * they are turned off.  The routines ifFlagGet() and ifFlagSet() are called
  540. * to do the actual work.
  541. *
  542. * RETURNS: OK or ERROR.
  543. *
  544. * SEE ALSO: ifAddrSet(), ifMaskSet(), ifFlagSet(), ifFlagGet()
  545. */
  546. STATUS ifFlagChange
  547.     (
  548.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  549.     int   flags,                /* the flag to be changed */
  550.     BOOL  on                    /* TRUE=turn on, FALSE=turn off */
  551.     )
  552.     {
  553.     int oldFlags;
  554.     if (ifFlagGet (interfaceName, &oldFlags) == ERROR)
  555. {
  556. return (ERROR);
  557. }
  558.     if (on)
  559. oldFlags |= flags;
  560.     else
  561. oldFlags &= ~flags;
  562.     return (ifFlagSet (interfaceName, oldFlags));
  563.     }
  564. /*******************************************************************************
  565. *
  566. * ifFlagSet - specify the flags for a network interface
  567. *
  568. * This routine changes the flags for a specified network interface.
  569. * Any combination of the following flags can be specified:
  570. *
  571. * .iP "IFF_UP (0x1)" 20
  572. * Brings the network up or down.
  573. * .iP "IFF_DEBUG (0x4)"
  574. * Turns on debugging for the driver interface if supported.
  575. * .iP "IFF_LOOPBACK (0x8)"
  576. * Set for a loopback network.
  577. * .iP "IFF_NOTRAILERS (0x20)"
  578. * Always set (VxWorks does not use the trailer protocol).
  579. * .iP "IFF_PROMISC (0x100)"
  580. * Tells the driver to accept all packets, not just broadcast packets and
  581. * packets addressed to itself. 
  582. * .iP "IFF_ALLMULTI (0x200)"
  583. * Tells the driver to accept all multicast packets.
  584. * .iP "IFF_NOARP (0x80)"
  585. * Disables ARP for the interface.
  586. * .LP
  587. *
  588. * NOTE
  589. * The following flags can only be set at interface initialization time.
  590. * Specifying these flags does not change any settings in the interface
  591. * data structure.
  592. *
  593. * .iP "IFF_POINTOPOINT (0x10)" 20
  594. * Identifies a point-to-point interface such as PPP or SLIP.
  595. * .iP "IFF_RUNNING (0x40)"
  596. * Set when the device turns on.
  597. * .iP "IFF_BROADCAST (0x2)"
  598. * Identifies a broadcast interface.
  599. * .LP
  600. *
  601. * RETURNS: OK or ERROR.
  602. *
  603. * SEE ALSO: ifFlagChange(), ifFlagGet()
  604. */
  605. STATUS ifFlagSet
  606.     (
  607.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  608.     int   flags                 /* network flags */
  609.     )
  610.     {
  611.     return (ifIoctl (interfaceName, SIOCSIFFLAGS, flags));
  612.     }
  613. /*******************************************************************************
  614. *
  615. * ifFlagGet - get the network interface flags
  616. *
  617. * This routine gets the flags for a specified network interface.
  618. * The flags are copied to the buffer <flags>.
  619. *
  620. * RETURNS: OK or ERROR.
  621. *
  622. * SEE ALSO: ifFlagSet()
  623. */
  624. STATUS ifFlagGet
  625.     (
  626.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  627.     int  *flags                 /* network flags returned here */
  628.     )
  629.     {
  630.     return (ifIoctl (interfaceName, SIOCGIFFLAGS, (int)flags));
  631.     }
  632. /*******************************************************************************
  633. *
  634. * ifMetricSet - specify a network interface hop count
  635. *
  636. * This routine configures <metric> for a network interface from the host
  637. * machine to the destination network.  This information is used primarily by
  638. * the IP routing algorithm to compute the relative distance for a collection
  639. * of hosts connected to each interface.  For example, a higher <metric> for
  640. * SLIP interfaces can be specified to discourage routing a packet to slower
  641. * serial line connections.  Note that when <metric> is zero, the IP routing
  642. * algorithm allows for the direct sending of a packet having an IP network
  643. * address that is not necessarily the same as the local network address.
  644. *
  645. * RETURNS: OK or ERROR.
  646. *
  647. * SEE ALSO: ifMetricGet()
  648. */
  649. STATUS ifMetricSet
  650.     (
  651.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  652.     int   metric                /* metric for this interface */
  653.     )
  654.     {
  655.     return (ifIoctl (interfaceName, SIOCSIFMETRIC, metric));
  656.     }
  657. /*******************************************************************************
  658. *
  659. * ifMetricGet - get the metric for a network interface
  660. *
  661. * This routine retrieves the metric for a specified network interface.
  662. * The metric is copied to the buffer <pMetric>.
  663. *
  664. * RETURNS: OK or ERROR.
  665. *
  666. * SEE ALSO: ifMetricSet()
  667. */
  668. STATUS ifMetricGet
  669.     (
  670.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  671.     int  *pMetric               /* returned interface's metric */
  672.     )
  673.     {
  674.     return (ifIoctl (interfaceName, SIOCGIFMETRIC, (int)pMetric));
  675.     }
  676. /*******************************************************************************
  677. *
  678. * ifIoctl - network interface ioctl front-end
  679. *
  680. * Used to manipulate the characteristics of network interfaces
  681. * using socket specific ioctl functions SIOCSIFADDR, SIOCSIFBRDADDR, etc.
  682. * ifIoctl() accomplishes this by calling ifIoctlSet() and ifIoctlGet().
  683. *
  684. * RETURNS: OK or ERROR
  685. *
  686. * ERRNO: EOPNOTSUPP
  687. */
  688. LOCAL STATUS ifIoctl
  689.     (
  690.     char *interfaceName,        /* name of the interface, i.e. ei0 */
  691.     int code,                   /* ioctl function code */
  692.     int arg                     /* some argument */
  693.     )
  694.     {
  695.     int status;
  696.     int hostAddr;
  697.     switch ((u_int) code)
  698. {
  699. case SIOCAIFADDR:
  700. case SIOCDIFADDR:
  701. case SIOCSIFADDR:
  702. case SIOCSIFBRDADDR:
  703. case SIOCSIFDSTADDR:
  704.     /* verify Internet address is in correct format */
  705.     if ((hostAddr = (int) inet_addr ((char *)arg)) == ERROR &&
  706. (hostAddr = hostGetByName ((char *)arg)) == ERROR)
  707. {
  708. return (ERROR);
  709. }
  710.     status = ifIoctlSet (interfaceName, code, hostAddr);
  711.     break;
  712. case SIOCSIFNETMASK:
  713.         case SIOCSIFFLAGS:
  714.         case SIOCSIFMETRIC:
  715.     status = ifIoctlSet (interfaceName, code, arg);
  716.     break;
  717. case SIOCGIFNETMASK:
  718. case SIOCGIFFLAGS:
  719. case SIOCGIFADDR:
  720. case SIOCGIFBRDADDR:
  721. case SIOCGIFDSTADDR:
  722. case SIOCGIFMETRIC:
  723.     status = ifIoctlGet (interfaceName, code, (int *)arg);
  724.     break;
  725. default:
  726.     (void)errnoSet (EOPNOTSUPP); /* not supported operation */
  727.     status = ERROR;
  728.     break;
  729. }
  730.     return (status);
  731.     }
  732. /*******************************************************************************
  733. *
  734. * ifIoctlSet - configure network interface
  735. *
  736. * RETURNS: OK or ERROR
  737. */
  738. LOCAL STATUS ifIoctlSet
  739.     (
  740.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  741.     int   code,                 /* network interface ioctl function code */
  742.     int   val                   /* value to be changed */
  743.     )
  744.     {
  745.     struct ifreq ifr;
  746.     strncpy (ifr.ifr_name, interfaceName, sizeof (ifr.ifr_name));
  747.     switch ((u_int) code)
  748. {
  749. case SIOCSIFFLAGS:
  750.     ifr.ifr_flags = (short) val;
  751.     break;
  752.         case SIOCSIFMETRIC:
  753.     ifr.ifr_metric = val;
  754.     break;
  755.         default:
  756.     bzero ((caddr_t) &ifr.ifr_addr, sizeof (ifr.ifr_addr));
  757.     ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);
  758.     ifr.ifr_addr.sa_family = AF_INET;
  759.     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = val;
  760.     break;
  761. }
  762.     return (ifIoctlCall (code, &ifr));
  763.     }
  764. /*******************************************************************************
  765. *
  766. * ifIoctlGet - retrieve information about the network interface
  767. *
  768. * RETURNS: OK or ERROR
  769. */
  770. LOCAL STATUS ifIoctlGet
  771.     (
  772.     char *interfaceName,        /* name of the network interface, i.e. ei0 */
  773.     int   code,                 /* network interface ioctl function code */
  774.     int  *val                   /* where to return result */
  775.     )
  776.     {
  777.     struct ifreq  ifr;
  778.     strncpy (ifr.ifr_name, interfaceName, sizeof (ifr.ifr_name));
  779.     if (ifIoctlCall (code, &ifr) == ERROR)
  780. return (ERROR);
  781.     switch ((u_int) code)
  782. {
  783. case SIOCGIFFLAGS:
  784.     *val = ifr.ifr_flags;
  785.     break;
  786.         case SIOCGIFMETRIC:
  787.     *val = ifr.ifr_metric;
  788.     break;
  789. default:
  790.     *val = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
  791.     break;
  792. }
  793.     return (OK);
  794.     }
  795. /*******************************************************************************
  796. *
  797. * ifIoctlCall - make ioctl call to socket layer
  798. *
  799. * ifIoctlCall creates a dummy socket to get access to the socket layer
  800. * ioctl routines in order to manipulate the interface specific
  801. * configurations.
  802. *
  803. * RETURNS: OK or ERROR
  804. */
  805. LOCAL STATUS ifIoctlCall
  806.     (
  807.     int           code,         /* ioctl code */
  808.     struct ifreq *ifrp          /* pointer to the interface ioctl request */
  809.     )
  810.     {
  811.     int so;
  812.     int status;
  813.     if ((so = socket (AF_INET, SOCK_RAW, 0)) < 0)
  814. return (ERROR);
  815.     status = ioctl (so, code, (int)ifrp);
  816.     (void)close (so);
  817.     if (status != 0)
  818. {
  819. if (status != ERROR) /* iosIoctl() can return ERROR */
  820.     (void)errnoSet (status);
  821. return (ERROR);
  822. }
  823.     return (OK);
  824.     }
  825. /*******************************************************************************
  826. *
  827. * ifRouteDelete - delete routes associated with a network interface
  828. *
  829. * This routine deletes all routes that have been associated with the
  830. * specified interface. A route is associated with an interface if its 
  831. * destination equals to the assigned address, or network number. This routine
  832. * does not remove routes to arbitrary destinations that through the
  833. * given interface.
  834. *
  835. *
  836. * INTERNAL
  837. * This function only works for address families AF_INET
  838. *
  839. * RETURNS:
  840. * The number of routes deleted, or ERROR if an interface is not specified.
  841. */
  842. int ifRouteDelete
  843.     (
  844.     char *ifName,               /* name of the interface */
  845.     int   unit                  /* unit number for this interface */
  846.     )
  847.     {
  848.     FAST struct ifnet  *ifp;
  849.     FAST struct ifaddr  *ifa;
  850.     FAST struct in_ifaddr  *ia = 0;
  851.     int  deleted;
  852.     struct sockaddr_in inetAddr;
  853.     if (ifName == NULL)
  854. return (ERROR);
  855.     deleted = 0;
  856. #ifdef VIRTUAL_STACK
  857.     for (ifp = _ifnet; ifp; ifp = ifp->if_next)
  858. #else
  859.     for (ifp = ifnet; ifp; ifp = ifp->if_next)
  860. #endif /* VIRTUAL_STACK */
  861. {
  862. if (ifp->if_unit != unit || strcmp(ifName, ifp->if_name))
  863.     continue;
  864. for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
  865.     {
  866.             /* skip if address family does not belong to AF_INET */
  867.             if (ifa->ifa_addr->sa_family != AF_INET)
  868.                 continue;
  869.             /*
  870.      * Every element in the if_addrlist (type struct ifaddr) with
  871.      * family AF_INET is actually the first part of a larger
  872.      * in_ifaddr structure which includes the subnet mask. Access
  873.      * that structure to use the mask value.
  874.      */
  875.     ia = (struct in_ifaddr *) ifa;
  876.     /* 
  877.      * The following is a sanity test.
  878.      */
  879. #ifdef ROUTER_STACK  /* UNNUMBERED_SUPPORT */ 
  880.     /*
  881.      * This test is to prevent an ipDetach on an unnumbered interface
  882.      * from removing the routes generated by the real interface if that
  883.      * interface is still up. See ifUnnumberedSet for the definition
  884.      * of "real interface."
  885.      */
  886.     if (ifa == ifa_ifwithaddr (ifa->ifa_addr))
  887. #endif /* ROUTER_STACK */
  888. {
  889.                 if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_addr)->
  890.     sin_addr.s_addr, 0, 0xffffffff, 0, RTF_HOST, 
  891.     M2_ipRouteProto_local) == OK)
  892.                     ++deleted;
  893.                 inetAddr.sin_addr.s_addr =
  894.                     htonl (ia->ia_subnetmask) &
  895.                     ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
  896.                 if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_addr)->
  897.     sin_addr.s_addr, 0, htonl(ia->ia_subnetmask), 
  898.     0, 0, M2_ipRouteProto_local) == OK)
  899.                     ++deleted;
  900. }
  901.     if (ifp->if_flags & (IFF_POINTOPOINT|IFF_UNNUMBERED))
  902. {
  903.                 if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_dstaddr)->
  904.                                        sin_addr.s_addr, 
  905.                                        ((struct sockaddr_in*)ifa->ifa_addr)->
  906.                                        sin_addr.s_addr, 0x0, 0,
  907.                                        RTF_HOST, M2_ipRouteProto_local) == OK)
  908.     ++deleted;
  909. #ifdef ROUTER_STACK     /* UNNUMBERED_SUPPORT */
  910. else
  911.     {
  912.                     _arpCmd (SIOCDARP, 
  913.                              &(((struct sockaddr_in *)
  914.                                 ifa->ifa_dstaddr)->sin_addr), NULL, NULL);        
  915.     deleted++;
  916.     }
  917. #endif /* ROUTER_STACK */
  918. }
  919.     }
  920. }
  921.     return (deleted);
  922.     }
  923. /*******************************************************************************
  924. *
  925. * routeNodeDelete - delete the route associated with the network interface
  926. *
  927. * This routine deletes the route that has been associated with the
  928. * specified interface. Only the following route is deleted:
  929. * ml 
  930. * m -
  931. * the network route added when the interface address is initialized
  932. * m -
  933. * the static route added by the administrator that passes through the interface
  934. * m -
  935. * ARP routes passing through the interface
  936. * me
  937. * Routes added by routing protocols are not deleted.
  938. * For the Router stack, this routine first scans all duplicate routes
  939. * to determine which ones need to be deleted, and then processes the primary
  940. * route. This special handling is needed because the way the duplicate
  941. * routes are organized, deleting the primary route first might lead
  942. * to memory corruption.
  943. *
  944. * INTERNAL
  945. * This function only works for address families AF_INET
  946. *
  947. * RETURNS:
  948. * 0
  949. */
  950. LOCAL int routeNodeDelete
  951.     (
  952.     struct radix_node * pRoute,    /* pointer to the node structure */
  953.     void * pArg       /* pointer to the interface */
  954.     )
  955.     {
  956.     struct ifnet * ifp =  (struct ifnet *)((int *)pArg)[0];
  957.     int    type = ((int *)pArg)[1];
  958.     int * pDeleted = (int *)((int *)pArg)[2];
  959.     struct rtentry * pRt;
  960.     FAST struct sockaddr * destAddr = NULL;
  961.     FAST struct sockaddr * gateAddr;
  962.     char  aStr [INET_ADDR_LEN];
  963. #ifdef ROUTER_STACK
  964.     ROUTE_ENTRY * pHead; 
  965.     ROUTE_ENTRY * pDiffSave; 
  966.     ROUTE_ENTRY * pSameSave; 
  967.     ROUTE_ENTRY * pNext;
  968. #endif /* ROUTER_STACK */
  969.     pRt = (struct rtentry *)pRoute;
  970.     destAddr = rt_key(pRt); /* get the destination address */
  971.     gateAddr = pRt->rt_gateway; /* get the gateway address */
  972. #ifdef DEBUG
  973.     inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);
  974.     logMsg ("routeNodeDelete: Called for %s, if=%s%d, proto=%d, type = %sn", 
  975.             (int)aStr, (int)(pRt->rt_ifp->if_name), pRt->rt_ifp->if_unit,
  976.             RT_PROTO_GET (destAddr), 
  977.             (int)(type == RT_ARP ? "ARP" : "NON_ARP"), 0); 
  978. #endif /* DEBUG */
  979.     /* Just return if it is an ARP entry and we are not interested in it */
  980.     if (type != RT_ARP && 
  981.         ((pRt->rt_flags & RTF_HOST) && 
  982.          (pRt->rt_flags & RTF_LLINFO) && 
  983.          (pRt->rt_flags & RTF_GATEWAY) == 0 && 
  984.          gateAddr && (gateAddr->sa_family == AF_LINK)))
  985.         return(0);
  986.     /* Just return if we want an ARP entry, but this is not */
  987.     if (type == RT_ARP && 
  988.         !((pRt->rt_flags & RTF_HOST) && 
  989.           (pRt->rt_flags & RTF_LLINFO) && 
  990.           (pRt->rt_flags & RTF_GATEWAY) == 0 && 
  991.           gateAddr && (gateAddr->sa_family == AF_LINK)))
  992.         return(0);
  993.     /* 
  994.      * If it is an ARP entry and it passes through the interface, 
  995.      * delete the ARP entry 
  996.      */
  997.     if ((pRt->rt_flags & RTF_HOST) &&
  998.         (pRt->rt_flags & RTF_LLINFO) &&
  999.         (pRt->rt_flags & RTF_GATEWAY) == 0 &&
  1000.         gateAddr && (gateAddr->sa_family == AF_LINK)) 
  1001.         {
  1002.         if(pRt->rt_ifp == ifp)
  1003.             {
  1004.             inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);
  1005. #ifdef DEBUG
  1006.             logMsg ("routeNodeDelete: deleting ARP entry for %sn", 
  1007.                     (int)aStr,0,0,0,0,0); 
  1008. #endif /* DEBUG */
  1009.             _arpCmd (SIOCDARP, &((struct sockaddr_in *)destAddr)->sin_addr, 
  1010.                      NULL, NULL);        
  1011.             /* Increment the deletion counter */
  1012.             ++(*pDeleted);
  1013.             }
  1014.         return (0);
  1015.         }
  1016. #ifdef ROUTER_STACK
  1017.     /* 
  1018.      * Because of the way the duplicate route list is managed, we need to
  1019.      * delete all duplicate routes, before we delete the primary route.
  1020.      * So walk through all the duplicate routes if any, and delete them
  1021.      * if the interface matches.
  1022.      */
  1023.     pHead = (ROUTE_ENTRY *)pRoute;
  1024.     pNext = pHead->sameNode.pFrwd;
  1025.     if (pNext == NULL)
  1026.         {
  1027.         pHead = pNext = pHead->diffNode.pFrwd;
  1028.         }
  1029.     while (pHead)
  1030.         { 
  1031.         pDiffSave = pHead->diffNode.pFrwd;
  1032.         while (pNext)
  1033.             {
  1034.             /* Save the next pointer in case we delete this node */
  1035.             pSameSave = pNext->sameNode.pFrwd;
  1036.             /* If this route passes through the interface, delete it */
  1037.             if (pNext->rtEntry.rt_ifp == ifp) 
  1038.                 _routeNodeDelete ((struct rtentry *)pNext, pDeleted);
  1039.             pNext = pSameSave;
  1040.             }
  1041.         pHead = pNext = pDiffSave;
  1042.         }
  1043. #endif /* ROUTER_STACK */
  1044.     /* Now delete the primary route if it passes through the interface */
  1045.     if (pRt->rt_ifp == ifp) 
  1046.         _routeNodeDelete (pRt, pDeleted);
  1047.     return OK;
  1048.     }
  1049. /*******************************************************************************
  1050. *
  1051. * _routeNodeDelete - delete the route associated with the network interface
  1052. *
  1053. * This routine deletes the route that has been associated with the
  1054. * specified interface. Only the following route is deleted:
  1055. *
  1056. * ml
  1057. * m -
  1058. * the network route added by us when the interface address is initialized
  1059. * m -
  1060. * the static route added by the administrator that passes through the interface
  1061. * me
  1062. *
  1063. * Routes added by routing protocols are not deleted.
  1064. *
  1065. * INTERNAL
  1066. * This function only works for address families AF_INET.
  1067. *
  1068. * RETURNS:
  1069. * 0
  1070. */
  1071. LOCAL int _routeNodeDelete
  1072.     (
  1073.     struct rtentry * pRt, /* pointer to the rtentry structure */
  1074.     int * pDeleted /* counts # of deleted routes */
  1075.     )
  1076.     {
  1077.     FAST struct sockaddr * destAddr = NULL;
  1078.     FAST struct sockaddr * gateAddr;
  1079.     int proto;
  1080.     long mask;
  1081. #ifdef DEBUG
  1082.     char  aStr [INET_ADDR_LEN];
  1083.     char  bStr [INET_ADDR_LEN];
  1084.     char  cStr [INET_ADDR_LEN];
  1085. #endif /* DEBUG */
  1086.     destAddr = rt_key(pRt); /* get the destination address */
  1087.     gateAddr = pRt->rt_gateway; /* get the gateway address */
  1088. #ifdef DEBUG
  1089.     inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);
  1090.     logMsg ("_routeNodeDelete: Called for %s, if=%s%d, proto=%d, type = %sn", 
  1091.             (int)aStr, (int)(pRt->rt_ifp->if_name), pRt->rt_ifp->if_unit,
  1092.             RT_PROTO_GET (destAddr), (int)"NON_ARP", 0); 
  1093. #endif /* DEBUG */
  1094.     /*
  1095.      * We delete only statically added routes, interface routes and ICMP
  1096.      * routes. All other routes belong to the respective routing protocols
  1097.      * that should be deleting them
  1098.      */
  1099.     if ((proto = RT_PROTO_GET (destAddr)) != M2_ipRouteProto_other &&
  1100.         proto != M2_ipRouteProto_local &&
  1101.         proto != M2_ipRouteProto_icmp)
  1102.         return (0);
  1103.     /* If it is an interface route, get the interface address */
  1104.     if (gateAddr->sa_family == AF_LINK)
  1105.         gateAddr = pRt->rt_ifa->ifa_addr; 
  1106.     if (rt_mask (pRt) == NULL)
  1107.         {
  1108.         mask = 0;
  1109.         }
  1110.     else
  1111.         {
  1112.         mask = ((struct sockaddr_in *) rt_mask (pRt))->sin_addr.s_addr;
  1113.         }
  1114. #ifdef DEBUG
  1115.     inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);
  1116.     if (mask)
  1117.         inet_ntoa_b (((struct sockaddr_in *) rt_mask (pRt))->sin_addr, bStr);
  1118.     else
  1119.         bStr[0] = 0;
  1120.     inet_ntoa_b (((struct sockaddr_in *)gateAddr)->sin_addr, cStr);
  1121.     logMsg ("_routeNodeDelete: Deleting following route: dest = %s, nmask = %s,"
  1122.             "gate = %sn", (int)aStr, (int)bStr, (int)cStr, 0, 0, 0);
  1123. #endif /* DEBUG */
  1124.     /* Now delete the route */
  1125.     mRouteEntryDelete (((struct sockaddr_in*)destAddr)->sin_addr.s_addr, 
  1126.                        ((struct sockaddr_in*)gateAddr)->sin_addr.s_addr, 
  1127.                        mask, TOS_GET (destAddr), pRt->rt_flags, proto);
  1128.     /* Increment the deletion counter */
  1129.     ++(*pDeleted);
  1130.     return 0;
  1131.     }
  1132. /*******************************************************************************
  1133. * ifAllRoutesDelete - delete all routes associated with a network interface
  1134. *
  1135. * This routine deletes all routes that have been associated with the
  1136. * specified interface. The routes deleted are:
  1137. * ml
  1138. * m - 
  1139. * the network route added when the interface address is initialized
  1140. * m - 
  1141. * the static routes added by the administrator
  1142. * m - 
  1143. * ARP routes passing through the interface
  1144. * me
  1145. * Routes added by routing protocols are not deleted.
  1146. *
  1147. * INTERNAL
  1148. * This function only works for address families AF_INET.
  1149. *
  1150. * RETURNS:
  1151. * The number of routes deleted, or ERROR if an interface is not specified.
  1152. */
  1153. int ifAllRoutesDelete
  1154.     (
  1155.     char *ifName,               /* name of the interface */
  1156.     int   unit                  /* unit number for this interface */
  1157.     )
  1158.     {
  1159.     FAST struct ifnet  *ifp;
  1160.     FAST struct ifaddr  *ifa;
  1161.     FAST struct in_ifaddr  *ia = 0;
  1162.     int    deleted;
  1163.     int  args[3];
  1164.     struct radix_node_head *   rnh;
  1165.     if (ifName == NULL)
  1166.         return (ERROR);
  1167.     deleted = 0;
  1168. #ifdef VIRTUAL_STACK
  1169.     for (ifp = _ifnet; ifp; ifp = ifp->if_next)
  1170. #else
  1171.     for (ifp = ifnet; ifp; ifp = ifp->if_next)
  1172. #endif /* VIRTUAL_STACK */
  1173.         {
  1174.             if (ifp->if_unit != unit || strcmp(ifName, ifp->if_name))
  1175.                 continue;
  1176. /*
  1177.  * Find address for this interface, if it exists.
  1178.  */
  1179. #ifdef VIRTUAL_STACK
  1180. for (ia = _in_ifaddr; ia; ia = ia->ia_next)
  1181. #else
  1182. for (ia = in_ifaddr; ia; ia = ia->ia_next)
  1183. #endif /* VIRTUAL_STACK */
  1184.     if (ia->ia_ifp == ifp)
  1185. break;
  1186. for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
  1187.             {
  1188.             /* skip if address family does not belong to AF_INET */
  1189.             
  1190.             if (ifa->ifa_addr->sa_family != AF_INET)
  1191.                 continue;
  1192.             /*
  1193.              * Walk through the entire table and delete routes associated
  1194.              * with the interface.
  1195.              */
  1196.             /* First delete the ARP entries */
  1197.             args[0] = (int)ifp;
  1198.             args[1] = RT_ARP;
  1199.             args[2] = (int)&deleted;
  1200.             rnh = rt_tables[AF_INET];
  1201.             if (rnh) 
  1202.                 rn_walktree(rnh, routeNodeDelete, (void *)args);
  1203.             
  1204.             /* Next delete the non-ARP routes */
  1205.             args[0] = (int)ifp;
  1206.             args[1] = ~RT_ARP;
  1207.             args[2] = (int)&deleted;
  1208.             if (rnh) 
  1209.                 rn_walktree(rnh, routeNodeDelete, (void *)args);
  1210.             
  1211.             break;
  1212.             }
  1213.         }
  1214.     return (deleted);
  1215.     }
  1216. /*******************************************************************************
  1217. *
  1218. * ifunit - map an interface name to an interface structure pointer
  1219. *
  1220. * This routine returns a pointer to a network interface structure for <name> or
  1221. * NULL if no such interface exists.  For example:
  1222. * .CS
  1223. *     struct ifnet *pIf;
  1224. *     ...
  1225. *     pIf = ifunit ("ln0");
  1226. * .CE
  1227. * `pIf' points to the data structure that describes the first network interface
  1228. * device if ln0 is mapped successfully.
  1229. *
  1230. * RETURNS:
  1231. * A pointer to the interface structure, or NULL if an interface is not
  1232. * found.
  1233. *
  1234. */
  1235. struct ifnet *ifunit
  1236.     (
  1237.     register char *ifname    /* name of the interface */
  1238.     )
  1239.     {
  1240.     register char *cp;
  1241.     register struct ifnet *ifp;
  1242.     int unit;
  1243.     unsigned len;
  1244.     char *ep, c;
  1245.     char name [IFNAMSIZ];
  1246.     if (ifname == NULL)
  1247. return ((struct ifnet *)0);
  1248.     strncpy (name, ifname, IFNAMSIZ);
  1249.     for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
  1250. if (*cp >= '0' && *cp <= '9')
  1251.     break;
  1252.     if (*cp == '' || cp == name + IFNAMSIZ)
  1253. return ((struct ifnet *)0);
  1254.     /*
  1255.      * Save first char of unit, and pointer to it,
  1256.      * so we can put a null there to avoid matching
  1257.      * initial substrings of interface names.
  1258.      */
  1259.     len = cp - name + 1;
  1260.     c = *cp;
  1261.     ep = cp;
  1262.     for (unit = 0; *cp >= '0' && *cp <= '9'; )
  1263.         unit = unit * 10 + *cp++ - '0';
  1264.     *ep = 0;
  1265. #ifdef VIRTUAL_STACK
  1266.     for (ifp = _ifnet; ifp; ifp = ifp->if_next)
  1267. #else
  1268.     for (ifp = ifnet; ifp; ifp = ifp->if_next)
  1269. #endif /* VIRTUAL_STACK */
  1270. {
  1271. if (bcmp(ifp->if_name, name, len))
  1272.     continue;
  1273.         if (unit == ifp->if_unit)
  1274.     break;
  1275. }
  1276.     *ep = c;
  1277.     return (ifp);
  1278.     }
  1279. /****************************************************************************
  1280. *
  1281. * ifNameToIfIndex - returns the interface index given the interface name
  1282. *
  1283. * This routine returns the interface index for the interface named by the 
  1284. * <ifName> parameter, which proviedes a string describing the full interface 
  1285. * name. For example, "fei0".
  1286. *
  1287. * RETURNS: The interface index, if the interface could be located,  
  1288. * 0, otherwise.  0 is not a valid value for interface index.
  1289. */
  1290. unsigned short ifNameToIfIndex 
  1291.     (
  1292.     char * ifName /* a string describing the full interface name. */
  1293.      /* e.g., "fei0" */
  1294.     )
  1295.     {
  1296.     FAST struct ifnet * ifp;
  1297.     int s;
  1298.     int ifIndex;
  1299.     /* Call ifunit under splnet protection as it is not protected */
  1300.     s = splnet ();
  1301.     ifp = ifunit (ifName);
  1302.     ifIndex = (ifp != NULL) ? ifp->if_index : 0;
  1303.     splx (s);
  1304.     return (ifIndex);
  1305.     }
  1306. /****************************************************************************
  1307. *
  1308. * ifIndexToIfName - returns the interface name given the interface index
  1309. *
  1310. * This routine returns the interface name for the interface referenced
  1311. * by the <ifIndex> parameter. 
  1312. *
  1313. * is
  1314. * i <ifIndex>
  1315. *    The index for the interface.
  1316. * i <ifName>
  1317. *    The location where the interface name is copied
  1318. * ie
  1319. *
  1320. * RETURNS: OK on success, ERROR otherwise.
  1321. */
  1322. STATUS ifIndexToIfName 
  1323.     (
  1324.     unsigned short ifIndex,/* Interface index */
  1325.     char * ifName /* Where the name is to be stored */
  1326.     )
  1327.     {
  1328.     FAST struct ifnet * ifp;
  1329.     int s;
  1330.     if (ifName == NULL)
  1331.         return (ERROR);
  1332.     s = splnet ();
  1333.     if ((ifp = ifIndexToIfp (ifIndex)) == NULL)
  1334.         {
  1335.         splx (s);
  1336.         return (ERROR);
  1337.         }
  1338.     sprintf (ifName, "%s%d", ifp->if_name, ifp->if_unit);
  1339.     splx (s);
  1340.     return (OK);
  1341.     }