xxAlgorithm for finding hosts which provide a UDP-based service on a large network

Algorithm for finding hosts which provide a UDP-based service on a large network

gene m. stover

created Friday, 2006 January 13 updated Tuesday, 2006 January 17

Copyright copyright 2006 Gene Michael Stover. All rights reserved. Permission to copy, store, & view this document unmodified & in its entirety is granted.

Contents

1 What is this? 2 Inputs 3 Output 4 The Algorithm 5 How it works 6 Example: echo 7 Example: daytime 8 Example: ONC RPC portmapper 9 Example: SNMP 10 Example: CIFS A Source Code B What about nmap?

1 What is this? As of Monday, 2006 January 16, this is almost finished. I’d like to do the SNMP & CIFS examples before I declare it complete.

I describe an algorithm which finds hosts which provide a UDP-based service. The algorithm is fast; it can scan the 10.x.y.z network in about 2.5 hours if you have enough memory & there are few providers of the service. (The algorithm’s run time increases as the number of providers increases.)

The algorithm allows you to specify the UDP-based service. It does not know anything of the service.

The algorithm produces short bursts of UDP traffice, but there are significant pauses between the bursts.

The algorithm uses just one thread.

The algorithm does not contain any stealth features.

I have implemented the algorithm in a command line program which is licensed under the terms of the Gnu General Public License. The source code is available for download.

2 Inputs The inputs to the algorithm are:

The UDP port number for the desired service.

A message to send to hosts & to which service providers will reply. The algorithm treats the message as opaque data; it does not interpret the message or the replies. You must create a message which is appropriate for the service that interests you.

An I/O timeout duration T, such as 10 seconds.

A list of Internet addresses (IP addresses) to search.

3 Output The algorithm produces a list of the IP addresses of the hosts which responded to the message.

I assume the list of IP addresses is available on standard input (stdin).

4 The Algorithm The algorithm uses the unix select (2) system call. In the pseudocode here, I’ll express that as “wait for an event on the socket”.

Create a UDP socket s.

Until there are no more addresses to scan

Load IP addresses into a list in memory. Load as many as will fit, but it’s okay if they don’t all fit.

Until the list is empty

Wait for an event on socket s with timeout T. If we have not sent to all of the list, we are interested in input & output. If we have sent to all of the list, we are only ready for input.

If input is waiting on s, read it with recvfrom. Extract the sender’s IP address & print it. Remove that IP address from the list.

If s is ready for output & we have not sent all of the list, send the message to the next IP address on the list.

If there was a timeout (i.e., we were only interested in input, & there was none), clear the list.

Exit

5 How it works Imagine asking the algorithm to scan a bunch of IP addresses, & it just happens that none of the hosts provide the service that interests you. As the algorithm sends the message to the hosts, none of them reply. So, T seconds after sending the final address, the algorithm times out, clears the list, & announces that it’s done & none of the hosts are service providers.

Run time for that instance is T seconds plus the number of seconds to send all the UDP messages.

Now imagine that one of the IP addresses is for a host that does provide the service. Then the algorithm will send many of the IP addresses before receiving a reply from that host. It will print that host’s IP address, remove it from the list, & begin the process again. But this time, the process is the case in which none of the hosts are providers. So it’s the run time from the “no providers” case (a little over T seconds), plus the number of seconds for the one host to reply, which will be one or two seconds in practice, & just under T seconds in the worst case. So the run time will be roughtly T + 2 seconds in practice or 2T seconds in the words case.

As you imagine cases in which more & more of the hosts are service providers, it just increases the number of iterations through the list. Each iteration removes one IP address from the list, so that it eventually degeneratese to the case in which none of the hosts are providers.

6 Example: echo The echo service, which isn’t used much (probably for security reasons), is on UDP port 7. You send it a line, & it sends you that same line. The message to make echo reply can be just about anything. Here’s the one I used:

$xcatxsrc/echo.sca
xhello,xworld
x$

I have echo running on one of my computers, at 10.1.0.5. The generator I used generates all the 10.1.[01].y addresses, preceeded by 128,000 others (which might be routed over the Internet – it’s a test). It finds 10.1.0.5.

7 Example: daytime The daytime is an old one, like echo. It’s on port 13. I used the same generator as for the echo test. I used a file of one empty line for the message. (Just about any file would have worked. As with echo, daytime does not examine the payload it receives.)

I’m running daytime on 10.1.0.2.

$xbin/genx|bin/scanx13xsrc/daytime.scax>001.txt
x
xMAX_OCTETS_IN_LISTxisx1048576.
xS_lst_lenxisx262144.
xsrc/scan.c:159:xMessagexcontainsx1xoctets
xsrc/scan.c:239:xS_LoadLst:xS_countxisx131584.xLastxisx10.1.1.255.
xsendto:xPermissionxdenied
xsrc/scan.c:344:xsendtox(10.1.0.0)xfailed
xsendto:xPermissionxdenied
xsrc/scan.c:344:xsendtox(10.1.0.0)xfailed
xsrc/scan.c:239:xS_LoadLst:xS_countxisx0.xLastxisx0.0.0.0.$
x$xcatx001.txt
x10.1.0.2
x$

8 Example: ONC RPC portmapper The portmapper service for ONC RPC is on port 111 (both TCP & UDP, but we’re only scanning the UDP ports).

