1184610Salfred/* 2184610Salfred * Copyright (c) 1988, 1993 3184610Salfred * The Regents of the University of California. All rights reserved. 4184610Salfred * 5184610Salfred * Redistribution and use in source and binary forms, with or without 6184610Salfred * modification, are permitted provided that the following conditions 7184610Salfred * are met: 8184610Salfred * 1. Redistributions of source code must retain the above copyright 9184610Salfred * notice, this list of conditions and the following disclaimer. 10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright 11184610Salfred * notice, this list of conditions and the following disclaimer in the 12184610Salfred * documentation and/or other materials provided with the distribution. 13184610Salfred * 3. All advertising materials mentioning features or use of this software 14184610Salfred * must display the following acknowledgement: 15184610Salfred * This product includes software developed by the University of 16184610Salfred * California, Berkeley and its contributors. 17184610Salfred * 4. Neither the name of the University nor the names of its contributors 18184610Salfred * may be used to endorse or promote products derived from this software 19184610Salfred * without specific prior written permission. 20184610Salfred * 21184610Salfred * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24184610Salfred * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26188417Sthompsa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29191746Sthompsa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30191746Sthompsa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31191746Sthompsa * SUCH DAMAGE. 32191746Sthompsa */ 33191746Sthompsa 34194677Sthompsa#if 0 35191746Sthompsa#ifndef lint 36191746Sthompsastatic const char sccsid[] = "@(#)network.c 8.2 (Berkeley) 12/15/93"; 37191746Sthompsa#endif 38191746Sthompsa#endif 39191746Sthompsa#include <sys/cdefs.h> 40191746Sthompsa__FBSDID("$FreeBSD$"); 41191746Sthompsa 42191746Sthompsa#include <sys/types.h> 43191746Sthompsa#include <sys/socket.h> 44191746Sthompsa#include <sys/time.h> 45191746Sthompsa 46191746Sthompsa#include <errno.h> 47191746Sthompsa#include <stdlib.h> 48191746Sthompsa 49191746Sthompsa#include <arpa/telnet.h> 50191746Sthompsa#include <unistd.h> 51191746Sthompsa 52191746Sthompsa#include "ring.h" 53191746Sthompsa 54191746Sthompsa#include "defines.h" 55191746Sthompsa#include "externs.h" 56191746Sthompsa#include "fdset.h" 57191746Sthompsa 58191746SthompsaRing netoring, netiring; 59191746Sthompsaunsigned char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 60191746Sthompsa 61191746Sthompsa/* 62191746Sthompsa * Initialize internal network data structures. 63191746Sthompsa */ 64206358Srpaulo 65191746Sthompsavoid 66188942Sthompsainit_network(void) 67194677Sthompsa{ 68194677Sthompsa if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 69191746Sthompsa exit(1); 70184610Salfred } 71188942Sthompsa if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 72188942Sthompsa exit(1); 73184610Salfred } 74207077Sthompsa NetTrace = stdout; 75184610Salfred} 76184610Salfred 77227309Sed 78192502Sthompsa/* 79184610Salfred * Check to see if any out-of-band data exists on a socket (for 80188417Sthompsa * Telnet "synch" processing). 81188417Sthompsa */ 82188417Sthompsa 83188417Sthompsaint 84188417Sthompsastilloob(void) 85188417Sthompsa{ 86188417Sthompsa static struct timeval timeout = { 0, 0 }; 87188417Sthompsa fd_set excepts; 88188417Sthompsa int value; 89188417Sthompsa 90188417Sthompsa do { 91188417Sthompsa FD_ZERO(&excepts); 92188417Sthompsa FD_SET(net, &excepts); 93188417Sthompsa value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 94188417Sthompsa } while ((value == -1) && (errno == EINTR)); 95188419Sthompsa 96188417Sthompsa if (value < 0) { 97188417Sthompsa perror("select"); 98188417Sthompsa (void) quit(); 99188417Sthompsa /* NOTREACHED */ 100188417Sthompsa } 101188417Sthompsa if (FD_ISSET(net, &excepts)) { 102184610Salfred return 1; 103184610Salfred } else { 104188419Sthompsa return 0; 105194228Sthompsa } 106188419Sthompsa} 107188417Sthompsa 108184610Salfred 109184610Salfred/* 110184610Salfred * setneturg() 111193045Sthompsa * 112193045Sthompsa * Sets "neturg" to the current location. 113193045Sthompsa */ 114193045Sthompsa 115184610Salfredvoid 116185948Sthompsasetneturg(void) 117228621Sbschmidt{ 118228621Sbschmidt ring_mark(&netoring); 119228621Sbschmidt} 120185948Sthompsa 121188417Sthompsa 122188419Sthompsa/* 123188419Sthompsa * netflush 124188417Sthompsa * Send as much data as possible to the network, 125188417Sthompsa * handling requests for urgent data. 126188601Sthompsa * 127188417Sthompsa * The return value indicates whether we did any 128188417Sthompsa * useful work. 129188417Sthompsa */ 130188417Sthompsa 131188417Sthompsaint 132188417Sthompsanetflush(void) 133188417Sthompsa{ 134188417Sthompsa int n, n1; 135188417Sthompsa 136188417Sthompsa#ifdef ENCRYPTION 137188417Sthompsa if (encrypt_output) 138188417Sthompsa ring_encrypt(&netoring, encrypt_output); 139188417Sthompsa#endif /* ENCRYPTION */ 140188417Sthompsa if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 141188417Sthompsa if (!ring_at_mark(&netoring)) { 142188417Sthompsa n = send(net, (char *)netoring.consume, n, 0); /* normal write */ 143188417Sthompsa } else { 144188417Sthompsa /* 145188417Sthompsa * In 4.2 (and 4.3) systems, there is some question about 146188417Sthompsa * what byte in a sendOOB operation is the "OOB" data. 147188417Sthompsa * To make ourselves compatible, we only send ONE byte 148188417Sthompsa * out of band, the one WE THINK should be OOB (though 149192984Sthompsa * we really have more the TCP philosophy of urgent data 150193803Sweongyo * rather than the Unix philosophy of OOB data). 151185948Sthompsa */ 152188417Sthompsa n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */ 153188417Sthompsa } 154185948Sthompsa } 155188417Sthompsa if (n < 0) { 156191746Sthompsa if (errno != ENOBUFS && errno != EWOULDBLOCK) { 157188417Sthompsa setcommandmode(); 158191746Sthompsa perror(hostname); 159188417Sthompsa (void)NetClose(net); 160188417Sthompsa ring_clear_mark(&netoring); 161188417Sthompsa ExitString("Connection closed by foreign host.\n", 1); 162188417Sthompsa /*NOTREACHED*/ 163188417Sthompsa } 164188417Sthompsa n = 0; 165188417Sthompsa } 166188417Sthompsa if (netdata && n) { 167188417Sthompsa Dump('>', netoring.consume, n); 168188417Sthompsa } 169188417Sthompsa if (n) { 170188417Sthompsa ring_consumed(&netoring, n); 171188417Sthompsa /* 172188417Sthompsa * If we sent all, and more to send, then recurse to pick 173188417Sthompsa * up the other half. 174188417Sthompsa */ 175188417Sthompsa if ((n1 == n) && ring_full_consecutive(&netoring)) { 176188417Sthompsa (void) netflush(); 177188417Sthompsa } 178188417Sthompsa return 1; 179188417Sthompsa } else { 180193420Sweongyo return 0; 181193420Sweongyo } 182193420Sweongyo} 183193420Sweongyo