Changes made to Netcat from OpenBSD: source --------------------------------------------------------------------- netcat.c: - removed jumbo frames support (-j) SO_JUMBO setsockopt() option - Solaris does not have that option - some drivers support jumbo frames though but that is entirely different level - MD5 signatures (-S) TCP_MD5SIG setsockopt() option - no support in Solaris - changed SO_REUSEPORT -> SO_REUSEADDR in setsockopt() call Solaris does not know SO_REUSEPORT - using SO_REUSEPORT is the best thing we could do /usr/include/sys/socket.h contains only SO_REUSEADDR - details: 6432031 No way to access SO_REUSEPORT on sockets 4120748 can not bind IPv6 and IPv4 endpoints to the same port. http://www.unixguide.net/network/socketfaq/4.11.shtml From a later Stevens posting, with minor editing: Basically SO_REUSEPORT is a BSD'ism that arose when multicasting was added, even thought it was not used in the original Steve Deering code. I believe some BSD-derived systems may also include it (OSF, now Digital Unix, perhaps?). SO_REUSEPORT lets you bind the same address *and* port, but only if all the binders have specified it. But when binding a multicast address (its main use), SO_REUSEADDR is considered identical to SO_REUSEPORT (p. 731, "TCP/IP Illustrated, Volume 2"). So for portability of multicasting applications I always use SO_REUSEADDR. - strsep() call proxyhost = strsep(&proxy, ":"); proxyport = proxy; http://www.openbsd.org/cgi-bin/man.cgi?query=strsep&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html - strsep() present in src/cmd/ssh/libopenbsd-compat/common/ - the include file is in src/cmd/ssh/include/ - does not seem to be delivered into Solaris - solution: replace strsep() with equivalent (strtok()) - filed CR 6487100 - UNIX sockets renamed 'struct sockaddr_un sun' to 'sunaddr' - the 'sun' keyword seems to be reserved :) vklocal:moose:~/CRs/netcat-4664622.onnv$ cat sun.c #include int main(void) { struct sockaddr_un sun; printf("0x%x\n", &sun); } vklocal:moose:~/CRs/netcat-4664622.onnv$ gcc -o sun sun.c sun.c: In function `main': sun.c:4: error: syntax error before numeric constant sun.c:6: error: invalid lvalue in unary `&' socks.c: - needs readpassphrase() - resides in src/cmd/ssh/libopenbsd-compat/common/ - copied it over together with readpassphrase.h - needs includes from src/cmd/ssh/include/includes.h - I have added only those needed - added _PATH_TTY defined from src/cmd/ssh/include/defines.h - final solution: use getpassphrase() instead (see getpass(3C)) - lib/libc/port/stdio/getpass.c:getpassphrase() is part of libc - free((void *)proxypass) (which is called after getproxypass() returns) must be ok: http://adorus.czech.sun.com:8080/source-onnv-clone/xref/src/lib/libc/port/stdio/getpass.c#64 - allocates password storage buffer via tsdalloc() which calls lmalloc() - little test: vklocal:moose:~/CRs/netcat-4664622.onnv$ cat ./getpass.c #include #include int main(void) { const char *pw = NULL; if ((pw = getpassphrase("Dej mi heslo: ")) == NULL) { fprintf(stderr, "Unable to read proxy passphrase"); exit(1); } printf("read password: '%s' [0x%x]\n", pw, pw); free((void *)pw); printf("freed password [0x%x]\n", pw); } vklocal:moose:~/CRs/netcat-4664622.onnv$ ./getpass Dej mi heslo: read password: 'AAAAAAAAAAAAAAAAAA' [0xfee41c00] freed password [0xfee41c00] vklocal:moose:~/CRs/netcat-4664622.onnv$ linking -------------------------------------------------------------------- gcc -o nc socks.o readpassphrase.o netcat.o atomicio.o -lnsl -lsocket - problems with following functions: Undefined first referenced symbol in file err socks.o errx socks.o warn netcat.o b64_ntop socks.o arc4random netcat.o strtonum netcat.o - arc4random() - part of ssh and also in src/lib/crypt_modules/bsdbf/ - this means /usr/lib/security/crypt_bsdbf.so - but cannot link against it (no 'lib' prefix) - Darren Moffat's advice: reimplement it by reading bytes from /dev/urandom - my take: arc4random() outputs high-quality random data the output is long type random() in Solaris is pseudo-random but it's sufficient to use it for netcat's purpose - used random(3C)/srandom(3C) - err[x]() , warn() take from ssh taken it from src/lib/libipsecutil/common/err.c - now linking looks like this: gcc -o nc socks.o readpassphrase.o netcat.o atomicio.o err.o \ -lnsl -lsocket -lresolv - final soltion: CR 6495220 - socks.c: call to b64_ntop() src/lib/libresolv2/common/isc/base64.c - part of libresolv.so - strtonum() present in ON's $SRC but none of the function declarations match the prototype - need to use the one from OpenBSD http://www.openbsd.org/cgi-bin/man.cgi?query=strtonum&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html copied strtonum.c over from http://cvsup.de.openbsd.org/pub/FreeBSD/ports/local-distfiles/flz/openbgpd/strtonum.c gcc -o nc socks.o readpassphrase.o netcat.o atomicio.o err.o strtonum.o \ -lnsl -lsocket -lresolv ---------------------------------------------------------------------------- strtonum() problems: - crash after arguments to strtonum() were not specified with 'LL' suffix - conversion was bad - we do not need long long for TCP/UDP port numbers, intervals RFC 793/RFC 768 - ports are 16 bit numbers - crash in strtonum.c:strtonum() : *errstrp = ev[error].errstr; /* crash */ C-style ---------------------------------------------------------------------- - made all *.[ch] files C-style clean - don't know what to do with following line: readpassphrase.c:135: for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r'; ) { - had to use following hack: for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r'; nr += 0) { - filed CR 6488570 - final fix: for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r'; /* */) { compilation with Sun Studio ------------------------------------------------- socks.c: changed: int socks_connect(const char *host, const char *port, struct addrinfo hints __attribute__((__unused__)), const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, int socksv, const char *proxyuser) { to: int socks_connect(const char *host, const char *port, struct addrinfo hints, const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, int socksv, const char *proxyuser) { - added couple of includes (strings.h, string.h) - created strtonum.h - changed unsigned char buf[1024]; to char buf[1024]; in socks_connect() declarations to satisfy prototype: "socks.c", line 268: warning: argument #1 is incompatible with prototype: prototype: pointer to char : "/usr/include/iso/stdio_c99.h", line 89 argument : pointer to unsigned char - this actually collides with prototype of b64_ntop() src/lib/libresolv2/common/isc/base64.c#148 148 b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) { - but cast to (unsigned char *) fixed that: if (r == -1 || (size_t)r >= sizeof (buf) || b64_ntop((unsigned char *)buf, strlen(buf), resp, sizeof (resp)) == -1) errx(1, "Proxy username/password too long"); - but: socks.c: In function `socks_connect': socks.c:177: warning: comparison is always false due to limited range of data type if (buf[1] == SOCKS_NOMETHOD) errx(1, "authentication method negotiation failed"); - used cast for the comparison - had to use cast for b64_ntop() lint cleanup ---------------------------------------------------------------- - removed 'hints' from socks_connect() - unused argument - couple of (void)s: "/export/home/netcat-4664622.onnv/usr/src/cmd/cmd-inet/usr.bin/netcat/socks.c", line 92: warning: function returns value which is always ignored: memcpy (E_FUNC_RET_ALWAYS_IGNOR2) "/export/home/netcat-4664622.onnv/usr/src/cmd/cmd-inet/usr.bin/netcat/netcat.c", line 250: warning: function returns value which is always ignored: memset (E_FUNC_RET_ALWAYS_IGNOR2) "/export/home/netcat-4664622.onnv/usr/src/cmd/cmd-inet/usr.bin/netcat/netcat.c", line 802: warning: function returns value which is always ignored: fprintf (E_FUNC_RET_ALWAYS_IGNOR2) - for: close(), shutdown(), snprintf(), printf(), fprintf(), memset(), memcpy() socks.c:proxy_read_line() - it's ok to ignore retval because success is detected via argument 'buf' socks.c:decode_addrport() - will exit() on failure - typedef'd &tos in netcat.c:parse_iptos to (unisgned int *)