The only trick to scanning for the portmapper is that the message is not obvious. I looked through the <rpc/*.h>xheader files to figure out how to construct a remote call to the portmapper. Then I wrote

src/msg-portmapper.c1 ^{1src/msg-portmapper.c} xto construct the message & send it to stdout. The message does not have to be perfect; it just needs to motivate the portmapper to reply.

Here are the results of the run. I used the same generator as for the previous two examples.

$xbin/msg-portmapperx>src/portmapper.sca
x$xtimexbin/genx|bin/scanx111xsrc/portmapper.scax>001.txt
x
xMAX_OCTETS_IN_LISTxisx1048576.
xS_lst_lenxisx262144.
xsrc/scan.c:159:xMessagexcontainsx56xoctets
xsrc/scan.c:239:xS_LoadLst:xS_countxisx131584.xLastxisx10.1.1.255.
xsendto:xPermissionxdenied
xsrc/scan.c:344:xsendtox(10.1.0.0)xfailed
xsendto:xPermissionxdenied
xsrc/scan.c:344:xsendtox(10.1.0.0)xfailed
xsrc/scan.c:239:xS_LoadLst:xS_countxisx0.xLastxisx0.0.0.0.
xreal 1m4.705s
xuser 0m1.010s
xsys 0m3.390s
x$xcatx001.txt
x10.1.0.2
x10.1.0.5
x$

You can see that I’m running the RPC portmapper service at 10.1.0.2 &

10.1.0.5.2 ^{2That means that 10.1.0.4 & 10.1.0.9 have problems. Oh well.}

9 Example: SNMP To construct a message for SNMP, I used a remote printer-controlling application to query a printer while I had a network sniffer running. The sniffer showed the forty or so octets that the application sent to the printer in its first transmission. I typed those numbers into a Lisp expression which dumped them as octets into the

src/snmp.sca3 ^{3snmp.sca} xfile.

SNMP is on port 161.

After that, I ran the scanner on a LAN which contains a lot of SNMP devices, & the scanner located most of them. It worked better when the timeout was 60 seconds.

I won’t show the results here because I’m writing this essay at home, & that network with all the SNMP devices is at a customer’s site.

10 Example: CIFS

A Source Code

The program which scans is src/scan.c4 ^{4scan.c} .

src/gen.c5 ^{5gen.c} xgenerates IP addresses from some hard-coded data. It’s for testing or demo purposes.

src/counter.c6 ^{6counter.c} xis a simple UDP service that can be helpful for tests or demos.

src/msg-portmapper.c7 ^{7msg-portmapper.c} xgenerates the message for scanning for the ONC RPC portmapper service.

Makefile8 8Makefile

, 710 octets

Makefile.msdos9 9Makefile.msdos , 2260 octets

bin/ bin/counter10 10counter , 8979 octets

bin/counter.exe11 11counter.exe , 36864 octets

bin/gen12 12gen , 4840 octets

bin/gen.exe13 13gen.exe , 28672 octets

bin/msg-portmapper14 14msg-portmapper , 6771 octets

bin/scan15 15scan , 14245 octets

bin/scan.exe16 16scan.exe , 45056 octets

src/

src/counter.c17 17counter.c , 6249 octets

src/daytime.sca18 18daytime.sca , 1 octets

src/debug.c19 19debug.c , 1921 octets src/debug.h20 20debug.h , 1532 octets

src/echo.sca21 21echo.sca , 13 octets

src/gen.c22 22gen.c , 1252 octets

src/msg-portmapper.c23 23msg-portmapper.c , 3955 octets

src/portmapper.sca24 24portmapper.sca , 56 octets

src/scan.c25 25scan.c , 12735 octets

src/snmp.sca26 26snmp.sca , 40 octets

src/this.h27 27this.h , 1849 octets

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/counter.c,vx1.4x2006/01/18x03:45:54xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x/*
xx*xThisxisxaxsimplexservice,xsortxofxlikex"echo"xexceptxthatxit
xx*xreturnsxaxnumber,xnotxthexpacketxthatxyouxsendxit.
xx*/
x
x#includex"this.h"
x
x/*
xx*xPortxwherexwexarexlookingxforxlivexhosts.
xx*/
xstaticxu_shortxS_portx=x0;
x
x/*
xx*/
xstaticxcharx*S_prognamex=x"";
x
x/*
xx*/
xenumx{xACTION_RUN,xACTION_HELPx};
xstaticxintxS_actionx=xACTION_RUN;
x
x/*
xx*/
xstaticxint
xS_CommandLinex(intxargc,xcharx*argv[])

