README.TXT
上传用户:shhspump
上传日期:2007-01-07
资源大小:85k
文件大小:61k
源码类别:

远程控制编程

开发平台:

Visual C++

  1. THE DEFCON RELEASE 7/26/96
  2. This is a beta release of netcat for Windows 95 and Windows NT.  It was
  3. ported from hobbit's netcat 1.0.
  4. This was built on NT 4.0 using Visual C++ 4.0.  It has had some superficial
  5. testing on Windows 95 as well as NT 3.51 and 4.0.
  6. *Things that don't work yet*
  7. - None of the timer settings for delays and timeouts are implemented.
  8. - source routing may never work on NT.
  9. - the gaping security hole feature or exec function is not done.
  10. I am planning on cleaning up the gnarly IFDEFs for Win32 and brining this
  11. release back into the fold of the standard unix make if possible.  NT
  12. pretends to be unix but it's only pretty close.
  13. Please report any problems to the address below.
  14. Weld Pond (weld@l0pht.com)
  15. L0pht Heavy Industries
  16. NOW ON TO hobbit's FULL README FILE
  17. Netcat 1.10
  18. ===========                                   /_/
  19.                                        / 0 0 
  20. Netcat is a simple Unix utility which reads and writes data  ====v====
  21. across network connections, using TCP or UDP protocol.     W  /
  22. It is designed to be a reliable "back-end" tool that can   |     |     _
  23. be used directly or easily driven by other programs and   / ___     /
  24. scripts.  At the same time, it is a feature-rich network  / /      |
  25. debugging and exploration tool, since it can create almost (((-----)))-'
  26. any kind of connection you would need and has several  /
  27. interesting built-in capabilities.  Netcat, or "nc" as the (      ___
  28. actual program is named, should have been supplied long ago  __.=|___E
  29. as another one of those cryptic but standard Unix tools.         /
  30. In the simplest usage, "nc host port" creates a TCP connection to the given
  31. port on the given target host.  Your standard input is then sent to the host,
  32. and anything that comes back across the connection is sent to your standard
  33. output.  This continues indefinitely, until the network side of the connection
  34. shuts down.  Note that this behavior is different from most other applications
  35. which shut everything down and exit after an end-of-file on the standard input.
  36. Netcat can also function as a server, by listening for inbound connections
  37. on arbitrary ports and then doing the same reading and writing.  With minor
  38. limitations, netcat doesn't really care if it runs in "client" or "server"
  39. mode -- it still shovels data back and forth until there isn't any more left.
  40. In either mode, shutdown can be forced after a configurable time of inactivity
  41. on the network side.
  42. And it can do this via UDP too, so netcat is possibly the "udp telnet-like"
  43. application you always wanted for testing your UDP-mode servers.  UDP, as the
  44. "U" implies, gives less reliable data transmission than TCP connections and
  45. some systems may have trouble sending large amounts of data that way, but it's
  46. still a useful capability to have.
  47. You may be asking "why not just use telnet to connect to arbitrary ports?"
  48. Valid question, and here are some reasons.  Telnet has the "standard input
  49. EOF" problem, so one must introduce calculated delays in driving scripts to
  50. allow network output to finish.  This is the main reason netcat stays running
  51. until the *network* side closes.  Telnet also will not transfer arbitrary
  52. binary data, because certain characters are interpreted as telnet options and
  53. are thus removed from the data stream.  Telnet also emits some of its
  54. diagnostic messages to standard output, where netcat keeps such things
  55. religiously separated from its *output* and will never modify any of the real
  56. data in transit unless you *really* want it to.  And of course telnet is
  57. incapable of listening for inbound connections, or using UDP instead.  Netcat
  58. doesn't have any of these limitations, is much smaller and faster than telnet,
  59. and has many other advantages.
  60. Some of netcat's major features are:
  61. Outbound or inbound connections, TCP or UDP, to or from any ports
  62. Full DNS forward/reverse checking, with appropriate warnings
  63. Ability to use any local source port
  64. Ability to use any locally-configured network source address
  65. Built-in port-scanning capabilities, with randomizer
  66. Built-in loose source-routing capability
  67. Can read command line arguments from standard input
  68. Slow-send mode, one line every N seconds
  69. Hex dump of transmitted and received data
  70. Optional ability to let another program service established connections
  71. Optional telnet-options responder
  72. Efforts have been made to have netcat "do the right thing" in all its various
  73. modes.  If you believe that it is doing the wrong thing under whatever
  74. circumstances, please notify me and tell me how you think it should behave.
  75. If netcat is not able to do some task you think up, minor tweaks to the code
  76. will probably fix that.  It provides a basic and easily-modified template for
  77. writing other network applications, and I certainly encourage people to make
  78. custom mods and send in any improvements they make to it.  This is the second
  79. release; the overall differences from 1.00 are relatively minor and have mostly
  80. to do with portability and bugfixes.  Many people provided greatly appreciated
  81. fixes and comments on the 1.00 release.  Continued feedback from the Internet
  82. community is always welcome!
  83. Netcat is entirely my own creation, although plenty of other code was used as
  84. examples.  It is freely given away to the Internet community in the hope that
  85. it will be useful, with no restrictions except giving credit where it is due.
  86. No GPLs, Berkeley copyrights or any of that nonsense.  The author assumes NO
  87. responsibility for how anyone uses it.  If netcat makes you rich somehow and
  88. you're feeling generous, mail me a check.  If you are affiliated in any way
  89. with Microsoft Network, get a life.  Always ski in control.  Comments,
  90. questions, and patches to hobbit@avian.org.
  91. Building
  92. ========
  93. Compiling is fairly straightforward.  Examine the Makefile for a SYSTYPE that
  94. matches yours, and do "make <systype>".  The executable "nc" should appear.
  95. If there is no relevant SYSTYPE section, try "generic".  If you create new
  96. sections for generic.h and Makefile to support another platform, please follow
  97. the given format and mail back the diffs.
  98. There are a couple of other settable #defines in netcat.c, which you can
  99. include as DFLAGS="-DTHIS -DTHAT" to your "make" invocation without having to
  100. edit the Makefile.  See the following discussions for what they are and do.
  101. If you want to link against the resolver library on SunOS [recommended] and
  102. you have BIND 4.9.x, you may need to change XLIBS=-lresolv in the Makefile to
  103. XLIBS="-lresolv -l44bsd".
  104. Linux sys/time.h does not really support presetting of FD_SETSIZE; a harmless
  105. warning is issued.
  106. Some systems may warn about pointer types for signal().  No problem, though.
  107. Exploration of features
  108. =======================
  109. Where to begin?  Netcat is at the same time so simple and versatile, it's like
  110. trying to describe everything you can do with your Swiss Army knife.  This will
  111. go over the basics; you should also read the usage examples and notes later on
  112. which may give you even more ideas about what this sort of tool is good for.
  113. If no command arguments are given at all, netcat asks for them, reads a line
  114. from standard input, and breaks it up into arguments internally.  This can be
  115. useful when driving netcat from certain types of scripts, with the side effect
  116. of hiding your command line arguments from "ps" displays.
  117. The host argument can be a name or IP address.  If -n is specified, netcat
  118. will only accept numeric IP addresses and do no DNS lookups for anything.  If
  119. -n is not given and -v is turned on, netcat will do a full forward and reverse
  120. name and address lookup for the host, and warn you about the all-too-common
  121. problem of mismatched names in the DNS.  This often takes a little longer for
  122. connection setup, but is useful to know about.  There are circumstances under
  123. which this can *save* time, such as when you want to know the name for some IP
  124. address and also connect there.  Netcat will just tell you all about it, saving
  125. the manual steps of looking up the hostname yourself.  Normally mismatch-
  126. checking is case-insensitive per the DNS spec, but you can define ANAL at
  127. compile time to make it case-sensitive -- sometimes useful for uncovering minor
  128. errors in your own DNS files while poking around your networks.
  129. A port argument is required for outbound connections, and can be numeric or a
  130. name as listed in /etc/services.  If -n is specified, only numeric arguments
  131. are valid.  Special syntax and/or more than one port argument cause different
  132. behavior -- see details below about port-scanning.
  133. The -v switch controls the verbosity level of messages sent to standard error.
  134. You will probably want to run netcat most of the time with -v turned on, so you
  135. can see info about the connections it is trying to make.  You will probably
  136. also want to give a smallish -w argument, which limits the time spent trying to
  137. make a connection.  I usually alias "nc" to "nc -v -w 3", which makes it
  138. function just about the same for things I would otherwise use telnet to do.
  139. The timeout is easily changed by a subsequent -w argument which overrides the
  140. earlier one.  Specifying -v more than once makes diagnostic output MORE
  141. verbose.  If -v is not specified at all, netcat silently does its work unless
  142. some error happens, whereupon it describes the error and exits with a nonzero
  143. status.  Refused network connections are generally NOT considered to be errors,
  144. unless you only asked for a single TCP port and it was refused.
  145. Note that -w also sets the network inactivity timeout.  This does not have any
  146. effect until standard input closes, but then if nothing further arrives from
  147. the network in the next <timeout> seconds, netcat tries to read the net once
  148. more for good measure, and then closes and exits.  There are a lot of network
  149. services now that accept a small amount of input and return a large amount of
  150. output, such as Gopher and Web servers, which is the main reason netcat was
  151. written to "block" on the network staying open rather than standard input.
  152. Handling the timeout this way gives uniform behavior with network servers that
  153. *don't* close by themselves until told to.
  154. UDP connections are opened instead of TCP when -u is specified.  These aren't
  155. really "connections" per se since UDP is a connectionless protocol, although
  156. netcat does internally use the "connected UDP socket" mechanism that most
  157. kernels support.  Although netcat claims that an outgoing UDP connection is
  158. "open" immediately, no data is sent until something is read from standard
  159. input.  Only thereafter is it possible to determine whether there really is a
  160. UDP server on the other end, and often you just can't tell.  Most UDP protocols
  161. use timeouts and retries to do their thing and in many cases won't bother
  162. answering at all, so you should specify a timeout and hope for the best.  You
  163. will get more out of UDP connections if standard input is fed from a source
  164. of data that looks like various kinds of server requests.
  165. To obtain a hex dump file of the data sent either way, use "-o logfile".  The
  166. dump lines begin with "<" or ">" to respectively indicate "from the net" or
  167. "to the net", and contain the total count per direction, and hex and ascii
  168. representations of the traffic.  Capturing a hex dump naturally slows netcat
  169. down a bit, so don't use it where speed is critical.
  170. Netcat can bind to any local port, subject to privilege restrictions and ports
  171. that are already in use.  It is also possible to use a specific local network
  172. source address if it is that of a network interface on your machine.  [Note:
  173. this does not work correctly on all platforms.]  Use "-p portarg" to grab a
  174. specific local port, and "-s ip-addr" or "-s name" to have that be your source
  175. IP address.  This is often referred to as "anchoring the socket".  Root users
  176. can grab any unused source port including the "reserved" ones less than 1024.
  177. Absence of -p will bind to whatever unused port the system gives you, just like
  178. any other normal client connection, unless you use -r [see below].
  179. Listen mode will cause netcat to wait for an inbound connection, and then the
  180. same data transfer happens.  Thus, you can do "nc -l -p 1234 < filename" and
  181. when someone else connects to your port 1234, the file is sent to them whether
  182. they wanted it or not.  Listen mode is generally used along with a local port
  183. argument -- this is required for UDP mode, while TCP mode can have the system
  184. assign one and tell you what it is if -v is turned on.  If you specify a target
  185. host and optional port in listen mode, netcat will accept an inbound connection
  186. only from that host and if you specify one, only from that foreign source port.
  187. In verbose mode you'll be informed about the inbound connection, including what
  188. address and port it came from, and since listening on "any" applies to several
  189. possibilities, which address it came *to* on your end.  If the system supports
  190. IP socket options, netcat will attempt to retrieve any such options from an
  191. inbound connection and print them out in hex.
  192. If netcat is compiled with -DGAPING_SECURITY_HOLE, the -e argument specifies
  193. a program to exec after making or receiving a successful connection.  In the
  194. listening mode, this works similarly to "inetd" but only for a single instance.
  195. Use with GREAT CARE.  This piece of the code is normally not enabled; if you
  196. know what you're doing, have fun.  This hack also works in UDP mode.  Note that
  197. you can only supply -e with the name of the program, but no arguments.  If you
  198. want to launch something with an argument list, write a two-line wrapper script
  199. or just use inetd like always.
  200. If netcat is compiled with -DTELNET, the -t argument enables it to respond
  201. to telnet option negotiation [always in the negative, i.e. DONT or WONT].
  202. This allows it to connect to a telnetd and get past the initial negotiation
  203. far enough to get a login prompt from the server.  Since this feature has
  204. the potential to modify the data stream, it is not enabled by default.  You
  205. have to understand why you might need this and turn on the #define yourself.
  206. Data from the network connection is always delivered to standard output as
  207. efficiently as possible, using large 8K reads and writes.  Standard input is
  208. normally sent to the net the same way, but the -i switch specifies an "interval
  209. time" which slows this down considerably.  Standard input is still read in
  210. large batches, but netcat then tries to find where line breaks exist and sends
  211. one line every interval time.  Note that if standard input is a terminal, data
  212. is already read line by line, so unless you make the -i interval rather long,
  213. what you type will go out at a fairly normal rate.  -i is really designed
  214. for use when you want to "measure out" what is read from files or pipes.
  215. Port-scanning is a popular method for exploring what's out there.  Netcat
  216. accepts its commands with options first, then the target host, and everything
  217. thereafter is interpreted as port names or numbers, or ranges of ports in M-N
  218. syntax.  CAVEAT: some port names in /etc/services contain hyphens -- netcat
  219. currently will not correctly parse those, so specify ranges using numbers if
  220. you can.  If more than one port is thus specified, netcat connects to *all* of
  221. them, sending the same batch of data from standard input [up to 8K worth] to
  222. each one that is successfully connected to.  Specifying multiple ports also
  223. suppresses diagnostic messages about refused connections, unless -v is
  224. specified twice for "more verbosity".  This way you normally get notified only
  225. about genuinely open connections.  Example: "nc -v -w 2 -z target 20-30" will
  226. try connecting to every port between 20 and 30 [inclusive] at the target, and
  227. will likely inform you about an FTP server, telnet server, and mailer along the
  228. way.  The -z switch prevents sending any data to a TCP connection and very
  229. limited probe data to a UDP connection, and is thus useful as a fast scanning
  230. mode just to see what ports the target is listening on.  To limit scanning
  231. speed if desired, -i will insert a delay between each port probe.  There are
  232. some pitfalls with regard to UDP scanning, described later, but in general it
  233. works well.
  234. For each range of ports specified, scanning is normally done downward within
  235. that range.  If the -r switch is used, scanning hops randomly around within
  236. that range and reports open ports as it finds them.  [If you want them listed
  237. in order regardless, pipe standard error through "sort"...]  In addition, if
  238. random mode is in effect, the local source ports are also randomized.  This
  239. prevents netcat from exhibiting any kind of regular pattern in its scanning.
  240. You can exert fairly fine control over your scan by judicious use of -r and
  241. selected port ranges to cover.  If you use -r for a single connection, the
  242. source port will have a random value above 8192, rather than the next one the
  243. kernel would have assigned you.  Note that selecting a specific local port
  244. with -p overrides any local-port randomization.
  245. Many people are interested in testing network connectivity using IP source
  246. routing, even if it's only to make sure their own firewalls are blocking
  247. source-routed packets.  On systems that support it, the -g switch can be used
  248. multiple times [up to 8] to construct a loose-source-routed path for your
  249. connection, and the -G argument positions the "hop pointer" within the list.
  250. If your network allows source-routed traffic in and out, you can test
  251. connectivity to your own services via remote points in the internet.  Note that
  252. although newer BSD-flavor telnets also have source-routing capability, it isn't
  253. clearly documented and the command syntax is somewhat clumsy.  Netcat's
  254. handling of "-g" is modeled after "traceroute".
  255. Netcat tries its best to behave just like "cat".  It currently does nothing to
  256. terminal input modes, and does no end-of-line conversion.  Standard input from
  257. a terminal is read line by line with normal editing characters in effect.  You
  258. can freely suspend out of an interactive connection and resume.  ^C or whatever
  259. your interrupt character is will make netcat close the network connection and
  260. exit.  A switch to place the terminal in raw mode has been considered, but so
  261. far has not been necessary.  You can send raw binary data by reading it out of
  262. a file or piping from another program, so more meaningful effort would be spent
  263. writing an appropriate front-end driver.
  264. Netcat is not an "arbitrary packet generator", but the ability to talk to raw
  265. sockets and/or nit/bpf/dlpi may appear at some point.  Such things are clearly
  266. useful; I refer you to Darren Reed's excellent ip_filter package, which now
  267. includes a tool to construct and send raw packets with any contents you want.
  268. Example uses -- the light side
  269. ==============================
  270. Again, this is a very partial list of possibilities, but it may get you to
  271. think up more applications for netcat.  Driving netcat with simple shell or
  272. expect scripts is an easy and flexible way to do fairly complex tasks,
  273. especially if you're not into coding network tools in C.  My coding isn't
  274. particularly strong either [although undoubtedly better after writing this
  275. thing!], so I tend to construct bare-metal tools like this that I can trivially
  276. plug into other applications.  Netcat doubles as a teaching tool -- one can
  277. learn a great deal about more complex network protocols by trying to simulate
  278. them through raw connections!
  279. An example of netcat as a backend for something else is the shell-script
  280. Web browser, which simply asks for the relevant parts of a URL and pipes
  281. "GET /what/ever" into a netcat connection to the server.  I used to do this
  282. with telnet, and had to use calculated sleep times and other stupidity to
  283. kludge around telnet's limitations.  Netcat guarantees that I get the whole
  284. page, and since it transfers all the data unmodified, I can even pull down
  285. binary image files and display them elsewhere later.  Some folks may find the
  286. idea of a shell-script web browser silly and strange, but it starts up and
  287. gets me my info a hell of a lot faster than a GUI browser and doesn't hide
  288. any contents of links and forms and such.  This is included, as scripts/web,
  289. along with several other web-related examples.
  290. Netcat is an obvious replacement for telnet as a tool for talking to daemons.
  291. For example, it is easier to type "nc host 25", talk to someone's mailer, and
  292. just ^C out than having to type ^]c or QUIT as telnet would require you to do.
  293. You can quickly catalog the services on your network by telling netcat to
  294. connect to well-known services and collect greetings, or at least scan for open
  295. ports.  You'll probably want to collect netcat's diagnostic messages in your
  296. output files, so be sure to include standard error in the output using
  297. `>& file' in *csh or `> file 2>&1' in bourne shell.
  298. A scanning example: "echo QUIT | nc -v -w 5 target 20-250 500-600 5990-7000"
  299. will inform you about a target's various well-known TCP servers, including
  300. r-services, X, IRC, and maybe a few you didn't expect.  Sending in QUIT and
  301. using the timeout will almost guarantee that you see some kind of greeting or
  302. error from each service, which usually indicates what it is and what version.
  303. [Beware of the "chargen" port, though...]  SATAN uses exactly this technique to
  304. collect host information, and indeed some of the ideas herein were taken from
  305. the SATAN backend tools.  If you script this up to try every host in your
  306. subnet space and just let it run, you will not only see all the services,
  307. you'll find out about hosts that aren't correctly listed in your DNS.  Then you
  308. can compare new snapshots against old snapshots to see changes.  For going
  309. after particular services, a more intrusive example is in scripts/probe.
  310. Netcat can be used as a simple data transfer agent, and it doesn't really
  311. matter which end is the listener and which end is the client -- input at one
  312. side arrives at the other side as output.  It is helpful to start the listener
  313. at the receiving side with no timeout specified, and then give the sending side
  314. a small timeout.  That way the listener stays listening until you contact it,
  315. and after data stops flowing the client will time out, shut down, and take the
  316. listener with it.  Unless the intervening network is fraught with problems,
  317. this should be completely reliable, and you can always increase the timeout.  A
  318. typical example of something "rsh" is often used for: on one side,
  319. nc -l -p 1234 | uncompress -c | tar xvfp -
  320. and then on the other side
  321. tar cfp - /some/dir | compress -c | nc -w 3 othermachine 1234
  322. will transfer the contents of a directory from one machine to another, without
  323. having to worry about .rhosts files, user accounts, or inetd configurations
  324. at either end.  Again, it matters not which is the listener or receiver; the
  325. "tarring" machine could just as easily be running the listener instead.  One
  326. could conceivably use a scheme like this for backups, by having cron-jobs fire
  327. up listeners and backup handlers [which can be restricted to specific addresses
  328. and ports between each other] and pipe "dump" or "tar" on one machine to "dd
  329. of=/dev/tapedrive" on another as usual.  Since netcat returns a nonzero exit
  330. status for a denied listener connection, scripts to handle such tasks could
  331. easily log and reject connect attempts from third parties, and then retry.
  332. Another simple data-transfer example: shipping things to a PC that doesn't have
  333. any network applications yet except a TCP stack and a web browser.  Point the
  334. browser at an arbitrary port on a Unix server by telling it to download
  335. something like http://unixbox:4444/foo, and have a listener on the Unix side
  336. ready to ship out a file when the connect comes in.  The browser may pervert
  337. binary data when told to save the URL, but you can dig the raw data out of
  338. the on-disk cache.
  339. If you build netcat with GAPING_SECURITY_HOLE defined, you can use it as an
  340. "inetd" substitute to test experimental network servers that would otherwise
  341. run under "inetd".  A script or program will have its input and output hooked
  342. to the network the same way, perhaps sans some fancier signal handling.  Given
  343. that most network services do not bind to a particular local address, whether
  344. they are under "inetd" or not, it is possible for netcat avoid the "address
  345. already in use" error by binding to a specific address.  This lets you [as
  346. root, for low ports] place netcat "in the way" of a standard service, since
  347. inbound connections are generally sent to such specifically-bound listeners
  348. first and fall back to the ones bound to "any".  This allows for a one-off
  349. experimental simulation of some service, without having to screw around with
  350. inetd.conf.  Running with -v turned on and collecting a connection log from
  351. standard error is recommended.
  352. Netcat as well can make an outbound connection and then run a program or script
  353. on the originating end, with input and output connected to the same network
  354. port.  This "inverse inetd" capability could enhance the backup-server concept
  355. described above or help facilitate things such as a "network dialback" concept.
  356. The possibilities are many and varied here; if such things are intended as
  357. security mechanisms, it may be best to modify netcat specifically for the
  358. purpose instead of wrapping such functions in scripts.
  359. Speaking of inetd, netcat will function perfectly well *under* inetd as a TCP
  360. connection redirector for inbound services, like a "plug-gw" without the
  361. authentication step.  This is very useful for doing stuff like redirecting
  362. traffic through your firewall out to other places like web servers and mail
  363. hubs, while posing no risk to the firewall machine itself.  Put netcat behind
  364. inetd and tcp_wrappers, perhaps thusly:
  365. www stream tcp nowait nobody /etc/tcpd /bin/nc -w 3 realwww 80
  366. and you have a simple and effective "application relay" with access control
  367. and logging.  Note use of the wait time as a "safety" in case realwww isn't
  368. reachable or the calling user aborts the connection -- otherwise the relay may
  369. hang there forever.
  370. You can use netcat to generate huge amounts of useless network data for
  371. various performance testing.  For example, doing
  372. yes AAAAAAAAAAAAAAAAAAAAAA | nc -v -v -l -p 2222 > /dev/null
  373. on one side and then hitting it with
  374. yes BBBBBBBBBBBBBBBBBBBBBB | nc othermachine 2222 > /dev/null
  375. from another host will saturate your wires with A's and B's.  The "very
  376. verbose" switch usage will tell you how many of each were sent and received
  377. after you interrupt either side.  Using UDP mode produces tremendously MORE
  378. trash per unit time in the form of fragmented 8 Kbyte mobygrams -- enough to
  379. stress-test kernels and network interfaces.  Firing random binary data into
  380. various network servers may help expose bugs in their input handling, which
  381. nowadays is a popular thing to explore.  A simple example data-generator is
  382. given in data/data.c included in this package, along with a small collection
  383. of canned input files to generate various packet contents.  This program is
  384. documented in its beginning comments, but of interest here is using "%r" to
  385. generate random bytes at well-chosen points in a data stream.  If you can
  386. crash your daemon, you likely have a security problem.
  387. The hex dump feature may be useful for debugging odd network protocols,
  388. especially if you don't have any network monitoring equipment handy or aren't
  389. root where you'd need to run "tcpdump" or something.  Bind a listening netcat
  390. to a local port, and have it run a script which in turn runs another netcat
  391. to the real service and captures the hex dump to a log file.  This sets up a
  392. transparent relay between your local port and wherever the real service is.
  393. Be sure that the script-run netcat does *not* use -v, or the extra info it
  394. sends to standard error may confuse the protocol.  Note also that you cannot
  395. have the "listen/exec" netcat do the data capture, since once the connection
  396. arrives it is no longer netcat that is running.
  397. Binding to an arbitrary local port allows you to simulate things like r-service
  398. clients, if you are root locally.  For example, feeding "^@root^@joe^@pwd^@"
  399. [where ^@ is a null, and root/joe could be any other local/remote username
  400. pair] into a "rsh" or "rlogin" server, FROM your port 1023 for example,
  401. duplicates what the server expects to receive.  Thus, you can test for insecure
  402. .rhosts files around your network without having to create new user accounts on
  403. your client machine.  The program data/rservice.c can aid this process by
  404. constructing the "rcmd" protocol bytes.  Doing this also prevents "rshd" from
  405. trying to create that separate standard-error socket and still gives you an
  406. input path, as opposed to the usual action of "rsh -n".  Using netcat for
  407. things like this can be really useful sometimes, because rsh and rlogin
  408. generally want a host *name* as an argument and won't accept IP addresses.  If
  409. your client-end DNS is hosed, as may be true when you're trying to extract
  410. backup sets on to a dumb client, "netcat -n" wins where normal rsh/rlogin is
  411. useless.
  412. If you are unsure that a remote syslogger is working, test it with netcat.
  413. Make a UDP connection to port 514 and type in "<0>message", which should
  414. correspond to "kern.emerg" and cause syslogd to scream into every file it has
  415. open [and possibly all over users' terminals].  You can tame this down by
  416. using a different number and use netcat inside routine scripts to send syslog
  417. messages to places that aren't configured in syslog.conf.  For example,
  418. "echo '<38>message' | nc -w 1 -u loggerhost 514" should send to auth.notice
  419. on loggerhost.  The exact number may vary; check against your syslog.h first.
  420. Netcat provides several ways for you to test your own packet filters.  If you
  421. bind to a port normally protected against outside access and make a connection
  422. to somewhere outside your own network, the return traffic will be coming to
  423. your chosen port from the "outside" and should be blocked.  TCP may get through
  424. if your filter passes all "ack syn", but it shouldn't be even doing that to low
  425. ports on your network.  Remember to test with UDP traffic as well!  If your
  426. filter passes at least outbound source-routed IP packets, bouncing a connection
  427. back to yourself via some gateway outside your network will create "incoming"
  428. traffic with your source address, which should get dropped by a correctly
  429. configured anti-spoofing filter.  This is a "non-test" if you're also dropping
  430. source-routing, but it's good to be able to test for that too.  Any packet
  431. filter worth its salt will be blocking source-routed packets in both
  432. directions, but you never know what interesting quirks you might turn up by
  433. playing around with source ports and addresses and watching the wires with a
  434. network monitor.
  435. You can use netcat to protect your own workstation's X server against outside
  436. access.  X is stupid enough to listen for connections on "any" and never tell
  437. you when new connections arrive, which is one reason it is so vulnerable.  Once
  438. you have all your various X windows up and running you can use netcat to bind
  439. just to your ethernet address and listen to port 6000.  Any new connections
  440. from outside the machine will hit netcat instead your X server, and you get a
  441. log of who's trying.  You can either tell netcat to drop the connection, or
  442. perhaps run another copy of itself to relay to your actual X server on
  443. "localhost".  This may not work for dedicated X terminals, but it may be
  444. possible to authorize your X terminal only for its boot server, and run a relay
  445. netcat over on the server that will in turn talk to your X terminal.  Since
  446. netcat only handles one listening connection per run, make sure that whatever
  447. way you rig it causes another one to run and listen on 6000 soon afterward, or
  448. your real X server will be reachable once again.  A very minimal script just
  449. to protect yourself could be
  450. while true ; do
  451.   nc -v -l -s <your-addr> -p 6000 localhost 2
  452. done
  453. which causes netcat to accept and then close any inbound connection to your
  454. workstation's normal ethernet address, and another copy is immediately run by
  455. the script.  Send standard error to a file for a log of connection attempts.
  456. If your system can't do the "specific bind" thing all is not lost; run your
  457. X server on display ":1" or port 6001, and netcat can still function as a probe
  458. alarm by listening on 6000.
  459. Does your shell-account provider allow personal Web pages, but not CGI scripts?
  460. You can have netcat listen on a particular port to execute a program or script
  461. of your choosing, and then just point to the port with a URL in your homepage.
  462. The listener could even exist on a completely different machine, avoiding the
  463. potential ire of the homepage-host administrators.  Since the script will get
  464. the raw browser query as input it won't look like a typical CGI script, and
  465. since it's running under your UID you need to write it carefully.  You may want
  466. to write a netcat-based script as a wrapper that reads a query and sets up
  467. environment variables for a regular CGI script.  The possibilities for using
  468. netcat and scripts to handle Web stuff are almost endless.  Again, see the
  469. examples under scripts/.
  470. Example uses -- the dark side
  471. =============================
  472. Equal time is deserved here, since a versatile tool like this can be useful
  473. to any Shade of Hat.  I could use my Victorinox to either fix your car or
  474. disassemble it, right?  You can clearly use something like netcat to attack
  475. or defend -- I don't try to govern anyone's social outlook, I just build tools.
  476. Regardless of your intentions, you should still be aware of these threats to
  477. your own systems.
  478. The first obvious thing is scanning someone *else's* network for vulnerable
  479. services.  Files containing preconstructed data, be it exploratory or
  480. exploitive, can be fed in as standard input, including command-line arguments
  481. to netcat itself to keep "ps" ignorant of your doings.  The more random the
  482. scanning, the less likelihood of detection by humans, scan-detectors, or
  483. dynamic filtering, and with -i you'll wait longer but avoid loading down the
  484. target's network.  Some examples for crafting various standard UDP probes are
  485. given in data/*.d.
  486. Some configurations of packet filters attempt to solve the FTP-data problem by
  487. just allowing such connections from the outside.  These come FROM port 20, TO
  488. high TCP ports inside -- if you locally bind to port 20, you may find yourself
  489. able to bypass filtering in some cases.  Maybe not to low ports "inside", but
  490. perhaps to TCP NFS servers, X servers, Prospero, ciscos that listen on 200x
  491. and 400x...  Similar bypassing may be possible for UDP [and maybe TCP too] if a
  492. connection comes from port 53; a filter may assume it's a nameserver response.
  493. Using -e in conjunction with binding to a specific address can enable "server
  494. takeover" by getting in ahead of the real ones, whereupon you can snarf data
  495. sent in and feed your own back out.  At the very least you can log a hex dump
  496. of someone else's session.  If you are root, you can certainly use -s and -e to
  497. run various hacked daemons without having to touch inetd.conf or the real
  498. daemons themselves.  You may not always have the root access to deal with low
  499. ports, but what if you are on a machine that also happens to be an NFS server?
  500. You might be able to collect some interesting things from port 2049, including
  501. local file handles.  There are several other servers that run on high ports
  502. that are likely candidates for takeover, including many of the RPC services on
  503. some platforms [yppasswdd, anyone?].  Kerberos tickets, X cookies, and IRC
  504. traffic also come to mind.  RADIUS-based terminal servers connect incoming
  505. users to shell-account machines on a high port, usually 1642 or thereabouts.
  506. SOCKS servers run on 1080.  Do "netstat -a" and get creative.
  507. There are some daemons that are well-written enough to bind separately to all
  508. the local interfaces, possibly with an eye toward heading off this sort of
  509. problem.  Named from recent BIND releases, and NTP, are two that come to mind.
  510. Netstat will show these listening on address.53 instead of *.53.  You won't
  511. be able to get in front of these on any of the real interface addresses, which
  512. of course is especially interesting in the case of named, but these servers
  513. sometimes forget about things like "alias" interface addresses or interfaces
  514. that appear later on such as dynamic PPP links.  There are some hacked web
  515. servers and versions of "inetd" floating around that specifically bind as well,
  516. based on a configuration file -- these generally *are* bound to alias addresses
  517. to offer several different address-based services from one machine.
  518. Using -e to start a remote backdoor shell is another obvious sort of thing,
  519. easier than constructing a file for inetd to listen on "ingreslock" or
  520. something, and you can access-control it against other people by specifying a
  521. client host and port.  Experience with this truly demonstrates how fragile the
  522. barrier between being "logged in" or not really is, and is further expressed by
  523. scripts/bsh.  If you're already behind a firewall, it may be easier to make an
  524. *outbound* connection and then run a shell; a small wrapper script can
  525. periodically try connecting to a known place and port, you can later listen
  526. there until the inbound connection arrives, and there's your shell.  Running
  527. a shell via UDP has several interesting features, although be aware that once
  528. "connected", the UDP stub sockets tend to show up in "netstat" just like TCP
  529. connections and may not be quite as subtle as you wanted.  Packets may also be
  530. lost, so use TCP if you need reliable connections.  But since UDP is
  531. connectionless, a hookup of this sort will stick around almost forever, even if
  532. you ^C out of netcat or do a reboot on your side, and you only need to remember
  533. the ports you used on both ends to reestablish.  And outbound UDP-plus-exec
  534. connection creates the connected socket and starts the program immediately.  On
  535. a listening UDP connection, the socket is created once a first packet is
  536. received.  In either case, though, such a "connection" has the interesting side
  537. effect that only your client-side IP address and [chosen?] source port will
  538. thereafter be able to talk to it.  Instant access control!  A non-local third
  539. party would have to do ALL of the following to take over such a session:
  540. forge UDP with your source address [trivial to do; see below]
  541. guess the port numbers of BOTH ends, or sniff the wire for them
  542. arrange to block ICMP or UDP return traffic between it and your real
  543.   source, so the session doesn't die with a network write error.
  544. The companion program data/rservice.c is helpful in scripting up any sort of
  545. r-service username or password guessing attack.  The arguments to "rservice"
  546. are simply the strings that get null-terminated and passed over an "rcmd"-style
  547. connection, with the assumption that the client does not need a separate
  548. standard-error port.  Brute-force password banging is best done via "rexec" if
  549. it is available since it is less likely to log failed attempts.  Thus, doing
  550. "rservice joe joespass pwd | nc target exec" should return joe's home dir if
  551. the password is right, or "Permission denied."  Plug in a dictionary and go to
  552. town.  If you're attacking rsh/rlogin, remember to be root and bind to a port
  553. between 512 and 1023 on your end, and pipe in "rservice joe joe pwd" and such.
  554. Netcat can prevent inadvertently sending extra information over a telnet
  555. connection.  Use "nc -t" in place of telnet, and daemons that try to ask for
  556. things like USER and TERM environment variables will get no useful answers, as
  557. they otherwise would from a more recent telnet program.  Some telnetds actually
  558. try to collect this stuff and then plug the USER variable into "login" so that
  559. the caller is then just asked for a password!  This mechanism could cause a
  560. login attempt as YOUR real username to be logged over there if you use a
  561. Borman-based telnet instead of "nc -t".
  562. Got an unused network interface configured in your kernel [e.g. SLIP], or
  563. support for alias addresses?  Ifconfig one to be any address you like, and bind
  564. to it with -s to enable all sorts of shenanigans with bogus source addresses.
  565. The interface probably has to be UP before this works; some SLIP versions
  566. need a far-end address before this is true.  Hammering on UDP services is then
  567. a no-brainer.  What you can do to an unfiltered syslog daemon should be fairly
  568. obvious; trimming the conf file can help protect against it.  Many routers out
  569. there still blindly believe what they receive via RIP and other routing
  570. protocols.  Although most UDP echo and chargen servers check if an incoming
  571. packet was sent from *another* "internal" UDP server, there are many that still
  572. do not, any two of which [or many, for that matter] could keep each other
  573. entertained for hours at the expense of bandwidth.  And you can always make
  574. someone wonder why she's being probed by nsa.gov.
  575. Your TCP spoofing possibilities are mostly limited to destinations you can
  576. source-route to while locally bound to your phony address.  Many sites block
  577. source-routed packets these days for precisely this reason.  If your kernel
  578. does oddball things when sending source-routed packets, try moving the pointer
  579. around with -G.  You may also have to fiddle with the routing on your own
  580. machine before you start receiving packets back.  Warning: some machines still
  581. send out traffic using the source address of the outbound interface, regardless
  582. of your binding, especially in the case of localhost.  Check first.  If you can
  583. open a connection but then get no data back from it, the target host is
  584. probably killing the IP options on its end [this is an option inside TCP
  585. wrappers and several other packages], which happens after the 3-way handshake
  586. is completed.  If you send some data and observe the "send-q" side of "netstat"
  587. for that connection increasing but never getting sent, that's another symptom.
  588. Beware: if Sendmail 8.7.x detects a source-routed SMTP connection, it extracts
  589. the hop list and sticks it in the Received: header!
  590. SYN bombing [sometimes called "hosing"] can disable many TCP servers, and if
  591. you hit one often enough, you can keep it unreachable for days.  As is true of
  592. many other denial-of-service attacks, there is currently no defense against it
  593. except maybe at the human level.  Making kernel SOMAXCONN considerably larger
  594. than the default and the half-open timeout smaller can help, and indeed some
  595. people running large high-performance web servers have *had* to do that just to
  596. handle normal traffic.  Taking out mailers and web servers is sociopathic, but
  597. on the other hand it is sometimes useful to be able to, say, disable a site's
  598. identd daemon for a few minutes.  If someone realizes what is going on,
  599. backtracing will still be difficult since the packets have a phony source
  600. address, but calls to enough ISP NOCs might eventually pinpoint the source.
  601. It is also trivial for a clueful ISP to watch for or even block outgoing
  602. packets with obviously fake source addresses, but as we know many of them are
  603. not clueful or willing to get involved in such hassles.  Besides, outbound
  604. packets with an [otherwise unreachable] source address in one of their net
  605. blocks would look fairly legitimate.
  606. Notes
  607. =====
  608. A discussion of various caveats, subtleties, and the design of the innards.
  609. As of version 1.07 you can construct a single file containing command arguments
  610. and then some data to transfer.  Netcat is now smart enough to pick out the
  611. first line and build the argument list, and send any remaining data across the
  612. net to one or multiple ports.  The first release of netcat had trouble with
  613. this -- it called fgets() for the command line argument, which behind the
  614. scenes does a large read() from standard input, perhaps 4096 bytes or so, and
  615. feeds that out to the fgets() library routine.  By the time netcat 1.00 started
  616. directly read()ing stdin for more data, 4096 bytes of it were gone.  It now
  617. uses raw read() everywhere and does the right thing whether reading from files,
  618. pipes, or ttys.  If you use this for multiple-port connections, the single
  619. block of data will now be a maximum of 8K minus the first line.  Improvements
  620. have been made to the logic in sending the saved chunk to each new port.  Note
  621. that any command-line arguments hidden using this mechanism could still be
  622. extracted from a core dump.
  623. When netcat receives an inbound UDP connection, it creates a "connected socket"
  624. back to the source of the connection so that it can also send out data using
  625. normal write().  Using this mechanism instead of recvfrom/sendto has several
  626. advantages -- the read/write select loop is simplified, and ICMP errors can in
  627. effect be received by non-root users.  However, it has the subtle side effect
  628. that if further UDP packets arrive from the caller but from different source
  629. ports, the listener will not receive them.  UDP listen mode on a multihomed
  630. machine may have similar quirks unless you specifically bind to one of its
  631. addresses.  It is not clear that kernel support for UDP connected sockets
  632. and/or my understanding of it is entirely complete here, so experiment...
  633. You should be aware of some subtleties concerning UDP scanning.  If -z is on,
  634. netcat attempts to send a single null byte to the target port, twice, with a
  635. small time in between.  You can either use the -w timeout, or netcat will try
  636. to make a "sideline" TCP connection to the target to introduce a small time
  637. delay equal to the round-trip time between you and the target.  Note that if
  638. you have a -w timeout and -i timeout set, BOTH take effect and you wait twice
  639. as long.  The TCP connection is to a normally refused port to minimize traffic,
  640. but if you notice a UDP fast-scan taking somewhat longer than it should, it
  641. could be that the target is actually listening on the TCP port.  Either way,
  642. any ICMP port-unreachable messages from the target should have arrived in the
  643. meantime.  The second single-byte UDP probe is then sent.  Under BSD kernels,
  644. the ICMP error is delivered to the "connected socket" and the second write
  645. returns an error, which tells netcat that there is NOT a UDP service there.
  646. While Linux seems to be a fortunate exception, under many SYSV derived kernels
  647. the ICMP is not delivered, and netcat starts reporting that *all* the ports are
  648. "open" -- clearly wrong.  [Some systems may not even *have* the "udp connected
  649. socket" concept, and netcat in its current form will not work for UDP at all.]
  650. If -z is specified and only one UDP port is probed, netcat's exit status
  651. reflects whether the connection was "open" or "refused" as with TCP.
  652. It may also be that UDP packets are being blocked by filters with no ICMP error
  653. returns, in which case everything will time out and return "open".  This all
  654. sounds backwards, but that's how UDP works.  If you're not sure, try "echo
  655. w00gumz | nc -u -w 2 target 7" to see if you can reach its UDP echo port at
  656. all.  You should have no trouble using a BSD-flavor system to scan for UDP
  657. around your own network, although flooding a target with the high activity that
  658. -z generates will cause it to occasionally drop packets and indicate false
  659. "opens".  A more "correct" way to do this is collect and analyze the ICMP
  660. errors, as does SATAN's "udp_scan" backend, but then again there's no guarantee
  661. that the ICMP gets back to you either.  Udp_scan also does the zero-byte
  662. probes but is excruciatingly careful to calculate its own round-trip timing
  663. average and dynamically set its own response timeouts along with decoding any
  664. ICMP received.  Netcat uses a much sleazier method which is nonetheless quite
  665. effective.  Cisco routers are known to have a "dead time" in between ICMP
  666. responses about unreachable UDP ports, so a fast scan of a cisco will show
  667. almost everything "open".  If you are looking for a specific UDP service, you
  668. can construct a file containing the right bytes to trigger a response from the
  669. other end and send that as standard input.  Netcat will read up to 8K of the
  670. file and send the same data to every UDP port given.  Note that you must use a
  671. timeout in this case [as would any other UDP client application] since the
  672. two-write probe only happens if -z is specified.
  673. Many telnet servers insist on a specific set of option negotiations before
  674. presenting a login banner.  On a raw connection you will see this as small
  675. amount of binary gook.  My attempts to create fixed input bytes to make a
  676. telnetd happy worked some places but failed against newer BSD-flavor ones,
  677. possibly due to timing problems, but there are a couple of much better
  678. workarounds.  First, compile with -DTELNET and use -t if you just want to get
  679. past the option negotiation and talk to something on a telnet port.  You will
  680. still see the binary gook -- in fact you'll see a lot more of it as the options
  681. are responded to behind the scenes.  The telnet responder does NOT update the
  682. total byte count, or show up in the hex dump -- it just responds negatively to
  683. any options read from the incoming data stream.  If you want to use a normal
  684. full-blown telnet to get to something but also want some of netcat's features
  685. involved like settable ports or timeouts, construct a tiny "foo" script:
  686. #! /bin/sh
  687. exec nc -otheroptions targethost 23
  688. and then do
  689. nc -l -p someport -e foo localhost &
  690. telnet localhost someport
  691. and your telnet should connect transparently through the exec'ed netcat to
  692. the target, using whatever options you supplied in the "foo" script.  Don't
  693. use -t inside the script, or you'll wind up sending *two* option responses.
  694. I've observed inconsistent behavior under some Linuxes [perhaps just older
  695. ones?] when binding in listen mode.  Sometimes netcat binds only to "localhost"
  696. if invoked with no address or port arguments, and sometimes it is unable to
  697. bind to a specific address for listening if something else is already listening
  698. on "any".  The former problem can be worked around by specifying "-s 0.0.0.0",
  699. which will do the right thing despite netcat claiming that it's listening on
  700. [127.0.0.1].  This is a known problem -- for example, there's a mention of it
  701. in the makefile for SOCKS.  On the flip side, binding to localhost and sending
  702. packets to some other machine doesn't work as you'd expect -- they go out with
  703. the source address of the sending interface instead.  The Linux kernel contains
  704. a specific check to ensure that packets from 127.0.0.1 are never sent to the
  705. wire; other kernels may contain similar code.  Linux, of course, *still*
  706. doesn't support source-routing, but they claim that it and many other network
  707. improvements are at least breathing hard.
  708. There are several possible errors associated with making TCP connections, but
  709. to specifically see anything other than "refused", one must wait the full
  710. kernel-defined timeout for a connection to fail.  Netcat's mechanism of
  711. wrapping an alarm timer around the connect prevents the *real* network error
  712. from being returned -- "errno" at that point indicates "interrupted system
  713. call" since the connect attempt was interrupted.  Some old 4.3 BSD kernels
  714. would actually return things like "host unreachable" immediately if that was
  715. the case, but most newer kernels seem to wait the full timeout and *then* pass
  716. back the real error.  Go figure.  In this case, I'd argue that the old way was
  717. better, despite those same kernels generally being the ones that tear down
  718. *established* TCP connections when ICMP-bombed.
  719. Incoming socket options are passed to applications by the kernel in the
  720. kernel's own internal format.  The socket-options structure for source-routing
  721. contains the "first-hop" IP address first, followed by the rest of the real
  722. options list.  The kernel uses this as is when sending reply packets -- the
  723. structure is therefore designed to be more useful to the kernel than to humans,
  724. but the hex dump of it that netcat produces is still useful to have.
  725. Kernels treat source-routing options somewhat oddly, but it sort of makes sense
  726. once one understands what's going on internally.  The options list of addresses
  727. must contain hop1, hop2, ..., destination.  When a source-routed packet is sent
  728. by the kernel [at least BSD], the actual destination address becomes irrelevant
  729. because it is replaced with "hop1", "hop1" is removed from the options list,
  730. and all the other addresses in the list are shifted up to fill the hole.  Thus
  731. the outbound packet is sent from your chosen source address to the first
  732. *gateway*, and the options list now contains hop2, ..., destination.  During
  733. all this address shuffling, the kernel does NOT change the pointer value, which
  734. is why it is useful to be able to set the pointer yourself -- you can construct
  735. some really bizarre return paths, and send your traffic fairly directly to the
  736. target but around some larger loop on the way back.  Some Sun kernels seem to
  737. never flip the source-route around if it contains less than three hops, never
  738. reset the pointer anyway, and tries to send the packet [with options containing
  739. a "completed" source route!!] directly back to the source.  This is way broken,
  740. of course.  [Maybe ipforwarding has to be on?  I haven't had an opportunity to
  741. beat on it thoroughly yet.]
  742. "Credits" section: The original idea for netcat fell out of a long-standing
  743. desire and fruitless search for a tool resembling it and having the same
  744. features.  After reading some other network code and realizing just how many
  745. cool things about sockets could be controlled by the calling user, I started
  746. on the basics and the rest fell together pretty quickly.  Some port-scanning
  747. ideas were taken from Venema/Farmer's SATAN tool kit, and Pluvius' "pscan"
  748. utility.  Healthy amounts of BSD kernel source were perused in an attempt to
  749. dope out socket options and source-route handling; additional help was obtained
  750. from Dave Borman's telnet sources.  The select loop is loosely based on fairly
  751. well-known code from "rsh" and Richard Stevens' "sock" program [which itself is
  752. sort of a "netcat" with more obscure features], with some more paranoid
  753. sanity-checking thrown in to guard against the distinct likelihood that there
  754. are subtleties about such things I still don't understand.  I found the
  755. argument-hiding method cleanly implemented in Barrett's "deslogin"; reading the
  756. line as input allows greater versatility and is much less prone to cause
  757. bizarre problems than the more common trick of overwriting the argv array.
  758. After the first release, several people contributed portability fixes; they are
  759. credited in generic.h and the Makefile.  Lauren Burka inspired the ascii art
  760. for this revised document.  Dean Gaudet at Wired supplied a precursor to
  761. the hex-dump code, and mudge@l0pht.com originally experimented with and
  762. supplied code for the telnet-options responder.  Outbound "-e <prog>" resulted
  763. from a need to quietly bypass a firewall installation.  Other suggestions and
  764. patches have rolled in for which I am always grateful, but there are only 26
  765. hours per day and a discussion of feature creep near the end of this document.
  766. Netcat was written with the Russian railroad in mind -- conservatively built
  767. and solid, but it *will* get you there.  While the coding style is fairly
  768. "tight", I have attempted to present it cleanly [keeping *my* lines under 80
  769. characters, dammit] and put in plenty of comments as to why certain things
  770. are done.  Items I know to be questionable are clearly marked with "XXX".
  771. Source code was made to be modified, but determining where to start is
  772. difficult with some of the tangles of spaghetti code that are out there.
  773. Here are some of the major points I feel are worth mentioning about netcat's
  774. internal design, whether or not you agree with my approach.
  775. Except for generic.h, which changes to adapt more platforms, netcat is a single
  776. source file.  This has the distinct advantage of only having to include headers
  777. once and not having to re-declare all my functions in a billion different
  778. places.  I have attempted to contain all the gross who's-got-what-.h-file
  779. things in one small dumping ground.  Functions are placed "dependencies-first",
  780. such that when the compiler runs into the calls later, it already knows the
  781. type and arguments and won't complain.  No function prototyping -- not even the
  782. __P(()) crock -- is used, since it is more portable and a file of this size is
  783. easy enough to check manually.  Each function has a standard-format comment
  784. ahead of it, which is easily found using the regexp " :$".  I freely use gotos.
  785. Loops and if-clauses are made as small and non-nested as possible, and the ends
  786. of same *marked* for clarity [I wish everyone would do this!!].
  787. Large structures and buffers are all malloc()ed up on the fly, slightly larger
  788. than the size asked for and zeroed out.  This reduces the chances of damage
  789. from those "end of the buffer" fencepost errors or runaway pointers escaping
  790. off the end.  These things are permanent per run, so nothing needs to be freed
  791. until the program exits.
  792. File descriptor zero is always expected to be standard input, even if it is
  793. closed.  If a new network descriptor winds up being zero, a different one is
  794. asked for which will be nonzero, and fd zero is simply left kicking around
  795. for the rest of the run.  Why?  Because everything else assumes that stdin is
  796. always zero and "netfd" is always positive.  This may seem silly, but it was a
  797. lot easier to code.  The new fd is obtained directly as a new socket, because
  798. trying to simply dup() a new fd broke subsequent socket-style use of the new fd
  799. under Solaris' stupid streams handling in the socket library.
  800. The catch-all message and error handlers are implemented with an ample list of
  801. phoney arguments to get around various problems with varargs.  Varargs seems
  802. like deliberate obfuscation in the first place, and using it would also
  803. require use of vfprintf() which not all platforms support.  The trailing
  804. sleep in bail() is to allow output to flush, which is sometimes needed if
  805. netcat is already on the other end of a network connection.
  806. The reader may notice that the section that does DNS lookups seems much
  807. gnarlier and more confusing than other parts.  This is NOT MY FAULT.  The
  808. sockaddr and hostent abstractions are an abortion that forces the coder to
  809. deal with it.  Then again, a lot of BSD kernel code looks like similar
  810. struct-pointer hell.  I try to straighten it out somewhat by defining my own
  811. HINF structure, containing names, ascii-format IP addresses, and binary IP
  812. addresses.  I fill this structure exactly once per host argument, and squirrel
  813. everything safely away and handy for whatever wants to reference it later.
  814. Where many other network apps use the FIONBIO ioctl to set non-blocking I/O
  815. on network sockets, netcat uses straightforward blocking I/O everywhere.
  816. This makes everything very lock-step, relying on the network and filesystem
  817. layers to feed in data when needed.  Data read in is completely written out
  818. before any more is fetched.  This may not be quite the right thing to do under
  819. some OSes that don't do timed select() right, but this remains to be seen.
  820. The hexdump routine is written to be as fast as possible, which is why it does
  821. so much work itself instead of just sprintf()ing everything together.  Each
  822. dump line is built into a single buffer and atomically written out using the
  823. lowest level I/O calls.  Further improvements could undoubtedly be made by
  824. using writev() and eliminating all sprintf()s, but it seems to fly right along
  825. as is.  If both exec-a-prog mode and a hexdump file is asked for, the hexdump
  826. flag is deliberately turned off to avoid creating random zero-length files.
  827. Files are opened in "truncate" mode; if you want "append" mode instead, change
  828. the open flags in main().
  829. main() may look a bit hairy, but that's only because it has to go down the
  830. argv list and handle multiple ports, random mode, and exit status.  Efforts
  831. have been made to place a minimum of code inside the getopt() loop.  Any real
  832. work is sent off to functions in what is hopefully a straightforward way.
  833. Obligatory vendor-bash: If "nc" had become a standard utility years ago,
  834. the commercial vendors would have likely packaged it setuid root and with
  835. -DGAPING_SECURITY_HOLE turned on but not documented.  It is hoped that netcat
  836. will aid people in finding and fixing the no-brainer holes of this sort that
  837. keep appearing, by allowing easier experimentation with the "bare metal" of
  838. the network layer.
  839. It could be argued that netcat already has too many features.  I have tried
  840. to avoid "feature creep" by limiting netcat's base functionality only to those
  841. things which are truly relevant to making network connections and the everyday
  842. associated DNS lossage we're used to.  Option switches already have slightly
  843. overloaded functionality.  Random port mode is sort of pushing it.  The
  844. hex-dump feature went in later because it *is* genuinely useful.  The
  845. telnet-responder code *almost* verges on the gratuitous, especially since it
  846. mucks with the data stream, and is left as an optional piece.  Many people have
  847. asked for example "how 'bout adding encryption?" and my response is that such
  848. things should be separate entities that could pipe their data *through* netcat
  849. instead of having their own networking code.  I am therefore not completely
  850. enthusiastic about adding any more features to this thing, although you are
  851. still free to send along any mods you think are useful.
  852. Nonetheless, at this point I think of netcat as my tcp/ip swiss army knife,
  853. and the numerous companion programs and scripts to go with it as duct tape.
  854. Duct tape of course has a light side and a dark side and binds the universe
  855. together, and if I wrap enough of it around what I'm trying to accomplish,
  856. it *will* work.  Alternatively, if netcat is a large hammer, there are many
  857. network protocols that are increasingly looking like nails by now...
  858. _H* 960320 v1.10 RELEASE -- happy spring!