Annotation of sys/arch/i386/stand/pxeboot/net.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: net.c,v 1.1 2004/03/19 13:48:19 tom Exp $ */
2: /* $NetBSD: net.c,v 1.14 1996/10/13 02:29:02 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1992 Regents of the University of California.
6: * All rights reserved.
7: *
8: * This software was developed by the Computer Systems Engineering group
9: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10: * contributed to Berkeley.
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 University of
23: * California, Lawrence Berkeley Laboratory and its contributors.
24: * 4. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
40: * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL)
41: */
42:
43: #include <sys/param.h>
44: #include <sys/socket.h>
45:
46: #include <net/if.h>
47: #include <netinet/in.h>
48:
49: #include <netinet/in.h>
50: #include <netinet/if_ether.h>
51: #include <netinet/in_systm.h>
52: #include <netinet/ip.h>
53: #include <netinet/ip_var.h>
54: #include <netinet/udp.h>
55: #include <netinet/udp_var.h>
56:
57: #include <lib/libsa/stand.h>
58: #include <lib/libsa/net.h>
59:
60: #include <pxeboot.h>
61:
62: /* Caller must leave room for ethernet, ip and udp headers in front!! */
63: ssize_t
64: sendudp(struct iodesc *d, void *pkt, size_t len)
65: {
66: return pxesendudp(d, pkt, len);
67: }
68:
69: /*
70: * Receive a UDP packet and validate it is for us.
71: * Caller leaves room for the headers (Ether, IP, UDP)
72: */
73: ssize_t
74: readudp(struct iodesc *d, void *pkt, size_t len, time_t tleft)
75: {
76: return pxereadudp(d, pkt, len, tleft);
77: }
78:
79: /*
80: * Send a packet and wait for a reply, with exponential backoff.
81: *
82: * The send routine must return the actual number of bytes written.
83: *
84: * The receive routine can indicate success by returning the number of
85: * bytes read; it can return 0 to indicate EOF; it can return -1 with a
86: * non-zero errno to indicate failure; finally, it can return -1 with a
87: * zero errno to indicate it isn't done yet.
88: */
89: ssize_t
90: sendrecv(struct iodesc *d, ssize_t (*sproc)(struct iodesc *, void *, size_t),
91: void *sbuf, size_t ssize,
92: ssize_t (*rproc)(struct iodesc *, void *, size_t, time_t),
93: void *rbuf, size_t rsize)
94: {
95: ssize_t cc;
96: time_t t, tmo, tlast;
97: long tleft;
98:
99: #ifdef NET_DEBUG
100: if (debug)
101: printf("sendrecv: called\n");
102: #endif
103:
104: tmo = MINTMO;
105: tlast = tleft = 0;
106: t = getsecs();
107: for (;;) {
108: if (tleft <= 0) {
109: if (tmo >= MAXTMO) {
110: errno = ETIMEDOUT;
111: return -1;
112: }
113: cc = (*sproc)(d, sbuf, ssize);
114: if (cc < 0 || (size_t)cc < ssize)
115: panic("sendrecv: short write! (%d < %d)",
116: cc, ssize);
117:
118: tleft = tmo;
119: tmo <<= 1;
120: if (tmo > MAXTMO)
121: tmo = MAXTMO;
122: tlast = t;
123: }
124:
125: /* Try to get a packet and process it. */
126: cc = (*rproc)(d, rbuf, rsize, tleft);
127: /* Return on data, EOF or real error. */
128: if (cc != -1 || errno != 0)
129: return (cc);
130:
131: /* Timed out or didn't get the packet we're waiting for */
132: t = getsecs();
133: tleft -= t - tlast;
134: tlast = t;
135: }
136: }
137:
138: /*
139: * Like inet_addr() in the C library, but we only accept base-10.
140: * Return values are in network order.
141: */
142: n_long
143: inet_addr(char *cp)
144: {
145: u_long val;
146: int n;
147: char c;
148: u_int parts[4];
149: u_int *pp = parts;
150:
151: for (;;) {
152: /*
153: * Collect number up to ``.''.
154: * Values are specified as for C:
155: * 0x=hex, 0=octal, other=decimal.
156: */
157: val = 0;
158: while ((c = *cp) != '\0') {
159: if (c >= '0' && c <= '9') {
160: val = (val * 10) + (c - '0');
161: cp++;
162: continue;
163: }
164: break;
165: }
166: if (*cp == '.') {
167: /*
168: * Internet format:
169: * a.b.c.d
170: * a.b.c (with c treated as 16-bits)
171: * a.b (with b treated as 24 bits)
172: */
173: if (pp >= parts + 3 || val > 0xff)
174: goto bad;
175: *pp++ = val, cp++;
176: } else
177: break;
178: }
179: /*
180: * Check for trailing characters.
181: */
182: if (*cp != '\0')
183: goto bad;
184:
185: /*
186: * Concoct the address according to
187: * the number of parts specified.
188: */
189: n = pp - parts + 1;
190: switch (n) {
191:
192: case 1: /* a -- 32 bits */
193: break;
194:
195: case 2: /* a.b -- 8.24 bits */
196: if (val > 0xffffff)
197: goto bad;
198: val |= parts[0] << 24;
199: break;
200:
201: case 3: /* a.b.c -- 8.8.16 bits */
202: if (val > 0xffff)
203: goto bad;
204: val |= (parts[0] << 24) | (parts[1] << 16);
205: break;
206:
207: case 4: /* a.b.c.d -- 8.8.8.8 bits */
208: if (val > 0xff)
209: goto bad;
210: val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
211: break;
212: }
213:
214: return (htonl(val));
215: bad:
216: return (htonl(INADDR_NONE));
217: }
218:
219: char *
220: inet_ntoa(struct in_addr ia)
221: {
222: return (intoa(ia.s_addr));
223: }
224:
225: /* Similar to inet_ntoa() */
226: char *
227: intoa(n_long addr)
228: {
229: char *cp;
230: u_int byte;
231: int n;
232: static char buf[sizeof(".255.255.255.255")];
233:
234: NTOHL(addr);
235: cp = &buf[sizeof buf];
236: *--cp = '\0';
237:
238: n = 4;
239: do {
240: byte = addr & 0xff;
241: *--cp = byte % 10 + '0';
242: byte /= 10;
243: if (byte > 0) {
244: *--cp = byte % 10 + '0';
245: byte /= 10;
246: if (byte > 0)
247: *--cp = byte + '0';
248: }
249: *--cp = '.';
250: addr >>= 8;
251: } while (--n > 0);
252:
253: return (cp+1);
254: }
255:
256: static char *
257: number(char *s, int *n)
258: {
259: for (*n = 0; isdigit(*s); s++)
260: *n = (*n * 10) + *s - '0';
261: return s;
262: }
263:
264: n_long
265: ip_convertaddr(char *p)
266: {
267: #define IP_ANYADDR 0
268: n_long addr = 0, n;
269:
270: if (p == (char *)0 || *p == '\0')
271: return IP_ANYADDR;
272: p = number(p, &n);
273: addr |= (n << 24) & 0xff000000;
274: if (*p == '\0' || *p++ != '.')
275: return IP_ANYADDR;
276: p = number(p, &n);
277: addr |= (n << 16) & 0xff0000;
278: if (*p == '\0' || *p++ != '.')
279: return IP_ANYADDR;
280: p = number(p, &n);
281: addr |= (n << 8) & 0xff00;
282: if (*p == '\0' || *p++ != '.')
283: return IP_ANYADDR;
284: p = number(p, &n);
285: addr |= n & 0xff;
286: if (*p != '\0')
287: return IP_ANYADDR;
288:
289: return htonl(addr);
290: }
CVSweb