xxxintxrcx=x0;
xxxintxoptindx=x1;
x
xxxS_prognamex=xargv[0];
xxxifx(optindx<xargc)x{
xxxxxifx(sscanfx(argv[optind],x"%hu",x&S_port)x==x1)x{
xxxxxxxifx(0x<xS_portx&&xS_portx<=x65535)x{
xxxxxxxxx++optind;
xxxxxxxxxifx(optindx<xargc)x{
xxxxxxxxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxxxxxxxfprintfx(stderr,x"xIgnoringxextraxcommandxlinexarguments.");
xxxxxxxxx}
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxxxxxfprintfx(stderr,x"x%dxisxoutxofxrangexforxaxUDPxport.",xS_port);
xxxxxxxxxS_actionx=xACTION_HELP;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:",xx__FILE__,x__LINE__);
xxxxxxxfprintfx(stderr,x"xCannotxparsex\"%s\"xintoxaxport",xargv[optind]);
xxxxxxxfprintfx(stderr,x"xnumber.");
xxxxxxxS_actionx=xACTION_HELP;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:",xx__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xMissingxportxnumberx&xnamexofxmessagexfile");
xxxxxfprintfx(stderr,x"xonxthexcommandxline.");
xxxxxS_actionx=xACTION_HELP;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Helpx()
x{
xxxprintfx("\nUsage:x%sxPORT",xS_progname);
xxxprintfx("\nPORTxisxthexUDPxportxnumber");
xxxprintfx("\n");
xxxreturnx0;
x}
x
x/*
xx*/
xstaticxSOCKET
xS_CloseSocketx(SOCKETxs)
x{
xxxifx(sx!=xINVALID_SOCKET)x{

x#ifxIS_UNIX
xxxxxclosex(s);
x#endif
x#ifxIS_WINDERS
xxxxxclosesocketx(s);
x#endif
xxx}
xxxreturnxINVALID_SOCKET;
x}
x
x/*
xx*/
xstaticxSOCKET
xS_MakeSocketx()
x{
xxxSOCKETxs;
xxxstructxsockaddr_inxsin;
xxxstructxsockaddrx*sa;
x
xxxsx=xsocket(PF_INET,xSOCK_DGRAM,x0);
xxxifx(sx!=xINVALID_SOCKET)x{
xxxxxbzerox(&sin,xsizeofxsin);
xxxxxsin.sin_familyx=xAF_INET;
xxxxxsin.sin_portx=xhtonsx(S_port);
xxxxxsin.sin_addr.s_addrx=xINADDR_ANY;
xxxxxsax=x(structxsockaddrx*)x&sin;
xxxxxifx(bindx(s,xsa,xsizeofxsin)x==x0)x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n");
xxxxxxxperrorx("bind");
xxxxxxxfprintfx(stderr,x"%s:%d:xbindxfailed",x__FILE__,x__LINE__);
xxxxxxxS_CloseSocketx(s);
xxxxxxxsx=xINVALID_SOCKET;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n");
xxxxxperrorx("socket");
xxxxxfprintfx(stderr,x"%s:%d:xsocketxfailed",x__FILE__,x__LINE__);
xxx}
xxxfprintfx(stderr,x"\n%s:%d:xtrace:xsxisx%d",x__FILE__,x__LINE__,xs);
xxxreturnxs;
x}
x
x/*
xx*/
xstaticxint
xS_DoRecvx(structxsockaddr_inx*sin,xSOCKETxs)
x{
xxxintxrcx=x0,xi;

xxxcharxbuffer[8000];
xxxstructxsockaddrx*sa;
xxxintxsin_len;
x
xxxfprintfx(stderr,x"\n%s:%d:xtrace:xsxisx%d",x__FILE__,x__LINE__,xs);
xxxbzerox(sin,xsizeofx*sin);
xxxsin_lenx=xsizeofx*sin;
xxxsax=x(structxsockaddrx*)xsin;
xxxix=xrecvfromx(s,xbuffer,xsizeofxbuffer,x0,xsa,x&sin_len);
xxxifx(ix>x0)x{
xxxxx/*xgoodx*/
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n");
xxxxxperrorx("recvfrom");
xxxxxfprintfx(stderr,x"%s:%d:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xrecvfromxfailed");
xxxxxrcx=x219;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_DoSendx(intxcount,xstructxsockaddr_inx*sin,xSOCKETxs)
x{
xxxintxrcx=x0,xi;
xxxstructxsockaddrx*sa;
xxxcharxbuffer[12];
x
xxxsprintfx(buffer,x"%d\n",xcount);
xxxsax=x(structxsockaddrx*)xsin;
xxxix=xsendtox(s,xbuffer,xstrlenx(buffer),x0,xsa,xsizeofx*sin);
xxxifx(ix>x0)x{
xxxxx/*xgoodx*/
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n");
xxxxxperrorx("sendto");
xxxxxfprintfx(stderr,x"%s:%d:xsendtoxfailed",x__FILE__,x__LINE__);
xxxxxrcx=x219;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Loopx(SOCKETxs)
x{
xxxintxrcx=x0;

xxxintxcountx=x0;
xxxstructxsockaddr_inxaddy;
x
xxxwhilex(rcx==x0)x{
xxxxxifx(S_DoRecvx(&addy,xs)x==x0)x{
xxxxxxxprintfx("\n%s",xinet_ntoax(addy.sin_addr));xfflushx(stdout);
xxxxxxxifx(S_DoSendx(count,x&addy,xs)x==x0)x{
xxxxxxxxx/*xgoodx*/
xxxxxxxxx++count;
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:xS_DoSendxfailed",x__FILE__,x__LINE__);
xxxxxxxxxrcx=x3;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_DoRecvxfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x-172;
xxxxx}
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Runx()
x{
xxxintxrcx=x0;
xxxSOCKETxs;
x
xxxsx=xS_MakeSocketx();
xxxifx(sx!=xINVALID_SOCKET)x{
xxxxxifx(S_Loopx(s)x==x0)x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_Loopxfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x134;
xxxxx}
xxxxxS_CloseSocketx(s);
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xS_MakeSocketxfailed",x__FILE__,x__LINE__);
xxxxxrcx=x-116;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Dispatchx()

xxxintxrcx=x0;
x
xxxswitchx(S_action)x{
xxxcasexACTION_RUN:
xxxxxrcx=xS_Runx();
xxxxxbreak;
xxxcasexACTION_HELP:
xxxxxrcx=xS_Helpx();
xxxxxbreak;
xxxdefault:
xxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xS_actionxisx%d.",xS_action);
xxxxxfprintfx(stderr,x"xxThisxshouldxneverxhappen!");
xxxxxrcx=x102;
xxx}
xxxreturnxrc;
x}
x
xint
xmainx(intxargc,xcharx*argv[])
x{
xxxintxrcx=x0;
x
xxxifx(S_CommandLinex(argc,xargv)x==x0)x{
xxxxxifx(S_Dispatchx()x==x0)x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_Dispatchfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x234;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xS_CommandLinexfailed",x__FILE__,x__LINE__);
xxxxxrcx=x234;
xxx}
xxxreturnxrcx==x0x?xEXIT_SUCCESSx:xEXIT_FAILURE;
x}
x
x/*x---xendxofxfilex---x*/

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/debug.h,vx1.3x2006/01/18x03:47:30xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x#ifx__cplusplus
xexternx"C"x{
x#endif
x
xxx/*
xxxx*xSOMExDEBUGGINGxSTOOF
xxxx*/
x#definexTrace(moo)xDEBUG_Printx(__FILE__,x__LINE__,xmoo)
x
xxx/*
xxxx*/
xxxBooleanxDEBUG_IsVerbosex(void);
x
xxx/*
xxxx*xPrintxthexmessagexifxdebuggingxIsxVerbose.
xxxx*/
xxxvoidxDEBUG_Printx(charxfile[],xintxline,xcharxfmt[],x...);
x
xxx/*
xxxx*xIt'sxappropriatextoxcallxthisxfunctionxlikexthis:
xxxx*xDEBUG_PrintLastErrorx(__FILE__,x__LINE__,
xxxx*xxxxxxxxxxxxxxxxxxxxxxx"name-of-function-which-caused-error");
xxxx*/
xxxvoidxDEBUG_PrintLastErrorx(charxfile[],xintxline,xcharxmoo[]);

x#ifx__cplusplus
x}
x#endif
x
x/*x---xendxofxfilex---x*/

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/gen.c,vx1.4x2006/01/18x03:46:22xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x#includex"this.h"
x
xint
xmainx()
x{
xxxintxw,xx,xy,xz;
x
xxx/*x10.1.y.zx*/
xxxforx(wx=x10;xwx<=x10;x++w)x{
xxxxxforx(xx=x1;xxx<=x1;x++x)x{
xxxxxxxforx(yx=x0;xyx<=x10;x++y)x{
xxxxxxxxxforx(zx=x0;xzx<=x255;x++z)x{
xxxxxxxxxxxprintfx("%d.%d.%d.%d\n",xw,xx,xy,xz);
xxxxxxxxx}
xxxxxxx}
xxxxx}
xxx}
xxxreturnx0;
x}
x
x/*x---xendxofxfilex---x*/

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/msg-portmapper.c,vx1.2x2006/01/18x03:46:26xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x#includex"this.h"
x
x/*
xx*/
xstaticxcharx*S_prognamex=x"";
x
x/*
xx*/
xenumx{xACTION_RUN,xACTION_HELPx};
xstaticxintxS_actionx=xACTION_RUN;
x
x/*
xx*/
xstaticxint
xS_CommandLinex(intxargc,xcharx*argv[])
x{
xxxintxrcx=x0;
x#ifxIS_UNIX
xxxintxc;
x#endif
x#ifxIS_WINDERS
xxxintxoptindx=x1;
x#endif

xxxS_prognamex=xargv[0];
x#ifxIS_UNIX
xxxwhilex(rcx==x0x&&x(cx=xgetoptx(argc,xargv,x"h"))x!=x-1)x{
xxxxxswitchx(c)x{
xxxxxcasex'h':
xxxxxxxS_actionx=xACTION_HELP;
xxxxxxxbreak;
xxxxxdefault:
xxxxxxxfprintfx(stderr,x"\n%s:%d:xwarning:",x__FILE__,x__LINE__);
xxxxxxxfprintfx(stderr,x"xIgnoringxunexpectedxcommandxline");
xxxxxxxfprintfx(stderr,x"xoptionx\"%c\".",xc);
xxxxx}
xxx}
x#endif
x#ifxIS_WINDERS
xxx/*xWindersxdoesn'txhavexgetopt.x*/
xxxwhilex(rcx==x0x&&xoptindx<xargcx&&xargv[optind][0]x==x'-')x{
xxxxxifx(strcmpx(argv[optind],x"-h")x==x0)x{
xxxxxxxS_actionx=xACTION_HELP;
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xIgnoringxunexpectedxswitch,x\"%s\".",
xxxxxxxxxxxxxxxx__FILE__,x__LINE__,xargv[optind]);
xxxxx}
xxxxx++optind;
xxx}
x#endif
xxxifx(optindx<xargc)x{
xxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xIgnoringxextraxcommandxlinexarguments.");
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Helpx()
x{
xxxprintfx("\nUsage:x%sx[-h]",xS_progname);
xxxprintfx("\n");
xxxreturnx0;
x}
x
x/*
xx*/
xstaticxint
xS_Runx()
x{
xxxintxrcx=x0;
xxxXDRxxdrs;

xxxstructxrpc_msgxmsg;
xxxstructxpmapxspmap;
x
xxxxdrstdio_createx(&xdrs,xstdout,xXDR_ENCODE);
xxxbzerox(&msg,xsizeofxmsg);
xxxmsg.rm_xidx=x17;xxxxxxxxxxxxxxxxxxxxxx/*xmsgxid,xpulledxfromxanxorificex*/
xxxmsg.rm_directionx=xCALL;
xxxmsg.ru.RM_cmb.cb_rpcversx=x2;
xxxmsg.ru.RM_cmb.cb_progx=xPMAPPROG;
xxxmsg.ru.RM_cmb.cb_versx=xPMAPVERS;
xxxmsg.ru.RM_cmb.cb_procx=xPMAPPROC_NULL;
xxxifx(xdr_callmsgx(&xdrs,x&msg))x{
xxxxxbzerox(&spmap,xsizeofxspmap);
xxxxx/*xWe'llxaskxthexportmapperxforxthexportmapper.x*/
xxxxxspmap.pm_progx=xPMAPPROG;
xxxxxspmap.pm_versx=xPMAPVERS;
xxxxxspmap.pm_protx=xIPPROTO_UDP;
xxxxx/*xspmap_pm_portx=x?;x*/
xxxxxifx(xdr_pmapx(&xdrs,x&spmap))x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xxdr_pmapxfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x234;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xxdr_callmsgxfailed",x__FILE__,x__LINE__);
xxxxxrcx=x333;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Dispatchx()
x{
xxxintxrcx=x0;
x
xxxswitchx(S_action)x{
xxxcasexACTION_RUN:
xxxxxrcx=xS_Runx();
xxxxxbreak;
xxxcasexACTION_HELP:
xxxxxrcx=xS_Helpx();
xxxxxbreak;
xxxdefault:
xxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xS_actionxisx%d.",xS_action);
xxxxxfprintfx(stderr,x"xxThisxshouldxneverxhappen!");
xxxxxrcx=x102;

xxxreturnxrc;
x}
x
xint
xmainx(intxargc,xcharx*argv[])
x{
xxxintxrcx=x0;
x
xxxifx(S_CommandLinex(argc,xargv)x==x0)x{
xxxxxifx(S_Dispatchx()x==x0)x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_Dispatchfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x234;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xS_CommandLinexfailed",x__FILE__,x__LINE__);
xxxxxrcx=x234;
xxx}
xxxreturnxrcx==x0x?xEXIT_SUCCESSx:xEXIT_FAILURE;
x}
x
x/*x---xendxofxfilex---x*/

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/scan.c,vx1.4x2006/01/18x03:46:37xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x#includex"this.h"
x
x/*
xx*xMaximumxnumberxofxoctetsxforxthexlist.
xx*/
x#definexMAX_OCTETS_IN_LISTx(1x<<x16x/*x64xkilobytex*/)
x
x/*
xx*/
x#definexS_lst_lenx(MAX_OCTETS_IN_LISTx/xsizeofx(structxin_addr))
xstaticxstructxin_addrxS_lst[S_lst_len];
xstaticxsize_txS_countx=x0;
xstaticxsize_txS_ix=x0;
x
x/*
xx*xPortxwherexwexarexlookingxforxlivexhosts.
xx*/
xstaticxu_shortxS_portx=x0;
x
x/*
xx*xTimeoutx(inxseconds)xtoxwaitxforxinputxonxthexsocket.
xx*xSetxwithxthex"-t"xcommandxlinexoption.
xx*/
xstaticxintxS_timeoutx=x10;

x/*
xx*xPathnamexofxfilexfromxwhichxwexreadxthexmessagextoxsend.
xx*/
xstaticxcharx*S_pathname;
x
x/*
xx*xThexmessagextoxsend.xxMaximumxsizexisx8,000xoctetsxbecause
xx*xthat'sxprettyxmuchxthexmaximumxpayloadxofxaxUDPxpacket.
xx*/
xstaticxcharxS_message[8000];
xstaticxintxS_message_len;
x
x/*
xx*/
xstaticxcharx*S_prognamex=x"";
x
x/*
xx*/
xenumx{xACTION_RUN,xACTION_HELPx};
xstaticxintxS_actionx=xACTION_RUN;
x
x/*
xx*/
xstaticxint
xS_Initx()
x{
xxxintxrcx=x0;
x#ifxIS_WINDERS
xxxWORDxw;
xxxstaticxWSADATAxwsadata;
x#endif
x
xxxsrandx(timex(NULL)x+xgetpidx());
x#ifxIS_WINDERS
xxxwx=xMAKEWORDx(2,x0);
xxxifx(WSAStartupx(w,x&wsadata)x==x0)x{
xxxxx/*xgoodx*/
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xWSAStartupxfailed",x__FILE__,x__LINE__);
xxxxxrcx=x56;
xxx}
x#endif
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_CommandLinex(intxargc,xcharx*argv[])

xxxintxrcx=x0;
x#ifxIS_UNIX
xxxintxc;
x#endif
x#ifxIS_WINDERS
xxxintxoptindx=x1;
x#endif
x
xxxS_prognamex=xargv[0];
x#ifxIS_UNIX
xxxwhilex(rcx==x0x&&x(cx=xgetoptx(argc,xargv,x"t:"))x!=x-1)x{
xxxxxswitchx(c)x{
xxxxxcasex't':
xxxxxxxifx(sscanfx(optarg,x"%d",x&S_timeout)x==x1)x{
xxxxxxxxx/*xgoodx*/
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:xwarning:",x__FILE__,x__LINE__);
xxxxxxxxxfprintfx(stderr,x"xCan'txparsex\"%s\"xintoxanxintegeral",xoptarg);
xxxxxxxxxfprintfx(stderr,x"xtimeout.xxUsingx10xsecondsxforxthextimeout.");
xxxxxxxxxS_timeoutx=x10;
xxxxxxx}
xxxxxxxbreak;
xxxxxdefault:
xxxxxxxfprintfx(stderr,x"\n%s:%d:xwarning:",x__FILE__,x__LINE__);
xxxxxxxfprintfx(stderr,x"xIgnoringxunexpectedxcommandxline");
xxxxxxxfprintfx(stderr,x"xoptionx\"%c\".",xc);
xxxxx}
xxx}
x#endif
x#ifxIS_WINDERS
xxx/*xWindersxdoesn'txhavexgetopt.x*/
xxxwhilex(rcx==x0x&&xoptindx<xargcx&&xargv[optind][0]x==x'-')x{
xxxxxifx(strcmpx(argv[optind],x"-t")x==x0)x{
xxxxxxx++optind;
xxxxxxxifx(optindx<xargc)x{
xxxxxxxxxifx(sscanfx(argv[optind],x"%d",x&S_timeout)x==x1)x{
xxxxxxxxxxx/*xgoodx*/
xxxxxxxxx}xelsex{
xxxxxxxxxxxfprintfx(stderr,x"\n%s:%d:xwarning:",x__FILE__,x__LINE__);
xxxxxxxxxxxfprintfx(stderr,x"xCan'txparsex\"%s\"xintoxanxintegeral",
xxxxxxxxxxxxxxxxxxxargv[optind]);
xxxxxxxxxxxfprintfx(stderr,x"xtimeout.xxUsingx10xsecondsxforxthextimeout.");
xxxxxxxxxxxS_timeoutx=x10;
xxxxxxxxx}
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:xwarning:",x__FILE__,x__LINE__);
xxxxxxxxxfprintfx(stderr,x"xMustxhavexintegralxnumberxofxsecondsxfollowing");
xxxxxxxxxfprintfx(stderr,x"xthex\"-t\"xargument.xxAssumingxthexdefault,");
xxxxxxxxxfprintfx(stderr,x"x10xseconds.");

xxxxxxxxxS_timeoutx=x10;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xIgnoringxunexpectedxswitch,x\"%s\".",
xxxxxxxxxxxxxxxx__FILE__,x__LINE__,xargv[optind]);
xxxxx}
xxxxx++optind;
xxx}
x#endif
x
xxxifx(optindx<xargc)x{
xxxxxifx(sscanfx(argv[optind],x"%hu",x&S_port)x==x1)x{
xxxxxxx++optind;
xxxxxxxifx(optindx<xargc)x{
xxxxxxxxxS_pathnamex=xargv[optind];
xxxxxxxxx++optind;
xxxxxxxxxifx(optindx<xargc)x{
xxxxxxxxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxxxxxxxfprintfx(stderr,x"xIgnoringxextraxcommandxlinexarguments.");
xxxxxxxxx}
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:",xx__FILE__,x__LINE__);
xxxxxxxxxfprintfx(stderr,x"xMissingxnamexofxmessagexfilexonxthe");
xxxxxxxxxfprintfx(stderr,x"xcommandxline.");
xxxxxxxxxS_actionx=xACTION_HELP;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:",xx__FILE__,x__LINE__);
xxxxxxxfprintfx(stderr,x"xCannotxparsex\"%s\"xintoxaxport",xargv[optind]);
xxxxxxxfprintfx(stderr,x"xnumber.");
xxxxxxxS_actionx=xACTION_HELP;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:",xx__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xMissingxportxnumberx&xnamexofxmessagexfile");
xxxxxfprintfx(stderr,x"xonxthexcommandxline.");
xxxxxS_actionx=xACTION_HELP;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Helpx()
x{
xxxprintfx("\nUsage:x%sx[-txSECONDS]xPORTxFILENAME",xS_progname);
xxxprintfx("\nPORTxisxthexUDPxportxnumber");
xxxprintfx("\nFILENAMExidentifiesxaxfilexwhichxcontainsxthexmessagexto");
xxxprintfx("\nxxxxsendxtoxeachxhostxtoxseexifxit'sxalive.");

xxxprintfx("\n");
xxxreturnx0;
x}
x
x/*
xx*/
xstaticxint
xS_LoadMessagex()
x{
xxxintxrcx=x0;
xxxstaticxcharxmode[]x=x"rb";
xxxFILEx*fp;
x
xxxfpx=xfopenx(S_pathname,xmode);
xxxifx(fpx!=xNULL)x{
xxxxxS_message_lenx=xfreadx(S_message,x1,xsizeofxS_message,xfp);
xxxxxifx(S_message_lenx>x0)x{
xxxxxxx/*xgoodx*/
xxxxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxxxfprintfx(stderr,x"xMessagexcontainsx%dxoctets",xS_message_len);
xxxxx}xelsex{
xxxxxxxDEBUG_PrintLastErrorx(__FILE__,x__LINE__,x"S_LoadMessage");
xxxxxxxrcx=x121;
xxxxx}
xxxxxfclosex(fp);
xxx}xelsex{
xxxxxDEBUG_PrintLastErrorx(__FILE__,x__LINE__,x"S_LoadMessage");
xxxxxrcx=x55;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxSOCKET
xS_CloseSocketx(SOCKETxs)
x{
xxxifx(sx!=xINVALID_SOCKET)x{
x#ifxIS_UNIX
xxxxxclosex(s);
x#endif
x#ifxIS_WINDERS
xxxxxclosesocketx(s);
x#endif
xxx}
xxxreturnxINVALID_SOCKET;
x}
x
x/*

xstaticxSOCKET
xS_MakeSocketx()
x{
xxxSOCKETxs;
x
xxxfprintfx(stderr,x"\n%s:%d:xS_MakeSocket",x__FILE__,x__LINE__);
xxxsx=xsocketx(PF_INET,xSOCK_DGRAM,x0);
xxxifx(sx!=xINVALID_SOCKET)x{
xxxxx/*xgoodx*/
xxx}xelsex{
xxxxxDEBUG_PrintLastErrorx(__FILE__,x__LINE__,x"S_MakeSocket");
xxx}
xxxreturnxs;
x}
x
x/*
xx*/
xstaticxvoid
xS_Trimx(charxx[])
x{
xxxwhilex(strlenx(x)x>x0x&&xisspacex(x[strlen(x)x-x1]))x{
xxxxxx[strlen(x)x-x1]x=x'\0';
xxx}
x}
x
x/*
xx*/
xstaticxint
xS_ReadAddyx(structxin_addrx*addy)
x{
xxxintxrcx=x0;
xxxcharxline[100];
x
xxxifx(fgetsx(line,xsizeofxline,xstdin)x==xline)x{
xxxxxS_Trimx(line);
xxxxxbzerox(addy,xsizeofx*addy);
xxxxx/*xsin->sin_familyx=xAF_INET;x*/
xxxxx/*xsin->sin_portx=xhtonsx(S_port);x*/
xxxxx/*xsin->sin_addr.s_addrx=xinet_addrx(line);x*/
xxxxxaddy->s_addrx=xinet_addrx(line);
xxx}xelsex{
xxxxx/*
xxxxxx*xProbablyxnormalxendxofxfile,xthoughxIxsupposexsomexother
xxxxxx*xproblemsxarexpossible.
xxxxxx*/
xxxxxrcx=x3;
xxx}
xxxreturnxrc;
x}

xx*/
xstaticxvoid
xS_RandomizeLstx()
x{
xxxsize_txi,xr;
xxxstructxin_addrxtmp;
x
xxxforx(ix=x1;xix<xS_count;x++i)x{
xxxxxrx=xrandx()x%x(S_countx-xi)x+xi;
xxxxxmemcpyx(&tmp,x&S_lst[i],xsizeofxS_lst[i]);
xxxxxmemcpyx(&S_lst[i],x&S_lst[r],xsizeofxS_lst[i]);
xxxxxmemcpyx(&S_lst[r],x&tmp,xsizeofxS_lst[i]);
xxx}
x}
x
x/*
xx*/
xstaticxint
xS_LoadLstx()
x{
xxxstructxin_addrxaddy;
x
xxxS_countx=x0;
xxxwhilex(S_countx<xS_lst_lenx&&xS_ReadAddyx(&addy)x==x0)x{
xxxxxmemcpyx(&S_lst[S_count++],x&addy,xsizeofxS_lst[S_count]);
xxx}
xxxfprintfx(stderr,x"\n%s:%d:xS_LoadLst:",x__FILE__,x__LINE__);
xxxfprintfx(stderr,x"xS_countxisx%d.",xS_count);
xxxfprintfx(stderr,x"xLastxisx%s.",xinet_ntoax(S_lst[S_countx-x1]));
xxxreturnxS_countx>x0x?x0x:x-123;
x}
x
x/*
xx*/
xstaticxint
xS_CmpInAddrx(constxvoidx*va,xconstxvoidx*vb)
x{
xxxintxcmpx=x0;
xxxstructxin_addrx*ina,x*inb;
x
xxxinax=x(structxin_addrx*)xva;
xxxinbx=x(structxin_addrx*)xvb;
xxxifx(ina->s_addrx<xinb->s_addr)xcmpx=x-1;
xxxelsexifx(ina->s_addrx==xinb->s_addr)xcmpx=x0;
xxxelsexcmpx=x1;
xxxreturnxcmp;
x}
x

xstaticxvoid
xS_RemoveAddyx(structxin_addrx*addy)
x{
xxxstructxin_addrx*elt;
x
xxxeltx=xlfindx(addy,xS_lst,x&S_count,xsizeofxS_lst[0],x&S_CmpInAddr);
xxxifx(eltx!=xNULL)x{
xxxxx/*
xxxxxx*xRemovexthexelementxfromxthexlistxbyxcopyingxthexlastxelement
xxxxxx*xonxtopxofxit,xthenxdecrementingxthexcount.
xxxxxx*/
xxxxxifx(S_countx>=x2x&&xeltx<x&S_lst[S_countx-x1])x{
xxxxxxx/*
xxxxxxxx*xListxhasxatxleastx2xelements,x&xthexonextoxremove
xxxxxxxx*xisxnotxthexlast.
xxxxxxxx*/
xxxxxxxmemcpyx(elt,x&S_lst[--S_count],xsizeofx*elt);
xxxxx}xelsexifx(S_countx>=x1)x{
xxxxxxx/*
xxxxxxxx*xListxhasxjustxonexelement,xorxthexonextoxremovexis
xxxxxxxx*xthexlastxone.
xxxxxxxx*/
xxxxxxx--S_count;
xxxxx}xelsex{
xxxxxxx/*xListxisxalreadyxempty.x*/
xxxxx}
xxxxxS_ix=x0;x/*xresetxthexwritexlocationx*/
xxx}xelsex{
xxxxx/*xfprintfx(stderr,x".xxNotxinxlist???");x*/
xxx}
x}
x
x/*
xx*/
xstaticxSOCKET
xS_DoRecvx(SOCKETxs)
x{
xxxintxi;
xxxcharxbuffer[8000];
xxxstructxsockaddr_inxsin;
xxxstructxsockaddrx*sa;
xxxintxsin_len;
x
xxxbzerox(&sin,xsizeofxsin);
xxxsin_lenx=xsizeofxsin;
xxxsax=x(structxsockaddrx*)x&sin;
xxxix=xrecvfromx(s,xbuffer,xsizeofxbuffer,x0,xsa,x&sin_len);
xxxifx(ix>x0)x{
xxxxxprintfx("%s\n",xinet_ntoax(sin.sin_addr));

xxxxxS_RemoveAddyx(&sin.sin_addr);
xxx}xelsex{
xxxxxDEBUG_PrintLastErrorx(__FILE__,x__LINE__,x"S_DoRecv");
xxxxx/*xsx=xS_CloseSocketx(s);x*/
xxx}
xxxreturnxs;
x}
x
x/*
xx*/
xstaticxSOCKET
xS_DoSendx(SOCKETxs)
x{
xxxintxi;
xxxstructxsockaddr_inxsin;
xxxstructxsockaddrx*sa;
x
xxxifx(S_countx>x0)x{
xxxxxifx(S_ix>=xS_count)xS_ix=x0;
xxxxxfprintfx(stderr,x"\n%s:%d:xSendx%s",x__FILE__,x__LINE__,
xxxxxxxxxxxxxxinet_ntoax(S_lst[S_i]));
xxxxxbzerox(&sin,xsizeofxsin);
xxxxxsin.sin_familyx=xAF_INET;
xxxxxsin.sin_addrx=xS_lst[S_i];
xxxxxsin.sin_portx=xhtonsx(S_port);
xxxxxsax=x(structxsockaddrx*)x&sin;
xxxxxix=xsendtox(s,xS_message,xS_message_len,x0,xsa,xsizeofxsin);
xxxxxifx(ix>x0)x{
xxxxxxx/*xgoodx*/
xxxxx}xelsex{
xxxxxxxDEBUG_PrintLastErrorx(__FILE__,x__LINE__,x"S_DoSend");
xxxxxxxfprintfx(stderr,x"%s:%d:xRemovingx%s",x__FILE__,x__LINE__,
xxxxxxxxxxxxxxxxinet_ntoax(S_lst[S_i]));
xxxxxxxS_RemoveAddyx(&S_lst[S_i]);
xxxxxxxsx=xS_CloseSocketx(s);
xxxxx}
xxxxx++S_i;
xxx}xelsex{
xxxxx/*
xxxxxx*xThexlistxisxempty,xsoxdon'txsendxanytingxatxall.
xxxxxx*/
xxxxxfprintfx(stderr,x"\n%s:%d:xS_DoSend:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xlistxisxempty");
xxx}
xxxreturnxs;
x}
x
x/*
xx*/
xstaticxint

xS_Loopx()
x{
xxxintxrcx=x0;
xxxSOCKETxsx=xINVALID_SOCKET;
xxxfd_setxrfds,xwfds;
xxxstructxtimevalxstv;
xxxintxi;
x
xxxwhilex(rcx==x0x&&xS_countx>x0)x{
xxxxxifx(sx==xINVALID_SOCKET)x{
xxxxxxxsx=xS_MakeSocketx();xS_ix=x0;xS_RandomizeLstx();
xxxxx}
xxxxxifx(sx!=xINVALID_SOCKET)x{
xxxxxxxFD_ZEROx(&rfds);xFD_SETx(s,x&rfds);
xxxxxxxFD_ZEROx(&wfds);xFD_SETx(s,x&wfds);
xxxxxxxstv.tv_secx=xS_timeout;xstv.tv_usecx=x0;
xxxxxxxassertx(FD_ISSETx(s,x&rfds));
xxxxxxxassertx(FD_ISSETx(s,x&wfds));
xxxxxxxix=xselectx(sx+x1,
xxxxxxxxxxxxxxxxxx/*xalwaysxwantxtoxreadx*/
xxxxxxxxxxxxxxxxxx&rfds,
xxxxxxxxxxxxxxxxxx/*xonlyxwantxtoxwritexifxwexhavexnotxwritten
xxxxxxxxxxxxxxxxxxx*xeverything.xxOtherwise,xwexbusy-writex*/
xxxxxxxxxxxxxxxxxxS_ix<xS_countx?x&wfdsx:xNULL,
xxxxxxxxxxxxxxxxxxNULL,x/*xneverxexceptionsx*/
xxxxxxxxxxxxxxxxxx&stv);
xxxxxxxifx(ix>x0)x{
xxxxxxxxxifx(FD_ISSETx(s,x&rfds))x{
xxxxxxxxxxxsx=xS_DoRecvx(s);
xxxxxxxxx}
xxxxxxxxxifx(FD_ISSETx(s,x&wfds))x{
xxxxxxxxxxxsx=xS_DoSendx(s);
xxxxxxxxx}
xxxxxxx}xelsex{
xxxxxxxxx/*xTimeoutx*/
xxxxxxxxxS_countx=x0;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_MakeSocketxfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x3;
xxxxx}
xxx}
xxxifx(sx!=xINVALID_SOCKET)x{
xxxxxsx=xS_CloseSocketx(s);
xxx}
xxxreturnxrc;
x}
x
x/*

xstaticxint
xS_Runx()
x{
xxxintxrcx=x0;
x
xxxifx(S_LoadMessagex()x==x0)x{
xxxxxwhilex(S_LoadLstx()x==x0)x{
xxxxxxxifx(S_Loopx()x==x0)x{
xxxxxxxxx/*xgoodx*/
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:xS_Loopxfailed",x__FILE__,x__LINE__);
xxxxxxxxxrcx=x134;
xxxxxxx}
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xS_LoadMessagexfailed",x__FILE__,x__LINE__);
xxxxxrcx=x154;
xxx}
xxxreturnxrc;
x}
x
x/*
xx*/
xstaticxint
xS_Dispatchx()
x{
xxxintxrcx=x0;
x
xxxswitchx(S_action)x{
xxxcasexACTION_RUN:
xxxxxrcx=xS_Runx();
xxxxxbreak;
xxxcasexACTION_HELP:
xxxxxrcx=xS_Helpx();
xxxxxbreak;
xxxdefault:
xxxxxfprintfx(stderr,x"\n%s:%d:",x__FILE__,x__LINE__);
xxxxxfprintfx(stderr,x"xS_actionxisx%d.",xS_action);
xxxxxfprintfx(stderr,x"xxThisxshouldxneverxhappen!");
xxxxxrcx=x102;
xxx}
xxxreturnxrc;
x}
x
xint
xmainx(intxargc,xcharx*argv[])
x{
xxxintxrcx=x0;
x
xxxfprintfx(stderr,x"\nMAX_OCTETS_IN_LISTxisx%d.",xMAX_OCTETS_IN_LIST);

xxxfprintfx(stderr,x"\nS_lst_lenxisx%d.",xS_lst_len);
xxxifx(S_Initx()x==x0)x{
xxxxxifx(S_CommandLinex(argc,xargv)x==x0)x{
xxxxxxxifx(S_Dispatchx()x==x0)x{
xxxxxxxxx/*xgoodx*/
xxxxxxx}xelsex{
xxxxxxxxxfprintfx(stderr,x"\n%s:%d:xS_Dispatchfailed",x__FILE__,x__LINE__);
xxxxxxxxxrcx=x234;
xxxxxxx}
xxxxx}xelsex{
xxxxxxxfprintfx(stderr,x"\n%s:%d:xS_CommandLinexfailed",x__FILE__,x__LINE__);
xxxxxxxrcx=x234;
xxxxx}
xxx}xelsex{
xxxxxfprintfx(stderr,x"\n%s:%d:xS_Initxfailed",x__FILE__,x__LINE__);
xxxxxrcx=x526;
xxx}
xxxreturnxrcx==x0x?xEXIT_SUCCESSx:xEXIT_FAILURE;
x}
x
x/*x---xendxofxfilex---x*/

/*
xx*x$Header:x/home/gene/library/website/docsrc/sca/src/RCS/this.h,vx1.5x2006/01/18x03:46:41xgenexExpx$
xx*
xx*xxCopyrightx(c)x2006xGenexMichaelxStover.xxAllxrightsxreserved.
xx*
xx*xxThisxprogramxisxfreexsoftware;xyouxcanxredistributexitxand/orxmodify
xx*xxitxunderxthextermsxofxthexGNUxLesserxGeneralxPublicxLicensexas
xx*xxpublishedxbyxthexFreexSoftwarexFoundation;xeitherxversionx2xofxthe
xx*xxLicense,xorx(atxyourxoption)xanyxlaterxversion.
xx*
xx*xxThisxprogramxisxdistributedxinxthexhopexthatxitxwillxbexuseful,
xx*xxbutxWITHOUTxANYxWARRANTY;xwithoutxevenxtheximpliedxwarrantyxof
xx*xxMERCHANTABILITYxorxFITNESSxFORxAxPARTICULARxPURPOSE.xxSeexthe
xx*xxGNUxLesserxGeneralxPublicxLicensexforxmorexdetails.
xx*
xx*xxYouxshouldxhavexreceivedxaxcopyxofxthexGNUxLesserxGeneralxPublic
xx*xxLicensexalongxwithxthisxprogram;xifxnot,xwritextoxthexFreexSoftware
xx*xxFoundation,xInc.,x51xFranklinxSt,xFifthxFloor,xBoston,xMAxx02110-1301
xx*xxUSA
xx*/
x
x/*xStandardxCx*/
x#includex<assert.h>
x#includex<ctype.h>
x#includex<errno.h>
x#includex<stdarg.h>
x#includex<stdio.h>
x#includex<stdlib.h>
x#includex<string.h>
x#includex<time.h>
x
x/*xPOSIX,xunix,xlinuxx*/
x#ifxIS_UNIX
x#includex<unistd.h>
x#includex<sys/socket.h>
x#includex<netinet/in.h>
x#includex<arpa/inet.h>
x#includex<search.h>
x#includex<rpc/rpc.h>
x#includex<rpc/pmap_prot.h>
x#endif
x
x/*xMicroslothxWindersx*/
x#ifxIS_WINDERS
x#xxincludex<windows.h>

x#xxdefinexbzero(p,sz)xmemset(p,0,sz)
xxxintxgetpidx();
xxxvoidx*lfind(constxvoidx*key,xconstxvoidx*base,xunsignedxintx*num,
xxxxxxxxxxxxxxxunsignedxintxwidth,xintx(*cmp)(constxvoidx*,xconstxvoidx*));
x#xxdefinexCloseSocketxclosesocket
x#else
xxxx/*
xxxxx*xOnxnon-Windersxsystems,xusexthesexsymbolsx(SOCKET,
xxxxx*xINVALID_SOCKET,x&xCloseSocket).
xxxxx*/
xxxxtypedefxintxSOCKET;
x#xxdefinexINVALID_SOCKETx-1
x#endif
x
x/*xThisx*/
xtypedefxintxBoolean;
x#includex"debug.h"
x
x/*x---xendxofxfilex---x*/

B What about nmap? Yes, nmap can scan like this.

I didn’t use nmap because my client needed code which was unencumbered by the license agreement on nmap.

“Unencumbered by the GPL? But you, yourself, slapped the GPL on your own code?” Yes, I did, & since I’m the license-holder, I can create a custom, non-GPL license for my client.

“If the user installed nmap separately, wouldn’t that allow your client’s software to work with nmap without itself being GPLed?” I believe it would.

“So could you do that? Could you require the user to install nmap himself?” No.

References