1 1.36 christos /* $NetBSD: net.c,v 1.36 2019/03/31 20:08:45 christos Exp $ */ 2 1.3 cgd 3 1.1 brezak /* 4 1.1 brezak * Copyright (c) 1992 Regents of the University of California. 5 1.1 brezak * All rights reserved. 6 1.1 brezak * 7 1.1 brezak * This software was developed by the Computer Systems Engineering group 8 1.1 brezak * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 1.1 brezak * contributed to Berkeley. 10 1.1 brezak * 11 1.1 brezak * Redistribution and use in source and binary forms, with or without 12 1.1 brezak * modification, are permitted provided that the following conditions 13 1.1 brezak * are met: 14 1.1 brezak * 1. Redistributions of source code must retain the above copyright 15 1.1 brezak * notice, this list of conditions and the following disclaimer. 16 1.1 brezak * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 brezak * notice, this list of conditions and the following disclaimer in the 18 1.1 brezak * documentation and/or other materials provided with the distribution. 19 1.1 brezak * 3. All advertising materials mentioning features or use of this software 20 1.1 brezak * must display the following acknowledgement: 21 1.1 brezak * This product includes software developed by the University of 22 1.1 brezak * California, Lawrence Berkeley Laboratory and its contributors. 23 1.1 brezak * 4. Neither the name of the University nor the names of its contributors 24 1.1 brezak * may be used to endorse or promote products derived from this software 25 1.1 brezak * without specific prior written permission. 26 1.1 brezak * 27 1.1 brezak * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 1.1 brezak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 1.1 brezak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 1.1 brezak * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 1.1 brezak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 1.1 brezak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 1.1 brezak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 1.1 brezak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 1.1 brezak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 1.1 brezak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 1.1 brezak * SUCH DAMAGE. 38 1.1 brezak * 39 1.3 cgd * @(#) Header: net.c,v 1.9 93/08/06 19:32:15 leres Exp (LBL) 40 1.1 brezak */ 41 1.1 brezak 42 1.1 brezak #include <sys/param.h> 43 1.1 brezak #include <sys/socket.h> 44 1.1 brezak 45 1.25 thorpej #ifdef _STANDALONE 46 1.25 thorpej #include <lib/libkern/libkern.h> 47 1.25 thorpej #else 48 1.25 thorpej #include <string.h> 49 1.25 thorpej #endif 50 1.25 thorpej 51 1.1 brezak #include <net/if.h> 52 1.17 drochner #include <net/if_ether.h> 53 1.1 brezak 54 1.1 brezak #include <netinet/in.h> 55 1.1 brezak #include <netinet/in_systm.h> 56 1.1 brezak #include <netinet/ip.h> 57 1.1 brezak 58 1.30 dsl #ifdef _STANDALONE 59 1.1 brezak #include "stand.h" 60 1.30 dsl #define delay() 61 1.30 dsl #else 62 1.30 dsl #include <errno.h> 63 1.30 dsl #include <stdio.h> 64 1.30 dsl #include <unistd.h> 65 1.30 dsl #define panic printf 66 1.30 dsl #define delay() usleep(100000) 67 1.30 dsl #endif 68 1.30 dsl 69 1.34 isaki #include "net.h" 70 1.1 brezak 71 1.1 brezak /* 72 1.1 brezak * Send a packet and wait for a reply, with exponential backoff. 73 1.1 brezak * 74 1.20 scottr * The send routine must return the actual number of bytes written, 75 1.20 scottr * or -1 on error. 76 1.1 brezak * 77 1.1 brezak * The receive routine can indicate success by returning the number of 78 1.1 brezak * bytes read; it can return 0 to indicate EOF; it can return -1 with a 79 1.1 brezak * non-zero errno to indicate failure; finally, it can return -1 with a 80 1.1 brezak * zero errno to indicate it isn't done yet. 81 1.1 brezak */ 82 1.6 pk ssize_t 83 1.31 isaki sendrecv(struct iodesc *d, 84 1.31 isaki ssize_t (*sproc)(struct iodesc *, void *, size_t), 85 1.31 isaki void *sbuf, size_t ssize, 86 1.32 tsutsui ssize_t (*rproc)(struct iodesc *, void *, size_t, saseconds_t), 87 1.31 isaki void *rbuf, size_t rsize) 88 1.1 brezak { 89 1.26 augustss ssize_t cc; 90 1.32 tsutsui satime_t t, tlast; 91 1.32 tsutsui saseconds_t tmo, tleft; 92 1.1 brezak 93 1.1 brezak #ifdef NET_DEBUG 94 1.1 brezak if (debug) 95 1.36 christos printf("%s: called\n", __func__); 96 1.1 brezak #endif 97 1.4 mycroft 98 1.1 brezak tmo = MINTMO; 99 1.32 tsutsui tlast = 0; 100 1.32 tsutsui tleft = 0; 101 1.1 brezak t = getsecs(); 102 1.1 brezak for (;;) { 103 1.1 brezak if (tleft <= 0) { 104 1.12 pk if (tmo >= MAXTMO) { 105 1.8 pk errno = ETIMEDOUT; 106 1.8 pk return -1; 107 1.8 pk } 108 1.1 brezak cc = (*sproc)(d, sbuf, ssize); 109 1.1 brezak 110 1.1 brezak tleft = tmo; 111 1.1 brezak tmo <<= 1; 112 1.1 brezak if (tmo > MAXTMO) 113 1.1 brezak tmo = MAXTMO; 114 1.20 scottr 115 1.20 scottr if (cc == -1) { 116 1.20 scottr /* Error on transmit; wait before retrying */ 117 1.30 dsl while ((getsecs() - t) < tmo) 118 1.30 dsl delay(); 119 1.20 scottr tleft = 0; 120 1.20 scottr continue; 121 1.20 scottr } 122 1.35 lukem if ((size_t)cc < ssize) 123 1.36 christos panic("%s: short write! (%zd < %zu)", __func__, 124 1.30 dsl cc, ssize); 125 1.20 scottr 126 1.1 brezak tlast = t; 127 1.1 brezak } 128 1.1 brezak 129 1.4 mycroft /* Try to get a packet and process it. */ 130 1.4 mycroft cc = (*rproc)(d, rbuf, rsize, tleft); 131 1.4 mycroft /* Return on data, EOF or real error. */ 132 1.4 mycroft if (cc != -1 || errno != 0) 133 1.31 isaki return cc; 134 1.4 mycroft 135 1.1 brezak /* Timed out or didn't get the packet we're waiting for */ 136 1.1 brezak t = getsecs(); 137 1.1 brezak tleft -= t - tlast; 138 1.1 brezak tlast = t; 139 1.1 brezak } 140 1.1 brezak } 141