1 /*-
2  * Copyright (c) 2012 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Paul Fleischer <paul@xpg.dk>
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  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include <sys/param.h>
30 
31 #include <netinet/in.h>
32 #include <netinet/in_systm.h>
33 
34 #include <lib/libsa/stand.h>
35 #include <lib/libsa/net.h>
36 #include <lib/libsa/bootp.h>
37 #include <lib/libsa/nfs.h>
38 
39 #include <lib/libkern/libkern.h>
40 
41 
42 extern int netif_open(void*);
43 extern int netif_init(unsigned int tag);
44 
45 extern struct in_addr servip;
46 
47 static int netdev_sock = -1;
48 
49 int
net_open(struct open_file * f,...)50 net_open(struct open_file *f, ...)
51 {
52           va_list ap;
53           char *path, *proto;
54           int error = 0;
55 
56           if( netif_init(0) == 0 ) {
57                     error = ENODEV;
58                     goto out;
59           }
60 
61           va_start(ap, f);
62           path = va_arg(ap, char *);
63           proto = va_arg(ap, char *);
64           va_end(ap);
65           if ((netdev_sock = netif_open(path)) < 0) {
66                     error = errno;
67                     goto out;
68           }
69 
70           /* send DHCP request */
71           bootp(netdev_sock);
72 
73           /* IP address was not found */
74           if (myip.s_addr == 0) {
75                     error = ENOENT;
76                     goto out;
77           }
78 
79           if (path[0] != '\0') {
80                     char *c;
81                     char ip_addr[200];
82                     /* Parse path specification as IP-ADDR:PATH and overwrite
83                        rootip and rootpath with those
84                      */
85 
86                     for(c=path; *c != '\0' && *c != ':'; c++);
87 
88                     if (*c == ':') {
89                               char *filename;
90                               strncpy(ip_addr, path, (c-path));
91                               ip_addr[(c-path)] = '\0';
92                               printf("IP addr: %s\n", ip_addr);
93                               rootip.s_addr = inet_addr(ip_addr);
94 
95                               c++;
96                               /* Finally, strip away file-component and copy it to
97                                  bootfile */
98                               for(filename = c+strlen(c); *filename != '/' && filename > c; filename--);
99                               strncpy(rootpath, c, (filename-c));
100                               rootpath[(filename-c)] = '\0';
101                               printf("Root path: %s\n", rootpath);
102                               strcpy(bootfile, ++filename);
103                               printf("Bootfile: %s\n", bootfile);
104                     } else {
105                               /* No ':' found, assume it's just a filename */
106                               strcpy(bootfile, path);
107                     }
108           }
109 
110           /* boot filename was not found */
111           if (bootfile[0] == '\0')
112                     strcpy(bootfile, "netbsd");
113 
114           if (strcmp(proto, "nfs") == 0
115               && (nfs_mount(netdev_sock, rootip, rootpath) != 0)) {
116                     error = errno;
117                     goto out;
118           }
119 
120           f->f_devdata = &netdev_sock;
121 out:
122           return (error);
123 }
124 
125 int
net_close(struct open_file * f)126 net_close(struct open_file *f)
127 
128 {
129           return (0);
130 }
131 
132 int
net_strategy(void * d,int f,daddr_t b,size_t s,void * buf,size_t * r)133 net_strategy(void *d, int f, daddr_t b, size_t s, void *buf, size_t *r)
134 {
135 
136           return (EIO);
137 }
138