[BACK]Return to net.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / stand / pxeboot

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