zoukankan      html  css  js  c++  java
  • 编译 netcat for lineage-17.1-20210303-UNOFFICIAL-dipper.zip (ARM)

    external/netcat/netcat.c

    /* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */
    /*
     * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *   notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *   notice, this list of conditions and the following disclaimer in the
     *   documentation and/or other materials provided with the distribution.
     * 3. The name of the author may not be used to endorse or promote products
     *   derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     * Re-written nc(1) for OpenBSD. Original implementation by
     * *Hobbit* <hobbit@avian.org>.
     */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <sys/un.h>
    
    #include <netinet/in.h>
    #include <netinet/in_systm.h>
    #include <netinet/tcp.h>
    #include <netinet/ip.h>
    #include <arpa/telnet.h>
    
    #include <err.h>
    #include <errno.h>
    #include <netdb.h>
    #include <poll.h>
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <limits.h>
    #include "atomicio.h"
    
    #ifndef SUN_LEN
    #define SUN_LEN(su) 
    	(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
    #endif
    
    #define PORT_MAX	65535
    #define PORT_MAX_LEN	6
    #define UNIX_DG_TMP_SOCKET_SIZE	19
    
    /* Command Line Options */
    unsigned char qoe = 0;				/* QoE parameter passed to Android Kernel */			// # add the line
    int	dflag;					/* detached, no stdin */
    unsigned int iflag;				/* Interval Flag */
    #ifdef ANDROID
    int	jflag = 0;
    #else
    int	jflag;					/* use jumbo frames if we can */
    #endif /* !ANDROID */
    int	kflag;					/* More than one connect */
    int	lflag;					/* Bind to local port */
    int	nflag;					/* Don't do name look up */
    char   *Pflag;					/* Proxy username */
    char   *pflag;					/* Localport flag */
    int	rflag;					/* Random ports flag */
    char   *sflag;					/* Source Address */
    int	tflag;					/* Telnet Emulation */
    int	uflag;					/* UDP - Default to TCP */
    int	vflag;					/* Verbosity */
    #ifndef ANDROID
    int	xflag;					/* Socks proxy */
    #endif /* !ANDROID */
    int	zflag;					/* Port Scan Flag */
    int	Dflag;					/* sodebug */
    int	Iflag;					/* TCP receive buffer size */
    int	Oflag;					/* TCP send buffer size */
    #ifndef ANDROID
    int	Sflag;					/* TCP MD5 signature option */
    int	Tflag = -1;				/* IP Type of Service */
    u_int	rtableid;
    #endif /* !ANDROID */
    
    int timeout = -1;
    int family = AF_UNSPEC;
    char *portlist[PORT_MAX+1];
    char *unix_dg_tmp_socket;
    
    void	atelnet(int, unsigned char *, unsigned int);
    void	build_ports(char *);
    void	help(void);
    int	local_listen(char *, char *, struct addrinfo);
    void	readwrite(int);
    int	remote_connect(const char *, const char *, struct addrinfo);
    int	timeout_connect(int, const struct sockaddr *, socklen_t);
    #ifndef ANDROID
    int	socks_connect(const char *, const char *, struct addrinfo,
    	    const char *, const char *, struct addrinfo, int, const char *);
    #endif /* !ANDROID */
    int	udptest(int);
    int	unix_bind(char *);
    int	unix_connect(char *);
    int	unix_listen(char *);
    void	set_common_sockopts(int);
    int	map_tos(char *, int *);
    void	usage(int);
    
    int
    main(int argc, char *argv[])
    {
    	int ch, s, ret, socksv;
    	char *host, *uport;
    	struct addrinfo hints;
    	struct servent *sv;
    	socklen_t len;
    	struct sockaddr_storage cliaddr;
    
    //ztg
    #ifndef ANDROID
    	char *proxy;
    	const char *errstr, *proxyhost = "", *proxyport = NULL;
    	struct addrinfo proxyhints;
    //ztg
    #endif /* !ANDROID */
    
    	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
    
    	ret = 1;
    	s = 0;
    	socksv = 5;
    	host = NULL;
    	uport = NULL;
    	sv = NULL;
    
    	while ((ch = getopt(argc, argv,
    //	    "46DdhI:i:jklnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {							// # alter the line as the following line
    	    "46DdhI:i:jklnO:P:p:q:rSs:tT:UuV:vw:X:x:z")) != -1) {
    		switch (ch) {
    		case '4':
    			family = AF_INET;
    			break;
    		case '6':
    			family = AF_INET6;
    			break;
    		case 'U':
    			family = AF_UNIX;
    			break;
    		case 'X':
    			if (strcasecmp(optarg, "connect") == 0)
    				socksv = -1; /* HTTP proxy CONNECT */
    			else if (strcmp(optarg, "4") == 0)
    				socksv = 4; /* SOCKS v.4 */
    			else if (strcmp(optarg, "5") == 0)
    				socksv = 5; /* SOCKS v.5 */
    			else
    				errx(1, "unsupported proxy protocol");
    			break;
    		case 'd':
    			dflag = 1;
    			break;
    		case 'h':
    			help();
    			break;
    		case 'i':
    #ifdef ANDROID
    			iflag = atoi(optarg);
    #else
    			iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
    			if (errstr)
    				errx(1, "interval %s: %s", errstr, optarg);
    #endif /* ANDROID */
    			break;
    #ifndef ANDROID
    		case 'j':
    			jflag = 1;
    			break;
    #endif /* !ANDROID */
    		case 'k':
    			kflag = 1;
    			break;
    		case 'l':
    			lflag = 1;
    			break;
    		case 'n':
    			nflag = 1;
    			break;
    		case 'P':
    			Pflag = optarg;
    			break;
    		case 'p':
    			pflag = optarg;
    			break;
    		case 'q':													// # add the following three lines
    			qoe = atoi(optarg);
    			break;
    		case 'r':
    			rflag = 1;
    			break;
    		case 's':
    			sflag = optarg;
    			break;
    		case 't':
    			tflag = 1;
    			break;
    		case 'u':
    			uflag = 1;
    			break;
    #ifndef ANDROID
    		case 'V':
    			rtableid = (unsigned int)strtonum(optarg, 0,
    			    RT_TABLEID_MAX, &errstr);
    			if (errstr)
    				errx(1, "rtable %s: %s", errstr, optarg);
    			break;
    #endif /* !ANDROID */
    		case 'v':
    			vflag = 1;
    			break;
    		case 'w':
    #ifdef ANDROID
    			timeout = atoi(optarg);
    #else
    			timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
    			if (errstr)
    				errx(1, "timeout %s: %s", errstr, optarg);
    #endif
    			timeout *= 1000;
    			break;
    #ifndef ANDROID
    		case 'x':
    			xflag = 1;
    			if ((proxy = strdup(optarg)) == NULL)
    				err(1, NULL);
    			break;
    #endif /* !ANDROID */
    		case 'z':
    			zflag = 1;
    			break;
    		case 'D':
    			Dflag = 1;
    			break;
    		case 'I':
    #ifdef ANDROID
    			Iflag = atoi(optarg);
    #else
    			Iflag = strtonum(optarg, 1, 65536 << 14, &errstr);
    			if (errstr != NULL)
    				errx(1, "TCP receive window %s: %s",
    				    errstr, optarg);
    #endif
    			break;
    		case 'O':
    #ifdef ANDROID
    			Oflag = atoi(optarg);
    #else
    			Oflag = strtonum(optarg, 1, 65536 << 14, &errstr);
    			if (errstr != NULL)
    				errx(1, "TCP send window %s: %s",
    				    errstr, optarg);
    #endif
    			break;
    #ifndef ANDROID
    		case 'S':
    			Sflag = 1;
    			break;
    		case 'T':
    			errstr = NULL;
    			errno = 0;
    			if (map_tos(optarg, &Tflag))
    				break;
    			if (strlen(optarg) > 1 && optarg[0] == '0' &&
    			    optarg[1] == 'x')
    				Tflag = (int)strtol(optarg, NULL, 16);
    			else
    				Tflag = (int)strtonum(optarg, 0, 255,
    				    &errstr);
    			if (Tflag < 0 || Tflag > 255 || errstr || errno)
    				errx(1, "illegal tos value %s", optarg);
    			break;
    #endif /* !ANDROID */
    		default:
    			usage(1);
    		}
    	}
    	argc -= optind;
    	argv += optind;
    
    	/* Cruft to make sure options are clean, and used properly. */
    	if (argv[0] && !argv[1] && family == AF_UNIX) {
    		host = argv[0];
    		uport = NULL;
    	} else if (argv[0] && !argv[1]) {
    		if  (!lflag)
    			usage(1);
    		uport = argv[0];
    		host = NULL;
    	} else if (argv[0] && argv[1]) {
    		host = argv[0];
    		uport = argv[1];
    	} else
    		usage(1);
    
    	if (lflag && sflag)
    		errx(1, "cannot use -s and -l");
    	if (lflag && pflag)
    		errx(1, "cannot use -p and -l");
    	if (lflag && zflag)
    		errx(1, "cannot use -z and -l");
    	if (!lflag && kflag)
    		errx(1, "must use -l with -k");
    
    	/* Get name of temporary socket for unix datagram client */
    	if ((family == AF_UNIX) && uflag && !lflag) {
    		if (sflag) {
    			unix_dg_tmp_socket = sflag;
    		} else {
    //ztg
    //			strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
    			strlcpy(unix_dg_tmp_socket_buf, "/data/local/tmp/nc.XXXXXXXXXX",
    				UNIX_DG_TMP_SOCKET_SIZE);
    //ztg
    //			if (mktemp(unix_dg_tmp_socket_buf) == NULL)
    //				err(1, "mktemp");
    			if (mkstemp(unix_dg_tmp_socket_buf) == -1)
    				err(1, "mkstemp");
    
    			unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
    		}
    	}
    
    	/* Initialize addrinfo structure. */
    	if (family != AF_UNIX) {
    		memset(&hints, 0, sizeof(struct addrinfo));
    		hints.ai_family = family;
    		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
    		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
    		if (nflag)
    			hints.ai_flags |= AI_NUMERICHOST;
    	}
    
    #ifndef ANDROID
    	if (xflag) {
    		if (uflag)
    			errx(1, "no proxy support for UDP mode");
    
    		if (lflag)
    			errx(1, "no proxy support for listen");
    
    		if (family == AF_UNIX)
    			errx(1, "no proxy support for unix sockets");
    
    		/* XXX IPv6 transport to proxy would probably work */
    		if (family == AF_INET6)
    			errx(1, "no proxy support for IPv6");
    
    		if (sflag)
    			errx(1, "no proxy support for local source address");
    
    		proxyhost = strsep(&proxy, ":");
    		proxyport = proxy;
    
    		memset(&proxyhints, 0, sizeof(struct addrinfo));
    		proxyhints.ai_family = family;
    		proxyhints.ai_socktype = SOCK_STREAM;
    		proxyhints.ai_protocol = IPPROTO_TCP;
    		if (nflag)
    			proxyhints.ai_flags |= AI_NUMERICHOST;
    	}
    #endif /* !ANDROID */
    
    	if (lflag) {
    		int connfd;
    		ret = 0;
    
    		if (family == AF_UNIX) {
    			if (uflag)
    				s = unix_bind(host);
    			else
    				s = unix_listen(host);
    		}
    
    		/* Allow only one connection at a time, but stay alive. */
    		for (;;) {
    			if (family != AF_UNIX)
    				s = local_listen(host, uport, hints);
    			if (s < 0)
    				err(1, NULL);
    			/*
    			 * For UDP, we will use recvfrom() initially
    			 * to wait for a caller, then use the regular
    			 * functions to talk to the caller.
    			 */
    			if (uflag) {
    				int rv, plen;
    				char buf[16384];
    				struct sockaddr_storage z;
    
    				len = sizeof(z);
    				plen = jflag ? 16384 : 2048;
    				rv = recvfrom(s, buf, plen, MSG_PEEK,
    				    (struct sockaddr *)&z, &len);
    				if (rv < 0)
    					err(1, "recvfrom");
    
    				rv = connect(s, (struct sockaddr *)&z, len);
    				if (rv < 0)
    					err(1, "connect");
    
    				readwrite(s);
    			} else {
    				len = sizeof(cliaddr);
    				connfd = accept(s, (struct sockaddr *)&cliaddr,
    				    &len);
    				readwrite(connfd);
    				close(connfd);
    			}
    
    			if (family != AF_UNIX)
    				close(s);
    			else if (uflag) {
    				if (connect(s, NULL, 0) < 0)
    					err(1, "connect");
    			}
    
    			if (!kflag)
    				break;
    		}
    	} else if (family == AF_UNIX) {
    		ret = 0;
    
    		if ((s = unix_connect(host)) > 0 && !zflag) {
    			readwrite(s);
    			close(s);
    		} else
    			ret = 1;
    
    		if (uflag)
    			unlink(unix_dg_tmp_socket);
    		exit(ret);
    
    	} else {
    		int i = 0;
    
    		/* Construct the portlist[] array. */
    		build_ports(uport);
    
    		/* Cycle through portlist, connecting to each port. */
    		for (i = 0; portlist[i] != NULL; i++) {
    			if (s)
    				close(s);
    
    #ifndef ANDROID
    			if (xflag)
    				s = socks_connect(host, portlist[i], hints,
    				    proxyhost, proxyport, proxyhints, socksv,
    				    Pflag);
    			else
    #endif /* !ANDROID */
    				s = remote_connect(host, portlist[i], hints);
    
    			if (s < 0)
    				continue;
    
    			ret = 0;
    			if (vflag || zflag) {
    				/* For UDP, make sure we are connected. */
    				if (uflag) {
    					if (udptest(s) == -1) {
    						ret = 1;
    						continue;
    					}
    				}
    
    				/* Don't look up port if -n. */
    				if (nflag)
    					sv = NULL;
    				else {
    					sv = getservbyport(
    					    ntohs(atoi(portlist[i])),
    					    uflag ? "udp" : "tcp");
    				}
    
    				fprintf(stderr,
    				    "Connection to %s %s port [%s/%s] "
    				    "succeeded!
    ", host, portlist[i],
    				    uflag ? "udp" : "tcp",
    				    sv ? sv->s_name : "*");
    			}
    			if (!zflag)
    				readwrite(s);
    		}
    	}
    
    	if (s)
    		close(s);
    
    	exit(ret);
    }
    
    /*
     * unix_bind()
     * Returns a unix socket bound to the given path
     */
    int
    unix_bind(char *path)
    {
    	struct sockaddr_un sun;
    	int s;
    
    	/* Create unix domain socket. */
    	if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
    	     0)) < 0)
    		return (-1);
    
    	memset(&sun, 0, sizeof(struct sockaddr_un));
    	sun.sun_family = AF_UNIX;
    
    	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
    	    sizeof(sun.sun_path)) {
    		close(s);
    		errno = ENAMETOOLONG;
    		return (-1);
    	}
    
    	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
    		close(s);
    		return (-1);
    	}
    	return (s);
    }
    
    /*
     * unix_connect()
     * Returns a socket connected to a local unix socket. Returns -1 on failure.
     */
    int
    unix_connect(char *path)
    {
    	struct sockaddr_un sun;
    	int s;
    
    	if (uflag) {
    		if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
    			return (-1);
    	} else {
    		if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    			return (-1);
    	}
    	(void)fcntl(s, F_SETFD, 1);
    
    	memset(&sun, 0, sizeof(struct sockaddr_un));
    	sun.sun_family = AF_UNIX;
    
    	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
    	    sizeof(sun.sun_path)) {
    		close(s);
    		errno = ENAMETOOLONG;
    		return (-1);
    	}
    	if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
    		close(s);
    		return (-1);
    	}
    	return (s);
    
    }
    
    /*
     * unix_listen()
     * Create a unix domain socket, and listen on it.
     */
    int
    unix_listen(char *path)
    {
    	int s;
    	if ((s = unix_bind(path)) < 0)
    		return (-1);
    
    	if (listen(s, 5) < 0) {
    		close(s);
    		return (-1);
    	}
    	return (s);
    }
    
    /*
     * remote_connect()
     * Returns a socket connected to a remote host. Properly binds to a local
     * port or source address if needed. Returns -1 on failure.
     */
    int
    remote_connect(const char *host, const char *port, struct addrinfo hints)
    {
    	struct addrinfo *res, *res0;
    //ztg
    //	int s, error, on = 1;
    	int s, error;
    
    //ztg
    #ifndef ANDROID
    	int on = 1;
    #endif /* !ANDROID */
    
    
    	if ((error = getaddrinfo(host, port, &hints, &res)))
    		errx(1, "getaddrinfo: %s", gai_strerror(error));
    
    	res0 = res;
    	do {
    		if ((s = socket(res0->ai_family, res0->ai_socktype,
    		    res0->ai_protocol)) < 0)
    			continue;
    
    #ifndef ANDROID
    		if (rtableid) {
    			if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid,
    			    sizeof(rtableid)) == -1)
    				err(1, "setsockopt SO_RTABLE");
    		}
    #endif /* !ANDROID */
    
    		/* Bind to a local port or source address if specified. */
    		if (sflag || pflag) {
    			struct addrinfo ahints, *ares;
    
    #ifndef ANDROID
    			/* try SO_BINDANY, but don't insist */
    			setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
    #endif /* !ANDROID */
    			memset(&ahints, 0, sizeof(struct addrinfo));
    			ahints.ai_family = res0->ai_family;
    			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
    			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
    			ahints.ai_flags = AI_PASSIVE;
    			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
    				errx(1, "getaddrinfo: %s", gai_strerror(error));
    
    			if (bind(s, (struct sockaddr *)ares->ai_addr,
    			    ares->ai_addrlen) < 0)
    				errx(1, "bind failed: %s", strerror(errno));
    			freeaddrinfo(ares);
    		}
    
    		set_common_sockopts(s);
    
    		if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
    			break;
    		else if (vflag)
    			warn("connect to %s port %s (%s) failed", host, port,
    			    uflag ? "udp" : "tcp");
    
    		close(s);
    		s = -1;
    	} while ((res0 = res0->ai_next) != NULL);
    
    	freeaddrinfo(res);
    
    	return (s);
    }
    
    int
    timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
    {
    	struct pollfd pfd;
    	socklen_t optlen;
    	int flags, optval;
    	int ret;
    
    	if (timeout != -1) {
    		flags = fcntl(s, F_GETFL, 0);
    		if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
    			err(1, "set non-blocking mode");
    	}
    
    	( (struct sockaddr_in *) name)->sin_zero[7] = qoe;		/* QoE parameter passed to Android Kernel */		// # add the line
    	if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
    		pfd.fd = s;
    		pfd.events = POLLOUT;
    		if ((ret = poll(&pfd, 1, timeout)) == 1) {
    			optlen = sizeof(optval);
    			if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
    			    &optval, &optlen)) == 0) {
    				errno = optval;
    				ret = optval == 0 ? 0 : -1;
    			}
    		} else if (ret == 0) {
    			errno = ETIMEDOUT;
    			ret = -1;
    		} else
    			err(1, "poll failed");
    	}
    
    	if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1)
    		err(1, "restoring flags");
    
    	return (ret);
    }
    
    /*
     * local_listen()
     * Returns a socket listening on a local port, binds to specified source
     * address. Returns -1 on failure.
     */
    int
    local_listen(char *host, char *port, struct addrinfo hints)
    {
    	struct addrinfo *res, *res0;
    	int s, ret, x = 1;
    	int error;
    
    	/* Allow nodename to be null. */
    	hints.ai_flags |= AI_PASSIVE;
    
    	/*
    	 * In the case of binding to a wildcard address
    	 * default to binding to an ipv4 address.
    	 */
    	if (host == NULL && hints.ai_family == AF_UNSPEC)
    		hints.ai_family = AF_INET;
    
    	if ((error = getaddrinfo(host, port, &hints, &res)))
    		errx(1, "getaddrinfo: %s", gai_strerror(error));
    
    	res0 = res;
    	do {
    		if ((s = socket(res0->ai_family, res0->ai_socktype,
    		    res0->ai_protocol)) < 0)
    			continue;
    
    #ifndef ANDROID
    		if (rtableid) {
    			if (setsockopt(s, IPPROTO_IP, SO_RTABLE, &rtableid,
    			    sizeof(rtableid)) == -1)
    				err(1, "setsockopt SO_RTABLE");
    		}
    #endif /* !ANDROID */
    
    #ifdef ANDROID
    		ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
    #else
    		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
    #endif
    		if (ret == -1)
    			err(1, NULL);
    
    		set_common_sockopts(s);
    
    		if (bind(s, (struct sockaddr *)res0->ai_addr,
    		    res0->ai_addrlen) == 0)
    			break;
    
    		close(s);
    		s = -1;
    	} while ((res0 = res0->ai_next) != NULL);
    
    	if (!uflag && s != -1) {
    		if (listen(s, 1) < 0)
    			err(1, "listen");
    	}
    
    	freeaddrinfo(res);
    
    	return (s);
    }
    
    /*
     * readwrite()
     * Loop that polls on the network file descriptor and stdin.
     */
    void
    readwrite(int nfd)
    {
    	struct pollfd pfd[2];
    	unsigned char buf[16384];
    	int n, wfd = fileno(stdin);
    	int lfd = fileno(stdout);
    	int plen;
    
    	plen = jflag ? 16384 : 2048;
    
    	/* Setup Network FD */
    	pfd[0].fd = nfd;
    	pfd[0].events = POLLIN;
    
    	/* Set up STDIN FD. */
    	pfd[1].fd = wfd;
    	pfd[1].events = POLLIN;
    
    	while (pfd[0].fd != -1) {
    		if (iflag)
    			sleep(iflag);
    
    		if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
    			close(nfd);
    			err(1, "Polling Error");
    		}
    
    		if (n == 0)
    			return;
    
    		if (pfd[0].revents & POLLIN) {
    			if ((n = read(nfd, buf, plen)) < 0)
    				return;
    			else if (n == 0) {
    				shutdown(nfd, SHUT_RD);
    				pfd[0].fd = -1;
    				pfd[0].events = 0;
    			} else {
    				if (tflag)
    					atelnet(nfd, buf, n);
    				if (atomicio(vwrite, lfd, buf, n) != n)
    					return;
    			}
    		}
    
    		if (!dflag && pfd[1].revents & POLLIN) {
    			if ((n = read(wfd, buf, plen)) < 0)
    				return;
    			else if (n == 0) {
    				shutdown(nfd, SHUT_WR);
    				pfd[1].fd = -1;
    				pfd[1].events = 0;
    			} else {
    				if (atomicio(vwrite, nfd, buf, n) != n)
    					return;
    			}
    		}
    	}
    }
    
    /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
    void
    atelnet(int nfd, unsigned char *buf, unsigned int size)
    {
    	unsigned char *p, *end;
    	unsigned char obuf[4];
    
    	if (size < 3)
    		return;
    	end = buf + size - 2;
    
    	for (p = buf; p < end; p++) {
    		if (*p != IAC)
    			continue;
    
    		obuf[0] = IAC;
    		p++;
    		if ((*p == WILL) || (*p == WONT))
    			obuf[1] = DONT;
    		else if ((*p == DO) || (*p == DONT))
    			obuf[1] = WONT;
    		else
    			continue;
    
    		p++;
    		obuf[2] = *p;
    		if (atomicio(vwrite, nfd, obuf, 3) != 3)
    			warn("Write Error!");
    	}
    }
    
    /*
     * build_ports()
     * Build an array or ports in portlist[], listing each port
     * that we should try to connect to.
     */
    void
    build_ports(char *p)
    {
    //ztg
    #ifndef ANDROID
    	const char *errstr;
    //ztg
    #endif /* !ANDROID */
    
    	char *n;
    	int hi, lo, cp;
    	int x = 0;
    
    	if ((n = strchr(p, '-')) != NULL) {
    		if (lflag)
    			errx(1, "Cannot use -l with multiple ports!");
    
    		*n = '';
    		n++;
    
    		/* Make sure the ports are in order: lowest->highest. */
    #ifdef ANDROID
    		hi = atoi(n);
    #else
    		hi = strtonum(n, 1, PORT_MAX, &errstr);
    		if (errstr)
    			errx(1, "port number %s: %s", errstr, n);
    #endif
    #ifdef ANDROID
    		lo = atoi(p);
    #else
    		lo = strtonum(p, 1, PORT_MAX, &errstr);
    		if (errstr)
    			errx(1, "port number %s: %s", errstr, p);
    #endif
    
    		if (lo > hi) {
    			cp = hi;
    			hi = lo;
    			lo = cp;
    		}
    
    		/* Load ports sequentially. */
    		for (cp = lo; cp <= hi; cp++) {
    			portlist[x] = calloc(1, PORT_MAX_LEN);
    			if (portlist[x] == NULL)
    				err(1, NULL);
    			snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
    			x++;
    		}
    
    		/* Randomly swap ports. */
    		if (rflag) {
    			int y;
    			char *c;
    
    			for (x = 0; x <= (hi - lo); x++) {
    				y = (arc4random() & 0xFFFF) % (hi - lo);
    				c = portlist[x];
    				portlist[x] = portlist[y];
    				portlist[y] = c;
    			}
    		}
    	} else {
    #ifdef ANDROID
    		hi = atoi(p);
    #else
    		hi = strtonum(p, 1, PORT_MAX, &errstr);
    		if (errstr)
    			errx(1, "port number %s: %s", errstr, p);
    #endif
    		portlist[0] = strdup(p);
    		if (portlist[0] == NULL)
    			err(1, NULL);
    	}
    }
    
    /*
     * udptest()
     * Do a few writes to see if the UDP port is there.
     * XXX - Better way of doing this? Doesn't work for IPv6.
     * Also fails after around 100 ports checked.
     */
    int
    udptest(int s)
    {
    	int i, ret;
    
    	for (i = 0; i <= 3; i++) {
    		if (write(s, "X", 1) == 1)
    			ret = 1;
    		else
    			ret = -1;
    	}
    	return (ret);
    }
    
    void
    set_common_sockopts(int s)
    {
    	int x = 1;
    
    #ifndef ANDROID
    	if (Sflag) {
    		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
    			&x, sizeof(x)) == -1)
    			err(1, NULL);
    	}
    #endif
    	if (Dflag) {
    		if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
    			&x, sizeof(x)) == -1)
    			err(1, NULL);
    	}
    #ifndef ANDROID
    	if (jflag) {
    		if (setsockopt(s, SOL_SOCKET, SO_JUMBO,
    			&x, sizeof(x)) == -1)
    			err(1, NULL);
    	}
    	if (Tflag != -1) {
    		if (setsockopt(s, IPPROTO_IP, IP_TOS,
    		    &Tflag, sizeof(Tflag)) == -1)
    			err(1, "set IP ToS");
    	}
    #endif
    	if (Iflag) {
    		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
    		    &Iflag, sizeof(Iflag)) == -1)
    			err(1, "set TCP receive buffer size");
    	}
    	if (Oflag) {
    		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
    		    &Oflag, sizeof(Oflag)) == -1)
    			err(1, "set TCP send buffer size");
    	}
    }
    
    #ifndef ANDROID
    int
    map_tos(char *s, int *val)
    {
    	/* DiffServ Codepoints and other TOS mappings */
    	const struct toskeywords {
    		const char	*keyword;
    		int		 val;
    	} *t, toskeywords[] = {
    		{ "af11",		IPTOS_DSCP_AF11 },
    		{ "af12",		IPTOS_DSCP_AF12 },
    		{ "af13",		IPTOS_DSCP_AF13 },
    		{ "af21",		IPTOS_DSCP_AF21 },
    		{ "af22",		IPTOS_DSCP_AF22 },
    		{ "af23",		IPTOS_DSCP_AF23 },
    		{ "af31",		IPTOS_DSCP_AF31 },
    		{ "af32",		IPTOS_DSCP_AF32 },
    		{ "af33",		IPTOS_DSCP_AF33 },
    		{ "af41",		IPTOS_DSCP_AF41 },
    		{ "af42",		IPTOS_DSCP_AF42 },
    		{ "af43",		IPTOS_DSCP_AF43 },
    		{ "critical",		IPTOS_PREC_CRITIC_ECP },
    		{ "cs0",		IPTOS_DSCP_CS0 },
    		{ "cs1",		IPTOS_DSCP_CS1 },
    		{ "cs2",		IPTOS_DSCP_CS2 },
    		{ "cs3",		IPTOS_DSCP_CS3 },
    		{ "cs4",		IPTOS_DSCP_CS4 },
    		{ "cs5",		IPTOS_DSCP_CS5 },
    		{ "cs6",		IPTOS_DSCP_CS6 },
    		{ "cs7",		IPTOS_DSCP_CS7 },
    		{ "ef",			IPTOS_DSCP_EF },
    		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
    		{ "lowdelay",		IPTOS_LOWDELAY },
    		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
    		{ "reliability",	IPTOS_RELIABILITY },
    		{ "throughput",		IPTOS_THROUGHPUT },
    		{ NULL, 		-1 },
    	};
    
    	for (t = toskeywords; t->keyword != NULL; t++) {
    		if (strcmp(s, t->keyword) == 0) {
    			*val = t->val;
    			return (1);
    		}
    	}
    
    	return (0);
    }
    #endif
    
    void
    help(void)
    {
    	usage(0);
    	fprintf(stderr, "	Command Summary:
    
    		-4		Use IPv4
    
    		-6		Use IPv6
    
    		-D		Enable the debug socket option
    
    		-d		Detach from stdin
    
    		-h		This help text
    
    		-I length	TCP receive buffer length
    
    		-i secs		Delay interval for lines sent, ports scanned
    
    		-k		Keep inbound sockets open for multiple connects
    
    		-l		Listen mode, for inbound connects
    
    		-n		Suppress name/port resolutions
    
    		-O length	TCP send buffer length
    
    		-P proxyuser	Username for proxy authentication
    
    		-p port		Specify local port for remote connects
    
    		-q QoE		QoE parameter passed to Android Kernel
    
    		-r		Randomize remote ports
    
    		-S		Enable the TCP MD5 signature option
    
    		-s addr		Local source address
    
    		-T toskeyword	Set IP Type of Service
    
    		-t		Answer TELNET negotiation
    
    		-U		Use UNIX domain socket
    
    		-u		UDP mode
    
    		-V rtable	Specify alternate routing table
    
    		-v		Verbose
    
    		-w secs		Timeout for connects and final net reads
    
    		-X proto	Proxy protocol: "4", "5" (SOCKS) or "connect"
    
    		-x addr[:port]	Specify proxy address and port
    
    		-z		Zero-I/O mode [used for scanning]
    
    	Port numbers can be individual or ranges: lo-hi [inclusive]
    ");
    	exit(1);
    }
    
    void
    usage(int ret)
    {
    	fprintf(stderr,
    	    "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]
    "
    	    "	  [-P proxy_username] [-p source_port] [-s source] [-T ToS]
    "
    	    "	  [-V rtable] [-w timeout] [-X proxy_protocol]
    "
    	    "	  [-x proxy_address[:port]] [destination] [port]
    ");
    	if (ret)
    		exit(1);
    }
    

    external/netcat/Android.mk

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_SRC_FILES:=
    	netcat.c 
    	atomicio.c
    
    
    LOCAL_CFLAGS:=-O2 -g
    #LOCAL_CFLAGS+=-DLINUX
    
    #LOCAL_MODULE_TAGS := eng
    
    LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
    
    LOCAL_MODULE:=qoe_nc
    
    # gold in binutils 2.22 will warn about the usage of mktemp
    LOCAL_LDFLAGS += -Wl,--no-fatal-warnings
    
    include $(BUILD_EXECUTABLE)
    

    su - ztg
    cd /mnt/ssd01/lineage-17.1-200823-mptcp-qoe/
    source build/envsetup.sh
    lunch lineage_dipper-userdebug
    mmm external/netcat

        out/target/product/dipper/system/xbin/qoe_nc

  • 相关阅读:
    OpenCV -- Mat 转 QImage 函数
    Qt--checkbox
    QT 发布release版本
    JS_0014:JS刷新页面
    JS_0013:JS获取文件后缀名
    JS_0012:JS从一个有规则的字符串中随机选择一个字符再循环生成一个新的无规则的字符串
    JQuery0016:JQuery等待页面全部加载完后执行代码块
    JQuery0015:JQuery查找指定元素并修改其属性
    JS_0011:通过JS给div添加html标签内容
    JS_0010:获取url中指定的参数
  • 原文地址:https://www.cnblogs.com/ztguang/p/14476495.html
Copyright © 2011-2022 走看看