The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/common/dev_net.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      
    2  * $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $
    3  */
    4 
    5 /*-
    6  * Copyright (c) 1997 The NetBSD Foundation, Inc.
    7  * All rights reserved.
    8  *
    9  * This code is derived from software contributed to The NetBSD Foundation
   10  * by Gordon W. Ross.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *        This product includes software developed by the NetBSD
   23  *        Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __FBSDID("$FreeBSD$");
   43 
   44 /*-
   45  * This module implements a "raw device" interface suitable for
   46  * use by the stand-alone I/O library NFS code.  This interface
   47  * does not support any "block" access, and exists only for the
   48  * purpose of initializing the network interface, getting boot
   49  * parameters, and performing the NFS mount.
   50  *
   51  * At open time, this does:
   52  *
   53  * find interface      - netif_open()
   54  * RARP for IP address - rarp_getipaddress()
   55  * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
   56  * RPC/mountd          - nfs_mount(sock, ip, path)
   57  *
   58  * the root file handle from mountd is saved in a global
   59  * for use by the NFS open code (NFS/lookup).
   60  */
   61 
   62 #include <machine/stdarg.h>
   63 #include <sys/param.h>
   64 #include <sys/socket.h>
   65 #include <net/if.h>
   66 #include <netinet/in.h>
   67 #include <netinet/in_systm.h>
   68 
   69 #include <stand.h>
   70 #include <string.h>
   71 #include <net.h>
   72 #include <netif.h>
   73 #include <bootp.h>
   74 #include <bootparam.h>
   75 
   76 #include "dev_net.h"
   77 #include "bootstrap.h"
   78 
   79 int debug = 0;
   80 
   81 static int netdev_sock = -1;
   82 static int netdev_opens;
   83 
   84 static int      net_init(void);
   85 static int      net_open(struct open_file *, ...);
   86 static int      net_close(struct open_file *);
   87 static int      net_strategy();
   88 static void     net_print(int);
   89 
   90 static int net_getparams(int sock);
   91 
   92 struct devsw netdev = {
   93     "net", 
   94     DEVT_NET, 
   95     net_init,
   96     net_strategy, 
   97     net_open, 
   98     net_close, 
   99     noioctl,
  100     net_print
  101 };
  102 
  103 int
  104 net_init(void)
  105 {
  106     return 0;
  107 }
  108 
  109 /*
  110  * Called by devopen after it sets f->f_dev to our devsw entry.
  111  * This opens the low-level device and sets f->f_devdata.
  112  * This is declared with variable arguments...
  113  */
  114 int
  115 net_open(struct open_file *f, ...)
  116 {
  117     va_list args;
  118     char *devname;              /* Device part of file name (or NULL). */
  119     int error = 0;
  120 
  121     va_start(args, f);
  122     devname = va_arg(args, char*);
  123     va_end(args);
  124 
  125     /* On first open, do netif open, mount, etc. */
  126     if (netdev_opens == 0) {
  127         /* Find network interface. */
  128         if (netdev_sock < 0) {
  129             netdev_sock = netif_open(devname);
  130             if (netdev_sock < 0) {
  131                 printf("net_open: netif_open() failed\n");
  132                 return (ENXIO);
  133             }
  134             if (debug)
  135                 printf("net_open: netif_open() succeeded\n");
  136         }
  137         if (rootip.s_addr == 0) {
  138             /* Get root IP address, and path, etc. */
  139             error = net_getparams(netdev_sock);
  140             if (error) {
  141                                 /* getparams makes its own noise */
  142                 netif_close(netdev_sock);
  143                 netdev_sock = -1;
  144                 return (error);
  145             }
  146         }
  147         netdev_opens++;
  148     }
  149     netdev_opens++;
  150     f->f_devdata = &netdev_sock;
  151     return (error);
  152 }
  153 
  154 int
  155 net_close(f)
  156     struct open_file *f;
  157 {
  158 
  159 #ifdef  NETIF_DEBUG
  160     if (debug)
  161         printf("net_close: opens=%d\n", netdev_opens);
  162 #endif
  163 
  164     /* On last close, do netif close, etc. */
  165     f->f_devdata = NULL;
  166     /* Extra close call? */
  167     if (netdev_opens <= 0)
  168         return (0);
  169     netdev_opens--;
  170     /* Not last close? */
  171     if (netdev_opens > 0)
  172         return(0);
  173     rootip.s_addr = 0;
  174     if (netdev_sock >= 0) {
  175         if (debug)
  176             printf("net_close: calling netif_close()\n");
  177         netif_close(netdev_sock);
  178         netdev_sock = -1;
  179     }
  180     return (0);
  181 }
  182 
  183 int
  184 net_strategy()
  185 {
  186     return EIO;
  187 }
  188 
  189 #define SUPPORT_BOOTP
  190 
  191 /*
  192  * Get info for NFS boot: our IP address, our hostname,
  193  * server IP address, and our root path on the server.
  194  * There are two ways to do this:  The old, Sun way,
  195  * and the more modern, BOOTP way. (RFC951, RFC1048)
  196  *
  197  * The default is to use the Sun bootparams RPC
  198  * (because that is what the kernel will do).
  199  * MD code can make try_bootp initialied data,
  200  * which will override this common definition.
  201  */
  202 #ifdef  SUPPORT_BOOTP
  203 int try_bootp = 1;
  204 #endif
  205 
  206 extern n_long ip_convertaddr(char *p);
  207 
  208 static int
  209 net_getparams(sock)
  210     int sock;
  211 {
  212     char buf[MAXHOSTNAMELEN];
  213     char temp[FNAME_SIZE];
  214     struct iodesc *d;
  215     int i;
  216     n_long smask;
  217 
  218 #ifdef  SUPPORT_BOOTP
  219     /*
  220      * Try to get boot info using BOOTP.  If we succeed, then
  221      * the server IP address, gateway, and root path will all
  222      * be initialized.  If any remain uninitialized, we will
  223      * use RARP and RPC/bootparam (the Sun way) to get them.
  224      */
  225     if (try_bootp)
  226         bootp(sock, BOOTP_NONE);
  227     if (myip.s_addr != 0)
  228         goto exit;
  229     if (debug)
  230         printf("net_open: BOOTP failed, trying RARP/RPC...\n");
  231 #endif
  232 
  233     /*
  234      * Use RARP to get our IP address.  This also sets our
  235      * netmask to the "natural" default for our address.
  236      */
  237     if (rarp_getipaddress(sock)) {
  238         printf("net_open: RARP failed\n");
  239         return (EIO);
  240     }
  241     printf("net_open: client addr: %s\n", inet_ntoa(myip));
  242 
  243     /* Get our hostname, server IP address, gateway. */
  244     if (bp_whoami(sock)) {
  245         printf("net_open: bootparam/whoami RPC failed\n");
  246         return (EIO);
  247     }
  248     printf("net_open: client name: %s\n", hostname);
  249 
  250     /*
  251      * Ignore the gateway from whoami (unreliable).
  252      * Use the "gateway" parameter instead.
  253      */
  254     smask = 0;
  255     gateip.s_addr = 0;
  256     if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
  257         /* Got it!  Parse the netmask. */
  258         smask = ip_convertaddr(buf);
  259     }
  260     if (smask) {
  261         netmask = smask;
  262         printf("net_open: subnet mask: %s\n", intoa(netmask));
  263     }
  264     if (gateip.s_addr)
  265         printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
  266 
  267     /* Get the root server and pathname. */
  268     if (bp_getfile(sock, "root", &rootip, rootpath)) {
  269         printf("net_open: bootparam/getfile RPC failed\n");
  270         return (EIO);
  271     }
  272  exit:
  273     /*  
  274      * If present, strip the server's address off of the rootpath
  275      * before passing it along.  This allows us to be compatible with
  276      * the kernel's diskless (BOOTP_NFSROOT) booting conventions
  277      */
  278     for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
  279             if (rootpath[i] == ':')
  280                     break;
  281     if (i && i != FNAME_SIZE && rootpath[i] == ':') {
  282             rootpath[i++] = '\0';
  283             if (inet_addr(&rootpath[0]) != INADDR_NONE)
  284                     rootip.s_addr = inet_addr(&rootpath[0]);
  285             bcopy(&rootpath[i], &temp[0], strlen(&rootpath[i])+1);
  286             bcopy(&temp[0], &rootpath[0], strlen(&rootpath[i])+1);          
  287     }
  288     printf("net_open: server addr: %s\n", inet_ntoa(rootip));
  289     printf("net_open: server path: %s\n", rootpath);        
  290 
  291     d = socktodesc(sock);
  292     sprintf(temp, "%6D", d->myea, ":");
  293     setenv("boot.netif.ip", inet_ntoa(myip), 1);
  294     setenv("boot.netif.netmask", intoa(netmask), 1);
  295     setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
  296     setenv("boot.netif.hwaddr", temp, 1);
  297     setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
  298     setenv("boot.nfsroot.path", rootpath, 1);
  299 
  300     return (0);
  301 }
  302 
  303 static void
  304 net_print(int verbose)
  305 {
  306     return;
  307 }

Cache object: df046c8bdabc42657b414fc0d6b8777c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.