xref: /netbsd/sys/arch/i386/stand/netboot/dev_net.c (revision 6550d01e)
1 /*	$NetBSD: dev_net.c,v 1.15 2009/10/22 19:10:42 snj Exp $	 */
2 
3 /*
4  * Copyright (c) 1995 Gordon W. Ross
5  * All rights reserved.
6  * Copyright (c) 1996
7  *	Matthias Drochner.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * network device for libsa
32  * supports BOOTP, RARP and BOOTPARAM
33  */
34 
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <net/if.h>
38 #include <netinet/in.h>
39 #include <netinet/in_systm.h>
40 
41 #include <lib/libsa/stand.h>
42 #include <lib/libsa/net.h>
43 #include <lib/libsa/bootparam.h>
44 #include <machine/stdarg.h>
45 
46 #include <netif/netif_small.h>
47 
48 #include <lib/libkern/libkern.h>
49 
50 #include "dev_net.h"
51 
52 #ifdef SUPPORT_BOOTP
53 void bootp(int);
54 #endif
55 
56 static int      netdev_sock = -1;
57 
58 /*
59  * Called by devopen after it sets f->f_dev to our devsw entry.
60  * This opens the low-level device and sets f->f_devdata.
61  */
62 int
63 net_open(struct open_file *f, ...)
64 {
65 	int error = 0;
66 
67 #ifdef NET_DEBUG
68 	if (netdev_sock != -1)
69 	    panic("net_open");
70 #endif
71 
72 	/* Find network interface. */
73 	if ((netdev_sock = netif_open()) < 0)
74 		return (ENXIO);
75 
76 #ifdef SUPPORT_BOOTP
77 	printf("configure network...trying bootp\n");
78 	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
79 	bootp(netdev_sock);
80 #endif
81 
82 	if (myip.s_addr != INADDR_ANY) {	/* got bootp reply or
83 							 * manually set */
84 
85 #ifdef TFTP_HACK
86 	    int             num, i;
87 	    /* XXX (some) tftp servers don't like leading "/" */
88 	    for (num = 0; bootfile[num] == '/'; num++);
89 	    for (i = 0; (bootfile[i] = bootfile[i + num]) != 0; i++);
90 #endif
91 
92 	    printf("boot: client IP address: %s\n",
93 		   inet_ntoa(myip));
94 	    printf("boot: client name: %s\n", hostname);
95 	} else {
96 
97 #ifdef SUPPORT_RARP
98 	    /*
99 	     * no answer, Get boot info using RARP and Sun
100 	     * bootparams.
101 	     */
102 	    printf("configure network...trying rarp\n");
103 
104 	    /* Get our IP address.  (rarp.c) */
105 	    if (rarp_getipaddress(netdev_sock)) {
106 		error = EIO;
107 		goto bad;
108 	    }
109 	    printf("boot: client IP address: %s\n",
110 		   inet_ntoa(myip));
111 
112 #ifdef SUPPORT_BOOTPARAM
113 	    /* Get our hostname, server IP address. */
114 	    if (!bp_whoami(netdev_sock)) {
115 		printf("boot: client name: %s\n", hostname);
116 
117 		/* Get the root pathname. */
118 		bp_getfile(netdev_sock, "root", &rootip,
119 			   rootpath);
120 	    }
121 #else
122 	    /*
123 	     * else fallback: use rarp server address
124 	     */
125 #endif
126 
127 #else				/* no SUPPORT_RARP */
128 	    error = EIO;
129 	    goto bad;
130 #endif
131 
132 	}
133 	printf("boot: server: %s, rootpath: %s, bootfile: %s\n",
134 	       inet_ntoa(rootip), rootpath, bootfile);
135 
136 	f->f_devdata = &netdev_sock;
137 	return (error);
138 
139 bad:
140 	printf("net_open failed\n");
141 	netif_close(netdev_sock);
142 	return (error);
143 }
144 
145 int
146 net_close(struct open_file *f)
147 {
148 #ifdef NET_DEBUG
149 	if (netdev_sock == -1)
150 		panic("net_close");
151 #endif
152 
153 	netif_close(netdev_sock);
154 	netdev_sock = -1;
155 
156 	f->f_devdata = NULL;
157 
158 	return (0);
159 }
160 
161 int
162 net_ioctl(struct open_file *f, u_long c, void *d)
163 {
164 	return EIO;
165 }
166 
167 int
168 net_strategy(void *d, int f, daddr_t b, size_t s, void *buf, size_t *r)
169 {
170 	return EIO;
171 }
172