1e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ 2e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 3e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 4e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 5e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Redistribution and use in source and binary forms, with or without 6e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * modification, are permitted provided that the following conditions 7e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * are met: 8e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 9e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 1. Redistributions of source code must retain the above copyright 10e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * notice, this list of conditions and the following disclaimer. 11e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 2. Redistributions in binary form must reproduce the above copyright 12e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * notice, this list of conditions and the following disclaimer in the 13e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * documentation and/or other materials provided with the distribution. 14e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 3. The name of the author may not be used to endorse or promote products 15e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * derived from this software without specific prior written permission. 16e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 17e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 28e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 29e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 30e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Re-written nc(1) for OpenBSD. Original implementation by 31e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * *Hobbit* <hobbit@avian.org>. 32e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 33e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 34e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <sys/types.h> 35e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <sys/socket.h> 36e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <sys/time.h> 37e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <sys/un.h> 38e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 39e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <netinet/in.h> 40e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <netinet/in_systm.h> 41e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <netinet/tcp.h> 42e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <netinet/ip.h> 43e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <arpa/telnet.h> 44e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 45e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <err.h> 46e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <errno.h> 47e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <netdb.h> 48e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <poll.h> 49e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <stdarg.h> 50e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <stdio.h> 51e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <stdlib.h> 52e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <string.h> 53e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <unistd.h> 54e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <fcntl.h> 55e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <limits.h> 56e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include "atomicio.h" 57e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 58e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef SUN_LEN 59e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#define SUN_LEN(su) \ 60e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) 615e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 625e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 63e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#define PORT_MAX 65535 64e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#define PORT_MAX_LEN 6 65e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#define UNIX_DG_TMP_SOCKET_SIZE 19 66e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 67e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* Command Line Options */ 68e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint dflag; /* detached, no stdin */ 69e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichunsigned int iflag; /* Interval Flag */ 70e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 71e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint jflag = 0; 72e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 73e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint jflag; /* use jumbo frames if we can */ 74e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 75e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint kflag; /* More than one connect */ 76e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint lflag; /* Bind to local port */ 77e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint nflag; /* Don't do name look up */ 78e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichchar *Pflag; /* Proxy username */ 79e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichchar *pflag; /* Localport flag */ 80e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint rflag; /* Random ports flag */ 81e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichchar *sflag; /* Source Address */ 82e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint tflag; /* Telnet Emulation */ 83e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint uflag; /* UDP - Default to TCP */ 84e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint vflag; /* Verbosity */ 85e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 86e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint xflag; /* Socks proxy */ 87e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 88e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint zflag; /* Port Scan Flag */ 89e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint Dflag; /* sodebug */ 90e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint Iflag; /* TCP receive buffer size */ 91e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint Oflag; /* TCP send buffer size */ 92e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 93e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint Sflag; /* TCP MD5 signature option */ 94e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint Tflag = -1; /* IP Type of Service */ 95e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichu_int rtableid; 96e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 97e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 98e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint timeout = -1; 99e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint family = AF_UNSPEC; 100e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichchar *portlist[PORT_MAX+1]; 101e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichchar *unix_dg_tmp_socket; 102e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 103e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid atelnet(int, unsigned char *, unsigned int); 104e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid build_ports(char *); 105e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid help(void); 106e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint local_listen(char *, char *, struct addrinfo); 107e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid readwrite(int); 108e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint remote_connect(const char *, const char *, struct addrinfo); 109e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint timeout_connect(int, const struct sockaddr *, socklen_t); 110e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 111e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint socks_connect(const char *, const char *, struct addrinfo, 112e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich const char *, const char *, struct addrinfo, int, const char *); 113e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 114e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint udptest(int); 115e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint unix_bind(char *); 116e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint unix_connect(char *); 117e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint unix_listen(char *); 118e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid set_common_sockopts(int); 119e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint map_tos(char *, int *); 120e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid usage(int); 121e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 122e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 123e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichmain(int argc, char *argv[]) 124e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich{ 125e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int ch, s, ret, socksv; 126e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char *host, *uport; 127e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct addrinfo hints; 128e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct servent *sv; 129e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socklen_t len; 130e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct sockaddr_storage cliaddr; 131e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char *proxy; 132e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich const char *errstr, *proxyhost = "", *proxyport = NULL; 133e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct addrinfo proxyhints; 134e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; 135e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 136e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 1; 137e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = 0; 138e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socksv = 5; 139e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich host = NULL; 140e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uport = NULL; 141e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sv = NULL; 142e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 143e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich while ((ch = getopt(argc, argv, 144e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "46DdhI:i:jklnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { 145e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich switch (ch) { 146e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case '4': 147e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich family = AF_INET; 148e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 149e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case '6': 150e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich family = AF_INET6; 151e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 152e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'U': 153e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich family = AF_UNIX; 154e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 155e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'X': 156e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (strcasecmp(optarg, "connect") == 0) 157e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socksv = -1; /* HTTP proxy CONNECT */ 158e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (strcmp(optarg, "4") == 0) 159e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socksv = 4; /* SOCKS v.4 */ 160e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (strcmp(optarg, "5") == 0) 161e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socksv = 5; /* SOCKS v.5 */ 162e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 163e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "unsupported proxy protocol"); 164e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 165e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'd': 166e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich dflag = 1; 167e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 168e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'h': 169e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich help(); 170e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 171e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'i': 172e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 173e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich iflag = atoi(optarg); 174e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 175e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich iflag = strtonum(optarg, 0, UINT_MAX, &errstr); 176e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 177e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "interval %s: %s", errstr, optarg); 178e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* ANDROID */ 179e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 180e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 181e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'j': 182e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich jflag = 1; 183e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 184e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 185e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'k': 186e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich kflag = 1; 187e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 188e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'l': 189e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich lflag = 1; 190e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 191e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'n': 192e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich nflag = 1; 193e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 194e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'P': 195e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Pflag = optarg; 196e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 197e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'p': 198e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pflag = optarg; 199e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 200e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'r': 201e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich rflag = 1; 202e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 203e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 's': 204e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sflag = optarg; 205e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 206e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 't': 207e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich tflag = 1; 208e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 209e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'u': 210e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uflag = 1; 211e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 212e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 213e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'V': 214e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich rtableid = (unsigned int)strtonum(optarg, 0, 215e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich RT_TABLEID_MAX, &errstr); 216e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 217e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "rtable %s: %s", errstr, optarg); 218e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 219e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 220e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'v': 221e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich vflag = 1; 222e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 223e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'w': 224e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 225e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich timeout = atoi(optarg); 226e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 227e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); 228e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 229e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "timeout %s: %s", errstr, optarg); 230e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif 231e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich timeout *= 1000; 232e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 233e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 234e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'x': 235e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich xflag = 1; 236e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((proxy = strdup(optarg)) == NULL) 237e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 238e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 239e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 240e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'z': 241e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich zflag = 1; 242e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 243e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'D': 244e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Dflag = 1; 245e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 246e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'I': 247e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 248e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Iflag = atoi(optarg); 2495e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#else 250e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); 251e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr != NULL) 252e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "TCP receive window %s: %s", 253e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errstr, optarg); 2545e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 255e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 256e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'O': 257e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 258e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Oflag = atoi(optarg); 259e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 260e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); 261e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr != NULL) 262e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "TCP send window %s: %s", 263e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errstr, optarg); 2645e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 265e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 266e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 267e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'S': 268e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Sflag = 1; 269e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 270e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 'T': 271e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errstr = NULL; 272e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = 0; 273e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (map_tos(optarg, &Tflag)) 274e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 275e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (strlen(optarg) > 1 && optarg[0] == '0' && 276e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich optarg[1] == 'x') 277e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Tflag = (int)strtol(optarg, NULL, 16); 278e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 279e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Tflag = (int)strtonum(optarg, 0, 255, 280e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &errstr); 281e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Tflag < 0 || Tflag > 255 || errstr || errno) 282e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "illegal tos value %s", optarg); 283e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 284e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 285e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich default: 286e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich usage(1); 287e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 288e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 289e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich argc -= optind; 290e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich argv += optind; 291e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 292e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Cruft to make sure options are clean, and used properly. */ 293e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (argv[0] && !argv[1] && family == AF_UNIX) { 294e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich host = argv[0]; 295e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uport = NULL; 296e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else if (argv[0] && !argv[1]) { 297e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!lflag) 298e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich usage(1); 299e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uport = argv[0]; 300e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich host = NULL; 301e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else if (argv[0] && argv[1]) { 302e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich host = argv[0]; 303e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uport = argv[1]; 304e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else 305e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich usage(1); 306e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 307e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag && sflag) 308e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "cannot use -s and -l"); 309e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag && pflag) 310e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "cannot use -p and -l"); 311e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag && zflag) 312e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "cannot use -z and -l"); 313e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!lflag && kflag) 314e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "must use -l with -k"); 315e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 316e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Get name of temporary socket for unix datagram client */ 317e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((family == AF_UNIX) && uflag && !lflag) { 318e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (sflag) { 319e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unix_dg_tmp_socket = sflag; 320e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 321e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", 322e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich UNIX_DG_TMP_SOCKET_SIZE); 323e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (mktemp(unix_dg_tmp_socket_buf) == NULL) 324e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "mktemp"); 325e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unix_dg_tmp_socket = unix_dg_tmp_socket_buf; 326e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 327e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 328e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 329e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Initialize addrinfo structure. */ 330e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family != AF_UNIX) { 331e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich memset(&hints, 0, sizeof(struct addrinfo)); 332e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_family = family; 333e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 334e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 335e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (nflag) 336e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_flags |= AI_NUMERICHOST; 337e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 3385e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 339e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 340e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (xflag) { 341e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) 342e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "no proxy support for UDP mode"); 3435e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 344e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag) 345e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "no proxy support for listen"); 3465e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 347e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family == AF_UNIX) 348e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "no proxy support for unix sockets"); 3495e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 350e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* XXX IPv6 transport to proxy would probably work */ 351e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family == AF_INET6) 352e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "no proxy support for IPv6"); 3535e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 354e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (sflag) 355e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "no proxy support for local source address"); 3565e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 357e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhost = strsep(&proxy, ":"); 358e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyport = proxy; 3595e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 360e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich memset(&proxyhints, 0, sizeof(struct addrinfo)); 361e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhints.ai_family = family; 362e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhints.ai_socktype = SOCK_STREAM; 363e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhints.ai_protocol = IPPROTO_TCP; 364e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (nflag) 365e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhints.ai_flags |= AI_NUMERICHOST; 366e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 367e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 368e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 369e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag) { 370e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int connfd; 371e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 0; 372e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 373e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family == AF_UNIX) { 374e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) 375e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = unix_bind(host); 376e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 377e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = unix_listen(host); 378e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 379e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 380e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Allow only one connection at a time, but stay alive. */ 381e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (;;) { 382e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family != AF_UNIX) 383e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = local_listen(host, uport, hints); 384e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (s < 0) 385e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 386e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* 387e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * For UDP, we will use recvfrom() initially 388e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * to wait for a caller, then use the regular 389e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * functions to talk to the caller. 390e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 391e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) { 392e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int rv, plen; 393e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char buf[16384]; 394e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct sockaddr_storage z; 395e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 396e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich len = sizeof(z); 397e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich plen = jflag ? 16384 : 2048; 398e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich rv = recvfrom(s, buf, plen, MSG_PEEK, 399e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich (struct sockaddr *)&z, &len); 400e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (rv < 0) 401e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "recvfrom"); 402e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 403e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich rv = connect(s, (struct sockaddr *)&z, len); 404e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (rv < 0) 405e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "connect"); 406e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 407e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich readwrite(s); 408e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 409e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich len = sizeof(cliaddr); 410e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich connfd = accept(s, (struct sockaddr *)&cliaddr, 411e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &len); 412e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich readwrite(connfd); 413e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(connfd); 414e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 415e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 416e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (family != AF_UNIX) 417e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 418e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (uflag) { 419e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (connect(s, NULL, 0) < 0) 420e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "connect"); 421e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 422e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 423e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!kflag) 424e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 425e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 426e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else if (family == AF_UNIX) { 427e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 0; 428e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 429e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = unix_connect(host)) > 0 && !zflag) { 430e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich readwrite(s); 431e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 432e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else 433e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 1; 434e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 435e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) 436e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unlink(unix_dg_tmp_socket); 437e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich exit(ret); 4385e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 439e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 440e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int i = 0; 441e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 442e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Construct the portlist[] array. */ 443e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich build_ports(uport); 444e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 445e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Cycle through portlist, connecting to each port. */ 446e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (i = 0; portlist[i] != NULL; i++) { 447e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (s) 448e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 449e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 450e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 451e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (xflag) 452e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = socks_connect(host, portlist[i], hints, 453e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich proxyhost, proxyport, proxyhints, socksv, 454e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Pflag); 455e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 456e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 457e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = remote_connect(host, portlist[i], hints); 458e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 459e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (s < 0) 460e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 461e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 462e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 0; 463e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (vflag || zflag) { 464e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* For UDP, make sure we are connected. */ 465e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) { 466e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (udptest(s) == -1) { 467e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 1; 468e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 469e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 470e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 471e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 472e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Don't look up port if -n. */ 473e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (nflag) 474e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sv = NULL; 475e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else { 476e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sv = getservbyport( 477e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ntohs(atoi(portlist[i])), 478e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uflag ? "udp" : "tcp"); 479e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 480e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 481e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich fprintf(stderr, 482e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "Connection to %s %s port [%s/%s] " 483e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "succeeded!\n", host, portlist[i], 484e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uflag ? "udp" : "tcp", 485e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sv ? sv->s_name : "*"); 486e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 487e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!zflag) 488e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich readwrite(s); 489e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 490e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 491e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 492e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (s) 493e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 494e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 495e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich exit(ret); 496e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 497e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 498e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 499e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * unix_bind() 500e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Returns a unix socket bound to the given path 501e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 502e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 503e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichunix_bind(char *path) 5045e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 505e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct sockaddr_un sun; 506e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int s; 507e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 508e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Create unix domain socket. */ 509e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, 510e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 0)) < 0) 511e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 512e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 513e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich memset(&sun, 0, sizeof(struct sockaddr_un)); 514e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sun.sun_family = AF_UNIX; 515e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 516e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 517e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sizeof(sun.sun_path)) { 518e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 519e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = ENAMETOOLONG; 520e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 521e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 522e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 523e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 524e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 525e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 526e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 527e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (s); 5285e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project} 5295e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 530e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 531e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * unix_connect() 532e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Returns a socket connected to a local unix socket. Returns -1 on failure. 533e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 534e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 535e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichunix_connect(char *path) 5365e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 537e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct sockaddr_un sun; 538e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int s; 539e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 540e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (uflag) { 541e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = unix_bind(unix_dg_tmp_socket)) < 0) 542e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 543e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 544e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 545e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 546e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 547e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich (void)fcntl(s, F_SETFD, 1); 548e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 549e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich memset(&sun, 0, sizeof(struct sockaddr_un)); 550e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sun.sun_family = AF_UNIX; 551e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 552e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 553e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sizeof(sun.sun_path)) { 554e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 555e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = ENAMETOOLONG; 556e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 557e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 558e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 559e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 560e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 561e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 562e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (s); 563e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 5645e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project} 5655e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 566e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 567e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * unix_listen() 568e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Create a unix domain socket, and listen on it. 569e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 570e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 571e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichunix_listen(char *path) 5725e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 573e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int s; 574e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = unix_bind(path)) < 0) 575e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 576e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 577e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (listen(s, 5) < 0) { 578e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 579e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (-1); 580e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 581e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (s); 582e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 583e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 584e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 585e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * remote_connect() 586e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Returns a socket connected to a remote host. Properly binds to a local 587e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * port or source address if needed. Returns -1 on failure. 588e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 589e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 590e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichremote_connect(const char *host, const char *port, struct addrinfo hints) 5915e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 592e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct addrinfo *res, *res0; 593e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int s, error, on = 1; 594e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 595e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((error = getaddrinfo(host, port, &hints, &res))) 596e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "getaddrinfo: %s", gai_strerror(error)); 597e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 598e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res0 = res; 599e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich do { 600e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = socket(res0->ai_family, res0->ai_socktype, 601e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res0->ai_protocol)) < 0) 602e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 603e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 604e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 605e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (rtableid) { 606e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, 607e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sizeof(rtableid)) == -1) 608e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "setsockopt SO_RTABLE"); 609e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 610e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 611e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 612e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Bind to a local port or source address if specified. */ 613e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (sflag || pflag) { 614e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct addrinfo ahints, *ares; 615e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 616e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 617e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* try SO_BINDANY, but don't insist */ 618e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); 619e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 620e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich memset(&ahints, 0, sizeof(struct addrinfo)); 621e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ahints.ai_family = res0->ai_family; 622e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 623e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 624e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ahints.ai_flags = AI_PASSIVE; 625e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) 626e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "getaddrinfo: %s", gai_strerror(error)); 627e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 628e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (bind(s, (struct sockaddr *)ares->ai_addr, 629e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ares->ai_addrlen) < 0) 630e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "bind failed: %s", strerror(errno)); 631e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich freeaddrinfo(ares); 632e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 633e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 634e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich set_common_sockopts(s); 635e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 636e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) 637e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 638e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (vflag) 639e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich warn("connect to %s port %s (%s) failed", host, port, 640e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich uflag ? "udp" : "tcp"); 641e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 642e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 643e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = -1; 644e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } while ((res0 = res0->ai_next) != NULL); 645e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 646e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich freeaddrinfo(res); 647e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 648e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (s); 649e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 650e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 651e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 652e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichtimeout_connect(int s, const struct sockaddr *name, socklen_t namelen) 6535e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 654e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct pollfd pfd; 655e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich socklen_t optlen; 656e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int flags, optval; 657e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int ret; 658e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 659e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (timeout != -1) { 660e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich flags = fcntl(s, F_GETFL, 0); 661e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) 662e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "set non-blocking mode"); 663e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 664e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 665e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { 666e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd.fd = s; 667e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd.events = POLLOUT; 668e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((ret = poll(&pfd, 1, timeout)) == 1) { 669e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich optlen = sizeof(optval); 670e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, 671e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &optval, &optlen)) == 0) { 672e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = optval; 673e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = optval == 0 ? 0 : -1; 674e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 675e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else if (ret == 0) { 676e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = ETIMEDOUT; 677e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = -1; 678e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else 679e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "poll failed"); 680e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 681e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 682e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) 683e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "restoring flags"); 684e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 685e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (ret); 686e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 687e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 688e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 689e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * local_listen() 690e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Returns a socket listening on a local port, binds to specified source 691e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * address. Returns -1 on failure. 692e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 693e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 694e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichlocal_listen(char *host, char *port, struct addrinfo hints) 6955e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 696e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct addrinfo *res, *res0; 697e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int s, ret, x = 1; 698e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int error; 699e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 700e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Allow nodename to be null. */ 701e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_flags |= AI_PASSIVE; 702e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 703e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* 704e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * In the case of binding to a wildcard address 705e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * default to binding to an ipv4 address. 706e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 707e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (host == NULL && hints.ai_family == AF_UNSPEC) 708e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hints.ai_family = AF_INET; 709e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 710e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((error = getaddrinfo(host, port, &hints, &res))) 711e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "getaddrinfo: %s", gai_strerror(error)); 712e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 713e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res0 = res; 714e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich do { 715e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((s = socket(res0->ai_family, res0->ai_socktype, 716e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res0->ai_protocol)) < 0) 717e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 718e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 719e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 720e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (rtableid) { 721e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, IPPROTO_IP, SO_RTABLE, &rtableid, 722e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sizeof(rtableid)) == -1) 723e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "setsockopt SO_RTABLE"); 724e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 725e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif /* !ANDROID */ 726e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 727e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 728e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 7295e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#else 730e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); 7315e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 732e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (ret == -1) 733e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 734e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 735e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich set_common_sockopts(s); 736e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 737e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (bind(s, (struct sockaddr *)res0->ai_addr, 738e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res0->ai_addrlen) == 0) 739e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich break; 740e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 741e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(s); 742e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich s = -1; 743e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } while ((res0 = res0->ai_next) != NULL); 744e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 745e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!uflag && s != -1) { 746e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (listen(s, 1) < 0) 747e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "listen"); 748e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 749e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 750e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich freeaddrinfo(res); 751e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 752e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (s); 753e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 754e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 755e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 756e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * readwrite() 757e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Loop that polls on the network file descriptor and stdin. 758e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 759e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid 760e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichreadwrite(int nfd) 7615e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 762e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct pollfd pfd[2]; 763e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unsigned char buf[16384]; 764e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int n, wfd = fileno(stdin); 765e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int lfd = fileno(stdout); 766e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int plen; 767e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 768e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich plen = jflag ? 16384 : 2048; 769e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 770e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Setup Network FD */ 771e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[0].fd = nfd; 772e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[0].events = POLLIN; 773e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 774e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Set up STDIN FD. */ 775e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[1].fd = wfd; 776e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[1].events = POLLIN; 777e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 778e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich while (pfd[0].fd != -1) { 779e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (iflag) 780e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich sleep(iflag); 781e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 782e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { 783e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich close(nfd); 784e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "Polling Error"); 785e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 786e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 787e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (n == 0) 788e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 789e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 790e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (pfd[0].revents & POLLIN) { 791e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((n = read(nfd, buf, plen)) < 0) 792e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 793e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (n == 0) { 794e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich shutdown(nfd, SHUT_RD); 795e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[0].fd = -1; 796e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[0].events = 0; 797e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 798e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (tflag) 799e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich atelnet(nfd, buf, n); 800e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (atomicio(vwrite, lfd, buf, n) != n) 801e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 802e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 803e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 804e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 805e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (!dflag && pfd[1].revents & POLLIN) { 806e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((n = read(wfd, buf, plen)) < 0) 807e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 808e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if (n == 0) { 809e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich shutdown(nfd, SHUT_WR); 810e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[1].fd = -1; 811e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd[1].events = 0; 812e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 813e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (atomicio(vwrite, nfd, buf, n) != n) 814e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 815e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 816e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 817e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 818e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 819e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 820e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ 821e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid 822e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichatelnet(int nfd, unsigned char *buf, unsigned int size) 8235e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 824e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unsigned char *p, *end; 825e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich unsigned char obuf[4]; 826e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 827e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (size < 3) 828e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return; 829e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich end = buf + size - 2; 830e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 831e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (p = buf; p < end; p++) { 832e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (*p != IAC) 833e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 834e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 835e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich obuf[0] = IAC; 836e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich p++; 837e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((*p == WILL) || (*p == WONT)) 838e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich obuf[1] = DONT; 839e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else if ((*p == DO) || (*p == DONT)) 840e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich obuf[1] = WONT; 841e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 842e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 843e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 844e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich p++; 845e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich obuf[2] = *p; 846e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (atomicio(vwrite, nfd, obuf, 3) != 3) 847e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich warn("Write Error!"); 848e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 849e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 850e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 851e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 852e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * build_ports() 853e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Build an array or ports in portlist[], listing each port 854e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * that we should try to connect to. 855e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 856e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid 857e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichbuild_ports(char *p) 8585e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 859e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich const char *errstr; 860e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char *n; 861e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int hi, lo, cp; 862e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int x = 0; 863e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 864e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((n = strchr(p, '-')) != NULL) { 865e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lflag) 866e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "Cannot use -l with multiple ports!"); 867e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 868e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich *n = '\0'; 869e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich n++; 870e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 871e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Make sure the ports are in order: lowest->highest. */ 872e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 873e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hi = atoi(n); 874e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 875e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hi = strtonum(n, 1, PORT_MAX, &errstr); 876e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 877e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "port number %s: %s", errstr, n); 8785e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 879e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 880e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich lo = atoi(p); 881e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 882e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich lo = strtonum(p, 1, PORT_MAX, &errstr); 883e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 884e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "port number %s: %s", errstr, p); 8855e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 886e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 887e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (lo > hi) { 888e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich cp = hi; 889e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hi = lo; 890e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich lo = cp; 891e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 892e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 893e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Load ports sequentially. */ 894e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (cp = lo; cp <= hi; cp++) { 895e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich portlist[x] = calloc(1, PORT_MAX_LEN); 896e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (portlist[x] == NULL) 897e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 898e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); 899e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich x++; 900e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 901e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 902e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* Randomly swap ports. */ 903e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (rflag) { 904e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int y; 905e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char *c; 906e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 907e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (x = 0; x <= (hi - lo); x++) { 908e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich y = (arc4random() & 0xFFFF) % (hi - lo); 909e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich c = portlist[x]; 910e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich portlist[x] = portlist[y]; 911e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich portlist[y] = c; 912e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 913e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 914e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } else { 915e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifdef ANDROID 916e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hi = atoi(p); 917e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#else 918e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich hi = strtonum(p, 1, PORT_MAX, &errstr); 919e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errstr) 920e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errx(1, "port number %s: %s", errstr, p); 921e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif 922e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich portlist[0] = strdup(p); 923e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (portlist[0] == NULL) 924e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 925e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 926e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 927e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 928e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 929e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * udptest() 930e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Do a few writes to see if the UDP port is there. 931e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * XXX - Better way of doing this? Doesn't work for IPv6. 932e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Also fails after around 100 ports checked. 933e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 934e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 935e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichudptest(int s) 9365e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 937e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int i, ret; 938e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 939e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (i = 0; i <= 3; i++) { 940e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (write(s, "X", 1) == 1) 941e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = 1; 942e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich else 943e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ret = -1; 944e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 945e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (ret); 946e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 947e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 948e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid 949e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichset_common_sockopts(int s) 9505e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 951e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int x = 1; 952e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 953e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 954e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Sflag) { 955e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, 956e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &x, sizeof(x)) == -1) 957e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 9585e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project } 959e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#endif 960e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Dflag) { 961e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 962e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &x, sizeof(x)) == -1) 963e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 9645e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project } 965e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 966e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (jflag) { 967e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, SOL_SOCKET, SO_JUMBO, 968e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &x, sizeof(x)) == -1) 969e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, NULL); 9705e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project } 971e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Tflag != -1) { 972e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, IPPROTO_IP, IP_TOS, 973e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &Tflag, sizeof(Tflag)) == -1) 974e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "set IP ToS"); 9755e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project } 9765e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 977e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Iflag) { 978e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 979e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &Iflag, sizeof(Iflag)) == -1) 980e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "set TCP receive buffer size"); 981e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 982e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (Oflag) { 983e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 984e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich &Oflag, sizeof(Oflag)) == -1) 985e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich err(1, "set TCP send buffer size"); 986e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 987e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 9885e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project 989e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#ifndef ANDROID 990e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichint 991e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichmap_tos(char *s, int *val) 992e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich{ 993e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich /* DiffServ Codepoints and other TOS mappings */ 994e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich const struct toskeywords { 995e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich const char *keyword; 996e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich int val; 997e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } *t, toskeywords[] = { 998e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af11", IPTOS_DSCP_AF11 }, 999e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af12", IPTOS_DSCP_AF12 }, 1000e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af13", IPTOS_DSCP_AF13 }, 1001e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af21", IPTOS_DSCP_AF21 }, 1002e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af22", IPTOS_DSCP_AF22 }, 1003e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af23", IPTOS_DSCP_AF23 }, 1004e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af31", IPTOS_DSCP_AF31 }, 1005e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af32", IPTOS_DSCP_AF32 }, 1006e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af33", IPTOS_DSCP_AF33 }, 1007e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af41", IPTOS_DSCP_AF41 }, 1008e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af42", IPTOS_DSCP_AF42 }, 1009e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "af43", IPTOS_DSCP_AF43 }, 1010e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "critical", IPTOS_PREC_CRITIC_ECP }, 1011e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs0", IPTOS_DSCP_CS0 }, 1012e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs1", IPTOS_DSCP_CS1 }, 1013e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs2", IPTOS_DSCP_CS2 }, 1014e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs3", IPTOS_DSCP_CS3 }, 1015e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs4", IPTOS_DSCP_CS4 }, 1016e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs5", IPTOS_DSCP_CS5 }, 1017e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs6", IPTOS_DSCP_CS6 }, 1018e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "cs7", IPTOS_DSCP_CS7 }, 1019e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "ef", IPTOS_DSCP_EF }, 1020e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, 1021e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "lowdelay", IPTOS_LOWDELAY }, 1022e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "netcontrol", IPTOS_PREC_NETCONTROL }, 1023e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "reliability", IPTOS_RELIABILITY }, 1024e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { "throughput", IPTOS_THROUGHPUT }, 1025e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich { NULL, -1 }, 1026e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich }; 1027e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 1028e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich for (t = toskeywords; t->keyword != NULL; t++) { 1029e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (strcmp(s, t->keyword) == 0) { 1030e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich *val = t->val; 1031e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (1); 1032e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 10335e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project } 1034e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 1035e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (0); 1036e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 10375e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project#endif 1038e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 10395e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Projectvoid 1040e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichhelp(void) 10415e0936b99e2d50769c5432b47c4d07c3dcdd37c6The Android Open Source Project{ 1042e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich usage(0); 1043e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich fprintf(stderr, "\tCommand Summary:\n\ 1044e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-4 Use IPv4\n\ 1045e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-6 Use IPv6\n\ 1046e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-D Enable the debug socket option\n\ 1047e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-d Detach from stdin\n\ 1048e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-h This help text\n\ 1049e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-I length TCP receive buffer length\n\ 1050e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-i secs\t Delay interval for lines sent, ports scanned\n\ 1051e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-k Keep inbound sockets open for multiple connects\n\ 1052e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-l Listen mode, for inbound connects\n\ 1053e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-n Suppress name/port resolutions\n\ 1054e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-O length TCP send buffer length\n\ 1055e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-P proxyuser\tUsername for proxy authentication\n\ 1056e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-p port\t Specify local port for remote connects\n\ 1057e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-r Randomize remote ports\n\ 1058e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-S Enable the TCP MD5 signature option\n\ 1059e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-s addr\t Local source address\n\ 1060e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-T toskeyword\tSet IP Type of Service\n\ 1061e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-t Answer TELNET negotiation\n\ 1062e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-U Use UNIX domain socket\n\ 1063e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-u UDP mode\n\ 1064e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-V rtable Specify alternate routing table\n\ 1065e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-v Verbose\n\ 1066e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-w secs\t Timeout for connects and final net reads\n\ 1067e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ 1068e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-x addr[:port]\tSpecify proxy address and port\n\ 1069e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich \t-z Zero-I/O mode [used for scanning]\n\ 1070e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 1071e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich exit(1); 1072e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 1073e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 1074e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichvoid 1075e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichusage(int ret) 1076e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich{ 1077e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich fprintf(stderr, 1078e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n" 1079e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" 1080e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" 1081e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich "\t [-x proxy_address[:port]] [destination] [port]\n"); 1082e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (ret) 1083e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich exit(1); 1084e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 1085