129088Smarkm/* 229088Smarkm * Copyright (c) 1988, 1993 329088Smarkm * The Regents of the University of California. All rights reserved. 429088Smarkm * 529088Smarkm * Redistribution and use in source and binary forms, with or without 629088Smarkm * modification, are permitted provided that the following conditions 729088Smarkm * are met: 829088Smarkm * 1. Redistributions of source code must retain the above copyright 929088Smarkm * notice, this list of conditions and the following disclaimer. 1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1129088Smarkm * notice, this list of conditions and the following disclaimer in the 1229088Smarkm * documentation and/or other materials provided with the distribution. 1329088Smarkm * 3. All advertising materials mentioning features or use of this software 1429088Smarkm * must display the following acknowledgement: 1529088Smarkm * This product includes software developed by the University of 1629088Smarkm * California, Berkeley and its contributors. 1729088Smarkm * 4. Neither the name of the University nor the names of its contributors 1829088Smarkm * may be used to endorse or promote products derived from this software 1929088Smarkm * without specific prior written permission. 2029088Smarkm * 2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2429088Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3129088Smarkm * SUCH DAMAGE. 3229088Smarkm */ 3329088Smarkm 34114630Sobrien#if 0 3529088Smarkm#ifndef lint 3629181Smarkmstatic const char sccsid[] = "@(#)network.c 8.2 (Berkeley) 12/15/93"; 3763248Speter#endif 38114630Sobrien#endif 39114630Sobrien#include <sys/cdefs.h> 40114630Sobrien__FBSDID("$FreeBSD$"); 4129088Smarkm 4229088Smarkm#include <sys/types.h> 4329088Smarkm#include <sys/socket.h> 4429088Smarkm#include <sys/time.h> 4529088Smarkm 4629088Smarkm#include <errno.h> 4796385Salfred#include <stdlib.h> 4829088Smarkm 4929088Smarkm#include <arpa/telnet.h> 5029181Smarkm#include <unistd.h> 5129088Smarkm 5229088Smarkm#include "ring.h" 5329088Smarkm 5429088Smarkm#include "defines.h" 5529088Smarkm#include "externs.h" 5629088Smarkm#include "fdset.h" 5729088Smarkm 5829088SmarkmRing netoring, netiring; 5929088Smarkmunsigned char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 6029088Smarkm 6129088Smarkm/* 6229088Smarkm * Initialize internal network data structures. 6329088Smarkm */ 6429088Smarkm 6587139Smarkmvoid 6687139Smarkminit_network(void) 6729088Smarkm{ 6829088Smarkm if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 6929088Smarkm exit(1); 7029088Smarkm } 7129088Smarkm if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 7229088Smarkm exit(1); 7329088Smarkm } 7429088Smarkm NetTrace = stdout; 7529088Smarkm} 7629088Smarkm 7729088Smarkm 7829088Smarkm/* 7929088Smarkm * Check to see if any out-of-band data exists on a socket (for 8029088Smarkm * Telnet "synch" processing). 8129088Smarkm */ 8229088Smarkm 8387139Smarkmint 8487139Smarkmstilloob(void) 8529088Smarkm{ 8687139Smarkm static struct timeval timeout = { 0, 0 }; 8729088Smarkm fd_set excepts; 8829088Smarkm int value; 8929088Smarkm 9029088Smarkm do { 9129088Smarkm FD_ZERO(&excepts); 9229088Smarkm FD_SET(net, &excepts); 9329088Smarkm value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 9429088Smarkm } while ((value == -1) && (errno == EINTR)); 9529088Smarkm 9629088Smarkm if (value < 0) { 9729088Smarkm perror("select"); 9829088Smarkm (void) quit(); 9929088Smarkm /* NOTREACHED */ 10029088Smarkm } 10129088Smarkm if (FD_ISSET(net, &excepts)) { 10229088Smarkm return 1; 10329088Smarkm } else { 10429088Smarkm return 0; 10529088Smarkm } 10629088Smarkm} 10729088Smarkm 10829088Smarkm 10929088Smarkm/* 11029088Smarkm * setneturg() 11129088Smarkm * 11229088Smarkm * Sets "neturg" to the current location. 11329088Smarkm */ 11429088Smarkm 11587139Smarkmvoid 11687139Smarkmsetneturg(void) 11729088Smarkm{ 11829088Smarkm ring_mark(&netoring); 11929088Smarkm} 12029088Smarkm 12129088Smarkm 12229088Smarkm/* 12329088Smarkm * netflush 12429088Smarkm * Send as much data as possible to the network, 12529088Smarkm * handling requests for urgent data. 12629088Smarkm * 12729088Smarkm * The return value indicates whether we did any 12829088Smarkm * useful work. 12929088Smarkm */ 13029088Smarkm 13187139Smarkmint 13287139Smarkmnetflush(void) 13329088Smarkm{ 13487139Smarkm int n, n1; 13529088Smarkm 13629088Smarkm#ifdef ENCRYPTION 13729088Smarkm if (encrypt_output) 13829088Smarkm ring_encrypt(&netoring, encrypt_output); 13929088Smarkm#endif /* ENCRYPTION */ 14029088Smarkm if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 14129088Smarkm if (!ring_at_mark(&netoring)) { 14229088Smarkm n = send(net, (char *)netoring.consume, n, 0); /* normal write */ 14329088Smarkm } else { 14429088Smarkm /* 14529088Smarkm * In 4.2 (and 4.3) systems, there is some question about 14629088Smarkm * what byte in a sendOOB operation is the "OOB" data. 14729088Smarkm * To make ourselves compatible, we only send ONE byte 14829088Smarkm * out of band, the one WE THINK should be OOB (though 14929088Smarkm * we really have more the TCP philosophy of urgent data 15029088Smarkm * rather than the Unix philosophy of OOB data). 15129088Smarkm */ 15229088Smarkm n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */ 15329088Smarkm } 15429088Smarkm } 15529088Smarkm if (n < 0) { 15629088Smarkm if (errno != ENOBUFS && errno != EWOULDBLOCK) { 15729088Smarkm setcommandmode(); 15829088Smarkm perror(hostname); 15929088Smarkm (void)NetClose(net); 16029088Smarkm ring_clear_mark(&netoring); 161207449Sjilles ExitString("Connection closed by foreign host.\n", 1); 16229088Smarkm /*NOTREACHED*/ 16329088Smarkm } 16429088Smarkm n = 0; 16529088Smarkm } 16629088Smarkm if (netdata && n) { 16729088Smarkm Dump('>', netoring.consume, n); 16829088Smarkm } 16929088Smarkm if (n) { 17029088Smarkm ring_consumed(&netoring, n); 17129088Smarkm /* 17229088Smarkm * If we sent all, and more to send, then recurse to pick 17329088Smarkm * up the other half. 17429088Smarkm */ 17529088Smarkm if ((n1 == n) && ring_full_consecutive(&netoring)) { 17629088Smarkm (void) netflush(); 17729088Smarkm } 17829088Smarkm return 1; 17929088Smarkm } else { 18029088Smarkm return 0; 18129088Smarkm } 18229088Smarkm} 183