diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/b-scan | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/b-scan')
86 files changed, 14187 insertions, 0 deletions
diff --git a/other/b-scan/INSTALL b/other/b-scan/INSTALL new file mode 100644 index 0000000..d11e398 --- /dev/null +++ b/other/b-scan/INSTALL | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | |||
| 2 | you need latest | ||
| 3 | libnet: http://www.packetfactory.net/libnet | ||
| 4 | libpcap: http://www.tcpdump.org | ||
| 5 | |||
| 6 | # tar xfvz b-scan.tar.gz | ||
| 7 | # make | ||
| 8 | # cd modules | ||
| 9 | # make | ||
| 10 | # cd .. | ||
| 11 | # ./bscan -h | ||
| 12 | |||
| 13 | Successfully compiled on: | ||
| 14 | Debian Linux fhs 2.4.0-test10 i586 unknown | ||
| 15 | RedHat Linux wu.sec 2.2.17 i586 unknown | ||
| 16 | SunOS 5.7 Generic_106541-04 sun4c sparc | ||
| 17 | SunOS 5.8 Generic sun4m sparc | ||
| 18 | |||
| 19 | |||
| 20 | |||
| 21 | |||
| 22 | send bug-reports to anonmous@segfault.net | ||
| 23 | |||
diff --git a/other/b-scan/MODULES b/other/b-scan/MODULES new file mode 100644 index 0000000..29e273d --- /dev/null +++ b/other/b-scan/MODULES | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | Nothing is more important than to see the | ||
| 2 | sources of invention, which are, in my | ||
| 3 | opinion, more interesting than the | ||
| 4 | invention themselves. | ||
| 5 | G.W.Leibniz (1646-1716) | ||
| 6 | |||
| 7 | [0] General | ||
| 8 | |||
| 9 | Load modules with the '-L' parameter. | ||
| 10 | |||
| 11 | -L "<modulename> <arg1> <arg2> ..." | ||
| 12 | arg1..argN are passed to the init-functioin | ||
| 13 | of the module (in int argc, char *argv[]-style). | ||
| 14 | |||
| 15 | The arg's are seperated by spaces. | ||
| 16 | If you want to pass an arguement with spaces in it | ||
| 17 | to the module you have to escape them: | ||
| 18 | -L "modules/mod_http.so -r GET\s/cgi-bin/test-cgi\sHTTP/1.0\r\n\r\n" | ||
| 19 | |||
| 20 | Each module has additional parameters. | ||
| 21 | bscan -h -L "modules/mod_banner.so" -L "modules/mod_ping.so" \ | ||
| 22 | -L "modules/mod_bind.so" -L "modules/mod_httpid.so" | ||
| 23 | gives usage information for bscan AND all modules. | ||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | Bscan comes with the following modules: | ||
| 28 | |||
| 29 | [1] mod_banner | ||
| 30 | |||
| 31 | This is the "generic" module + banner-scanner module. | ||
| 32 | ./bscan -h -L "modules/mod_banner.so" for help. | ||
| 33 | Use this module alone for banner-scan or tcp-open scan. | ||
| 34 | |||
| 35 | [2] mod_ping | ||
| 36 | |||
| 37 | ICMP_REQUEST module. | ||
| 38 | I always use this module in conjunction with mod_banner.so. | ||
| 39 | As i said....mod_banner.so is not just a tcp-banner module | ||
| 40 | but also a 'gerneric' module handling the tcp-userland stack | ||
| 41 | and icmp-host-unreachable packets. | ||
| 42 | |||
| 43 | [3] mod_httpd | ||
| 44 | |||
| 45 | This module requests "HEAD / HTTP/1.0" by default. | ||
| 46 | You can specify requests with the '-r' option: | ||
| 47 | Don't forget to escape ' ', '\n', '\r', '\t'! | ||
| 48 | |||
| 49 | for example: -r GET\s/cgi-bin/finger?@127.0.0.1\sHTTP/1.0\r\n\r\n | ||
| 50 | |||
| 51 | [4] mod_bind | ||
| 52 | |||
| 53 | Requests version.bind [type=txt, class=chaos] from nameservers. | ||
| 54 | Default sourceport = 53 (udp). | ||
| 55 | |||
| 56 | |||
| 57 | -=- | ||
| 58 | |||
| 59 | I'll add a small 'howto' on how to code modules for bscan, soon :) | ||
| 60 | For now, please take a look into mod_ping.so and mod_banner.so. | ||
| 61 | |||
| 62 | A module MUST declare the following shared functions: | ||
| 63 | int init (char **, int, char **, void *); /* init + getopt etc */ | ||
| 64 | int fini (); /* called on exit(); */ | ||
| 65 | void musage (); /* print out usage information for the module */ | ||
| 66 | int callmdl (int, void *); /* send first pkg, process rcvd pkg */ | ||
| 67 | |||
| 68 | callmdl (int, void *) does all the hard work. | ||
| 69 | There are two entry points to this function: | ||
| 70 | First entry-point is in the bscan parent process [MOD_FIRSTPKG]. | ||
| 71 | Second entry-point is in the 'snarf'-process [MOD_RCV]. | ||
| 72 | |||
| 73 | Return values are: | ||
| 74 | RMOD_OK: everything is ok. process as usual | ||
| 75 | RMOD_SKIP: everythin is fine, but jump to the next module. | ||
| 76 | RMOD_ERROR: currently not implemented | ||
| 77 | |||
| 78 | Ideas for modules: | ||
| 79 | - rpcinfo module [maybe udp (!) version. most ppl only deny tcp/111] | ||
| 80 | source-port = 53 | ||
| 81 | - mod_avt [telnetd-banner scanner] | ||
| 82 | - ftp module [scan for anonymous login and +w /incoming] | ||
| 83 | - nmap/queso like os-fingerprint module | ||
| 84 | - snmp 'system' or 'system.sysDescr' | ||
| 85 | - smbclient -L ? nmblookup -A ? | ||
| 86 | - <add your idea here :> | ||
| 87 | |||
| 88 | |||
diff --git a/other/b-scan/Makefile b/other/b-scan/Makefile new file mode 100644 index 0000000..8306b6c --- /dev/null +++ b/other/b-scan/Makefile | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | # | ||
| 2 | # Makefile of (m)bscan v0.0, skyper | ||
| 3 | # Massiv Banner Scanner | ||
| 4 | # | ||
| 5 | # GNU-make mandatory! | ||
| 6 | |||
| 7 | SUBDIRS=support src modules | ||
| 8 | |||
| 9 | # edit support/Makefile | ||
| 10 | # edit src/Makefile | ||
| 11 | # edit modules/Makefile | ||
| 12 | |||
| 13 | all: | ||
| 14 | for dir in $(SUBDIRS); do \ | ||
| 15 | $(MAKE) -C $$dir; \ | ||
| 16 | done | ||
| 17 | |||
| 18 | clean: | ||
| 19 | for dir in $(SUBDIRS); do \ | ||
| 20 | $(MAKE) -C $$dir clean; \ | ||
| 21 | done | ||
| 22 | |||
| 23 | pack: | ||
| 24 | rm -f bscan.tar.gz | ||
| 25 | tar cfvz bscan.tar.gz support/*.c support/Makefile src/*.c src/*.l src/Makefile include/bscan/*.h Makefile MODULES PROBLEMS INSTALL README modules/*.c modules/Makefile | ||
| 26 | |||
| 27 | |||
diff --git a/other/b-scan/PROBLEMS b/other/b-scan/PROBLEMS new file mode 100644 index 0000000..24db576 --- /dev/null +++ b/other/b-scan/PROBLEMS | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | No one believes an hypothesis except its | ||
| 2 | originator, but everyone believes an | ||
| 3 | experiment except the experimenter. | ||
| 4 | J.Anon, 1823 | ||
| 5 | |||
| 6 | |||
| 7 | [0] General | ||
| 8 | |||
| 9 | As larger the target network (10.0.0.0/8 is large) is as | ||
| 10 | faster you can scan (-X -l 5000+). | ||
| 11 | |||
| 12 | Use 'spreadmode' (-X) whereever possible. | ||
| 13 | |||
| 14 | Use an unused ip from your local network for spoofing. | ||
| 15 | (bscan comes with its own arp-daemon to handle arp-requests | ||
| 16 | to the spoofed ip) | ||
| 17 | |||
| 18 | |||
| 19 | [1] Scanning your own LOCAL network: | ||
| 20 | |||
| 21 | If you get packet loss and missing scan results while | ||
| 22 | scanning your local network, please lower the scan rate. | ||
| 23 | Your host is unable to resolve 1000 arp's per second | ||
| 24 | and therefor drops packets. | ||
| 25 | Try some smaller values at about 50-100 hosts/second. | ||
| 26 | |||
| 27 | |||
| 28 | [2] Why is 'spreadmode' so much better ? | ||
| 29 | |||
| 30 | First: its non-linear and so more 'stealthy'. | ||
| 31 | Default timeout for most IDS is around 4 mins. | ||
| 32 | If you scan linear [not spreadmode] you hit | ||
| 33 | the target network several thousand times the second. | ||
| 34 | |||
| 35 | Second: The last router has to resolve all mac's for | ||
| 36 | the hosts on the target network. | ||
| 37 | There is no router that can resolve 1000+ mac's per second. | ||
| 38 | 'Spreadmode' tries to guess the 'router distance' and | ||
| 39 | send packets to different routers [non-linear]. | ||
| 40 | It tries to achieve the maximum time-distance between | ||
| 41 | two packets hit the same router. | ||
| 42 | It's up to the reader to proof that a random scan | ||
| 43 | is inadequate in this situation. | ||
| 44 | |||
| 45 | |||
| 46 | [3] Does bscan work on other media than ethernet ? | ||
| 47 | |||
| 48 | Short answer: NO!. | ||
| 49 | Long answer: I'll add support for other media's later. | ||
| 50 | |||
| 51 | |||
| 52 | [4] Does it work through NAT ? | ||
| 53 | |||
| 54 | Yes. But be aware that most NAT-systems are unable to keep the | ||
| 55 | state of 100.000 seconds. Try reducing the scan-speed (-l 100?) | ||
| 56 | for instance. | ||
| 57 | |||
| 58 | |||
diff --git a/other/b-scan/README b/other/b-scan/README new file mode 100644 index 0000000..7927833 --- /dev/null +++ b/other/b-scan/README | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * This is unpublished proprietary source code. | ||
| 3 | * | ||
| 4 | * The contents of these coded instructions, statements and computer | ||
| 5 | * programs may not be disclosed to third parties, copied or duplicated in | ||
| 6 | * any form, in whole or in part, without the prior written permission of | ||
| 7 | * the author. | ||
| 8 | * (that includes you hack.co.za and other lame kid sites who dont | ||
| 9 | * get the point what hacking is about. damn kids.) | ||
| 10 | * | ||
| 11 | * (C) COPYRIGHT by me, 2000 | ||
| 12 | * All Rights Reserved | ||
| 13 | */ | ||
| 14 | |||
| 15 | Knowledge is of two kinds, | ||
| 16 | We know a subject ourselves, | ||
| 17 | or we know where we can find | ||
| 18 | information upon it. | ||
| 19 | Samuel Johnson, 1775 | ||
| 20 | |||
| 21 | /* | ||
| 22 | * DEVEL RELEASE - CALL FOR IDEAS - DO NOT DISTRIBUTE | ||
| 23 | */ | ||
| 24 | |||
| 25 | [0] What is bscan? | ||
| 26 | |||
| 27 | A fast, 100% spoofed, raw-mode scanner with module | ||
| 28 | and application layer support. | ||
| 29 | |||
| 30 | 100% spoofed means, that both adresses, IP and MAC, are spoofed. | ||
| 31 | |||
| 32 | Raw-Mode in this case means that Bscan uses its own tcp/ip | ||
| 33 | userland stack to perfom the scans. It doesn't keep track | ||
| 34 | of the packets and hence does not waste any kernel | ||
| 35 | structures, memory or filedescriptors. | ||
| 36 | It will need about 500kb of memory. | ||
| 37 | |||
| 38 | Modules: You can write, load and add your own modules which | ||
| 39 | will perform specific operations. | ||
| 40 | Bscan comes with some generic modules [see MODULES]. | ||
| 41 | |||
| 42 | Application layer means that Bscan won't just scan for open | ||
| 43 | TCP-ports. The Module 'mod_banner.so' for example | ||
| 44 | scans for TCP-banners in raw-mode [ which will get up to 5.000+ | ||
| 45 | hosts per sec]. | ||
| 46 | The module 'mod_bind.so' will requests the bind-version | ||
| 47 | from nameservers (version.bind chaos txt scan). | ||
| 48 | The module 'mod_httpd.so' performs http-requests. | ||
| 49 | 'HEAD / HTTP/1.0' by default. You can specify other | ||
| 50 | requests like 'GET /cgi-bin/test-cgi HTTP/1.0' on the | ||
| 51 | command-line. | ||
| 52 | Take a look into 'MODULES' for futher informations. | ||
| 53 | |||
| 54 | The scanner is not bound to any kernel/OS limits [like | ||
| 55 | fd-limit, memory, ...]. | ||
| 56 | The scan speed only depends on your connection and | ||
| 57 | the bandwidth of the target network. | ||
| 58 | You can scan with up to 10.000+ hosts/second on a 100mbit | ||
| 59 | connection without any problems [see PROBLEMS]. | ||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | [1] NEW | ||
| 64 | |||
| 65 | - module support and application layer support | ||
| 66 | - tcp.seq bugfix, tty-driven, ... | ||
| 67 | '-r' restore.bscan, resume interrupted scans | ||
| 68 | - 'john'-like status line: | ||
| 69 | 10.2.2.1/16 time: 0:00:00:05 7% p/s: 1000 [o:1 r:1 c:0 i:7] | ||
| 70 | '-O' Output the ip's only. Don't scan. | ||
| 71 | '-m' Use specified <mac>, add mac to arp-table and remove it when scan | ||
| 72 | is complete. | ||
| 73 | '-M' Use specified <mac>, dont add mac to arp-table. [use arp -s <ip> <mac>]. | ||
| 74 | '-l' limit packets per second | ||
| 75 | '-sS,-sF,-sX,-sN,-sP' Syn halfopen, Fin, Xmas, Null, Push scan | ||
| 76 | |||
| 77 | |||
| 78 | [2] How to compile | ||
| 79 | |||
| 80 | see INSTALL | ||
| 81 | You also may want to take a look into PROBLEMS and MODULES. | ||
| 82 | |||
| 83 | [3] Usage | ||
| 84 | |||
| 85 | bscan needs root privileges. it only works on ethernet (so far). | ||
| 86 | |||
| 87 | bscan -h for help | ||
| 88 | |||
| 89 | bscan -h -L <module1> for help on bscan mainprogramm and the module1. | ||
| 90 | |||
| 91 | |||
| 92 | You MUST specify an unused source-ip from your local network (-s <ip>). | ||
| 93 | |||
| 94 | '00:20:AF:A3:13:37' is the default mac source address. | ||
| 95 | Your can specify your own with the -m/-M option. | ||
| 96 | |||
| 97 | Press 'space' or send SIGUSR1 to the process to get a statusline. | ||
| 98 | |||
| 99 | Press ctrl-c once to abort scanning, twice to stop | ||
| 100 | the process [waiting for outstandig packets]. | ||
| 101 | Bscan saves the stata of an interrupted scan to 'restore.bscan' | ||
| 102 | that can be continued with the '-r' option. | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | Simple Examples: | ||
| 107 | |||
| 108 | # ./bscan -s 10.2.6.6 -L "mod_banner.so" -X 10.3.0.0/16 | ||
| 109 | scans for ftp-banners [first line only unless '-a' specified] from | ||
| 110 | spoofed source address '10.2.6.6' in spreadmode (-X). | ||
| 111 | |||
| 112 | # ./bscan -s 10.2.6.6 -i eth2 -L "mod_banner.so -a -p 25 -o 53" 10.2.0.0/16 | ||
| 113 | scans for smtp-banners [port 25 (-p 25) and all data (-a) with | ||
| 114 | sourceport 53 (-o 53)]. | ||
| 115 | Listen for packets on eth2 and scan 10.2.0.1-10.2.255.254 linear | ||
| 116 | (no recommendet. use spreadmode (-X) whenever possible). | ||
| 117 | |||
| 118 | # ./bscan -s 10.2.6.6 -i eth2 -L "mod_banner.so -q" -L "mod_bind.so" -l 1800 \ | ||
| 119 | -X 212.0.0.0/8 | ||
| 120 | Scan 'version.bind' (udp) with 1800 hosts/second in spreadmode (-X). | ||
| 121 | |||
| 122 | # ./bscan -s 10.2.6.6 -L "mod_banner.so -a -p 80 -o 1040" \ | ||
| 123 | -L "mod_httpd.so -p 80" -l 1200 -X 195.0.0.0/8 | ||
| 124 | Scan 'http HEAD / HTTP/1.0' on port 80 from sourceport 1040 with | ||
| 125 | 1200 hosts/second in spreadmode (-X). | ||
| 126 | |||
| 127 | # ./bscan -s 10.2.6.6 -L "mod_banner.so -a -p 80" \ | ||
| 128 | -L "mod_httpd.so -r GET\s/cgi-bin/test-cgi\sHTTP/1.0\r\n\r\n" \ | ||
| 129 | -X 210.0.0.0/8 | ||
| 130 | Scan the 210-ClassA network for vulnerable test-cgi hosts. | ||
| 131 | |||
| 132 | |||
| 133 | |||
| 134 | [4] technical details | ||
| 135 | |||
| 136 | Nothing here. not done yet. | ||
| 137 | See source. | ||
| 138 | blah blah here. | ||
| 139 | spoofed tcp 3-way handshake [e.g. userland tcp-stack]. | ||
| 140 | Sends out syn-packets (as fast as possible) trough raw-device. | ||
| 141 | captures syn-ack and replies with | ||
| 142 | 'best known answer' to get the final banner/data. | ||
| 143 | Handels ICMP unreachable-msg'es correctly. | ||
| 144 | |||
| 145 | |||
| 146 | *CALL FOR IDEAS* | ||
| 147 | anonymous@segfault.net | ||
| 148 | |||
diff --git a/other/b-scan/TODO b/other/b-scan/TODO new file mode 100644 index 0000000..977a47e --- /dev/null +++ b/other/b-scan/TODO | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | libnet/libpcap | ||
| 2 | Reason: | ||
| 3 | Easier to get bscan running on 'other' systems. | ||
| 4 | Goal/Ideas: | ||
| 5 | Distribute libnet/libpcap-package with bscan-package. | ||
| 6 | ./libnet | ||
| 7 | ./libpcap | ||
| 8 | May install themself into ./lib ? | ||
| 9 | |||
| 10 | |||
| 11 | reentrant/thread-safe | ||
| 12 | Reason: | ||
| 13 | We need shared 'garage' and threading is | ||
| 14 | the best solution for this. | ||
| 15 | Goal/Ideas: | ||
| 16 | making bscan threadable. | ||
| 17 | |||
| 18 | |||
| 19 | statefull | ||
| 20 | Reason: | ||
| 21 | UDP (and especialy snmp) behaves really bad without statefull | ||
| 22 | capability. | ||
| 23 | Goal/ideas: | ||
| 24 | Retransmit-timeout, retransmit packet x times before giving up. | ||
| 25 | Use mod_garage for this (depends on threaded-bscan). | ||
| 26 | |||
| 27 | |||
| 28 | bscand | ||
| 29 | Reason: | ||
| 30 | Making bscan distributed. | ||
| 31 | Goal/Ideas: | ||
| 32 | Making bscan distributed -> faster scanning. | ||
| 33 | One 'master'-host that servers the 'clients' with | ||
| 34 | ip-ranges. | ||
| 35 | 'mod_distri' is the client-site 'd-scan support module'. | ||
| 36 | We can overwrite getnextip() function. | ||
| 37 | |||
| 38 | |||
| 39 | mod_rpcinfo | ||
| 40 | Reason: | ||
| 41 | Coz its hot :> | ||
| 42 | Goal/Ideas: | ||
| 43 | Requesting, decoding rpcinfo -p <ip> like informations | ||
| 44 | UDP/TCP request _should_ be possible (many sites only deny 111/tcp). | ||
| 45 | Source port 53 as default. | ||
| 46 | |||
| 47 | |||
| 48 | autoconf/automake | ||
| 49 | Reason: | ||
| 50 | Better portability | ||
| 51 | Goal/Ideas: | ||
| 52 | Use of 'config.h' and ./configure with known options | ||
| 53 | like --prefix=blah etc. | ||
| 54 | |||
| 55 | |||
diff --git a/other/b-scan/bscanrc b/other/b-scan/bscanrc new file mode 100644 index 0000000..e1bea5e --- /dev/null +++ b/other/b-scan/bscanrc | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | b-scan: Warning! you are using the sample b-scan config | ||
| 2 | b-scan: edit bscanrc to get rid of this message! | ||
| 3 | |||
| 4 | SourceAddress 127.0.0.1 | ||
| 5 | StaticSpoofedMacAddress true | ||
| 6 | MacAddress ff:ff:ff:ff:ff:ff | ||
| 7 | Interface dummy0 | ||
| 8 | SpreadScan Yes | ||
| 9 | PacketsPerSecond 31337 | ||
| 10 | MaxWaitDelay 7350 | ||
| 11 | Verbose 1 | ||
| 12 | addModule modules/mod_ping.so -t time -s 64 | ||
| 13 | |||
| 14 | b-scan: read config file | ||
diff --git a/other/b-scan/contrib/BIND-distribution.awk b/other/b-scan/contrib/BIND-distribution.awk new file mode 100644 index 0000000..8dae39a --- /dev/null +++ b/other/b-scan/contrib/BIND-distribution.awk | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #!/usr/bin/env awk | ||
| 2 | # | ||
| 3 | # cat outlog | grep "VERSION.BIND" | awk -f BIND-distribution.awk | ||
| 4 | # | ||
| 5 | |||
| 6 | BEGIN { | ||
| 7 | FS = "\"" | ||
| 8 | hostcount = 0 | ||
| 9 | } | ||
| 10 | |||
| 11 | /^[0-9\.]+ VERSION\.BIND\. \"[^\"]+\"$/ { | ||
| 12 | # count one to the overall distribution countage | ||
| 13 | distribution[$2] += 1 | ||
| 14 | |||
| 15 | # count the overall distributions | ||
| 16 | hostcount += 1 | ||
| 17 | } | ||
| 18 | |||
| 19 | END { | ||
| 20 | for (distrib in distribution) { | ||
| 21 | printf ("/%s//%d/%.2f/\n", distrib, \ | ||
| 22 | distribution[distrib], \ | ||
| 23 | (distribution[distrib] * 100) / hostcount) | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
diff --git a/other/b-scan/contrib/NETBLOCKS.txt b/other/b-scan/contrib/NETBLOCKS.txt new file mode 100644 index 0000000..7927198 --- /dev/null +++ b/other/b-scan/contrib/NETBLOCKS.txt | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | # Class A networks in the Internet, with percental distribution of | ||
| 2 | # ICMP ECHO responding IPs. | ||
| 3 | # | ||
| 4 | # 209 6.28 -> 209.0.0.0/8 has 6.28 percent of all pingable IP addresses | ||
| 5 | # | ||
| 6 | # last update: 2001/02/03 | ||
| 7 | # | ||
| 8 | # based on 150,000 random ICMP ECHO queries send to random addresses | ||
| 9 | # | ||
| 10 | 209 6.28 | ||
| 11 | 216 4.60 | ||
| 12 | 6 3.79 | ||
| 13 | 207 3.35 | ||
| 14 | 210 3.20 | ||
| 15 | 24 3.19 | ||
| 16 | 152 3.00 | ||
| 17 | 195 2.93 | ||
| 18 | 208 2.72 | ||
| 19 | 206 2.40 | ||
| 20 | 212 2.34 | ||
| 21 | 128 2.24 | ||
| 22 | 63 2.00 | ||
| 23 | 194 1.91 | ||
| 24 | 203 1.75 | ||
| 25 | 148 1.72 | ||
| 26 | 129 1.71 | ||
| 27 | 193 1.68 | ||
| 28 | 167 1.68 | ||
| 29 | 131 1.63 | ||
| 30 | 204 1.62 | ||
| 31 | 170 1.58 | ||
| 32 | 157 1.45 | ||
| 33 | 172 1.43 | ||
| 34 | 199 1.42 | ||
| 35 | 130 1.41 | ||
| 36 | 133 1.34 | ||
| 37 | 202 1.32 | ||
| 38 | 171 1.27 | ||
| 39 | 155 1.27 | ||
| 40 | 205 1.21 | ||
| 41 | 137 1.17 | ||
| 42 | 211 1.15 | ||
| 43 | 132 1.12 | ||
| 44 | 168 1.07 | ||
| 45 | 198 1.03 | ||
| 46 | 160 0.98 | ||
| 47 | 158 0.98 | ||
| 48 | 144 0.97 | ||
| 49 | 200 0.95 | ||
| 50 | 146 0.91 | ||
| 51 | 134 0.91 | ||
| 52 | 163 0.89 | ||
| 53 | 142 0.89 | ||
| 54 | 165 0.86 | ||
| 55 | 159 0.85 | ||
| 56 | 139 0.83 | ||
| 57 | 166 0.82 | ||
| 58 | 161 0.82 | ||
| 59 | 164 0.80 | ||
| 60 | 64 0.79 | ||
| 61 | 62 0.79 | ||
| 62 | 151 0.79 | ||
| 63 | 162 0.78 | ||
| 64 | 140 0.78 | ||
| 65 | 192 0.77 | ||
| 66 | 147 0.75 | ||
| 67 | 150 0.71 | ||
| 68 | 143 0.70 | ||
| 69 | 141 0.66 | ||
| 70 | 12 0.66 | ||
| 71 | 38 0.65 | ||
| 72 | 213 0.59 | ||
| 73 | 138 0.53 | ||
| 74 | 196 0.35 | ||
| 75 | 4 0.33 | ||
| 76 | 169 0.33 | ||
| 77 | 149 0.31 | ||
| 78 | 136 0.27 | ||
| 79 | 156 0.24 | ||
| 80 | 153 0.23 | ||
| 81 | 145 0.11 | ||
| 82 | 61 0.08 | ||
| 83 | 32 0.07 | ||
| 84 | 55 0.05 | ||
| 85 | 154 0.05 | ||
| 86 | 35 0.04 | ||
| 87 | 18 0.04 | ||
| 88 | 135 0.03 | ||
| 89 | 9 0.01 | ||
| 90 | 57 0.01 | ||
| 91 | 47 0.01 | ||
| 92 | 33 0.01 | ||
| 93 | 20 0.01 | ||
| 94 | 44 0.00 | ||
| 95 | 36 0.00 | ||
| 96 | 15 0.00 | ||
diff --git a/other/b-scan/contrib/README b/other/b-scan/contrib/README new file mode 100644 index 0000000..45393f3 --- /dev/null +++ b/other/b-scan/contrib/README | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | |||
| 2 | contrib, external utilities and helper programs | ||
| 3 | |||
| 4 | |||
| 5 | BIND-distribution.awk | ||
| 6 | |||
| 7 | Takes a version.bind scanlog and counts the occurance of each BIND | ||
| 8 | version. At the end it outputs a machine parseable log of each version | ||
| 9 | number, the log entries counted with this version and the percentage | ||
| 10 | this version makes up in the IPs counted. | ||
| 11 | |||
| 12 | |||
| 13 | NETBLOCKS.txt | ||
| 14 | |||
| 15 | A list of most active IPv4 class A networks on the Internet. Maybe | ||
| 16 | should go to doc/ or something. | ||
| 17 | |||
diff --git a/other/b-scan/doc/bscan.pdf b/other/b-scan/doc/bscan.pdf new file mode 100644 index 0000000..807b5c9 --- /dev/null +++ b/other/b-scan/doc/bscan.pdf | |||
| Binary files differ | |||
diff --git a/other/b-scan/doc/bscan.tex b/other/b-scan/doc/bscan.tex new file mode 100644 index 0000000..4da94c3 --- /dev/null +++ b/other/b-scan/doc/bscan.tex | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | % just run: pdflatex bscan.tex | ||
| 2 | |||
| 3 | \ifx\pdfoutput\undefined | ||
| 4 | \documentclass[11pt,a4paper,twoside]{article} | ||
| 5 | \else | ||
| 6 | \documentclass[pdftex,11pt,a4paper,twoside]{article} | ||
| 7 | \pdfcompresslevel=9 | ||
| 8 | \fi | ||
| 9 | |||
| 10 | \ifx\pdfoutput\undefined | ||
| 11 | \else | ||
| 12 | \RequirePackage[colorlinks,hyperindex]{hyperref} | ||
| 13 | \def\pdfBorderAttrs{/Border [0 0 0] } | ||
| 14 | \fi | ||
| 15 | |||
| 16 | \usepackage{fancyhdr} | ||
| 17 | \pagestyle{fancy} | ||
| 18 | %\renewcommand{\chaptermark}[1]{\markboth{#1}{}} | ||
| 19 | %\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} | ||
| 20 | \fancyhf{} | ||
| 21 | \fancyhead[LE,RO]{\bfseries\thepage} | ||
| 22 | \fancyhead[LO]{\bfseries\rightmark} | ||
| 23 | \fancyhead[RE]{\bfseries\leftmark} | ||
| 24 | \renewcommand{\headrulewidth}{0.5pt} | ||
| 25 | \renewcommand{\footrulewidth}{0pt} | ||
| 26 | \addtolength{\headheight}{0.5pt} | ||
| 27 | \fancypagestyle{plain}{% | ||
| 28 | \fancyhead{}% | ||
| 29 | \renewcommand{\headrulewidth}{0pt}% | ||
| 30 | } | ||
| 31 | |||
| 32 | \begin{document} | ||
| 33 | |||
| 34 | \title{b-scan manual} | ||
| 35 | \author{b-scan team} | ||
| 36 | \maketitle | ||
| 37 | \begin{center} | ||
| 38 | version 0.0 | ||
| 39 | \end{center} | ||
| 40 | |||
| 41 | \tableofcontents | ||
| 42 | |||
| 43 | |||
| 44 | \section{Introduction} | ||
| 45 | B-scan is a network scan program. It probes a number of hosts for certain | ||
| 46 | properties and evaluates the responses, saving interesting data in a easy | ||
| 47 | to understand output format. In contrast to most other network scanning | ||
| 48 | programs, b-scan aims at being the best in both stability and speed. There are, | ||
| 49 | however very popular programs that are neither stable nor fast, but have | ||
| 50 | dozens of useless options you will not find in b-scan. | ||
| 51 | |||
| 52 | \section{How b-scan works} | ||
| 53 | |||
| 54 | \section{The network layout} | ||
| 55 | % include graphic how b-scan sees the network | ||
| 56 | |||
| 57 | \subsection{Setting up a proper host environment} | ||
| 58 | \subsection{Common problems} | ||
| 59 | \subsubsection{MAC address} | ||
| 60 | In case bscan will complain about `{\tt arp}' not being found, you have to | ||
| 61 | include the path to `{\tt arp}' in the {\tt PATH} variable. Often it is | ||
| 62 | found in {\tt /usr/sbin} or {\tt /sbin}, so a simple | ||
| 63 | `{\tt export PATH=\$PATH:/sbin:/usr/sbin}' before bscan is started will | ||
| 64 | solve this issue. | ||
| 65 | |||
| 66 | In case it still does not work, check whether bscans ARP daemon is running | ||
| 67 | properly and shows up in {\tt ps}. Then proceed by {\tt ping}ing the source | ||
| 68 | IP you have choosen and afterwards to a `{\tt arp -n}' to see whether the | ||
| 69 | correct MAC address shows up with the source IP. In case it does not show | ||
| 70 | up, you may have a device problem or another host in your LAN is using the | ||
| 71 | assigned IP. | ||
| 72 | |||
| 73 | \section{Options} | ||
| 74 | \subsection{Target} | ||
| 75 | \subsubsection{Random mode} | ||
| 76 | Using the random mode you can scan random IP addresses, for statistical | ||
| 77 | purposes. It is not recommended to use this random mode to scan complete | ||
| 78 | networks, there the spread mode fits better, since it takes care of | ||
| 79 | target-network routers and their load. However if you want to extrapolate | ||
| 80 | statistically correct data from randomly scanned hosts, this mode is the | ||
| 81 | right choice. It filters nonsense, reserved, private and multicast addresses | ||
| 82 | from the random ones and feeds the remaining ones into the scanner. You can | ||
| 83 | specify a counter which will stop bscan after having scanned a number of | ||
| 84 | random IPs using the `{\tt :}' suffix: | ||
| 85 | \begin{verbatim} | ||
| 86 | $ bscan ... random:2000 | ||
| 87 | \end{verbatim} | ||
| 88 | Will scan 2000 random IP addresses. If you leave the number out or give | ||
| 89 | `{\tt :0}', then bscan will scan forever, until it is terminated. | ||
| 90 | |||
| 91 | |||
| 92 | \section{Scans} | ||
| 93 | \subsection{ICMP} | ||
| 94 | \subsection{TCP} | ||
| 95 | \subsection{UDP} | ||
| 96 | \subsection{special} | ||
| 97 | |||
| 98 | \section{Logs} | ||
| 99 | \subsection{Logformat} | ||
| 100 | \subsection{Utilities} | ||
| 101 | \subsubsection{BIND-distribution.awk} | ||
| 102 | This utility parses the output logs of the {\tt VERSION.BIND} scan and shows | ||
| 103 | the percentage and count of each BIND version. It expects only properly | ||
| 104 | formatted lines, for example: | ||
| 105 | |||
| 106 | \begin{verbatim} | ||
| 107 | $ grep "VERSION.BIND" out.log | \ | ||
| 108 | awk -f contrib/BIND-distribution.awk | ||
| 109 | \end{verbatim} | ||
| 110 | |||
| 111 | \section{B-Scan internals} | ||
| 112 | \subsection{Directory structure} | ||
| 113 | \subsection{Code Layout} | ||
| 114 | \subsubsection{Structures} | ||
| 115 | \subsubsection{Modules} | ||
| 116 | |||
| 117 | \label{references} | ||
| 118 | \begin{thebibliography}{99} | ||
| 119 | \bibitem{blablafooauthor1} ICMP scanning blabla | ||
| 120 | \bibitem{foofooblaauthor2} NMAP portalskasa | ||
| 121 | \end{thebibliography} | ||
| 122 | |||
| 123 | \end{document} | ||
| 124 | |||
| 125 | |||
diff --git a/other/b-scan/include/bscan/arpg.h b/other/b-scan/include/bscan/arpg.h new file mode 100644 index 0000000..19ebddc --- /dev/null +++ b/other/b-scan/include/bscan/arpg.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #include <libnet.h> | ||
| 2 | |||
| 3 | struct _libnet | ||
| 4 | { | ||
| 5 | int packet_size; | ||
| 6 | u_char *packet; | ||
| 7 | char err_buf[LIBNET_ERRBUF_SIZE]; | ||
| 8 | u_char *device; | ||
| 9 | struct libnet_link_int *network; | ||
| 10 | }; | ||
| 11 | |||
| 12 | void prepare_libnet (struct _libnet *lnet); | ||
| 13 | int play_arpg (struct _libnet *, u_char *, u_char *, u_char *, u_char *); | ||
diff --git a/other/b-scan/include/bscan/bscan.h b/other/b-scan/include/bscan/bscan.h new file mode 100644 index 0000000..c1ad9bb --- /dev/null +++ b/other/b-scan/include/bscan/bscan.h | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* | ||
| 2 | * bscan, lame (and hopefully fast) banner scanner [port 21,25,110,...] | ||
| 3 | * | ||
| 4 | * "<es> skyper its a cool idea" | ||
| 5 | * "<es> i'd like to see the k0ad when ur finished" | ||
| 6 | * HI ES :) | ||
| 7 | * greetings to all my !el8 brothers :)) | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <stdio.h> | ||
| 11 | #include <stdarg.h> | ||
| 12 | #include <sys/socket.h> | ||
| 13 | #include <sys/wait.h> | ||
| 14 | #include <pthread.h> | ||
| 15 | #ifndef __FAVOR_BSD | ||
| 16 | #define __FAVOR_BSD | ||
| 17 | #endif | ||
| 18 | #ifndef __USE_BSD | ||
| 19 | #define __USE_BSD | ||
| 20 | #endif | ||
| 21 | #ifndef __BSD_SOURCE | ||
| 22 | #define __BSD_SOURCE | ||
| 23 | #endif | ||
| 24 | #include "arpg.h" | ||
| 25 | #include "network_raw.h" | ||
| 26 | |||
| 27 | |||
| 28 | #define SPF_SMAC "\x00\x20\xAF\xA3\x13\x37" | ||
| 29 | |||
| 30 | #define OPT_VERB 0x1 | ||
| 31 | #define OPT_RESERV1 0x2 | ||
| 32 | #define OPT_SETARP 0x4 | ||
| 33 | #define OPT_SPREADSCAN 0x8 | ||
| 34 | #define OPT_OUTONLY 0x10 | ||
| 35 | |||
| 36 | #define OPT_ABRT 0x20 | ||
| 37 | #define OPT_REST 0x40 | ||
| 38 | #define OPT_HOSTFILE 0x80 | ||
| 39 | #define OPT_W8SEMA 0x100 | ||
| 40 | |||
| 41 | |||
| 42 | struct _opt | ||
| 43 | { | ||
| 44 | int (*getnextip) (); | ||
| 45 | int sox; | ||
| 46 | u_char *packet; | ||
| 47 | int pkg_maxlen; | ||
| 48 | int pkg_len; /* actual length of contructed packet */ | ||
| 49 | char *hostfile; | ||
| 50 | char **argvlist; | ||
| 51 | FILE *ffd; /* e.g. input file */ | ||
| 52 | char *target; | ||
| 53 | unsigned long netmask; /* depricated */ | ||
| 54 | unsigned long network; /* depricated */ | ||
| 55 | unsigned int limit; | ||
| 56 | unsigned short flags; | ||
| 57 | unsigned long random_maxcount; | ||
| 58 | u_int delay; /* w8 for outstanding packets */ | ||
| 59 | u_int pscanstat; /* scan stats every x pkts, default NEVER */ | ||
| 60 | u_long start_ip; /* in HBO */ | ||
| 61 | u_long end_ip; /* in HBO */ | ||
| 62 | u_long ipscan_count; /* scanned ip's of a SPECIFIC range [temp!] */ | ||
| 63 | u_long iptotscan_count; /* total scan_count over all ranges */ | ||
| 64 | /* used for flood protection */ | ||
| 65 | u_long bsent_count; /* byte-sent counter. TMP (!) variable */ | ||
| 66 | u_long ip_offset; /* spread scan offset */ | ||
| 67 | u_long ip_blklen; /* block-length for spread-scan */ | ||
| 68 | u_long ip_pos; /* position for SPREAD scan, non-linear */ | ||
| 69 | struct timeval scan_start; /* scan start for ALL ranges */ | ||
| 70 | /* the real beginning */ | ||
| 71 | struct timeval tv2; /* flood protection timer 2 + restore */ | ||
| 72 | /* must be the last gettimeofday() from scan */ | ||
| 73 | float sec; /* flood protection distance time */ | ||
| 74 | struct _libnet lnet; | ||
| 75 | u_char spf_smac[6]; /* spoofed ethernet sender mac */ | ||
| 76 | pthread_t bscantid; /* 'parent' thread id */ | ||
| 77 | pthread_t snarftid; /* snarf thread id */ | ||
| 78 | struct _snarf | ||
| 79 | { | ||
| 80 | u_long icmp_c; | ||
| 81 | u_long close_c; | ||
| 82 | u_long open_c; | ||
| 83 | u_long refused_c; | ||
| 84 | } | ||
| 85 | snarf; | ||
| 86 | struct net_tuple nt; | ||
| 87 | }; | ||
| 88 | |||
| 89 | |||
| 90 | void make_iprange (u_long *, u_long *, u_long *, u_long *, char *); | ||
| 91 | void init_spreadscan (u_long diff); | ||
| 92 | void sigdriver (int); | ||
| 93 | void print_scanstat (FILE *); | ||
| 94 | void die (int); | ||
diff --git a/other/b-scan/include/bscan/cf_prse.h b/other/b-scan/include/bscan/cf_prse.h new file mode 100644 index 0000000..6185ab3 --- /dev/null +++ b/other/b-scan/include/bscan/cf_prse.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | struct confFileOpt | ||
| 2 | { | ||
| 3 | unsigned short flags; | ||
| 4 | unsigned int limit; | ||
| 5 | char *device; | ||
| 6 | unsigned long int delay; | ||
| 7 | unsigned long srcAddr; | ||
| 8 | unsigned short mac[5]; | ||
| 9 | } FileOpt; | ||
| 10 | |||
| 11 | int readConfFile (char *); | ||
diff --git a/other/b-scan/include/bscan/dcd_icmp.h b/other/b-scan/include/bscan/dcd_icmp.h new file mode 100644 index 0000000..215d0c8 --- /dev/null +++ b/other/b-scan/include/bscan/dcd_icmp.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* bscan - icmp include file | ||
| 2 | */ | ||
| 3 | |||
| 4 | #ifndef BS_DCD_ICMP_H | ||
| 5 | #define BS_DCD_ICMP_H | ||
| 6 | |||
| 7 | #define ICMP_HDRSIZE 8 | ||
| 8 | |||
| 9 | const char * | ||
| 10 | icmp_str (int type, int code); | ||
| 11 | |||
| 12 | #endif | ||
| 13 | |||
diff --git a/other/b-scan/include/bscan/garage.h b/other/b-scan/include/bscan/garage.h new file mode 100644 index 0000000..0d63774 --- /dev/null +++ b/other/b-scan/include/bscan/garage.h | |||
| @@ -0,0 +1,178 @@ | |||
| 1 | /* bscan - mod_garage.h - per IP storage functions include file | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef _MOD_GARAGE_H | ||
| 7 | #define _MOD_GARAGE_H | ||
| 8 | |||
| 9 | #include <sys/types.h> | ||
| 10 | |||
| 11 | #define GARAGE_VERSION "1.0.1" | ||
| 12 | |||
| 13 | |||
| 14 | typedef struct ip_elem { | ||
| 15 | struct ip_elem * next; /* more then one data stored */ | ||
| 16 | |||
| 17 | int data_free; /* 1 = do free() on destroy */ | ||
| 18 | size_t data_len; | ||
| 19 | void * data; /* must be free() able */ | ||
| 20 | } ip_elem; | ||
| 21 | |||
| 22 | |||
| 23 | typedef struct ip_list { | ||
| 24 | struct ip_list * next; /* another IP, always greater then this ! */ | ||
| 25 | unsigned long int ip; | ||
| 26 | |||
| 27 | ip_elem * data; | ||
| 28 | } ip_list; | ||
| 29 | |||
| 30 | |||
| 31 | /* not for use in other code then garage.c | ||
| 32 | */ | ||
| 33 | typedef struct { | ||
| 34 | char * name; | ||
| 35 | ip_list ** garage; | ||
| 36 | |||
| 37 | void (* cleaner)(ip_list *); | ||
| 38 | |||
| 39 | unsigned long int ip_count; | ||
| 40 | |||
| 41 | unsigned long int timeout_max; | ||
| 42 | unsigned long int timeout_idx; | ||
| 43 | unsigned long int * timeout_tbl; | ||
| 44 | } garage_hdlr; | ||
| 45 | |||
| 46 | |||
| 47 | /* mg_init | ||
| 48 | * | ||
| 49 | * setup the required structures for the garage | ||
| 50 | * | ||
| 51 | * return 0 on success | ||
| 52 | * return 1 on failure | ||
| 53 | */ | ||
| 54 | |||
| 55 | garage_hdlr * | ||
| 56 | mg_init (char *name, unsigned long int max_hosts_in_list, | ||
| 57 | void (* cleaner)(ip_list *)); | ||
| 58 | |||
| 59 | |||
| 60 | /* mg_destroy | ||
| 61 | * | ||
| 62 | * destroy all data in the garage `g', use the standard handler in case | ||
| 63 | * `do_handler' is not zero, otherwise just free. | ||
| 64 | */ | ||
| 65 | |||
| 66 | void | ||
| 67 | mg_destroy (garage_hdlr *g, int do_handler); | ||
| 68 | |||
| 69 | |||
| 70 | /* mg_write | ||
| 71 | * | ||
| 72 | * store pointer `data' with len `data_len' to the garage for IP `ip' | ||
| 73 | * if `data_free' is non-zero the `data' pointer will be freed if mg_clean | ||
| 74 | * or mg_destroy is called. | ||
| 75 | */ | ||
| 76 | |||
| 77 | void | ||
| 78 | mg_write (garage_hdlr *g, unsigned long int ip, void *data, size_t data_len, | ||
| 79 | int data_free); | ||
| 80 | |||
| 81 | |||
| 82 | /* mg_read | ||
| 83 | * | ||
| 84 | * return first ip_elem for ip `ip' on success (it is not removed from garage) | ||
| 85 | * return NULL on failure | ||
| 86 | */ | ||
| 87 | |||
| 88 | ip_elem * | ||
| 89 | mg_read (garage_hdlr *g, unsigned long int ip); | ||
| 90 | |||
| 91 | |||
| 92 | /* mg_clean | ||
| 93 | * | ||
| 94 | * clean everything stored in the garage for IP `ip' | ||
| 95 | */ | ||
| 96 | |||
| 97 | void | ||
| 98 | mg_clean (garage_hdlr *g, unsigned long int ip, void (*cleaner)(ip_list *)); | ||
| 99 | |||
| 100 | |||
| 101 | /* mg_show | ||
| 102 | * | ||
| 103 | * DEBUG function, to show IP distribution in garage | ||
| 104 | */ | ||
| 105 | |||
| 106 | void | ||
| 107 | mg_show (garage_hdlr *g); | ||
| 108 | |||
| 109 | |||
| 110 | /* mg_count | ||
| 111 | * | ||
| 112 | * count elements in garage | ||
| 113 | */ | ||
| 114 | |||
| 115 | unsigned long int | ||
| 116 | mg_count (garage_hdlr *g); | ||
| 117 | |||
| 118 | |||
| 119 | /* mg_ip_isin | ||
| 120 | * | ||
| 121 | * check whether the ip `ip' is stored in the garage pointed to by `g'. | ||
| 122 | * | ||
| 123 | * return zero in case it is not | ||
| 124 | * return != zero if it is | ||
| 125 | */ | ||
| 126 | |||
| 127 | int | ||
| 128 | mg_ip_isin (garage_hdlr *g, unsigned long int ip); | ||
| 129 | |||
| 130 | |||
| 131 | /* CIDR routines | ||
| 132 | */ | ||
| 133 | |||
| 134 | /* mg_cidr_getmask | ||
| 135 | * | ||
| 136 | * convert a netmask (eg 0xfffffc00) or a cidr notation (eg 24) given in | ||
| 137 | * `mask' to a netmask. | ||
| 138 | */ | ||
| 139 | |||
| 140 | unsigned long int | ||
| 141 | mg_cidr_getmask (unsigned long int mask); | ||
| 142 | |||
| 143 | |||
| 144 | /* mg_cidr_maskcount | ||
| 145 | * | ||
| 146 | * return the number of hosts that are possible using a mask `mask' in | ||
| 147 | * either CIDR or netmask notation | ||
| 148 | */ | ||
| 149 | |||
| 150 | unsigned long int | ||
| 151 | mg_cidr_maskcount (unsigned long int mask); | ||
| 152 | |||
| 153 | |||
| 154 | /* mg_cidr_match | ||
| 155 | * | ||
| 156 | * check whether `ip1' and `ip2' are in the same network, given the network | ||
| 157 | * size by `mask' (CIDR or netmask notation) | ||
| 158 | */ | ||
| 159 | |||
| 160 | int | ||
| 161 | mg_cidr_match (unsigned long int ip1, unsigned long int ip2, | ||
| 162 | unsigned long int mask); | ||
| 163 | |||
| 164 | |||
| 165 | /* mg_cidr_count | ||
| 166 | * | ||
| 167 | * count elements in garage `g', that are within the CIDR range build from | ||
| 168 | * ip `ip' and netmask `mask'. `mask' is either the number of bits, if it's in | ||
| 169 | * the range of 0-32, or the real mask, if it is greater then 32. (for the | ||
| 170 | * zero case the netmask is equal to the cidr notation). | ||
| 171 | */ | ||
| 172 | |||
| 173 | unsigned long int | ||
| 174 | mg_cidr_count (garage_hdlr *g, unsigned long int ip, unsigned long int mask); | ||
| 175 | |||
| 176 | |||
| 177 | #endif | ||
| 178 | |||
diff --git a/other/b-scan/include/bscan/module.h b/other/b-scan/include/bscan/module.h new file mode 100644 index 0000000..3ad316b --- /dev/null +++ b/other/b-scan/include/bscan/module.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | |||
| 2 | #define MAX_MODULES 8 | ||
| 3 | |||
| 4 | #define MOD_FIRSTPKG 0x00 | ||
| 5 | #define MOD_RCV 0x01 | ||
| 6 | |||
| 7 | #define RMOD_OK 0x00 | ||
| 8 | #define RMOD_SKIP 0x01 | ||
| 9 | #define RMOD_ERROR 0x02 | ||
| 10 | #define RMOD_ABRT 0x04 | ||
| 11 | |||
| 12 | struct _mods | ||
| 13 | { | ||
| 14 | int (*init) (char **, int, char **, void *); /* init the module stuff */ | ||
| 15 | int (*fini) (); /* finish the module */ | ||
| 16 | void (*musage) (); /* print out usage informations */ | ||
| 17 | int (*callmdl) (int, void *); /* call a function */ | ||
| 18 | const char *modname; /* name of the module after init */ | ||
| 19 | int modid; /* id of the module. who needs this ? */ | ||
| 20 | char *modarg; /* arg to module */ | ||
| 21 | }; | ||
| 22 | |||
| 23 | int add_module (char *, char *); | ||
| 24 | void split_margs (const char *, char ***, int *); | ||
| 25 | int loadinit_mod (char *); | ||
| 26 | |||
diff --git a/other/b-scan/include/bscan/network_raw.h b/other/b-scan/include/bscan/network_raw.h new file mode 100644 index 0000000..9ffed74 --- /dev/null +++ b/other/b-scan/include/bscan/network_raw.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * network_raw.h, depends on libnet.h | ||
| 4 | */ | ||
| 5 | |||
| 6 | |||
| 7 | #define ETH_SIZE 14 | ||
| 8 | #define IP_SIZE 20 | ||
| 9 | #define TCP_SIZE 20 | ||
| 10 | #define ICMP_SIZE 8 | ||
| 11 | #define UDP_SIZE 8 | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Checksum stuff | ||
| 15 | */ | ||
| 16 | #define CKSUM_CARRY(x) \ | ||
| 17 | (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) | ||
| 18 | #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) | ||
| 19 | |||
| 20 | |||
| 21 | /* | ||
| 22 | * leet net tuple | ||
| 23 | */ | ||
| 24 | struct net_tuple | ||
| 25 | { | ||
| 26 | uint32_t src; | ||
| 27 | unsigned short int sport; | ||
| 28 | uint32_t dst; | ||
| 29 | unsigned short int dport; | ||
| 30 | }; | ||
| 31 | |||
| 32 | |||
| 33 | /* | ||
| 34 | * pseudo TCP header for calculating the chksum | ||
| 35 | */ | ||
| 36 | struct _fakehead | ||
| 37 | { | ||
| 38 | uint32_t saddr; | ||
| 39 | uint32_t daddr; | ||
| 40 | uint8_t zero; | ||
| 41 | uint8_t protocol; | ||
| 42 | uint16_t tot_len; | ||
| 43 | }; | ||
| 44 | |||
| 45 | int init_network_raw (void); | ||
| 46 | int in_cksum (unsigned short *, int); | ||
| 47 | int send_ipv4 (int, u_char *, size_t); | ||
| 48 | void add_udphdr (unsigned char *, struct net_tuple *, int); | ||
| 49 | void add_tcphdr (unsigned char *, struct net_tuple *, uint8_t, int, | ||
| 50 | tcp_seq *, tcp_seq *); | ||
| 51 | void add_icmpping (unsigned char *, int, int); | ||
| 52 | void add_iphdr (unsigned char *, uint8_t ip_p, struct net_tuple *, int); | ||
| 53 | int answer_tcp (int, struct ip *, struct tcphdr *, uint8_t, u_char *, uint); | ||
| 54 | int vrfy_ip (struct ip *, uint32_t, u_short *); | ||
| 55 | int vrfy_tcp (struct tcphdr *, uint32_t, u_short *); | ||
| 56 | int decode_nvt(u_char *, uint, u_char *, uint *, u_char *, uint *); | ||
| 57 | |||
diff --git a/other/b-scan/include/bscan/restore.h b/other/b-scan/include/bscan/restore.h new file mode 100644 index 0000000..960efe6 --- /dev/null +++ b/other/b-scan/include/bscan/restore.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | /* | ||
| 2 | * restore.h | ||
| 3 | */ | ||
| 4 | |||
| 5 | int write_restore (void); | ||
| 6 | int read_restore (char *); | ||
diff --git a/other/b-scan/include/bscan/signal.h b/other/b-scan/include/bscan/signal.h new file mode 100644 index 0000000..fab56f6 --- /dev/null +++ b/other/b-scan/include/bscan/signal.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* | ||
| 2 | * this space for rent.... | ||
| 3 | */ | ||
| 4 | |||
| 5 | typedef void (*sighandler_t) (int); | ||
| 6 | |||
| 7 | #define SIG_SETALL 0x01 | ||
| 8 | |||
| 9 | |||
| 10 | int sigctl (int, sighandler_t); | ||
diff --git a/other/b-scan/include/bscan/snarf.h b/other/b-scan/include/bscan/snarf.h new file mode 100644 index 0000000..fee7047 --- /dev/null +++ b/other/b-scan/include/bscan/snarf.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | |||
| 2 | #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) | ||
| 3 | |||
| 4 | #define ETH_ALEN 6 | ||
| 5 | #define PCAP_FILTER "arp or tcp or icmp or udp" | ||
| 6 | |||
| 7 | struct Ether_header | ||
| 8 | { | ||
| 9 | uint8_t ether_dhost[ETH_ALEN]; | ||
| 10 | uint8_t ether_shost[ETH_ALEN]; | ||
| 11 | uint16_t ether_type; | ||
| 12 | }; | ||
| 13 | |||
| 14 | struct Arphdr | ||
| 15 | { | ||
| 16 | unsigned short int ar_hrd; /* Format of hardware address. */ | ||
| 17 | unsigned short int ar_pro; /* Format of protocol address. */ | ||
| 18 | unsigned char ar_hln; /* Length of hardware address. */ | ||
| 19 | unsigned char ar_pln; /* Length of protocol address. */ | ||
| 20 | unsigned short int ar_op; /* ARP opcode (command). */ | ||
| 21 | /* Ethernet looks like this : This bit is variable sized | ||
| 22 | however... */ | ||
| 23 | unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */ | ||
| 24 | unsigned char ar_sip[4]; /* Sender IP address. */ | ||
| 25 | unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */ | ||
| 26 | unsigned char ar_tip[4]; /* Target IP address. */ | ||
| 27 | }; | ||
| 28 | |||
| 29 | |||
| 30 | void *do_snarf (void *); | ||
| 31 | void undo_snarf (); | ||
diff --git a/other/b-scan/include/bscan/system.h b/other/b-scan/include/bscan/system.h new file mode 100644 index 0000000..6eed6d8 --- /dev/null +++ b/other/b-scan/include/bscan/system.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * generic system functions | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <sys/time.h> | ||
| 6 | #include <unistd.h> | ||
| 7 | #include <errno.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | #define DEV_ZERO "/dev/zero" | ||
| 12 | |||
| 13 | /* | ||
| 14 | * we use the 'do while' trick to use err_abort as if they were functions | ||
| 15 | */ | ||
| 16 | #define err_abort(code,text) do { \ | ||
| 17 | fprintf (stderr, "%s at \"%s\":%d: %s\n", \ | ||
| 18 | text, __FILE__, __LINE__, strerror (code)); \ | ||
| 19 | abort(); \ | ||
| 20 | } while (0) | ||
| 21 | |||
| 22 | #define errno_abort(text) do { \ | ||
| 23 | fprintf(stderr, "%s at \"%s\":%d: %s\n", \ | ||
| 24 | text, __FILE__, __LINE__, strerror (errno)); \ | ||
| 25 | abort(); \ | ||
| 26 | } while (0) | ||
| 27 | |||
| 28 | |||
| 29 | void *shmalloc (int, size_t); | ||
| 30 | void do_nanosleep (time_t, long); | ||
| 31 | void xchange (void *, void *, int); | ||
| 32 | void time_diff (struct timeval *, struct timeval *); | ||
| 33 | int ctoreal(char *, char *); | ||
| 34 | void save_write(FILE *, char *, unsigned char *, int); | ||
| 35 | int isprintdata(char *, int); | ||
| 36 | int dat2hexstr(unsigned char *, unsigned int, unsigned char *, unsigned int); | ||
| 37 | int dat2strip(unsigned char *, unsigned int, unsigned char *, unsigned int); | ||
| 38 | |||
diff --git a/other/b-scan/include/bscan/tty.h b/other/b-scan/include/bscan/tty.h new file mode 100644 index 0000000..09d73c0 --- /dev/null +++ b/other/b-scan/include/bscan/tty.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | /* | ||
| 2 | * tty support functions | ||
| 3 | */ | ||
| 4 | |||
| 5 | void tty_done (); | ||
| 6 | void tty_init (); | ||
| 7 | int tty_getchar (); | ||
diff --git a/other/b-scan/include/bscan/version.h b/other/b-scan/include/bscan/version.h new file mode 100644 index 0000000..39b1298 --- /dev/null +++ b/other/b-scan/include/bscan/version.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #define VER_MAJOR 0 | ||
| 2 | #define VER_MINOR 7 | ||
| 3 | #define VER_SUFFIX d | ||
| 4 | #define VER_EMAIL "anonymous@segfault.net" | ||
| 5 | #define VERSION "bscan v0.7-dev, anonymous@segfault.net" | ||
diff --git a/other/b-scan/modules/Makefile b/other/b-scan/modules/Makefile new file mode 100644 index 0000000..ccac359 --- /dev/null +++ b/other/b-scan/modules/Makefile | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | CC=gcc | ||
| 2 | COPT=-Wall -ggdb -shared -fPIC -I../include | ||
| 3 | DEFS=`libnet-config --defines` -DUSE_LIBNET #-DDEBUG | ||
| 4 | LIBS= | ||
| 5 | TARGETS=mod_snmp mod_banner mod_httpd mod_ping mod_bind | ||
| 6 | |||
| 7 | # HPUX 10.20 | ||
| 8 | # DEFS=`libnet-config --defines` -DUSE_LIBNET -DHP10 #-DDEBUG | ||
| 9 | |||
| 10 | all: | ||
| 11 | for trgt in $(TARGETS); do \ | ||
| 12 | $(CC) $(COPT) $(DEFS) -o $$trgt.so $$trgt.c; \ | ||
| 13 | done | ||
| 14 | |||
| 15 | |||
| 16 | clean: | ||
| 17 | for trgt in $(TARGETS); do \ | ||
| 18 | rm -f $$trgt.so; \ | ||
| 19 | done | ||
| 20 | rm -f core *~ | ||
| 21 | |||
| 22 | |||
diff --git a/other/b-scan/modules/mod_banner.c b/other/b-scan/modules/mod_banner.c new file mode 100644 index 0000000..6f02a39 --- /dev/null +++ b/other/b-scan/modules/mod_banner.c | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | /* | ||
| 2 | * mod_example.c | ||
| 3 | * Example module for bscan. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/module.h> | ||
| 8 | #include <bscan/dcd_icmp.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | #include <unistd.h> | ||
| 12 | |||
| 13 | |||
| 14 | #ifndef MOD_NAME | ||
| 15 | #define MOD_NAME "mod_banner" | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #define SCN_NVT 0x00000001 | ||
| 19 | #define SCN_HALFOPEN 0x00000002 | ||
| 20 | #define SCN_XMAS 0x00000004 | ||
| 21 | #define SCN_FIN 0x00000008 | ||
| 22 | #define SCN_NULL 0x00000010 | ||
| 23 | #define SCN_PUSH 0x00000020 | ||
| 24 | #define SCN_LETOPEN 0x00000040 | ||
| 25 | #define SCN_NOSCAN 0x00000080 | ||
| 26 | #define SCN_NOICMP 0x00000100 | ||
| 27 | |||
| 28 | |||
| 29 | static int isinit=0; | ||
| 30 | /* | ||
| 31 | * some variables from the binary-process | ||
| 32 | */ | ||
| 33 | extern int dlt_len; | ||
| 34 | extern u_char *align_buf; | ||
| 35 | extern unsigned short ip_options; | ||
| 36 | extern struct ip *ip; | ||
| 37 | extern struct Ether_header *eth; | ||
| 38 | extern u_int plen, pcaplen; | ||
| 39 | |||
| 40 | |||
| 41 | struct _mopt | ||
| 42 | { | ||
| 43 | u_int scanflags; | ||
| 44 | uint8_t th_flags; | ||
| 45 | } static mopt; | ||
| 46 | |||
| 47 | |||
| 48 | /* | ||
| 49 | * static functions prototypes | ||
| 50 | */ | ||
| 51 | static int mdo_opt(int, char **, struct _opt *); | ||
| 52 | static void init_vars(struct _opt *); | ||
| 53 | static int process_rcv(struct _opt *); | ||
| 54 | static void handle_icmp (); | ||
| 55 | |||
| 56 | |||
| 57 | |||
| 58 | /* | ||
| 59 | * print out usage informations | ||
| 60 | */ | ||
| 61 | void | ||
| 62 | musage() | ||
| 63 | { | ||
| 64 | printf ("\n"MOD_NAME"\n"); | ||
| 65 | printf (" -o <source port>, default 20\n"); | ||
| 66 | printf (" -p <port to scan>, default 21\n"); | ||
| 67 | printf (" -a grab all data and let the connecten established\n"); | ||
| 68 | printf (" -n NVT terminal support (use this for telnetd-scans)\n"); | ||
| 69 | printf (" -I dont report ICMP-errors\n"); | ||
| 70 | printf (" -q quite, dont send out any initial packages [first-pkg]\n"); | ||
| 71 | printf (" "MOD_NAME" only reports ICMP errors and doesn't start\n"); | ||
| 72 | printf (" scanning. It will still simulate the tcp-stack.\n"); | ||
| 73 | printf | ||
| 74 | (" -sS,-sF,-sX,-sN,-sP TCP SYN stealth, Fin, Xmas, Null, !Push scan\n"); | ||
| 75 | |||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | /* | ||
| 80 | * return 0 on success, != 0 on failure | ||
| 81 | */ | ||
| 82 | int | ||
| 83 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 84 | { | ||
| 85 | #ifdef DEBUG | ||
| 86 | printf("MODULE INIT\n"); | ||
| 87 | #endif | ||
| 88 | if (isinit) | ||
| 89 | return(-1); | ||
| 90 | |||
| 91 | *modname = MOD_NAME; | ||
| 92 | isinit = 1; | ||
| 93 | init_vars(opt); | ||
| 94 | |||
| 95 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 96 | return(-1); | ||
| 97 | |||
| 98 | return(0); | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | ||
| 102 | * fini-routine. called on cleanup | ||
| 103 | */ | ||
| 104 | int | ||
| 105 | fini() | ||
| 106 | { | ||
| 107 | #ifdef DEBUG | ||
| 108 | printf("MODULE FINI\n"); | ||
| 109 | #endif | ||
| 110 | return(0); | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | /* | ||
| 115 | * | ||
| 116 | */ | ||
| 117 | int | ||
| 118 | callmdl(int entry, struct _opt *opt) | ||
| 119 | { | ||
| 120 | #ifdef DEBUG | ||
| 121 | printf("MODULE CALLMDL\n"); | ||
| 122 | #endif | ||
| 123 | if (entry == MOD_FIRSTPKG) | ||
| 124 | { | ||
| 125 | if (mopt.scanflags & SCN_NOSCAN) | ||
| 126 | return(RMOD_SKIP); | ||
| 127 | |||
| 128 | add_tcphdr(opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, mopt.th_flags, 0, NULL, NULL); | ||
| 129 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_TCP, &opt->nt, TCP_SIZE); | ||
| 130 | opt->pkg_len = TCP_SIZE + IP_SIZE; | ||
| 131 | return(RMOD_OK); | ||
| 132 | } | ||
| 133 | |||
| 134 | if (entry == MOD_RCV) | ||
| 135 | process_rcv(opt); | ||
| 136 | |||
| 137 | return(RMOD_OK); | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | /* | ||
| 142 | *********************************************************** | ||
| 143 | * Our OWN/static functions for THIS module * | ||
| 144 | *********************************************************** | ||
| 145 | */ | ||
| 146 | |||
| 147 | /* | ||
| 148 | * initialize all local variables. | ||
| 149 | * We use some 'unused' variables of the masterprogramm | ||
| 150 | */ | ||
| 151 | static void | ||
| 152 | init_vars(struct _opt *opt) | ||
| 153 | { | ||
| 154 | opt->nt.sport = htons(20); /* not used by master programm */ | ||
| 155 | opt->nt.dport = htons(21); /* not used by master programm */ | ||
| 156 | |||
| 157 | mopt.scanflags = 0; | ||
| 158 | mopt.th_flags = TH_SYN; | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | /* | ||
| 163 | * LOCAL/STATIC function, only available in the module | ||
| 164 | * return 0 on success, != 0 on failure | ||
| 165 | */ | ||
| 166 | static int | ||
| 167 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 168 | { | ||
| 169 | extern char *optarg; | ||
| 170 | /*extern int optind, opterr, optopt;*/ | ||
| 171 | int c; | ||
| 172 | |||
| 173 | while ((c = getopt (argc, argv, "Iqans:p:o:")) != -1) | ||
| 174 | { | ||
| 175 | switch (c) | ||
| 176 | { | ||
| 177 | case 'I': | ||
| 178 | mopt.scanflags |= SCN_NOICMP; | ||
| 179 | break; | ||
| 180 | case 'q': | ||
| 181 | mopt.scanflags |= SCN_NOSCAN; | ||
| 182 | break; | ||
| 183 | case 'p': | ||
| 184 | opt->nt.dport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 185 | break; | ||
| 186 | case 'o': | ||
| 187 | opt->nt.sport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 188 | break; | ||
| 189 | case 'a': | ||
| 190 | mopt.scanflags |= SCN_LETOPEN; | ||
| 191 | break; | ||
| 192 | case 'n': | ||
| 193 | mopt.scanflags |= SCN_NVT; /* NVT parsing */ | ||
| 194 | break; | ||
| 195 | case 's': | ||
| 196 | switch (optarg[0]) | ||
| 197 | { | ||
| 198 | case 'S': | ||
| 199 | mopt.scanflags |= SCN_HALFOPEN; | ||
| 200 | mopt.th_flags = TH_SYN; | ||
| 201 | break; | ||
| 202 | case 'X': | ||
| 203 | mopt.scanflags |= SCN_XMAS; | ||
| 204 | mopt.th_flags = (TH_FIN | TH_PUSH | TH_URG); | ||
| 205 | break; | ||
| 206 | case 'F': | ||
| 207 | mopt.scanflags |= SCN_FIN; | ||
| 208 | mopt.th_flags = TH_FIN; | ||
| 209 | break; | ||
| 210 | case 'N': | ||
| 211 | mopt.scanflags |= SCN_NULL; | ||
| 212 | mopt.th_flags = 0; | ||
| 213 | break; | ||
| 214 | case 'P': | ||
| 215 | mopt.scanflags |= SCN_PUSH; | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | fprintf(stderr, "unrecognized option -s%c\n", optarg[0]); | ||
| 219 | return(-1); | ||
| 220 | } | ||
| 221 | break; | ||
| 222 | case ':': | ||
| 223 | fprintf(stderr, "missing parameter\n"); | ||
| 224 | return(-1); | ||
| 225 | default: | ||
| 226 | return(-1); | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | if ((mopt.scanflags & SCN_NVT) && !(mopt.scanflags & SCN_LETOPEN)) | ||
| 231 | fprintf(stderr, "WARNING: NVT used without -a. This is probably not what you want!\n"); | ||
| 232 | |||
| 233 | return(0); | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | /* | ||
| 238 | * vrfy the icmp packet and print out 'human readable'-icmp code | ||
| 239 | * dest-unreachable packages only! | ||
| 240 | */ | ||
| 241 | static void | ||
| 242 | handle_icmp (int offset) | ||
| 243 | { | ||
| 244 | struct icmp *icmp = (struct icmp *) (align_buf + offset); | ||
| 245 | struct ip *icmpip; | ||
| 246 | |||
| 247 | if (plen < offset + sizeof (*icmp) + dlt_len) | ||
| 248 | return; | ||
| 249 | |||
| 250 | icmpip = (struct ip *) (align_buf + offset + ICMP_HDRSIZE); | ||
| 251 | |||
| 252 | printf ("%s (%d/%d) %s", int_ntoa (icmpip->ip_dst.s_addr), | ||
| 253 | icmp->icmp_type, icmp->icmp_code, | ||
| 254 | icmp_str (icmp->icmp_type, icmp->icmp_code)); | ||
| 255 | printf ("(from %s)\n", int_ntoa (ip->ip_src.s_addr)); | ||
| 256 | } | ||
| 257 | |||
| 258 | |||
| 259 | /* | ||
| 260 | * process incoming packets | ||
| 261 | * IP-packet is verified and variables valid (ip_options, *ip) | ||
| 262 | */ | ||
| 263 | static int | ||
| 264 | process_rcv(struct _opt *opt) | ||
| 265 | { | ||
| 266 | struct tcphdr *tcp; | ||
| 267 | unsigned short tcp_options = 0; | ||
| 268 | u_char *data = NULL; | ||
| 269 | u_char *ans = NULL; /* tcpdata answer */ | ||
| 270 | u_char prefix[32]; | ||
| 271 | int data_len = 0; | ||
| 272 | uint ans_len = 0; | ||
| 273 | uint res_len = 0; | ||
| 274 | uint tcphdr_len = 0; | ||
| 275 | uint iphdr_len = 0; | ||
| 276 | |||
| 277 | |||
| 278 | if (ip->ip_p == IPPROTO_ICMP) | ||
| 279 | { | ||
| 280 | opt->snarf.icmp_c++; /* for statistics */ | ||
| 281 | if (!(mopt.scanflags & SCN_NOICMP)) | ||
| 282 | handle_icmp (sizeof (*ip) + ip_options); | ||
| 283 | |||
| 284 | return(0); | ||
| 285 | } | ||
| 286 | |||
| 287 | if (ip->ip_p != IPPROTO_TCP) | ||
| 288 | return(0); | ||
| 289 | |||
| 290 | iphdr_len = sizeof(*ip) + ip_options; | ||
| 291 | tcp = (struct tcphdr *) (align_buf + iphdr_len); | ||
| 292 | |||
| 293 | if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len , &tcp_options) != 0) | ||
| 294 | return(0); | ||
| 295 | |||
| 296 | if (tcp->th_flags & TH_RST) | ||
| 297 | { | ||
| 298 | opt->snarf.refused_c++; | ||
| 299 | printf ("%s:%d refused\n", int_ntoa (ip->ip_src.s_addr), | ||
| 300 | ntohs (tcp->th_sport)); | ||
| 301 | } | ||
| 302 | else if (tcp->th_flags & TH_FIN) | ||
| 303 | { | ||
| 304 | opt->snarf.close_c++; | ||
| 305 | answer_tcp (opt->sox, ip, tcp, TH_FIN | TH_ACK, NULL, 0); | ||
| 306 | printf ("%s:%d connection closed by foreig host\n", | ||
| 307 | int_ntoa (ip->ip_src.s_addr), ntohs (tcp->th_sport)); | ||
| 308 | } | ||
| 309 | else if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) | ||
| 310 | { | ||
| 311 | |||
| 312 | if (mopt.scanflags & SCN_HALFOPEN) | ||
| 313 | { | ||
| 314 | if (!(mopt.scanflags & SCN_LETOPEN)) | ||
| 315 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, NULL, 0); | ||
| 316 | return(0); | ||
| 317 | } | ||
| 318 | else | ||
| 319 | answer_tcp (opt->sox, ip, tcp, TH_ACK, NULL, 0); | ||
| 320 | |||
| 321 | opt->snarf.open_c++; | ||
| 322 | printf ("%s:%d open\n", int_ntoa (ip->ip_src.s_addr), | ||
| 323 | ntohs (tcp->th_sport)); | ||
| 324 | } | ||
| 325 | |||
| 326 | /* banner scanner output */ | ||
| 327 | tcphdr_len = sizeof(*tcp) + tcp_options; | ||
| 328 | if (plen - dlt_len > ntohs(ip->ip_len)) | ||
| 329 | data_len = ntohs(ip->ip_len) - iphdr_len - tcphdr_len; | ||
| 330 | else | ||
| 331 | data_len = plen - dlt_len - iphdr_len - tcphdr_len; | ||
| 332 | |||
| 333 | if (data_len <= 0) | ||
| 334 | return(0); | ||
| 335 | |||
| 336 | if ( (data = alloca(data_len + 1)) == NULL) | ||
| 337 | return(-1); | ||
| 338 | |||
| 339 | memcpy(data, align_buf + iphdr_len + tcphdr_len, data_len); | ||
| 340 | |||
| 341 | if (mopt.scanflags & SCN_NVT) | ||
| 342 | { | ||
| 343 | if ((ans = alloca(data_len)) == NULL) | ||
| 344 | return(-1); | ||
| 345 | |||
| 346 | decode_nvt(data, data_len, ans, &ans_len, data, &res_len); | ||
| 347 | data_len = res_len; /* we wrote everything into data */ | ||
| 348 | } | ||
| 349 | |||
| 350 | snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), | ||
| 351 | ntohs (tcp->th_sport)); | ||
| 352 | save_write(stdout, prefix, data, data_len); | ||
| 353 | |||
| 354 | if (tcp->th_flags & TH_RST) /* data_len != 0 */ | ||
| 355 | return(0); /* evil peer resetted our connection */ | ||
| 356 | |||
| 357 | /* close after first data package or ack last RST if data_len >0 */ | ||
| 358 | if (!(mopt.scanflags & SCN_LETOPEN) || (tcp->th_flags & TH_RST)) | ||
| 359 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, ans, ans_len); | ||
| 360 | else | ||
| 361 | answer_tcp (opt->sox, ip, tcp, TH_ACK, ans, ans_len); | ||
| 362 | |||
| 363 | |||
| 364 | return(0); | ||
| 365 | } | ||
diff --git a/other/b-scan/modules/mod_bind.c b/other/b-scan/modules/mod_bind.c new file mode 100644 index 0000000..2a09f49 --- /dev/null +++ b/other/b-scan/modules/mod_bind.c | |||
| @@ -0,0 +1,302 @@ | |||
| 1 | /* | ||
| 2 | * ping-module for bscan. | ||
| 3 | * IDEA: add record-route and source-route feature | ||
| 4 | * and -p pattern [where can we save our time-struct then ? | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <bscan/bscan.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef MOD_NAME | ||
| 14 | #define MOD_NAME "mod_bind" | ||
| 15 | #endif | ||
| 16 | |||
| 17 | /* | ||
| 18 | * this is our query. This is a DNS-formated string | ||
| 19 | * <length1><string1><length2><string2><0> | ||
| 20 | */ | ||
| 21 | #define DNSTXTREQ "\007version\004bind" | ||
| 22 | |||
| 23 | static int process_rcv(struct _opt *); | ||
| 24 | static void add_dnshdr(unsigned char *); | ||
| 25 | static void add_dnstxthdr(unsigned char *, char *, u_int *); | ||
| 26 | |||
| 27 | static int isinit=0; | ||
| 28 | /* | ||
| 29 | * some variables from the binary-process | ||
| 30 | */ | ||
| 31 | extern int dlt_len; | ||
| 32 | extern u_char *align_buf; | ||
| 33 | extern unsigned short ip_options; | ||
| 34 | extern struct ip *ip; | ||
| 35 | extern struct Ether_header *eth; | ||
| 36 | extern u_int plen, pcaplen; | ||
| 37 | extern struct timeval *pts; | ||
| 38 | |||
| 39 | |||
| 40 | struct _dnshdr | ||
| 41 | { | ||
| 42 | u_short id; /* DNS packet ID */ | ||
| 43 | u_short flags; /* DNS flags */ | ||
| 44 | u_short num_q; /* Number of questions */ | ||
| 45 | u_short num_answ_rr; /* Number of answer resource records */ | ||
| 46 | u_short num_auth_rr; /* Number of authority resource records */ | ||
| 47 | u_short num_addi_rr; /* Number of additional resource records */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct _dnsanswr | ||
| 51 | { | ||
| 52 | u_short type; | ||
| 53 | u_short class; | ||
| 54 | u_short ttl1; | ||
| 55 | u_short ttl2; | ||
| 56 | u_short len; | ||
| 57 | }; | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | /* | ||
| 62 | * static functions prototypes | ||
| 63 | */ | ||
| 64 | static int mdo_opt(int, char **, struct _opt *); | ||
| 65 | static void init_vars(struct _opt *); | ||
| 66 | |||
| 67 | /* | ||
| 68 | * print out usage informations | ||
| 69 | */ | ||
| 70 | void | ||
| 71 | musage() | ||
| 72 | { | ||
| 73 | printf ("\n"MOD_NAME"\n"); | ||
| 74 | printf ("verson.bind chaos txt module\n"); | ||
| 75 | printf (" -p <port>, destination port, default 53\n"); | ||
| 76 | printf (" -o <port>, source port, default 53\n"); | ||
| 77 | } | ||
| 78 | |||
| 79 | |||
| 80 | /* | ||
| 81 | * return 0 on success, != 0 on failure | ||
| 82 | */ | ||
| 83 | int | ||
| 84 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 85 | { | ||
| 86 | #ifdef DEBUG | ||
| 87 | printf("MODULE INIT\n"); | ||
| 88 | #endif | ||
| 89 | if (isinit) | ||
| 90 | return(-1); | ||
| 91 | |||
| 92 | *modname = MOD_NAME; | ||
| 93 | isinit = 1; | ||
| 94 | init_vars(opt); | ||
| 95 | |||
| 96 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 97 | return(-1); | ||
| 98 | |||
| 99 | return(0); | ||
| 100 | } | ||
| 101 | |||
| 102 | /* | ||
| 103 | * fini-routine. called on cleanup | ||
| 104 | */ | ||
| 105 | int | ||
| 106 | fini() | ||
| 107 | { | ||
| 108 | #ifdef DEBUG | ||
| 109 | printf("MODULE FINI\n"); | ||
| 110 | #endif | ||
| 111 | return(0); | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | * Module entry point [entry] | ||
| 117 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 118 | * or do nothing [MOD_RCV]. | ||
| 119 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 120 | */ | ||
| 121 | int | ||
| 122 | callmdl(int entry, struct _opt *opt) | ||
| 123 | { | ||
| 124 | #ifdef DEBUG | ||
| 125 | printf("MODULE CALLMDL\n"); | ||
| 126 | #endif | ||
| 127 | if (entry == MOD_FIRSTPKG) | ||
| 128 | { | ||
| 129 | add_dnstxthdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr), DNSTXTREQ, &opt->pkg_len); | ||
| 130 | add_dnshdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE); | ||
| 131 | add_udphdr (opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, opt->pkg_len + sizeof(struct _dnshdr)); | ||
| 132 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE + sizeof(struct _dnshdr)); | ||
| 133 | opt->pkg_len += IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr); | ||
| 134 | return(RMOD_OK); | ||
| 135 | } | ||
| 136 | |||
| 137 | if (entry == MOD_RCV) | ||
| 138 | process_rcv(opt); | ||
| 139 | |||
| 140 | return(RMOD_OK); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | /* | ||
| 145 | *********************************************************** | ||
| 146 | * Our OWN/static functions for THIS module * | ||
| 147 | *********************************************************** | ||
| 148 | */ | ||
| 149 | |||
| 150 | /* | ||
| 151 | * initialize all local variables. | ||
| 152 | * We use some 'unused' variables of the masterprogramm | ||
| 153 | */ | ||
| 154 | static void | ||
| 155 | init_vars(struct _opt *opt) | ||
| 156 | { | ||
| 157 | opt->nt.sport = htons(53); | ||
| 158 | opt->nt.dport = htons(53); | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | /* | ||
| 163 | * LOCAL/STATIC function, only available in the module | ||
| 164 | * return 0 on success, != 0 on failure | ||
| 165 | */ | ||
| 166 | static int | ||
| 167 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 168 | { | ||
| 169 | extern char *optarg; | ||
| 170 | /*extern int optind, opterr, optopt;*/ | ||
| 171 | int c; | ||
| 172 | |||
| 173 | while ((c = getopt (argc, argv, "p:o:")) != -1) | ||
| 174 | { | ||
| 175 | switch (c) | ||
| 176 | { | ||
| 177 | case 'p': | ||
| 178 | opt->nt.dport = htons(atoi(optarg)); | ||
| 179 | break; | ||
| 180 | case 'o': | ||
| 181 | opt->nt.sport = htons(atoi(optarg)); | ||
| 182 | break; | ||
| 183 | case ':': | ||
| 184 | fprintf(stderr, "missing parameter\n"); | ||
| 185 | return(-1); | ||
| 186 | default: | ||
| 187 | return(-1); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | return(0); | ||
| 191 | } | ||
| 192 | |||
| 193 | |||
| 194 | /* | ||
| 195 | * add a DNS header | ||
| 196 | */ | ||
| 197 | static void | ||
| 198 | add_dnshdr(unsigned char *pkt) | ||
| 199 | { | ||
| 200 | struct _dnshdr *dnshdr = (struct _dnshdr *)pkt; | ||
| 201 | |||
| 202 | dnshdr->id = htons(6); /* could be random */ | ||
| 203 | dnshdr->flags = htons(0x0100); /* do query recursivly */ | ||
| 204 | dnshdr->num_q = htons(1); | ||
| 205 | dnshdr->num_answ_rr = 0; | ||
| 206 | dnshdr->num_auth_rr = 0; | ||
| 207 | dnshdr->num_addi_rr = 0; | ||
| 208 | /* add request here. class TXT etc */ | ||
| 209 | } | ||
| 210 | |||
| 211 | /* | ||
| 212 | * add DNS-TXT header here | ||
| 213 | * returns length in *len | ||
| 214 | */ | ||
| 215 | static void | ||
| 216 | add_dnstxthdr(unsigned char *pkt, char *name, u_int *len) | ||
| 217 | { | ||
| 218 | u_short *type; | ||
| 219 | u_short *class; | ||
| 220 | |||
| 221 | if (name == NULL) | ||
| 222 | return; /* nah! specifiy "". we need \0 termination */ | ||
| 223 | |||
| 224 | memcpy(pkt, name, strlen(name)+1); | ||
| 225 | type = (u_short *)(pkt + strlen(name) + 1); | ||
| 226 | class = (u_short *)(pkt + strlen(name) + 1 + sizeof(*class)); | ||
| 227 | |||
| 228 | *type = htons(0x10); /* TEXT string */ | ||
| 229 | *class = htons(0x03); /* chaos */ | ||
| 230 | *len = strlen(name) + 1 + sizeof(*type) + sizeof(*class); | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | /* | ||
| 235 | * handle incoming DNS udp answers | ||
| 236 | */ | ||
| 237 | static int | ||
| 238 | process_rcv(struct _opt *opt) | ||
| 239 | { | ||
| 240 | struct _dnshdr *dns; | ||
| 241 | struct _dnsanswr *dnsanswr; | ||
| 242 | struct udphdr *udp; | ||
| 243 | char *ptr; | ||
| 244 | char buf[128]; | ||
| 245 | int len, dnstxtlen; | ||
| 246 | uint iphdr_len = 0; | ||
| 247 | |||
| 248 | if (ip->ip_p != IPPROTO_UDP) | ||
| 249 | return(0); | ||
| 250 | |||
| 251 | iphdr_len = IP_SIZE + ip_options; | ||
| 252 | if (plen < dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns)) | ||
| 253 | return(-1); /* invalid size */ | ||
| 254 | |||
| 255 | dns = (struct _dnshdr *) (align_buf + iphdr_len + sizeof(*udp)); | ||
| 256 | if (ntohs(dns->flags) & 0x000F) /* dns-error? query refused ? */ | ||
| 257 | return(-1); | ||
| 258 | |||
| 259 | ptr = (char *) (align_buf + iphdr_len + sizeof(*udp) + sizeof(*dns)); | ||
| 260 | len = dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns); | ||
| 261 | |||
| 262 | while (len++ < plen) | ||
| 263 | if (*ptr++ == '\0') | ||
| 264 | break; | ||
| 265 | |||
| 266 | if (len >= plen) | ||
| 267 | return(-1); | ||
| 268 | |||
| 269 | len += 4; | ||
| 270 | ptr += 4; | ||
| 271 | |||
| 272 | while (len++ < plen) /* skip VERSION.BIND answer string */ | ||
| 273 | if (*ptr++ == '\0') | ||
| 274 | break; | ||
| 275 | |||
| 276 | len += sizeof(*dnsanswr); | ||
| 277 | if (len >= plen) | ||
| 278 | return(-1); | ||
| 279 | |||
| 280 | dnsanswr = (struct _dnsanswr *) (ptr); | ||
| 281 | dnstxtlen = ntohs(dnsanswr->len); | ||
| 282 | if (len + dnstxtlen > plen) | ||
| 283 | return(0); | ||
| 284 | |||
| 285 | if ((dnstxtlen == 0) || (dnstxtlen > 128)) | ||
| 286 | return(-1); | ||
| 287 | |||
| 288 | memcpy(buf, ptr + sizeof(*dnsanswr) +1, dnstxtlen - 1); | ||
| 289 | buf[dnstxtlen - 1] = '\0'; | ||
| 290 | |||
| 291 | ptr = buf; /* evil hax0rs sending messed up strings ? */ | ||
| 292 | while (*++ptr != '\0') | ||
| 293 | if (!isprint((int)*ptr)) | ||
| 294 | *ptr = '_'; | ||
| 295 | |||
| 296 | printf("%s VERSION.BIND. \"%s\"\n", int_ntoa(ip->ip_src.s_addr), buf); | ||
| 297 | |||
| 298 | return(0); | ||
| 299 | |||
| 300 | } | ||
| 301 | |||
| 302 | |||
diff --git a/other/b-scan/modules/mod_httpd.c b/other/b-scan/modules/mod_httpd.c new file mode 100644 index 0000000..275125c --- /dev/null +++ b/other/b-scan/modules/mod_httpd.c | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* | ||
| 2 | * mod_example.c | ||
| 3 | * Example module for bscan. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/module.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | |||
| 10 | |||
| 11 | #ifndef MOD_NAME | ||
| 12 | #define MOD_NAME "mod_httpd" | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #define HEADREQ "HEAD / HTTP/1.0\r\n\r\n" | ||
| 16 | |||
| 17 | |||
| 18 | static int isinit=0; | ||
| 19 | /* | ||
| 20 | * some variables from the binary-process | ||
| 21 | */ | ||
| 22 | extern int dlt_len; | ||
| 23 | extern u_char *align_buf; | ||
| 24 | extern unsigned short ip_options; | ||
| 25 | extern struct ip *ip; | ||
| 26 | extern struct Ether_header *eth; | ||
| 27 | extern u_int plen, pcaplen; | ||
| 28 | |||
| 29 | struct _mopt | ||
| 30 | { | ||
| 31 | unsigned short int dport; /* dport in NBO */ | ||
| 32 | char *request; /* the http-request */ | ||
| 33 | } static mopt; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * static functions prototypes | ||
| 37 | */ | ||
| 38 | static int mdo_opt(int, char **, struct _opt *); | ||
| 39 | static void init_vars(struct _opt *); | ||
| 40 | static int process_rcv(struct _opt *); | ||
| 41 | |||
| 42 | /* | ||
| 43 | * print out usage informations | ||
| 44 | */ | ||
| 45 | void | ||
| 46 | musage() | ||
| 47 | { | ||
| 48 | printf ("\n"MOD_NAME"\n"); | ||
| 49 | printf (" -p <port>, default 80\n"); | ||
| 50 | printf (" -r <request>, default 'HEAD / HTTP/1.0'\n"); | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | /* | ||
| 55 | * return 0 on success, != 0 on failure | ||
| 56 | */ | ||
| 57 | int | ||
| 58 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 59 | { | ||
| 60 | #ifdef DEBUG | ||
| 61 | printf("MODULE INIT\n"); | ||
| 62 | #endif | ||
| 63 | if (isinit) | ||
| 64 | return(-1); | ||
| 65 | |||
| 66 | *modname = MOD_NAME; | ||
| 67 | isinit = 1; | ||
| 68 | init_vars(opt); | ||
| 69 | |||
| 70 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 71 | return(-1); | ||
| 72 | |||
| 73 | return(0); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* | ||
| 77 | * fini-routine. called on cleanup | ||
| 78 | */ | ||
| 79 | int | ||
| 80 | fini() | ||
| 81 | { | ||
| 82 | #ifdef DEBUG | ||
| 83 | printf("MODULE FINI\n"); | ||
| 84 | #endif | ||
| 85 | return(0); | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /* | ||
| 90 | * | ||
| 91 | */ | ||
| 92 | int | ||
| 93 | callmdl(int entry, struct _opt *opt) | ||
| 94 | { | ||
| 95 | #ifdef DEBUG | ||
| 96 | printf("MODULE CALLMDL\n"); | ||
| 97 | #endif | ||
| 98 | if (entry == MOD_FIRSTPKG) | ||
| 99 | return(RMOD_SKIP); | ||
| 100 | |||
| 101 | if (entry == MOD_RCV) | ||
| 102 | process_rcv(opt); | ||
| 103 | |||
| 104 | return(RMOD_OK); | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 108 | /* | ||
| 109 | *********************************************************** | ||
| 110 | * Our OWN/static functions for THIS module * | ||
| 111 | *********************************************************** | ||
| 112 | */ | ||
| 113 | |||
| 114 | /* | ||
| 115 | * initialize all local variables. | ||
| 116 | * We use some 'unused' variables of the masterprogramm | ||
| 117 | */ | ||
| 118 | static void | ||
| 119 | init_vars(struct _opt *opt) | ||
| 120 | { | ||
| 121 | mopt.dport = htons(80); | ||
| 122 | mopt.request = HEADREQ; | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | /* | ||
| 127 | * LOCAL/STATIC function, only available in the module | ||
| 128 | * return 0 on success, != 0 on failure | ||
| 129 | */ | ||
| 130 | static int | ||
| 131 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 132 | { | ||
| 133 | extern char *optarg; | ||
| 134 | /*extern int optind, opterr, optopt;*/ | ||
| 135 | int c; | ||
| 136 | |||
| 137 | while ((c = getopt (argc, argv, "p:r:")) != -1) | ||
| 138 | { | ||
| 139 | switch (c) | ||
| 140 | { | ||
| 141 | case 'p': | ||
| 142 | mopt.dport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 143 | break; | ||
| 144 | case 'r': | ||
| 145 | mopt.request = optarg; | ||
| 146 | fprintf(stderr, MOD_NAME ": requesting \"%s\"\n", optarg); | ||
| 147 | break; | ||
| 148 | case ':': | ||
| 149 | fprintf(stderr, "missing parameter\n"); | ||
| 150 | return(-1); | ||
| 151 | default: | ||
| 152 | return(-1); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | return(0); | ||
| 156 | } | ||
| 157 | |||
| 158 | |||
| 159 | /* | ||
| 160 | * process incoming packets | ||
| 161 | * IP-packet is verified and variables valid (ip_options, *ip) | ||
| 162 | */ | ||
| 163 | static int | ||
| 164 | process_rcv(struct _opt *opt) | ||
| 165 | { | ||
| 166 | struct tcphdr *tcp; | ||
| 167 | unsigned short tcp_options = 0; | ||
| 168 | uint iphdr_len = 0; | ||
| 169 | |||
| 170 | |||
| 171 | if (ip->ip_p != IPPROTO_TCP) | ||
| 172 | return(0); | ||
| 173 | |||
| 174 | iphdr_len = sizeof(*ip) + ip_options; | ||
| 175 | tcp = (struct tcphdr *) (align_buf + iphdr_len); | ||
| 176 | |||
| 177 | if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len, &tcp_options) != 0) | ||
| 178 | return(0); | ||
| 179 | |||
| 180 | if (tcp->th_sport != mopt.dport) | ||
| 181 | return(0); | ||
| 182 | |||
| 183 | if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) | ||
| 184 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_PUSH, mopt.request, strlen(mopt.request)); | ||
| 185 | |||
| 186 | return(0); | ||
| 187 | } | ||
| 188 | |||
diff --git a/other/b-scan/modules/mod_ping.c b/other/b-scan/modules/mod_ping.c new file mode 100644 index 0000000..73a90a4 --- /dev/null +++ b/other/b-scan/modules/mod_ping.c | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | /* | ||
| 2 | * ping-module for bscan. | ||
| 3 | * IDEA: add record-route and source-route feature | ||
| 4 | * and -p pattern [where can we save our time-struct then ? | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <bscan/bscan.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef MOD_NAME | ||
| 14 | #define MOD_NAME "mod_ping" | ||
| 15 | #endif | ||
| 16 | |||
| 17 | static int process_rcv(struct _opt *); | ||
| 18 | |||
| 19 | static int isinit=0; | ||
| 20 | /* | ||
| 21 | * some variables from the binary-process | ||
| 22 | */ | ||
| 23 | extern int dlt_len; | ||
| 24 | extern u_char *align_buf; | ||
| 25 | extern unsigned short ip_options; | ||
| 26 | extern struct ip *ip; | ||
| 27 | extern struct Ether_header *eth; | ||
| 28 | extern u_int plen, pcaplen; | ||
| 29 | extern struct timeval *pts; | ||
| 30 | |||
| 31 | struct _mopt | ||
| 32 | { | ||
| 33 | int type; | ||
| 34 | int size; | ||
| 35 | } static mopt; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * static functions prototypes | ||
| 39 | */ | ||
| 40 | static int mdo_opt(int, char **, struct _opt *); | ||
| 41 | static void init_vars(struct _opt *); | ||
| 42 | |||
| 43 | /* | ||
| 44 | * print out usage informations | ||
| 45 | */ | ||
| 46 | void | ||
| 47 | musage() | ||
| 48 | { | ||
| 49 | printf ("\n"MOD_NAME"\n"); | ||
| 50 | printf (" -t (echo|time) -s <size>, size of ping-data [default 56].\n"); | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | /* | ||
| 55 | * return 0 on success, != 0 on failure | ||
| 56 | */ | ||
| 57 | int | ||
| 58 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 59 | { | ||
| 60 | #ifdef DEBUG | ||
| 61 | printf("MODULE INIT\n"); | ||
| 62 | #endif | ||
| 63 | if (isinit) | ||
| 64 | return(-1); | ||
| 65 | |||
| 66 | *modname = MOD_NAME; | ||
| 67 | isinit = 1; | ||
| 68 | init_vars(opt); | ||
| 69 | |||
| 70 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 71 | return(-1); | ||
| 72 | |||
| 73 | return(0); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* | ||
| 77 | * fini-routine. called on cleanup | ||
| 78 | */ | ||
| 79 | int | ||
| 80 | fini() | ||
| 81 | { | ||
| 82 | #ifdef DEBUG | ||
| 83 | printf("MODULE FINI\n"); | ||
| 84 | #endif | ||
| 85 | return(0); | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /* | ||
| 90 | * Module entry point [entry] | ||
| 91 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 92 | * or do nothing [MOD_RCV]. | ||
| 93 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 94 | */ | ||
| 95 | int | ||
| 96 | callmdl(int entry, struct _opt *opt) | ||
| 97 | { | ||
| 98 | #ifdef DEBUG | ||
| 99 | printf("MODULE CALLMDL\n"); | ||
| 100 | #endif | ||
| 101 | if (entry == MOD_FIRSTPKG) | ||
| 102 | { | ||
| 103 | add_icmpping (opt->packet + ETH_SIZE + IP_SIZE, mopt.size, mopt.type); | ||
| 104 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_ICMP, &opt->nt, ICMP_SIZE + mopt.size); | ||
| 105 | opt->pkg_len = IP_SIZE + ICMP_SIZE + mopt.size; | ||
| 106 | return(RMOD_OK); | ||
| 107 | } | ||
| 108 | |||
| 109 | if (entry == MOD_RCV) | ||
| 110 | process_rcv(opt); | ||
| 111 | |||
| 112 | return(RMOD_OK); | ||
| 113 | } | ||
| 114 | |||
| 115 | |||
| 116 | /* | ||
| 117 | *********************************************************** | ||
| 118 | * Our OWN/static functions for THIS module * | ||
| 119 | *********************************************************** | ||
| 120 | */ | ||
| 121 | |||
| 122 | /* | ||
| 123 | * initialize all local variables. | ||
| 124 | * We use some 'unused' variables of the masterprogramm | ||
| 125 | */ | ||
| 126 | static void | ||
| 127 | init_vars(struct _opt *opt) | ||
| 128 | { | ||
| 129 | mopt.size = ICMP_ECHO; | ||
| 130 | mopt.size = 56; | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | /* | ||
| 135 | * LOCAL/STATIC function, only available in the module | ||
| 136 | * return 0 on success, != 0 on failure | ||
| 137 | */ | ||
| 138 | static int | ||
| 139 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 140 | { | ||
| 141 | extern char *optarg; | ||
| 142 | /*extern int optind, opterr, optopt;*/ | ||
| 143 | int c; | ||
| 144 | |||
| 145 | while ((c = getopt (argc, argv, "t:s:")) != -1) | ||
| 146 | { | ||
| 147 | switch (c) | ||
| 148 | { | ||
| 149 | case 't': | ||
| 150 | if (strcasecmp (optarg, "echo") == 0) | ||
| 151 | mopt.type = ICMP_ECHO; | ||
| 152 | else if (strcasecmp (optarg, "time") == 0) | ||
| 153 | mopt.type = ICMP_TSTAMP; | ||
| 154 | else | ||
| 155 | return (-1); | ||
| 156 | break; | ||
| 157 | case 's': | ||
| 158 | mopt.size = atoi(optarg); | ||
| 159 | break; | ||
| 160 | case ':': | ||
| 161 | fprintf(stderr, "missing parameter\n"); | ||
| 162 | return(-1); | ||
| 163 | default: | ||
| 164 | return(-1); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | return(0); | ||
| 168 | } | ||
| 169 | |||
| 170 | |||
| 171 | /* | ||
| 172 | * handle incoming icmp ECHO_REPLY packages | ||
| 173 | */ | ||
| 174 | static int | ||
| 175 | process_rcv(struct _opt *opt) | ||
| 176 | { | ||
| 177 | struct icmp *icmp; | ||
| 178 | struct timeval now; | ||
| 179 | double rrt; | ||
| 180 | |||
| 181 | if (ip->ip_p != IPPROTO_ICMP) | ||
| 182 | return(0); | ||
| 183 | |||
| 184 | if (plen < dlt_len + IP_SIZE + ip_options + sizeof(*icmp)) | ||
| 185 | return(0); /* invalid size */ | ||
| 186 | |||
| 187 | icmp = (struct icmp *) (align_buf + IP_SIZE + ip_options); | ||
| 188 | |||
| 189 | // if ((icmp->icmp_type != 0) || (icmp->icmp_code != 0)) | ||
| 190 | // return(0); | ||
| 191 | |||
| 192 | memcpy(&now, pts, sizeof(now)); | ||
| 193 | time_diff((struct timeval *)icmp->icmp_dun.id_data, &now); | ||
| 194 | rrt = now.tv_sec * 1000.0 + now.tv_usec / 1000.0; | ||
| 195 | |||
| 196 | printf("%d bytes from %s: icmp_seq=%u ttl=%d time=%.3f ms\n", | ||
| 197 | (int)(plen - dlt_len - IP_SIZE - ip_options), | ||
| 198 | int_ntoa(ip->ip_src.s_addr), icmp->icmp_hun.ih_idseq.icd_seq, | ||
| 199 | ip->ip_ttl, rrt); | ||
| 200 | |||
| 201 | return(0); | ||
| 202 | |||
| 203 | } | ||
| 204 | |||
| 205 | |||
diff --git a/other/b-scan/modules/mod_snmp.c b/other/b-scan/modules/mod_snmp.c new file mode 100644 index 0000000..db56455 --- /dev/null +++ b/other/b-scan/modules/mod_snmp.c | |||
| @@ -0,0 +1,899 @@ | |||
| 1 | /* | ||
| 2 | * SimpleNetworkManagementProtocol module for bscan. | ||
| 3 | * RFC 1157 | ||
| 4 | * <buggy/lame implementation> | ||
| 5 | * | ||
| 6 | * ###fixme todo: port to sparc | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <bscan/bscan.h> | ||
| 10 | #include <bscan/module.h> | ||
| 11 | #include <bscan/system.h> | ||
| 12 | #include <stdio.h> | ||
| 13 | |||
| 14 | |||
| 15 | #ifndef MOD_NAME | ||
| 16 | #define MOD_NAME "mod_snmp" | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #define SNMP_DFLT_REQOBJ "1.3.6.1.2.1.1" | ||
| 20 | |||
| 21 | #define MAX_VALSTRLEN 512 | ||
| 22 | |||
| 23 | #define MOPT_NOOBJ 0x01 | ||
| 24 | #define MOPT_STRIP 0x02 | ||
| 25 | |||
| 26 | #define SNMP_GET 0xa0 | ||
| 27 | #define SNMP_GET_NEXT 0xa1 | ||
| 28 | #define SNMP_SET 0xa3 | ||
| 29 | #define ASN_SUBCAT 0x30 /* BER encoding, sub-categorie */ | ||
| 30 | |||
| 31 | #ifndef ASN_INTEGER | ||
| 32 | #define ASN_INTEGER ((u_char)0x02) | ||
| 33 | #endif | ||
| 34 | #define ASN_INTEGERSTR "INTEGER" | ||
| 35 | #ifndef ASN_BIT_STR | ||
| 36 | #define ASN_BIT_STR ((u_char)0x03) | ||
| 37 | #endif | ||
| 38 | #define ASN_BIT_STRSTR "BITSTRING" | ||
| 39 | #ifndef ASN_OCTET_STR | ||
| 40 | #define ASN_OCTET_STR ((u_char)0x04) | ||
| 41 | #endif | ||
| 42 | #define ASN_OCTET_STRSTR "STRING" | ||
| 43 | #ifndef ASN_NULL | ||
| 44 | #define ASN_NULL ((u_char)0x05) | ||
| 45 | #endif | ||
| 46 | #define ASN_NULLSTR "NULL" | ||
| 47 | #ifndef ASN_OBJECT_ID | ||
| 48 | #define ASN_OBJECT_ID ((u_char)0x06) | ||
| 49 | #endif | ||
| 50 | #define ASN_OBJECT_IDSTR "OBJ" | ||
| 51 | #ifndef ASN_APPLICATION | ||
| 52 | #define ASN_APPLICATION ((u_char)0x40) | ||
| 53 | #endif | ||
| 54 | #ifndef ASN_LONG_LEN | ||
| 55 | #define ASN_LONG_LEN ((u_char)0x80) | ||
| 56 | #endif | ||
| 57 | #define ASN_APPLICATIONSTR "APPLICATION" | ||
| 58 | #ifndef ASN_IPADDRESS | ||
| 59 | #define ASN_IPADDRESS (ASN_APPLICATION | 0) | ||
| 60 | #endif | ||
| 61 | #define ASN_IPADDRESSSTR "IPADDR" | ||
| 62 | #ifndef ASN_UNSIGNED | ||
| 63 | #define ASN_UNSIGNED (ASN_APPLICATION | 2) | ||
| 64 | #endif | ||
| 65 | #define ASN_UNSIGNEDSTR ASN_INTEGERSTR | ||
| 66 | #ifndef ASN_TIMETICKS | ||
| 67 | #define ASN_TIMETICKS (ASN_APPLICATION | 3) | ||
| 68 | #endif | ||
| 69 | #define ASN_TIMETICKSSTR "TIMETICKS" | ||
| 70 | #ifndef ASN_COUNTER | ||
| 71 | #define ASN_COUNTER (ASN_APPLICATION | 1) | ||
| 72 | #endif | ||
| 73 | #define ASN_COUNTERSTR "COUNTER" | ||
| 74 | |||
| 75 | #define SNMP_ERR_WRONGTYPE (7) | ||
| 76 | #define SNMP_ERR_WRONGLENGTH (8) | ||
| 77 | #define SNMP_ERR_WRONGENCODING (9) | ||
| 78 | #define SNMP_ERR_WRONGVALUE (10) | ||
| 79 | #define SNMP_ERR_NOCREATION (11) | ||
| 80 | #define SNMP_ERR_INCONSISTENTVALUE (12) | ||
| 81 | #define SNMP_ERR_RESOURCEUNAVAILABLE (13) | ||
| 82 | #define SNMP_ERR_COMMITFAILED (14) | ||
| 83 | #define SNMP_ERR_UNDOFAILED (15) | ||
| 84 | #define SNMP_ERR_AUTHORIZATIONERROR (16) | ||
| 85 | #define SNMP_ERR_NOTWRITABLE (17) | ||
| 86 | |||
| 87 | char *snmp_error[] = { | ||
| 88 | "NO ERROR", | ||
| 89 | "TOO BIG", | ||
| 90 | "NO SUCH NAME", | ||
| 91 | "BAD VALUE", | ||
| 92 | "READONLY", | ||
| 93 | "GENERELL ERROR", | ||
| 94 | "NO ACCESS", | ||
| 95 | "WRONG TYPE", | ||
| 96 | "WRONG LENGTH", | ||
| 97 | "WRONG ENCODING", | ||
| 98 | "WRONG VALUE", | ||
| 99 | "NO CREATION", | ||
| 100 | "INCONSISTENT VALUE", | ||
| 101 | "RESOURCE UNAVAILABLE", | ||
| 102 | "COMMIT FAILED", | ||
| 103 | "UNDO FAILED", | ||
| 104 | "AUTORISATION ERROR", | ||
| 105 | "NOT WRITEABLE", | ||
| 106 | "INCONSISTENT NAME" }; | ||
| 107 | |||
| 108 | #define MAX_SNMP_ERR 18 | ||
| 109 | |||
| 110 | |||
| 111 | |||
| 112 | #define ADD_DATA(ptr, in, len, totlen) memcpy(ptr, in, len);\ | ||
| 113 | *totlen = *totlen + len; | ||
| 114 | |||
| 115 | #define min(a,b) ((a)<(b)?(a):(b)) | ||
| 116 | |||
| 117 | |||
| 118 | static int isinit=0; | ||
| 119 | /* | ||
| 120 | * some variables from the binary-process | ||
| 121 | */ | ||
| 122 | extern int dlt_len; | ||
| 123 | extern u_char *align_buf; | ||
| 124 | extern unsigned short ip_options; | ||
| 125 | extern struct ip *ip; | ||
| 126 | extern struct Ether_header *eth; | ||
| 127 | extern u_int plen, pcaplen; | ||
| 128 | extern struct timeval *pts; | ||
| 129 | |||
| 130 | struct _pdu | ||
| 131 | { | ||
| 132 | u_char *varbuf; | ||
| 133 | int varlen; | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct _mopt | ||
| 137 | { | ||
| 138 | char *community; | ||
| 139 | u_char flags; | ||
| 140 | u_char snmptor; /* type of request */ | ||
| 141 | struct _pdu pdu; | ||
| 142 | } static mopt; | ||
| 143 | |||
| 144 | struct _pdunfo | ||
| 145 | { | ||
| 146 | u_char *community; | ||
| 147 | u_char *pdu_type; | ||
| 148 | u_char *error_status; | ||
| 149 | u_char *error_idx; | ||
| 150 | } static pdunfo; | ||
| 151 | |||
| 152 | |||
| 153 | /* | ||
| 154 | * static functions prototypes | ||
| 155 | */ | ||
| 156 | static int mdo_opt(int, char **, struct _opt *); | ||
| 157 | static void init_vars(struct _opt *); | ||
| 158 | static int process_rcv(struct _opt *); | ||
| 159 | static int add_snmp (u_char *, int *); | ||
| 160 | static int add_snmpreq (u_char *, int *, u_char, u_char *, struct _pdu *); | ||
| 161 | static int add_snmp_var(struct _pdu *, u_char *); | ||
| 162 | static int build_snmp_objreq(u_char *, u_char *,u_char *, u_char, u_char *); | ||
| 163 | static int str2asnv(u_char *, u_char, u_char *, u_char *); | ||
| 164 | static int str2objid(u_char *, u_char *, u_char *); | ||
| 165 | |||
| 166 | |||
| 167 | /* | ||
| 168 | * print out usage informations | ||
| 169 | */ | ||
| 170 | void | ||
| 171 | musage() | ||
| 172 | { | ||
| 173 | printf ("\n"MOD_NAME"\n"); | ||
| 174 | printf ("snmp module\n"); | ||
| 175 | printf (" -p <port>, destination port, default 161\n"); | ||
| 176 | printf (" -o <port>, source port, default 53\n"); | ||
| 177 | printf (" -r <request[:type[:value]]>, default '1.3.6.1.2.1.1 (system)'\n"); | ||
| 178 | printf (" -c <community name>, default 'public'\n"); | ||
| 179 | printf (" -g <requesttype>, (get|getnext|set), default 'getnext'\n"); | ||
| 180 | printf (" -s strip unprintable characters from STRING types, and output as text\n"); | ||
| 181 | printf (" -q dont print out OBJ-types\n"); | ||
| 182 | printf ("\n"); | ||
| 183 | printf ("type: i: INTEGER, s: STRING, n: NULLOBJ, o: OBJID\n"); | ||
| 184 | printf (" t: TIMETICKS, a: IPADDRESS, b: BITSTRING, c: COUNTER\n"); | ||
| 185 | printf ("\n"); | ||
| 186 | printf ("you can request multiple objects with one request:\n"); | ||
| 187 | printf ("-g get -r 1.3.6.1.2.1.1.1.0 -r 1.3.6.1.2.1.1.4.0 -r 1.3.6.1.2.1.1.5.0\n"); | ||
| 188 | } | ||
| 189 | |||
| 190 | |||
| 191 | /* | ||
| 192 | * return 0 on success, != 0 on failure | ||
| 193 | */ | ||
| 194 | int | ||
| 195 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 196 | { | ||
| 197 | #ifdef DEBUG | ||
| 198 | printf("MODULE INIT\n"); | ||
| 199 | #endif | ||
| 200 | if (isinit) | ||
| 201 | return(-1); | ||
| 202 | |||
| 203 | *modname = MOD_NAME; | ||
| 204 | isinit = 1; | ||
| 205 | init_vars(opt); | ||
| 206 | |||
| 207 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 208 | return(-1); | ||
| 209 | |||
| 210 | return(0); | ||
| 211 | } | ||
| 212 | |||
| 213 | /* | ||
| 214 | * fini-routine. called on cleanup | ||
| 215 | */ | ||
| 216 | int | ||
| 217 | fini() | ||
| 218 | { | ||
| 219 | #ifdef DEBUG | ||
| 220 | printf("MODULE FINI\n"); | ||
| 221 | #endif | ||
| 222 | return(0); | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | /* | ||
| 227 | * Module entry point [entry] | ||
| 228 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 229 | * or do nothing [MOD_RCV]. | ||
| 230 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 231 | * RMOD_ERROR: failed to create packet. | ||
| 232 | * RMOD_ABRT: critical failure, abort! | ||
| 233 | */ | ||
| 234 | int | ||
| 235 | callmdl(int entry, struct _opt *opt) | ||
| 236 | { | ||
| 237 | #ifdef DEBUG | ||
| 238 | printf("MODULE CALLMDL\n"); | ||
| 239 | #endif | ||
| 240 | if (entry == MOD_FIRSTPKG) | ||
| 241 | { | ||
| 242 | add_snmp(opt->packet+ ETH_SIZE + IP_SIZE + UDP_SIZE, &opt->pkg_len); | ||
| 243 | add_udphdr (opt->packet+ ETH_SIZE+ IP_SIZE, &opt->nt, opt->pkg_len); | ||
| 244 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE); | ||
| 245 | opt->pkg_len += UDP_SIZE + IP_SIZE; | ||
| 246 | |||
| 247 | return(RMOD_OK); | ||
| 248 | } | ||
| 249 | |||
| 250 | if (entry == MOD_RCV) | ||
| 251 | process_rcv(opt); | ||
| 252 | |||
| 253 | return(RMOD_OK); | ||
| 254 | } | ||
| 255 | |||
| 256 | |||
| 257 | /* | ||
| 258 | *********************************************************** | ||
| 259 | * Our OWN/static functions for THIS module * | ||
| 260 | *********************************************************** | ||
| 261 | */ | ||
| 262 | |||
| 263 | /* | ||
| 264 | * initialize all local variables. | ||
| 265 | * We use some 'unused' variables of the masterprogramm | ||
| 266 | */ | ||
| 267 | static void | ||
| 268 | init_vars(struct _opt *opt) | ||
| 269 | { | ||
| 270 | opt->nt.sport = htons(32770); | ||
| 271 | opt->nt.dport = htons(161); | ||
| 272 | mopt.flags = 0; | ||
| 273 | mopt.community = "public"; | ||
| 274 | mopt.snmptor = SNMP_GET_NEXT; | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 278 | /* | ||
| 279 | * LOCAL/STATIC function, only available in the module | ||
| 280 | * return 0 on success, != 0 on failure | ||
| 281 | */ | ||
| 282 | static int | ||
| 283 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 284 | { | ||
| 285 | extern char *optarg; | ||
| 286 | /*extern int optind, opterr, optopt;*/ | ||
| 287 | int c; | ||
| 288 | |||
| 289 | while ((c = getopt (argc, argv, "qsg:c:r:p:o:")) != -1) | ||
| 290 | { | ||
| 291 | switch (c) | ||
| 292 | { | ||
| 293 | case 'q': | ||
| 294 | mopt.flags |= MOPT_NOOBJ; | ||
| 295 | break; | ||
| 296 | case 's': | ||
| 297 | mopt.flags |= MOPT_STRIP; | ||
| 298 | break; | ||
| 299 | case 'p': | ||
| 300 | opt->nt.dport = htons(atoi(optarg)); | ||
| 301 | break; | ||
| 302 | case 'o': | ||
| 303 | opt->nt.sport = htons(atoi(optarg)); | ||
| 304 | break; | ||
| 305 | case 'r': | ||
| 306 | add_snmp_var(&mopt.pdu, optarg); | ||
| 307 | break; | ||
| 308 | case 'c': | ||
| 309 | mopt.community = optarg; | ||
| 310 | break; | ||
| 311 | case 'g': | ||
| 312 | if (strcasecmp (optarg, "get") == 0) | ||
| 313 | mopt.snmptor = SNMP_GET; | ||
| 314 | else if (strcasecmp (optarg, "getnext") == 0) | ||
| 315 | mopt.snmptor = SNMP_GET_NEXT; | ||
| 316 | else if (strcasecmp (optarg, "set") == 0) | ||
| 317 | mopt.snmptor = SNMP_SET; | ||
| 318 | else | ||
| 319 | return (-1); | ||
| 320 | break; | ||
| 321 | case ':': | ||
| 322 | fprintf(stderr, "missing parameter\n"); | ||
| 323 | return(-1); | ||
| 324 | default: | ||
| 325 | return(-1); | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | if (mopt.pdu.varbuf == NULL) | ||
| 330 | add_snmp_var(&mopt.pdu, SNMP_DFLT_REQOBJ); | ||
| 331 | |||
| 332 | return(0); | ||
| 333 | } | ||
| 334 | |||
| 335 | |||
| 336 | static u_char | ||
| 337 | strtoasn_vtype(int src) | ||
| 338 | { | ||
| 339 | |||
| 340 | src = tolower(src); | ||
| 341 | |||
| 342 | switch (src) | ||
| 343 | { | ||
| 344 | case 'i': | ||
| 345 | return(ASN_INTEGER); | ||
| 346 | case 's': | ||
| 347 | return(ASN_OCTET_STR); | ||
| 348 | case 'n': | ||
| 349 | return(ASN_NULL); | ||
| 350 | case 'o': | ||
| 351 | return(ASN_OBJECT_ID); | ||
| 352 | case 't': | ||
| 353 | return(ASN_TIMETICKS); | ||
| 354 | case 'b': | ||
| 355 | return(ASN_BIT_STR); | ||
| 356 | case 'a': | ||
| 357 | return(ASN_IPADDRESS); | ||
| 358 | case 'u': | ||
| 359 | return(ASN_UNSIGNED); | ||
| 360 | case 'c': | ||
| 361 | return(ASN_COUNTER); | ||
| 362 | default: | ||
| 363 | fprintf(stderr, "WARNING: unsupported value-type.\n"); | ||
| 364 | return(src); | ||
| 365 | } | ||
| 366 | |||
| 367 | return(ASN_NULL); | ||
| 368 | } | ||
| 369 | |||
| 370 | /* | ||
| 371 | * add variable to our variable-queue | ||
| 372 | * input: <objid-dodded notation>:<value type>:<value>-format | ||
| 373 | * return 0 on success, !=0 on parse error etc | ||
| 374 | */ | ||
| 375 | static int | ||
| 376 | add_snmp_var(struct _pdu *pdu, u_char *src) | ||
| 377 | { | ||
| 378 | u_char *request; | ||
| 379 | u_char vtype = 5; | ||
| 380 | u_char *value = NULL; | ||
| 381 | u_char *ptr = NULL; | ||
| 382 | u_char reqlen=0; | ||
| 383 | |||
| 384 | if (pdu->varbuf == NULL) | ||
| 385 | { | ||
| 386 | pdu->varbuf = calloc(1, 1024); | ||
| 387 | pdu->varlen = 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | request = src; | ||
| 391 | |||
| 392 | if ( (ptr = strchr(src, ':')) != NULL) | ||
| 393 | *ptr++ = '\0'; | ||
| 394 | |||
| 395 | src = ptr; | ||
| 396 | if (ptr != NULL) | ||
| 397 | { | ||
| 398 | if ( (ptr = strchr(src, ':')) != NULL) | ||
| 399 | { | ||
| 400 | *ptr++ = '\0'; | ||
| 401 | if (strlen(ptr) > 0) | ||
| 402 | value = ptr; | ||
| 403 | } | ||
| 404 | vtype = strtoasn_vtype(*src); | ||
| 405 | } | ||
| 406 | |||
| 407 | if (build_snmp_objreq(pdu->varbuf + pdu->varlen, &reqlen, request, vtype, value) != 0) | ||
| 408 | { | ||
| 409 | fprintf(stderr, "WARNING: error while parsing reqOBJ\n"); | ||
| 410 | return(-1); | ||
| 411 | } | ||
| 412 | |||
| 413 | pdu->varlen += reqlen; | ||
| 414 | |||
| 415 | return(0); | ||
| 416 | } | ||
| 417 | |||
| 418 | /* | ||
| 419 | * convert OBJ-ID and build the snmp-request packet | ||
| 420 | * save the work and reuse [better performance, the snmp | ||
| 421 | * packet is always the same]. | ||
| 422 | * return 0 on success | ||
| 423 | */ | ||
| 424 | static int | ||
| 425 | add_snmp(u_char *ptr, int *lenptr) | ||
| 426 | { | ||
| 427 | static u_char *buf = NULL; | ||
| 428 | static int buflen; | ||
| 429 | |||
| 430 | if (buf != NULL) /* fastmode, use old copy of previous build snmppkg */ | ||
| 431 | { | ||
| 432 | *lenptr = buflen; | ||
| 433 | memcpy(ptr, buf, buflen); | ||
| 434 | return(0); | ||
| 435 | } | ||
| 436 | |||
| 437 | if (buf == NULL) | ||
| 438 | buf = malloc(1024); | ||
| 439 | |||
| 440 | add_snmpreq (ptr, lenptr, mopt.snmptor, mopt.community, &mopt.pdu); | ||
| 441 | |||
| 442 | memcpy(buf, ptr, *lenptr); /* for later reuse */ | ||
| 443 | buflen = *lenptr; | ||
| 444 | |||
| 445 | return(0); | ||
| 446 | } | ||
| 447 | |||
| 448 | /* | ||
| 449 | * convert snmp obj in dotted-notation, 0-terminated string to obj-id in asn.1 | ||
| 450 | */ | ||
| 451 | static int | ||
| 452 | str2objid(u_char *dst, u_char *retlen, u_char *src) | ||
| 453 | { | ||
| 454 | u_char *dotptr; | ||
| 455 | u_char len; | ||
| 456 | |||
| 457 | if (strncmp(src, "1.3.6.1.", 8) != 0) | ||
| 458 | return(-1); /* snmp only , iso.org.dot.internet.* */ | ||
| 459 | |||
| 460 | src += 8; /* we know the first 8 bytes. */ | ||
| 461 | |||
| 462 | memcpy(dst, "\x2b\x06\x01", 3); /* yepp, we know this. "1.3.6.1" */ | ||
| 463 | dst += 3; | ||
| 464 | dotptr = src; | ||
| 465 | len = 3; /* 2b-06-01 */ | ||
| 466 | while ( (dotptr = strchr (src, '.')) != NULL) | ||
| 467 | { | ||
| 468 | *dotptr = '\0'; | ||
| 469 | *dst++ = (u_char)atoi(src); | ||
| 470 | src = ++dotptr; | ||
| 471 | len++; | ||
| 472 | } | ||
| 473 | if (strlen(src) > 0) | ||
| 474 | { | ||
| 475 | *dst++ = (u_char)atoi(src); | ||
| 476 | len++; | ||
| 477 | } | ||
| 478 | |||
| 479 | *retlen = len; | ||
| 480 | return(0); | ||
| 481 | } | ||
| 482 | |||
| 483 | |||
| 484 | /* | ||
| 485 | * convert input to ASN.1 BER encodet <obj-id><value> | ||
| 486 | * dst: guess what. | ||
| 487 | * ptr: snmp obj in dotted-notation (1.3.6.1.2.1.1....), 0-terminated string | ||
| 488 | * tov: type of value, ASN.1 encodet (int, 8octet string, ...) | ||
| 489 | * value: the value (string, 0-terminated) | ||
| 490 | * return: 0 on success | ||
| 491 | */ | ||
| 492 | static int | ||
| 493 | build_snmp_objreq(u_char *dst, u_char *retlen, u_char *src, u_char tov, | ||
| 494 | u_char *value) | ||
| 495 | { | ||
| 496 | u_char *srcw; | ||
| 497 | u_char vlen = 0; | ||
| 498 | u_char *sublen; | ||
| 499 | u_char *subsublen; | ||
| 500 | u_char *subvlen; | ||
| 501 | u_char len; | ||
| 502 | |||
| 503 | srcw = alloca(strlen(src)+1); | ||
| 504 | memcpy(srcw, src, strlen(src)+1); | ||
| 505 | if (strlen(srcw) <= 4) | ||
| 506 | return(-1); | ||
| 507 | |||
| 508 | *dst++ = ASN_SUBCAT; | ||
| 509 | sublen = dst++; /* we set the length later coz we dont know it yet */ | ||
| 510 | |||
| 511 | *dst++ = 0x06; /* OBJ-ID */ | ||
| 512 | subsublen = dst++; /* and this also not */ | ||
| 513 | |||
| 514 | if (str2objid(dst, &len, srcw) != 0) | ||
| 515 | return(-1); | ||
| 516 | |||
| 517 | *subsublen = len; /* length of obj */ | ||
| 518 | dst += len; | ||
| 519 | |||
| 520 | *dst++ = tov; /* type of value */ | ||
| 521 | subvlen = dst++; /* we set this later..we dont know the length yet */ | ||
| 522 | str2asnv(value, tov, dst, &vlen); | ||
| 523 | |||
| 524 | *subvlen = vlen; /* length of value */ | ||
| 525 | |||
| 526 | *sublen = len + vlen + 4; /* length of <obj-id><tov:value> */ | ||
| 527 | |||
| 528 | *retlen = len + vlen + 6; | ||
| 529 | return(0); | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | /* | ||
| 534 | * convert 0-terminated string value to asn encodet value | ||
| 535 | * return 0 on success | ||
| 536 | * on return the length of rvalue < value. | ||
| 537 | * input: value [0 terminated string] | ||
| 538 | * tov [asn]-type of value | ||
| 539 | * output: rvalue [non 0-terminated string with asn-value] | ||
| 540 | * vlen [length of rvalue] | ||
| 541 | * return 0 on success | ||
| 542 | * attention: we use full integers (length=4, not reduced in length | ||
| 543 | * to the minimum size). the snmp-lib reduces the length of an | ||
| 544 | * integer to the minimum size...but this is not a must | ||
| 545 | */ | ||
| 546 | static int | ||
| 547 | str2asnv(u_char *value, u_char tov, u_char *rvalue, u_char *vlen) | ||
| 548 | { | ||
| 549 | unsigned long int ltmp; | ||
| 550 | |||
| 551 | if (rvalue == NULL) | ||
| 552 | return(0); /* yes, NULL is allowed */ | ||
| 553 | if ((rvalue != NULL) && (vlen == NULL)) | ||
| 554 | return(-1); | ||
| 555 | |||
| 556 | switch(tov) | ||
| 557 | { | ||
| 558 | case ASN_INTEGER: | ||
| 559 | ltmp = htonl(strtol(value, NULL, 10)); | ||
| 560 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 561 | *vlen = sizeof(ltmp); | ||
| 562 | break; | ||
| 563 | case ASN_UNSIGNED: | ||
| 564 | case ASN_COUNTER: | ||
| 565 | case ASN_TIMETICKS: | ||
| 566 | ltmp = htonl(strtoul(value, NULL, 10)); | ||
| 567 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 568 | *vlen = (sizeof(ltmp)); | ||
| 569 | break; | ||
| 570 | case ASN_IPADDRESS: | ||
| 571 | ltmp = inet_addr(value); | ||
| 572 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 573 | *vlen = sizeof(ltmp); | ||
| 574 | break; | ||
| 575 | case ASN_OBJECT_ID: | ||
| 576 | str2objid(rvalue, vlen, value); | ||
| 577 | break; | ||
| 578 | case ASN_OCTET_STR: | ||
| 579 | memcpy(rvalue, value, strlen(value)); | ||
| 580 | *vlen = strlen(value); | ||
| 581 | break; | ||
| 582 | case ASN_NULL: | ||
| 583 | *vlen = 0; | ||
| 584 | break; | ||
| 585 | default: | ||
| 586 | *vlen = 0; | ||
| 587 | fprintf(stderr, "WARNING, unsupported value type !\n"); | ||
| 588 | } | ||
| 589 | |||
| 590 | return(0); | ||
| 591 | } | ||
| 592 | |||
| 593 | /* | ||
| 594 | * add snmp request | ||
| 595 | * build the entire SNMP packet [version, community, pdu, id, error, idx, ..] | ||
| 596 | * req: objs + values [BER encodet, already with header and \x30 sub start] | ||
| 597 | * reqlen: len of entire req [objs + values] | ||
| 598 | * tor: type of request [get, getnext, set] | ||
| 599 | */ | ||
| 600 | static int | ||
| 601 | add_snmpreq (u_char *pkt, int *len, u_char tor, u_char *community, struct _pdu *pdu) | ||
| 602 | { | ||
| 603 | int le = 0; | ||
| 604 | |||
| 605 | *(pkt + le++) = ASN_SUBCAT; | ||
| 606 | *(pkt + le++) = (u_char)(pdu->varlen + strlen(community) + 18); | ||
| 607 | ADD_DATA(pkt + le, "\x02\x01\x00\x04" , 4, &le); /* SNMPv1 + STRINGOBJ*/ | ||
| 608 | *(pkt + le++) = (u_char)strlen(community); | ||
| 609 | ADD_DATA(pkt + le, community, strlen(community), &le); | ||
| 610 | *(pkt + le++) = tor; /* PDU GET-NEXTrequest */ | ||
| 611 | /* lenof(<req-id> + <err-state> + <err-idx> + <SUB> <obj+values>) */ | ||
| 612 | *(pkt + le++) = (u_char)(pdu->varlen + 11); | ||
| 613 | /* <req-id> + <err-state> + <err-idx> <SUB-OBJ> */ | ||
| 614 | ADD_DATA(pkt + le, "\x02\x01\x01\x02\x01\00\x02\x01\x00\x30", 10, &le); | ||
| 615 | *(pkt + le++) = (u_char)(pdu->varlen); | ||
| 616 | ADD_DATA(pkt + le, pdu->varbuf, pdu->varlen, &le); | ||
| 617 | |||
| 618 | *len = le; | ||
| 619 | return(0); | ||
| 620 | } | ||
| 621 | |||
| 622 | |||
| 623 | /* | ||
| 624 | * convert asn encoded obj to string | ||
| 625 | * input: string of <type of value><length of value><value> | ||
| 626 | * datalen: max len i'm allowed to read from "ptr --> ..." | ||
| 627 | * return: | ||
| 628 | * prefix is the string representation of the value-type e.g. "OCTET-STRING".. | ||
| 629 | * and '<trunc>' if value got truncated. | ||
| 630 | * is < 64 chars... | ||
| 631 | * val: the value (0-terminated string) | ||
| 632 | * return 0 on success | ||
| 633 | * 1 if truncated (value-length > size of snmp or val to small) | ||
| 634 | * -1 on error | ||
| 635 | */ | ||
| 636 | static int | ||
| 637 | asn2str(u_char *ptr, u_char *prefix, u_char *val, unsigned int datalen) | ||
| 638 | { | ||
| 639 | unsigned long int len, day, hour, min, sec, msec; | ||
| 640 | u_char *ptr2; | ||
| 641 | u_char vlen = *(ptr+1); /* saved value length */ | ||
| 642 | u_char tov = *ptr; | ||
| 643 | unsigned long int ltmp; | ||
| 644 | int i, slen = 0; | ||
| 645 | u_char buf[128]; | ||
| 646 | |||
| 647 | if (vlen > datalen-2) | ||
| 648 | len = datalen-2; | ||
| 649 | else | ||
| 650 | len = vlen; | ||
| 651 | |||
| 652 | *val = '\0'; | ||
| 653 | *prefix = '\0'; | ||
| 654 | |||
| 655 | switch(tov) | ||
| 656 | { | ||
| 657 | case ASN_IPADDRESS: | ||
| 658 | if (len > sizeof(ltmp)) | ||
| 659 | len = sizeof(ltmp); | ||
| 660 | |||
| 661 | ptr2 = (u_char *)<mp; | ||
| 662 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 663 | sprintf(val, "%s", int_ntoa(ltmp)); | ||
| 664 | strcpy(prefix, ASN_IPADDRESSSTR); | ||
| 665 | break; | ||
| 666 | case ASN_NULL: | ||
| 667 | strcpy(prefix, ASN_NULLSTR); | ||
| 668 | break; | ||
| 669 | case ASN_TIMETICKS: | ||
| 670 | if (len > sizeof(ltmp)) | ||
| 671 | len = sizeof(ltmp); | ||
| 672 | |||
| 673 | ltmp = 0; | ||
| 674 | ptr2 = (u_char *)<mp; | ||
| 675 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 676 | ltmp = ntohl(ltmp); | ||
| 677 | day = ltmp / 8640000; | ||
| 678 | hour = (ltmp % 8640000) / 360000; | ||
| 679 | min = (ltmp % 360000) / 6000; | ||
| 680 | sec = (ltmp % 6000) / 100; | ||
| 681 | msec = (ltmp % 100); | ||
| 682 | sprintf(val, "(%lu) %d days, %2.2d:%2.2d:%2.2d.%d", ltmp, | ||
| 683 | (int)day, (int)hour, (int)min, (int)sec, (int)msec); | ||
| 684 | if (tov == ASN_TIMETICKS) | ||
| 685 | strcpy(prefix, ASN_TIMETICKSSTR); | ||
| 686 | break; | ||
| 687 | case ASN_INTEGER: | ||
| 688 | case ASN_UNSIGNED: | ||
| 689 | case ASN_COUNTER: | ||
| 690 | ltmp = 0; | ||
| 691 | if (len > sizeof(ltmp)) | ||
| 692 | len = sizeof(ltmp); | ||
| 693 | |||
| 694 | ptr2 = (u_char *)<mp; | ||
| 695 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 696 | |||
| 697 | if (tov == ASN_INTEGER) | ||
| 698 | sprintf(val, "%lu", (unsigned long int)ntohl(ltmp)); | ||
| 699 | else | ||
| 700 | sprintf(val, "%ld", (long int)ntohl(ltmp)); | ||
| 701 | |||
| 702 | if (tov == ASN_INTEGER) | ||
| 703 | strcpy(prefix, ASN_INTEGERSTR); | ||
| 704 | if (tov == ASN_UNSIGNED) | ||
| 705 | strcpy(prefix, ASN_UNSIGNEDSTR); | ||
| 706 | if (tov == ASN_COUNTER) | ||
| 707 | strcpy(prefix, ASN_COUNTERSTR); | ||
| 708 | break; | ||
| 709 | case ASN_OCTET_STR: | ||
| 710 | if (isprintdata(ptr+2, len)) | ||
| 711 | { | ||
| 712 | if (len > MAX_VALSTRLEN-1) | ||
| 713 | len = MAX_VALSTRLEN-1; | ||
| 714 | memcpy(val, ptr+2, len); | ||
| 715 | val[len] = '\0'; | ||
| 716 | } else if ((mopt.flags & MOPT_STRIP) == MOPT_STRIP) { | ||
| 717 | dat2strip(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 718 | } else { | ||
| 719 | dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 720 | } | ||
| 721 | |||
| 722 | strcpy(prefix, ASN_OCTET_STRSTR); | ||
| 723 | break; | ||
| 724 | case ASN_OBJECT_ID: | ||
| 725 | i = 0; | ||
| 726 | slen = 0; | ||
| 727 | while(i < len) | ||
| 728 | { | ||
| 729 | if (*(ptr+2+i) == 0x2b) | ||
| 730 | strcpy(buf, "1.3."); /* substituate shorts */ | ||
| 731 | else | ||
| 732 | snprintf(buf, sizeof(buf), "%d.", *(ptr+2+i)); | ||
| 733 | |||
| 734 | buf[sizeof(buf)-1] = '\0'; | ||
| 735 | slen = strlen(val) + strlen(buf); | ||
| 736 | |||
| 737 | if (slen < MAX_VALSTRLEN -1) | ||
| 738 | strcat(val, buf); | ||
| 739 | else | ||
| 740 | break; | ||
| 741 | |||
| 742 | i++; | ||
| 743 | } | ||
| 744 | val[slen-1] = '\0'; /* remove last '.' */ | ||
| 745 | strcpy(prefix, ASN_OBJECT_IDSTR); | ||
| 746 | break; | ||
| 747 | default: | ||
| 748 | dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 749 | break; | ||
| 750 | } | ||
| 751 | |||
| 752 | if (*prefix == '\0') | ||
| 753 | strcpy(prefix, "UNKNOWN"); | ||
| 754 | |||
| 755 | if (vlen > len) | ||
| 756 | { | ||
| 757 | strcat(prefix, "<trunc>"); | ||
| 758 | return(1); | ||
| 759 | } | ||
| 760 | |||
| 761 | return(0); | ||
| 762 | } | ||
| 763 | |||
| 764 | /* | ||
| 765 | * return TypeOfValue and let next point to the next asn encodet obj | ||
| 766 | * ptr: pointer to asn.1 encodet obj | ||
| 767 | * len: returns the length of the OLD value + suffix [length we skipped] | ||
| 768 | * next: returns a pointer to the next obj. | ||
| 769 | */ | ||
| 770 | static u_char | ||
| 771 | asn_getnext(u_char *ptr, u_char *len, u_char **next) | ||
| 772 | { | ||
| 773 | u_char vlen = *(ptr+1); | ||
| 774 | |||
| 775 | if (*ptr == ASN_SUBCAT) | ||
| 776 | { | ||
| 777 | if (vlen & ASN_LONG_LEN) | ||
| 778 | vlen = vlen & ~ASN_LONG_LEN; | ||
| 779 | else | ||
| 780 | vlen = 0; | ||
| 781 | } | ||
| 782 | |||
| 783 | *next = ptr + vlen + 2; | ||
| 784 | |||
| 785 | *len = vlen + 2; | ||
| 786 | return(**next); | ||
| 787 | } | ||
| 788 | |||
| 789 | #define RETURN_ILLLEN(x,y,r) if (x >= y) return(r); | ||
| 790 | |||
| 791 | /* | ||
| 792 | * handle incoming snmp answers, answer with 'next' if not last record | ||
| 793 | */ | ||
| 794 | static int | ||
| 795 | process_rcv(struct _opt *opt) | ||
| 796 | { | ||
| 797 | struct udphdr *udp; | ||
| 798 | u_char *ptr; | ||
| 799 | int len; | ||
| 800 | int snmplen; | ||
| 801 | uint iphdr_len = 0; | ||
| 802 | u_char objlen; | ||
| 803 | u_char buf[MAX_VALSTRLEN]; | ||
| 804 | u_char prefix[32]; | ||
| 805 | u_char buf2[MAX_VALSTRLEN + 32]; | ||
| 806 | u_char asnprefix[128]; | ||
| 807 | u_char c; | ||
| 808 | |||
| 809 | if (ip->ip_p != IPPROTO_UDP) | ||
| 810 | return(0); | ||
| 811 | |||
| 812 | iphdr_len = IP_SIZE + ip_options; | ||
| 813 | if (plen < dlt_len + iphdr_len + sizeof(*udp)) | ||
| 814 | return(-1); /* invalid size */ | ||
| 815 | |||
| 816 | udp = (struct udphdr *) (align_buf + iphdr_len); | ||
| 817 | ptr = (u_char *) (align_buf + iphdr_len + sizeof(*udp)); | ||
| 818 | snmplen = plen - dlt_len - iphdr_len - sizeof(*udp); | ||
| 819 | len = 0; | ||
| 820 | |||
| 821 | /* | ||
| 822 | * we dont check the value of the ASN_SUBCAT-length coz many buggy | ||
| 823 | * hosts out there return a wrong length [0xff, 0x80, ...] | ||
| 824 | */ | ||
| 825 | |||
| 826 | ptr += 2; len += 3; /* pointing on the 3rd element */ | ||
| 827 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 828 | |||
| 829 | asn_getnext(ptr, &objlen, &ptr); /* skip version, get community */ | ||
| 830 | len += objlen; | ||
| 831 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 832 | pdunfo.community = ptr; | ||
| 833 | |||
| 834 | asn_getnext(ptr, &objlen, &ptr); /* skip community, get pdu */ | ||
| 835 | len += objlen; | ||
| 836 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 837 | pdunfo.pdu_type = ptr; | ||
| 838 | ptr += 2; | ||
| 839 | len += 2; /* skip pdu, get reqid */ | ||
| 840 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 841 | |||
| 842 | asn_getnext(ptr, &objlen, &ptr); /* skip reqid, get errorstatus */ | ||
| 843 | len += objlen; | ||
| 844 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 845 | pdunfo.error_status = ptr; | ||
| 846 | |||
| 847 | asn_getnext(ptr, &objlen, &ptr); /* skip errorstatus, get erroridx */ | ||
| 848 | len += objlen; | ||
| 849 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 850 | pdunfo.error_idx = ptr; | ||
| 851 | |||
| 852 | asn_getnext(ptr, &objlen, &ptr); /* skip erroridx, get */ | ||
| 853 | len += objlen; | ||
| 854 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 855 | |||
| 856 | asn_getnext(ptr, &objlen, &ptr); /* we reached the SUB section */ | ||
| 857 | len += objlen; | ||
| 858 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 859 | |||
| 860 | snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), | ||
| 861 | ntohs(udp->uh_sport)); | ||
| 862 | |||
| 863 | c = *(pdunfo.error_status+2); | ||
| 864 | if (c != 0) | ||
| 865 | { | ||
| 866 | if (c < MAX_SNMP_ERR) | ||
| 867 | { | ||
| 868 | printf("%s%s (%d)\n", prefix, snmp_error[c], | ||
| 869 | *(pdunfo.error_idx+2)); | ||
| 870 | } else { | ||
| 871 | printf("%s UNKNOWN ERROR\n", prefix); | ||
| 872 | } | ||
| 873 | } | ||
| 874 | |||
| 875 | while (1) | ||
| 876 | { | ||
| 877 | asn_getnext(ptr, &objlen, &ptr); | ||
| 878 | if (objlen == 0) | ||
| 879 | return(0); | ||
| 880 | |||
| 881 | len += objlen; | ||
| 882 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 883 | if (*ptr == ASN_SUBCAT) | ||
| 884 | continue; | ||
| 885 | |||
| 886 | if ((mopt.flags & MOPT_NOOBJ) && (*ptr == ASN_OBJECT_ID)) | ||
| 887 | continue; | ||
| 888 | |||
| 889 | asn2str(ptr, asnprefix, buf, snmplen - len + 1); | ||
| 890 | snprintf(buf2, sizeof(buf2)-1, "%s %s", asnprefix, buf); | ||
| 891 | buf2[sizeof(buf2)-1] = '\0'; | ||
| 892 | save_write(stdout, prefix, buf2, strlen(buf2)); | ||
| 893 | } | ||
| 894 | |||
| 895 | return(0); | ||
| 896 | |||
| 897 | } | ||
| 898 | |||
| 899 | |||
diff --git a/other/b-scan/src/Makefile b/other/b-scan/src/Makefile new file mode 100644 index 0000000..f1688a1 --- /dev/null +++ b/other/b-scan/src/Makefile | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | # | ||
| 2 | # Makefile of (m)bscan v0.0, skyper | ||
| 3 | # Massiv Banner Scanner | ||
| 4 | # | ||
| 5 | |||
| 6 | CC=gcc | ||
| 7 | COPT=-Wall -ggdb -I../include -I/usr/include/pcap | ||
| 8 | LEX=flex | ||
| 9 | LEXOPT= | ||
| 10 | OBJS=bscan.o arpg.o snarf.o network_raw.o restore.o | ||
| 11 | OBJS2=tty.o system.o signal.o dcd_icmp.o garage.o cf_prse.o module.o | ||
| 12 | SUPOBJ=../support/hpuxdl.o ../support/snprintf.o | ||
| 13 | TARGET=bscan | ||
| 14 | INDENT=indent | ||
| 15 | INDENT_OPT=-bap -nbc -bbo -bl -bli0 -bls -ncdb -nce -cp1 -cs -di2 -ndj -nfc1 -nfca -hnl -i4 -ip5 -lp -psl -nsc -nsob | ||
| 16 | |||
| 17 | # LINUX | ||
| 18 | ####### | ||
| 19 | LOPT=-export-dynamic | ||
| 20 | DEFS=`libnet-config --defines` -DHAVE_DLSYM -D_SVID_SOURCE #-DDEBUG | ||
| 21 | LIBS=-lpcap -ldl -lm `libnet-config --libs` -lpthread | ||
| 22 | |||
| 23 | # SunOS 5.7/5.8 + gcc | ||
| 24 | ##################### | ||
| 25 | #LOPT=-export-dynamic | ||
| 26 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 27 | #LIBS=-lpcap -ldl -lm `libnet-config --libs` -lpthread | ||
| 28 | |||
| 29 | # HP-UX 11.00 | ||
| 30 | ############# | ||
| 31 | #LOPT=-Xlinker -E | ||
| 32 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 33 | #LIBS=-lpcap -ldld -lm `libnet-config --libs` -lpthread | ||
| 34 | |||
| 35 | # HP-UX 10.20 | ||
| 36 | # HP-UX 10.20 is not supported. You need snprintf.c and | ||
| 37 | # some hacks to use IP_HDRINCL and the kernel patches | ||
| 38 | # to access the link_layer interface. | ||
| 39 | ############# | ||
| 40 | #LOPT=-Xlinker -E | ||
| 41 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM -DHP10 #-DDEBUG | ||
| 42 | #LIBS=-lpcap -ldld -lm `libnet-config --libs` -lpthread | ||
| 43 | |||
| 44 | # OpenBSD | ||
| 45 | ######### | ||
| 46 | #LOPT= | ||
| 47 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 48 | #LIBS=-lpcap -lm `libnet-config --libs` -lpthread | ||
| 49 | |||
| 50 | all: $(SUPOBJ) $(OBJS2) $(OBJS) | ||
| 51 | $(CC) $(SUPOBJ) $(OBJS) $(OBJS2) $(LOPT) $(LIBS) -o $(TARGET) | ||
| 52 | |||
| 53 | cf_prse.o: | ||
| 54 | $(LEX) $(LEXOPT) -ocf_prse.c cf_prse.l | ||
| 55 | $(CC) $(COPT) -c cf_prse.c | ||
| 56 | |||
| 57 | dcd_icmp.o: dcd_icmp.c | ||
| 58 | $(CC) $(COPT) -c dcd_icmp.c | ||
| 59 | |||
| 60 | garage.o: garage.c | ||
| 61 | $(CC) $(COPT) -c garage.c | ||
| 62 | |||
| 63 | module.o: module.c | ||
| 64 | $(CC) $(COPT) $(DEFS) -c module.c | ||
| 65 | |||
| 66 | system.o: system.c | ||
| 67 | $(CC) $(COPT) -c system.c | ||
| 68 | |||
| 69 | tty.o: tty.c | ||
| 70 | $(CC) $(COPT) -c tty.c | ||
| 71 | |||
| 72 | signal.o: signal.c | ||
| 73 | $(CC) $(COPT) -c signal.c | ||
| 74 | |||
| 75 | ../support/hpuxdl.o: ../support/hpuxdl.c | ||
| 76 | $(MAKE) -C ../support | ||
| 77 | |||
| 78 | ../support/snprintf.o: ../support/snprintf.c | ||
| 79 | $(MAKE) -C ../support | ||
| 80 | |||
| 81 | .c.o: | ||
| 82 | $(CC) $(COPT) $(DEFS) -c $< | ||
| 83 | |||
| 84 | clean: | ||
| 85 | rm -f $(OBJS) $(OBJS2) $(TARGET) cf_prse.c core *~ | ||
| 86 | |||
| 87 | indent: | ||
| 88 | $(INDENT) $(INDENT_OPT) *.c *.h | ||
diff --git a/other/b-scan/src/arpg.c b/other/b-scan/src/arpg.c new file mode 100644 index 0000000..0c8a620 --- /dev/null +++ b/other/b-scan/src/arpg.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * bscan arp routine | ||
| 3 | */ | ||
| 4 | #include <bscan/arpg.h> | ||
| 5 | #include <bscan/snarf.h> | ||
| 6 | #include <libnet.h> | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | void | ||
| 11 | prepare_libnet (struct _libnet *lnet) | ||
| 12 | { | ||
| 13 | |||
| 14 | if (lnet->device == NULL) | ||
| 15 | { | ||
| 16 | struct sockaddr_in sin; | ||
| 17 | if (libnet_select_device (&sin, &lnet->device, lnet->err_buf) == -1) | ||
| 18 | libnet_error (LIBNET_ERR_FATAL, | ||
| 19 | "libnet_select_device failed: %s\n", lnet->err_buf); | ||
| 20 | } | ||
| 21 | |||
| 22 | if ( | ||
| 23 | (lnet->network = | ||
| 24 | libnet_open_link_interface (lnet->device, lnet->err_buf)) == NULL) | ||
| 25 | libnet_error (LIBNET_ERR_FATAL, | ||
| 26 | "libnet_open_link_interface '%s': %s\n", lnet->device, | ||
| 27 | lnet->err_buf); | ||
| 28 | |||
| 29 | |||
| 30 | lnet->packet_size = 60; /* min ethernet frame length -4 CRC */ | ||
| 31 | if (libnet_init_packet (lnet->packet_size, &lnet->packet) == -1) | ||
| 32 | libnet_error (LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); | ||
| 33 | |||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * play arp-god: sends out arp-reply | ||
| 38 | * return: same as libnet_write_link_layer | ||
| 39 | * -1 on failure or bytes written | ||
| 40 | */ | ||
| 41 | int | ||
| 42 | play_arpg (struct _libnet *lnet, u_char spf_sip[4], u_char spf_smac[6], | ||
| 43 | u_char spf_dip[4], u_char spf_dmac[6]) | ||
| 44 | { | ||
| 45 | int c; | ||
| 46 | |||
| 47 | #ifdef DEBUG | ||
| 48 | printf ("sending out arp\n"); | ||
| 49 | #endif | ||
| 50 | libnet_build_ethernet (spf_dmac, | ||
| 51 | spf_smac, ETHERTYPE_ARP, NULL, 0, lnet->packet); | ||
| 52 | |||
| 53 | libnet_build_arp (ARPHRD_ETHER, ETHERTYPE_IP, /* arp for which protocol ? */ | ||
| 54 | 6, /* hardware addr. length */ | ||
| 55 | 4, /* protocol addr. length */ | ||
| 56 | ARPOP_REPLY, spf_smac, spf_sip, spf_dmac, spf_dip, NULL, /* packet payload */ | ||
| 57 | 0, /* length of payload */ | ||
| 58 | lnet->packet + LIBNET_ETH_H); | ||
| 59 | |||
| 60 | c = | ||
| 61 | libnet_write_link_layer (lnet->network, lnet->device, lnet->packet, | ||
| 62 | lnet->packet_size); | ||
| 63 | if (c < lnet->packet_size) | ||
| 64 | { | ||
| 65 | libnet_error (LN_ERR_WARNING, | ||
| 66 | "libnet_write_link_layer only wrote %d bytes\n", c); | ||
| 67 | } | ||
| 68 | #ifdef DEBUG | ||
| 69 | else | ||
| 70 | { | ||
| 71 | printf ("construction and injection completed, wrote all %d bytes\n", | ||
| 72 | c); | ||
| 73 | } | ||
| 74 | #endif | ||
| 75 | |||
| 76 | return (c); | ||
| 77 | } | ||
| 78 | |||
diff --git a/other/b-scan/src/bscan.c b/other/b-scan/src/bscan.c new file mode 100644 index 0000000..ed49d1b --- /dev/null +++ b/other/b-scan/src/bscan.c | |||
| @@ -0,0 +1,851 @@ | |||
| 1 | /* | ||
| 2 | * This is unpublished proprietary source code. | ||
| 3 | * | ||
| 4 | * The contents of these coded instructions, statements and computer | ||
| 5 | * programs may not be disclosed to third parties, copied or duplicated in | ||
| 6 | * any form, in whole or in part, without the prior written permission of | ||
| 7 | * the author. | ||
| 8 | * (that includes you hack.co.za and other lame kid sites who dont | ||
| 9 | * get the point what hacking is about. damn kids.) | ||
| 10 | * | ||
| 11 | * (C) COPYRIGHT by me, 2000 | ||
| 12 | * All Rights Reserved | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <stdlib.h> | ||
| 17 | #include <math.h> | ||
| 18 | #include <bscan/bscan.h> | ||
| 19 | #include <bscan/snarf.h> | ||
| 20 | #include <bscan/tty.h> | ||
| 21 | #include <bscan/system.h> | ||
| 22 | #include <bscan/restore.h> | ||
| 23 | #include <bscan/module.h> | ||
| 24 | #include <bscan/version.h> | ||
| 25 | #include <bscan/cf_prse.h> | ||
| 26 | #include <sys/types.h> | ||
| 27 | #include <signal.h> | ||
| 28 | #include <math.h> | ||
| 29 | #include <libnet.h> | ||
| 30 | |||
| 31 | #ifdef HAVE_DLSYM | ||
| 32 | extern const int modcount; | ||
| 33 | extern const struct _mods mods[MAX_MODULES]; | ||
| 34 | #endif | ||
| 35 | |||
| 36 | unsigned char packet[1024]; | ||
| 37 | struct _opt *opt; | ||
| 38 | |||
| 39 | #define OPTS "XOVhavr:C:L:M:m:l:d:p:i:s:f:o:" | ||
| 40 | |||
| 41 | static unsigned long int gennextip (void); | ||
| 42 | static unsigned long int gennext_spreadip (void); | ||
| 43 | static unsigned long int gennext_random (void); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * make static mac entry in arp-table. | ||
| 47 | * We use system() here [setting mac entry is heavily system dependent] | ||
| 48 | */ | ||
| 49 | int | ||
| 50 | setarp (uint32_t ip, u_char * mac) | ||
| 51 | { | ||
| 52 | char buf[128]; | ||
| 53 | u_char *p = (u_char *) mac; | ||
| 54 | |||
| 55 | snprintf (buf, sizeof (buf) - 1, | ||
| 56 | "arp -s %s %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", int_ntoa (ip), | ||
| 57 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 58 | /* put all your IFL fun in here ! this is the major security hole | ||
| 59 | you were looking for.... */ | ||
| 60 | |||
| 61 | return (system (buf)); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /* | ||
| 66 | * delete the mac entry from the arp-table. | ||
| 67 | * we use system() again | ||
| 68 | */ | ||
| 69 | int | ||
| 70 | unsetarp (uint32_t ip) | ||
| 71 | { | ||
| 72 | char buf[128]; | ||
| 73 | |||
| 74 | snprintf (buf, sizeof (buf) - 1, "arp -d %s", int_ntoa (ip)); | ||
| 75 | /* put all your IFL fun in here ! this is the major security hole | ||
| 76 | you were looking for.... */ | ||
| 77 | |||
| 78 | return (system (buf)); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static void | ||
| 83 | usage (int code, char *fmt, ...) | ||
| 84 | { | ||
| 85 | char buf[1024]; | ||
| 86 | va_list ap; | ||
| 87 | u_char *p = (u_char *) opt->spf_smac; | ||
| 88 | int c; | ||
| 89 | |||
| 90 | printf (VERSION "\n"); | ||
| 91 | printf (" b-scan -s <spoofed source ip> [options] <host/network> ...\n"); | ||
| 92 | printf (" format of <host/network>:\n"); | ||
| 93 | printf (" <host>, 10.23.0.1 or\n"); | ||
| 94 | printf (" <start ip>-<end ip>, 10.23.0.1-10.23.255.254 or\n"); | ||
| 95 | printf (" <start network/mask>, 10.23.0.1/16\n\n"); | ||
| 96 | printf ("Options:\n"); | ||
| 97 | printf (" -r <restore.bscan>\n"); | ||
| 98 | #ifdef HAVE_DLSYM | ||
| 99 | printf (" -L <module.so, shared library file>\n"); | ||
| 100 | #endif | ||
| 101 | printf (" -f <hostlist, one ip/line>\n"); | ||
| 102 | printf (" -s <spoofed ip address on your LOCAL (!) network>\n"); | ||
| 103 | printf (" -m <mac>, make a static arp-entry and spoof from this mac.\n"); | ||
| 104 | printf | ||
| 105 | (" -M <mac>, dont make the static arpentry but spoof from this mac.\n"); | ||
| 106 | printf (" Add the mac to your arp-table manually (arp -s ip mac),\n"); | ||
| 107 | printf (" If no mac is given default mac is used:\n"); | ||
| 108 | printf (" MAC : %x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], | ||
| 109 | p[5]); | ||
| 110 | printf (" -i <ethernet interface>, default eth0\n"); | ||
| 111 | printf | ||
| 112 | (" -X spreadmode [non-sequential, experimental but recommended]\n"); | ||
| 113 | printf (" -O output ip's, dont scan\n"); | ||
| 114 | printf | ||
| 115 | (" -l <pps> limit packets per second, default 1000, 0 = unlimited\n"); | ||
| 116 | printf | ||
| 117 | (" -d <delay> w8 delay seconds for outstanding packets, default 10\n"); | ||
| 118 | printf (" -C <configuration file>\n"); | ||
| 119 | printf (" -v verbose output\n\n"); | ||
| 120 | printf ("Example:\n"); | ||
| 121 | printf ("# bscan -s 10.1.6.6 -i eth2 -L \"modules/mod_banner.so\" -X 2.4.1.0-2.4.9.9\n"); | ||
| 122 | |||
| 123 | #ifdef HAVE_DLSYM | ||
| 124 | for (c = 0; c < modcount; c++) | ||
| 125 | mods[c].musage (); | ||
| 126 | #endif | ||
| 127 | |||
| 128 | if (fmt != NULL) | ||
| 129 | { | ||
| 130 | va_start (ap, fmt); | ||
| 131 | vsnprintf (buf, sizeof (buf) - 1, fmt, ap); | ||
| 132 | va_end (ap); | ||
| 133 | fprintf (stderr, "ERROR: %s\n", buf); | ||
| 134 | } | ||
| 135 | |||
| 136 | exit (code); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * read's next ip from file. | ||
| 141 | * returns ip in NBO | ||
| 142 | * returns -1 (eg. 255.255.255.255) on failure | ||
| 143 | */ | ||
| 144 | unsigned long int | ||
| 145 | readnextip (void) | ||
| 146 | { | ||
| 147 | char buf[64]; | ||
| 148 | |||
| 149 | if (opt->ffd == NULL) | ||
| 150 | { | ||
| 151 | if ((opt->ffd = fopen (opt->hostfile, "r")) == NULL) | ||
| 152 | { | ||
| 153 | perror ("unable to open hostfile"); | ||
| 154 | return (-1); | ||
| 155 | } | ||
| 156 | opt->target = opt->hostfile; | ||
| 157 | } | ||
| 158 | fgets (buf, sizeof (buf), opt->ffd); | ||
| 159 | |||
| 160 | return (inet_addr (buf)); | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * get next ip in NBO from network/mask | ||
| 165 | * [could be random order] | ||
| 166 | * returns -1 [255.255.255.255] if no more ip's | ||
| 167 | * hint: rfc: "the first and last ip in a subnetwork are reserved" | ||
| 168 | */ | ||
| 169 | static unsigned long int | ||
| 170 | gennextip (void) | ||
| 171 | { | ||
| 172 | |||
| 173 | if (opt->ip_pos <= opt->end_ip) | ||
| 174 | return (htonl (opt->ip_pos++)); | ||
| 175 | |||
| 176 | return (-1); | ||
| 177 | |||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 181 | * generate next ip in spread-mode | ||
| 182 | * must: ip.end_ip - ip.start_ip > 2 | ||
| 183 | */ | ||
| 184 | static unsigned long int | ||
| 185 | gennext_spreadip (void) | ||
| 186 | { | ||
| 187 | u_long pos = opt->ip_pos; | ||
| 188 | |||
| 189 | |||
| 190 | if ((opt->ip_offset + 1 >= opt->ip_blklen) && (opt->ip_pos > opt->end_ip)) | ||
| 191 | return (-1); | ||
| 192 | |||
| 193 | if ((opt->ip_pos + opt->ip_blklen > opt->end_ip) | ||
| 194 | && (opt->ip_offset + 1 < opt->ip_blklen)) | ||
| 195 | opt->ip_pos = opt->start_ip + (++opt->ip_offset); | ||
| 196 | else | ||
| 197 | opt->ip_pos += opt->ip_blklen; | ||
| 198 | |||
| 199 | return (htonl (pos)); | ||
| 200 | |||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | static unsigned long int | ||
| 205 | gennext_random (void) | ||
| 206 | { | ||
| 207 | unsigned long int ip; | ||
| 208 | |||
| 209 | if (opt->random_maxcount != 0) { | ||
| 210 | if (--opt->random_maxcount == 0) | ||
| 211 | return (-1); | ||
| 212 | } | ||
| 213 | |||
| 214 | pitch: | ||
| 215 | ip = (random () & 0xffff) << 16; | ||
| 216 | ip |= random () & 0xffff; | ||
| 217 | |||
| 218 | if (((ip & 0xe0000000) >= 0xe0000000) || /* 224.0.0.0/3 */ | ||
| 219 | ((ip & 0xff000000) == 0x7f000000) || /* 127.0.0.0/8 */ | ||
| 220 | ((ip & 0xff000000) == 0x0a000000) || /* 10.0.0.0/8 */ | ||
| 221 | ((ip & 0xffff0000) == 0xc0a80000) || /* 192.168.0.0/16 */ | ||
| 222 | ((ip & 0xffff0000) == 0xac100000) || /* 172.16.0.0/16 */ | ||
| 223 | (ip == 0x00000000)) /* 0.0.0.0/32 */ | ||
| 224 | goto pitch; | ||
| 225 | |||
| 226 | return (htonl (ip)); | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | /* | ||
| 231 | * process all the options and load/init modules | ||
| 232 | */ | ||
| 233 | void | ||
| 234 | do_opt (int argc, char *argv[]) | ||
| 235 | { | ||
| 236 | extern char *optarg; | ||
| 237 | extern int optind; /*, opterr, optopt;*/ | ||
| 238 | unsigned short int sp[ETH_ALEN]; | ||
| 239 | int c; | ||
| 240 | char do_usage = 0; | ||
| 241 | |||
| 242 | |||
| 243 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 244 | { | ||
| 245 | switch (c) | ||
| 246 | { | ||
| 247 | case 'C': /* process conf file */ | ||
| 248 | if (readConfFile (optarg)) | ||
| 249 | { | ||
| 250 | opt->flags |= FileOpt.flags; | ||
| 251 | opt->limit = FileOpt.limit; | ||
| 252 | opt->delay = FileOpt.delay; | ||
| 253 | opt->nt.src = FileOpt.srcAddr; | ||
| 254 | opt->lnet.device = FileOpt.device; | ||
| 255 | for (c = 0; c < 6; c++) | ||
| 256 | opt->spf_smac[c] = FileOpt.mac[c]; | ||
| 257 | } | ||
| 258 | else | ||
| 259 | fprintf (stderr, "%s is not a valid vonfig file\n", optarg); | ||
| 260 | break; | ||
| 261 | case 'L': | ||
| 262 | break; /* process module stuff AFTER main-opts */ | ||
| 263 | case 'h': | ||
| 264 | do_usage = 1; | ||
| 265 | break; | ||
| 266 | case 'r': | ||
| 267 | if (read_restore (optarg) != 0) | ||
| 268 | { | ||
| 269 | fprintf (stderr, "unable to read restore file '%s'\n", | ||
| 270 | optarg); | ||
| 271 | exit (-1); | ||
| 272 | } | ||
| 273 | opt->flags |= OPT_REST; | ||
| 274 | break; | ||
| 275 | case 'l': | ||
| 276 | opt->limit = atoi (optarg); | ||
| 277 | break; | ||
| 278 | case 'v': | ||
| 279 | opt->flags |= OPT_VERB; | ||
| 280 | break; | ||
| 281 | case 'X': | ||
| 282 | opt->flags |= OPT_SPREADSCAN; | ||
| 283 | break; | ||
| 284 | case 'O': | ||
| 285 | opt->flags |= OPT_OUTONLY; /* dont scan, output ip's only */ | ||
| 286 | break; | ||
| 287 | case 'm': | ||
| 288 | opt->flags |= OPT_SETARP; | ||
| 289 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 290 | &sp[3], &sp[4], &sp[5]); | ||
| 291 | for (c = 0; c < 6; c++) | ||
| 292 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 293 | break; | ||
| 294 | case 'M': | ||
| 295 | opt->flags &= ~OPT_SETARP; | ||
| 296 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 297 | &sp[3], &sp[4], &sp[5]); | ||
| 298 | for (c = 0; c < 6; c++) | ||
| 299 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 300 | break; | ||
| 301 | case 'd': | ||
| 302 | opt->delay = atoi (optarg); | ||
| 303 | break; | ||
| 304 | case 'i': | ||
| 305 | opt->lnet.device = optarg; | ||
| 306 | break; | ||
| 307 | case 's': | ||
| 308 | opt->nt.src = inet_addr (optarg); | ||
| 309 | break; | ||
| 310 | case 'f': | ||
| 311 | opt->hostfile = optarg; | ||
| 312 | opt->flags |= OPT_HOSTFILE; | ||
| 313 | break; | ||
| 314 | case 'V': | ||
| 315 | printf (VERSION "\n"); | ||
| 316 | exit (0); | ||
| 317 | case ':': | ||
| 318 | usage (0, "parameter missing", c); | ||
| 319 | break; | ||
| 320 | default: | ||
| 321 | break; | ||
| 322 | usage (0, "unknown option -%c", c); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | /* | ||
| 327 | * init modules AFTER processing main-opts | ||
| 328 | */ | ||
| 329 | #ifdef HAVE_DLSYM | ||
| 330 | optind = 1; | ||
| 331 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 332 | { | ||
| 333 | switch (c) | ||
| 334 | { | ||
| 335 | case 'L': | ||
| 336 | loadinit_mod(optarg); | ||
| 337 | break; | ||
| 338 | } /* eo switch(c) */ | ||
| 339 | } /* eo while */ | ||
| 340 | #endif | ||
| 341 | if (do_usage != 0) | ||
| 342 | usage (0, NULL); | ||
| 343 | |||
| 344 | if ((optind < argc) && (!(opt->flags & OPT_REST))) | ||
| 345 | opt->argvlist = &argv[optind]; | ||
| 346 | if (opt->flags & OPT_OUTONLY) | ||
| 347 | opt->delay = 0; | ||
| 348 | if (opt->nt.src == -1) | ||
| 349 | usage (0, "you must specify a -s source address"); | ||
| 350 | if ((opt->argvlist == NULL) && (opt->hostfile == NULL)) | ||
| 351 | usage (0, "you must specify a -f hostfile or an ip-range"); | ||
| 352 | |||
| 353 | } | ||
| 354 | |||
| 355 | /* | ||
| 356 | * called via SIGCHLD and w8 for the pid [to destroy last kernel structure] | ||
| 357 | * OBSOLETE, ###fixme | ||
| 358 | */ | ||
| 359 | void | ||
| 360 | waitchld (int sig) | ||
| 361 | { | ||
| 362 | int status; | ||
| 363 | wait (&status); /* exit status of the child */ | ||
| 364 | } | ||
| 365 | |||
| 366 | void | ||
| 367 | sig_handle_abort (int sig) | ||
| 368 | { | ||
| 369 | |||
| 370 | if (pthread_self() != opt->bscantid) | ||
| 371 | return; | ||
| 372 | |||
| 373 | fprintf (stderr, "Session aborted ...one more to kill process\n"); | ||
| 374 | signal (sig, die); | ||
| 375 | opt->flags |= OPT_ABRT; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * generic signal driver :> | ||
| 380 | */ | ||
| 381 | void | ||
| 382 | sigdriver (int sig) | ||
| 383 | { | ||
| 384 | |||
| 385 | if (pthread_self() != opt->bscantid) | ||
| 386 | return; | ||
| 387 | |||
| 388 | if (sig == SIGUSR1) | ||
| 389 | print_scanstat (stderr); | ||
| 390 | if ((sig == SIGINT) || (sig == SIGQUIT)) /* ctrl-c */ | ||
| 391 | sig_handle_abort (sig); | ||
| 392 | } | ||
| 393 | |||
| 394 | /* | ||
| 395 | * This function MUST be called on exit (..or use atexit():) | ||
| 396 | * we have threads. Doesnt matter which thread calls this | ||
| 397 | * function...do everything and exit() the process | ||
| 398 | * (kills all threads...not very gentle...but...). | ||
| 399 | */ | ||
| 400 | void | ||
| 401 | die (int sig) | ||
| 402 | { | ||
| 403 | int c = 0; | ||
| 404 | |||
| 405 | print_scanstat (stderr); /* print before cleanup routines...*/ | ||
| 406 | |||
| 407 | if (opt->flags & OPT_ABRT) | ||
| 408 | if (write_restore () != 0) | ||
| 409 | perror ("restorefile failed"); | ||
| 410 | if ((opt->flags & OPT_SETARP) && (unsetarp (opt->nt.src) != 0)) | ||
| 411 | fprintf (stderr, "unable to unset arpentry. do it manually\n"); | ||
| 412 | #ifdef HAVE_DLSYM | ||
| 413 | while (c < modcount) | ||
| 414 | mods[c++].fini (); | ||
| 415 | #endif | ||
| 416 | |||
| 417 | #ifdef DEBUG | ||
| 418 | printf ("calling exit.\n"); | ||
| 419 | #endif | ||
| 420 | |||
| 421 | fflush (stdout); | ||
| 422 | |||
| 423 | exit (0); | ||
| 424 | } | ||
| 425 | |||
| 426 | /* | ||
| 427 | * reset all vars used during the scan (counters, ...) | ||
| 428 | * should be called before the call to make_iprange() | ||
| 429 | * If not...make_iprange thinks we use restore-file | ||
| 430 | */ | ||
| 431 | void | ||
| 432 | reset_vars () | ||
| 433 | { | ||
| 434 | opt->target = NULL; | ||
| 435 | opt->ipscan_count = 0; | ||
| 436 | opt->bsent_count = 0; | ||
| 437 | opt->ip_offset = 0; | ||
| 438 | opt->ip_blklen = 0; | ||
| 439 | opt->ip_pos = 0; | ||
| 440 | opt->start_ip = 0; | ||
| 441 | opt->end_ip = 0; | ||
| 442 | opt->snarf.close_c = 0; | ||
| 443 | opt->snarf.open_c = 0; | ||
| 444 | opt->snarf.refused_c = 0; | ||
| 445 | opt->snarf.icmp_c = 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | void | ||
| 450 | init_vars (char **nullptr) | ||
| 451 | { | ||
| 452 | srandom ((unsigned int) time (NULL)); | ||
| 453 | |||
| 454 | if ((opt = calloc (1, sizeof (*opt))) == NULL) | ||
| 455 | { | ||
| 456 | perror ("calloc"); | ||
| 457 | exit (-1); | ||
| 458 | } | ||
| 459 | memset (opt, 0, sizeof (struct _opt)); | ||
| 460 | |||
| 461 | opt->bscantid = 0; | ||
| 462 | opt->snarftid = 0; | ||
| 463 | opt->packet = packet; | ||
| 464 | opt->pkg_maxlen = sizeof (packet); | ||
| 465 | opt->pkg_len = 0; | ||
| 466 | opt->scan_start.tv_sec = 0; | ||
| 467 | opt->iptotscan_count = 0; | ||
| 468 | opt->scan_start.tv_usec = 0; | ||
| 469 | opt->hostfile = NULL; | ||
| 470 | opt->limit = 1000; | ||
| 471 | opt->flags = OPT_SETARP; | ||
| 472 | opt->ffd = NULL; | ||
| 473 | opt->argvlist = nullptr; | ||
| 474 | opt->lnet.device = NULL; /* done by libnet and libpcap */ | ||
| 475 | memcpy (opt->spf_smac, SPF_SMAC, 6); | ||
| 476 | opt->nt.src = -1; | ||
| 477 | opt->nt.dst = -1; | ||
| 478 | opt->delay = 10; | ||
| 479 | opt->lnet.device = NULL; | ||
| 480 | reset_vars (); | ||
| 481 | |||
| 482 | signal (SIGINT, sigdriver); | ||
| 483 | signal (SIGQUIT, sigdriver); | ||
| 484 | signal (SIGTERM, die); /* also called by client */ | ||
| 485 | signal (SIGCHLD, SIG_IGN); | ||
| 486 | signal (SIGUSR1, sigdriver); | ||
| 487 | } | ||
| 488 | |||
| 489 | void | ||
| 490 | print_opt () | ||
| 491 | { | ||
| 492 | u_char *p = (u_char *) opt->spf_smac; | ||
| 493 | |||
| 494 | fprintf (stderr, "Pid : %d\n", getpid()); | ||
| 495 | fprintf (stderr, "Interface : %s\n", opt->lnet.device); | ||
| 496 | fprintf (stderr, "Source IP : %s\n", int_ntoa (opt->nt.src)); | ||
| 497 | fprintf (stderr, "Source MAC : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
| 498 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 499 | fprintf (stderr, "pps : %u\n", opt->limit); | ||
| 500 | } | ||
| 501 | |||
| 502 | /* | ||
| 503 | * print scanstatistics on filedes | ||
| 504 | */ | ||
| 505 | void | ||
| 506 | print_scanstat (FILE * fd) | ||
| 507 | { | ||
| 508 | char perc = 100; | ||
| 509 | struct timeval tv2; | ||
| 510 | time_t timep; | ||
| 511 | struct tm mytm; | ||
| 512 | |||
| 513 | gettimeofday (&tv2, NULL); | ||
| 514 | time_diff (&opt->scan_start, &tv2); | ||
| 515 | if (tv2.tv_sec == 0) | ||
| 516 | tv2.tv_sec = 1; | ||
| 517 | timep = tv2.tv_sec; | ||
| 518 | gmtime_r (&timep, &mytm); | ||
| 519 | |||
| 520 | if ((opt->end_ip - opt->start_ip) != 0) | ||
| 521 | perc = | ||
| 522 | (((float) | ||
| 523 | opt->ipscan_count / (float) (opt->end_ip - | ||
| 524 | opt->start_ip)) * 100); | ||
| 525 | |||
| 526 | fprintf (fd, | ||
| 527 | "%2.2d:%2.2d:%2.2d:%2.2d %s %3d%% p/s: %6d [o:%lu r:%lu c:%lu i:%lu]\n", | ||
| 528 | mytm.tm_yday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec, | ||
| 529 | opt->target, perc, (int) (opt->iptotscan_count / tv2.tv_sec), | ||
| 530 | opt->snarf.open_c, opt->snarf.refused_c, opt->snarf.close_c, | ||
| 531 | opt->snarf.icmp_c); | ||
| 532 | |||
| 533 | } | ||
| 534 | |||
| 535 | |||
| 536 | /* | ||
| 537 | * calculate beginning and end of ip-range | ||
| 538 | * set start_ip and end_ip and target | ||
| 539 | */ | ||
| 540 | void | ||
| 541 | make_iprange (u_long * network, u_long * netmask, u_long * start_ip, | ||
| 542 | u_long * end_ip, char *str) | ||
| 543 | { | ||
| 544 | char buf[64]; | ||
| 545 | char *ptr; | ||
| 546 | |||
| 547 | opt->target = str; | ||
| 548 | strncpy (buf, str, sizeof (buf)); | ||
| 549 | buf[sizeof (buf) - 1] = '\0'; | ||
| 550 | opt->getnextip = NULL; | ||
| 551 | *start_ip = 0; | ||
| 552 | |||
| 553 | if (strncmp (buf, "random", 6) == 0) { | ||
| 554 | opt->getnextip = (void *) gennext_random; | ||
| 555 | if (strchr (buf, ':') != NULL) { | ||
| 556 | sscanf (strchr (buf, ':') + 1, "%lu", &opt->random_maxcount); | ||
| 557 | } else { | ||
| 558 | opt->random_maxcount = 0; | ||
| 559 | } | ||
| 560 | return; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* a.b.c.d/e */ | ||
| 564 | if (strchr (buf, '/') != NULL) | ||
| 565 | { | ||
| 566 | *netmask = 0xffffffff; /* for the lamers who forget the /<netmask> */ | ||
| 567 | |||
| 568 | if ((ptr = (char *) strrchr (buf, '/')) != NULL) | ||
| 569 | *netmask = 0xffffffff << (32 - atoi (ptr + 1)); | ||
| 570 | |||
| 571 | if ((ptr = (char *) strchr (buf, '/')) != NULL) | ||
| 572 | *ptr = '\0'; | ||
| 573 | |||
| 574 | *network = (ntohl (inet_addr (buf)) & *netmask); | ||
| 575 | *start_ip = (*network & *netmask) + 1; | ||
| 576 | *end_ip = (*network | ~*netmask) - 1; | ||
| 577 | if (*netmask >= 0xfffffffe) | ||
| 578 | (*start_ip)--; | ||
| 579 | if (*netmask == 0xffffffff) | ||
| 580 | (*end_ip)++; | ||
| 581 | } | ||
| 582 | |||
| 583 | /* a.b.c.d - w.x.y.z */ | ||
| 584 | if ((*start_ip == 0) && ((ptr = (char *) strrchr (buf, '-')) != NULL)) | ||
| 585 | { | ||
| 586 | *end_ip = ntohl (inet_addr (ptr + 1)); | ||
| 587 | *ptr = '\0'; | ||
| 588 | *start_ip = ntohl (inet_addr (buf)); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* a.b.c.d */ | ||
| 592 | if (*start_ip == 0) | ||
| 593 | { | ||
| 594 | *end_ip = ntohl (inet_addr (buf)); | ||
| 595 | *start_ip = ntohl (inet_addr (buf)); | ||
| 596 | } | ||
| 597 | |||
| 598 | if (opt->ip_pos == 0) /* if != 0 we use restore-file */ | ||
| 599 | opt->ip_pos = *start_ip; | ||
| 600 | |||
| 601 | /* initialize getnextip-funtion and spread scan variables */ | ||
| 602 | if ((opt->flags & OPT_SPREADSCAN) && (opt->end_ip - opt->start_ip > 2)) | ||
| 603 | { | ||
| 604 | init_spreadscan (opt->end_ip - opt->start_ip); | ||
| 605 | opt->getnextip = (void *) gennext_spreadip; | ||
| 606 | } | ||
| 607 | else | ||
| 608 | { | ||
| 609 | opt->getnextip = (void *) gennextip; | ||
| 610 | } | ||
| 611 | |||
| 612 | } | ||
| 613 | |||
| 614 | /* | ||
| 615 | * initialize offset for spread-scan | ||
| 616 | * call make_iprange before | ||
| 617 | * | ||
| 618 | * most networks are /24. dont let ip_blklen get to big | ||
| 619 | */ | ||
| 620 | void | ||
| 621 | init_spreadscan (u_long diff) | ||
| 622 | { | ||
| 623 | opt->ip_blklen = (u_long) sqrt (diff); | ||
| 624 | |||
| 625 | if (opt->ip_blklen > 100) /* range is 100^2 large */ | ||
| 626 | opt->ip_blklen = 257 + opt->ip_blklen * 0.2; /* use a prime# here */ | ||
| 627 | |||
| 628 | } | ||
| 629 | |||
| 630 | |||
| 631 | /* | ||
| 632 | * output the ip's only. dont scan. | ||
| 633 | */ | ||
| 634 | void | ||
| 635 | do_outonly () | ||
| 636 | { | ||
| 637 | uint32_t ip; | ||
| 638 | |||
| 639 | while ((ip = (*opt->getnextip) ()) != -1) | ||
| 640 | { | ||
| 641 | opt->ipscan_count++; | ||
| 642 | printf ("%s\n", int_ntoa (ip)); | ||
| 643 | } | ||
| 644 | |||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | /* | ||
| 649 | * process a scanrange from argv | ||
| 650 | * Return -1 if abort | ||
| 651 | */ | ||
| 652 | int | ||
| 653 | process_iprange () | ||
| 654 | { | ||
| 655 | int c = 0; | ||
| 656 | int ret; | ||
| 657 | #ifdef HAVE_DLSYM | ||
| 658 | int mc = 0; | ||
| 659 | #endif | ||
| 660 | |||
| 661 | while ((opt->nt.dst = (*opt->getnextip) ()) != -1) | ||
| 662 | { | ||
| 663 | memset (opt->packet, 0, opt->pkg_maxlen); | ||
| 664 | |||
| 665 | opt->pkg_len = 0; | ||
| 666 | |||
| 667 | if (opt->flags & OPT_VERB) | ||
| 668 | fprintf (stderr, "scanning %s:%d\n", | ||
| 669 | int_ntoa (opt->nt.dst), ntohs (opt->nt.dport)); | ||
| 670 | |||
| 671 | #ifdef HAVE_DLSYM | ||
| 672 | for (mc = 0; mc < modcount; mc++) | ||
| 673 | { | ||
| 674 | ret = mods[mc].callmdl (MOD_FIRSTPKG, opt); | ||
| 675 | if (ret == RMOD_SKIP) | ||
| 676 | continue; | ||
| 677 | if (ret == RMOD_ABRT) | ||
| 678 | { | ||
| 679 | fprintf(stderr, "oops: callmdl returned RMOD_ABRT\n"); | ||
| 680 | return(-1); | ||
| 681 | } | ||
| 682 | #endif | ||
| 683 | |||
| 684 | opt->bsent_count += | ||
| 685 | send_ipv4 (opt->sox, opt->packet + ETH_SIZE, opt->pkg_len); | ||
| 686 | opt->iptotscan_count++; | ||
| 687 | opt->ipscan_count++; /* linear ipscan-offset */ | ||
| 688 | |||
| 689 | if (opt->ipscan_count % opt->limit == 0) /* every second */ | ||
| 690 | { | ||
| 691 | if ((c = tty_getchar ()) != -1) | ||
| 692 | print_scanstat (stderr); | ||
| 693 | if (opt->flags & OPT_ABRT) | ||
| 694 | return (-1); /* sig_abort_handler called */ | ||
| 695 | } | ||
| 696 | |||
| 697 | /* do floodprotection */ | ||
| 698 | while (opt->limit > 0) | ||
| 699 | { | ||
| 700 | /* | ||
| 701 | * forgett about the initial value of tv.tv_usec... | ||
| 702 | * This is called 'optimizing algorithms'. The usec does | ||
| 703 | * not count if you scan >>10seconds... | ||
| 704 | */ | ||
| 705 | gettimeofday (&opt->tv2, NULL); | ||
| 706 | opt->sec = (opt->tv2.tv_sec - opt->scan_start.tv_sec) | ||
| 707 | - (opt->scan_start.tv_usec - opt->tv2.tv_usec) / 1000000.0; | ||
| 708 | if ((opt->iptotscan_count / opt->sec) >= opt->limit) | ||
| 709 | usleep (10); /* should give up timeslice */ | ||
| 710 | else | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | #ifdef HAVE_DLSYM | ||
| 714 | } /* modcount-loop */ | ||
| 715 | #endif | ||
| 716 | } | ||
| 717 | return (0); | ||
| 718 | } | ||
| 719 | |||
| 720 | void * | ||
| 721 | p_doit(void *arg) | ||
| 722 | { | ||
| 723 | printf("first thread here\n"); | ||
| 724 | sleep(100); | ||
| 725 | return NULL; | ||
| 726 | } | ||
| 727 | |||
| 728 | |||
| 729 | int | ||
| 730 | main (int argc, char *argv[]) | ||
| 731 | { | ||
| 732 | struct sockaddr_in saddr; | ||
| 733 | struct timeval tv; | ||
| 734 | int size; | ||
| 735 | int pstatus; /* pthread error status */ | ||
| 736 | #ifdef IP_HDRINCL | ||
| 737 | const int on = 1; | ||
| 738 | #endif | ||
| 739 | |||
| 740 | init_vars (&argv[argc]); /* before do_opt */ | ||
| 741 | |||
| 742 | do_opt (argc, argv); | ||
| 743 | tty_init (); | ||
| 744 | |||
| 745 | if (opt->flags & OPT_SETARP) | ||
| 746 | if (setarp (opt->nt.src, opt->spf_smac) != 0) | ||
| 747 | { | ||
| 748 | fprintf (stderr, "unable to set arpentry. do it manually\n"); | ||
| 749 | exit (1); | ||
| 750 | } | ||
| 751 | |||
| 752 | init_network_raw (); | ||
| 753 | prepare_libnet (&opt->lnet); /* used by arpg.c and maybe by bscan.c */ | ||
| 754 | |||
| 755 | memset (&saddr, 0, sizeof (saddr)); | ||
| 756 | |||
| 757 | if ((opt->sox = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) | ||
| 758 | { | ||
| 759 | fprintf (stderr, "error creating socket\n"); | ||
| 760 | exit (1); | ||
| 761 | } | ||
| 762 | #ifdef IP_HDRINCL | ||
| 763 | if (setsockopt (opt->sox, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0) | ||
| 764 | { | ||
| 765 | fprintf (stderr, "error setsockopt\n"); | ||
| 766 | exit (1); | ||
| 767 | } | ||
| 768 | #endif | ||
| 769 | |||
| 770 | size = 160 * 1024; /* OK if setsockopt fails */ | ||
| 771 | setsockopt (opt->sox, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)); | ||
| 772 | |||
| 773 | opt->flags |= OPT_W8SEMA; | ||
| 774 | opt->bscantid = pthread_self(); | ||
| 775 | pstatus = pthread_create(&opt->snarftid, NULL, &do_snarf, opt->lnet.device); | ||
| 776 | if (pstatus != 0) | ||
| 777 | err_abort(pstatus, "pthread_create"); | ||
| 778 | |||
| 779 | while (opt->flags & OPT_W8SEMA) | ||
| 780 | usleep(50); | ||
| 781 | |||
| 782 | print_opt (); | ||
| 783 | |||
| 784 | if (opt->scan_start.tv_sec == 0) | ||
| 785 | gettimeofday (&opt->scan_start, NULL); | ||
| 786 | |||
| 787 | while ((*opt->argvlist != NULL) || (opt->flags & OPT_HOSTFILE)) | ||
| 788 | { | ||
| 789 | if (!(opt->flags & OPT_REST)) | ||
| 790 | reset_vars (); /* reset all counting variables */ | ||
| 791 | |||
| 792 | if (!(opt->flags & OPT_HOSTFILE)) | ||
| 793 | { | ||
| 794 | make_iprange (&opt->network, &opt->netmask, &opt->start_ip, | ||
| 795 | &opt->end_ip, *opt->argvlist++); | ||
| 796 | } | ||
| 797 | else | ||
| 798 | { | ||
| 799 | opt->getnextip = (void *) readnextip; | ||
| 800 | if (opt->flags & OPT_REST) | ||
| 801 | { | ||
| 802 | int c = 0; | ||
| 803 | |||
| 804 | fprintf (stderr, "restore: skipping %lu in '%s'\n", | ||
| 805 | opt->ipscan_count, opt->hostfile); | ||
| 806 | while (c++ < opt->ipscan_count) | ||
| 807 | if ((*opt->getnextip) () == -1) | ||
| 808 | break; | ||
| 809 | } | ||
| 810 | } | ||
| 811 | |||
| 812 | opt->flags &= ~OPT_REST; /* 2nd.. init not by restorefile */ | ||
| 813 | |||
| 814 | if ((opt->getnextip == NULL) || (opt->nt.src == 0) | ||
| 815 | || (opt->nt.src == -1)) | ||
| 816 | usage (0, "no ip/range given or nonparseable range, skip"); | ||
| 817 | if (opt->flags & OPT_OUTONLY) | ||
| 818 | { | ||
| 819 | do_outonly (); | ||
| 820 | continue; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (process_iprange () == -1) | ||
| 824 | { | ||
| 825 | print_scanstat (stderr); | ||
| 826 | break; /* abort scan ! */ | ||
| 827 | } | ||
| 828 | |||
| 829 | if (opt->flags & OPT_HOSTFILE) | ||
| 830 | break; /* process only ONE hostfile */ | ||
| 831 | |||
| 832 | if (*opt->argvlist != NULL) | ||
| 833 | print_scanstat (stderr); | ||
| 834 | } | ||
| 835 | |||
| 836 | gettimeofday (&tv, NULL); | ||
| 837 | time_diff (&opt->scan_start, &tv); | ||
| 838 | opt->sec = tv.tv_sec + tv.tv_usec / 1000000.0; | ||
| 839 | fprintf (stderr, "scanned %lu ip's in %.3f seconds\n", opt->iptotscan_count, | ||
| 840 | opt->sec); | ||
| 841 | if (opt->delay > 0) | ||
| 842 | { | ||
| 843 | fprintf (stderr, "waiting %d sec for outstanding packets...\n", | ||
| 844 | opt->delay); | ||
| 845 | signal (SIGINT, die); /* if waiting exit immediatly on INTR */ | ||
| 846 | sleep (opt->delay); | ||
| 847 | } | ||
| 848 | |||
| 849 | die (0); | ||
| 850 | return (0); | ||
| 851 | } | ||
diff --git a/other/b-scan/src/cf_prse.l b/other/b-scan/src/cf_prse.l new file mode 100644 index 0000000..592bf7a --- /dev/null +++ b/other/b-scan/src/cf_prse.l | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | VOID_LINE "b-scan:" | ||
| 2 | LOCAL_IP "SourceAddress" | ||
| 3 | STATIC_MAC "StaticSpoofedMacAddress" | ||
| 4 | SPOOF_MAC "MacAddress" | ||
| 5 | INTERFACE "Interface" | ||
| 6 | SPREADMODE "SpreadScan" | ||
| 7 | PACKETS_PS "PacketsPerSecond" | ||
| 8 | PATIENCY "MaxWaitDelay" | ||
| 9 | VERBOSE "Verbose" | ||
| 10 | LOAD_MOD "addModule" | ||
| 11 | |||
| 12 | %{ | ||
| 13 | /* | ||
| 14 | * options with a "bool" are allowed to take "yes", "1" and "true" | ||
| 15 | * and the negated counterparts (case insensitive) as argument. | ||
| 16 | * all others take their argument as supplyed on the command line. | ||
| 17 | * | ||
| 18 | * | ||
| 19 | * VOID_LINE lines beginning with this string will be passed directly to stderr | ||
| 20 | * LOCAL_IP -s option | ||
| 21 | * STATIC_MAC -m bool | ||
| 22 | * SPOOF_MAC -M | ||
| 23 | * INTERFACE -i | ||
| 24 | * SPREADMODE -X bool | ||
| 25 | * PACKETS_PS -l | ||
| 26 | * PATIENCY -d | ||
| 27 | * VERBOSE -v bool | ||
| 28 | * MODULE -L | ||
| 29 | */ | ||
| 30 | %} | ||
| 31 | |||
| 32 | |||
| 33 | %{ | ||
| 34 | #include <bscan/cf_prse.h> | ||
| 35 | #include <bscan/module.h> | ||
| 36 | #include <string.h> | ||
| 37 | #include <stdlib.h> | ||
| 38 | #include <sys/socket.h> | ||
| 39 | #include <netinet/in.h> | ||
| 40 | #include <arpa/inet.h> | ||
| 41 | |||
| 42 | |||
| 43 | /* defines from bscan.h. why not include? because it sucks! using libnet-config for pff! */ | ||
| 44 | #define OPT_VERB 0x1 | ||
| 45 | #define OPT_SETARP 0x4 | ||
| 46 | #define OPT_SPREADSCAN 0x8 | ||
| 47 | |||
| 48 | |||
| 49 | char * | ||
| 50 | getArg (char *s) | ||
| 51 | { | ||
| 52 | int x = strlen (s); | ||
| 53 | |||
| 54 | while (s[x] != ' ' && s[x] != '\t') | ||
| 55 | --x; | ||
| 56 | return (s + x + 1); | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | int | ||
| 61 | evaluateBoolArg (char *s) | ||
| 62 | { | ||
| 63 | s = getArg (s); | ||
| 64 | |||
| 65 | if (!strcasecmp (s, "yes") || !strcasecmp (s, "true") || !strcasecmp (s, "1")) | ||
| 66 | return (1); | ||
| 67 | else if (!strcasecmp (s, "no") || !strcasecmp (s, "false") || !strcasecmp (s, "0")) | ||
| 68 | return (0); | ||
| 69 | else | ||
| 70 | return (-1); | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | void | ||
| 75 | set_s_opt (char *s) | ||
| 76 | { | ||
| 77 | s = getArg (s); | ||
| 78 | FileOpt.srcAddr = inet_addr (s); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | void | ||
| 83 | set_m_opt (char *s) | ||
| 84 | { | ||
| 85 | s = getArg (s); | ||
| 86 | if (evaluateBoolArg (s)) | ||
| 87 | FileOpt.flags |= OPT_SETARP; | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 91 | void set_M_opt (char *s) | ||
| 92 | { | ||
| 93 | s = getArg (s); | ||
| 94 | sscanf (s, "%hx:%hx:%hx:%hx:%hx:%hx", &FileOpt.mac[0], &FileOpt.mac[1], | ||
| 95 | &FileOpt.mac[2], &FileOpt.mac[3], &FileOpt.mac[4], &FileOpt.mac[5]); | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | void set_i_opt (char *s) | ||
| 100 | { | ||
| 101 | s = getArg (s); | ||
| 102 | FileOpt.device = (char *) malloc (strlen (s) + 1); | ||
| 103 | memset (FileOpt.device, 0, strlen (s) + 1); | ||
| 104 | memcpy (FileOpt.device, s, strlen (s)); | ||
| 105 | } | ||
| 106 | |||
| 107 | void set_X_opt (char *s) | ||
| 108 | { | ||
| 109 | s = getArg (s); | ||
| 110 | if (evaluateBoolArg (s)) | ||
| 111 | FileOpt.flags |= OPT_SPREADSCAN; | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | void set_l_opt (char *s) | ||
| 116 | { | ||
| 117 | s = getArg (s); | ||
| 118 | FileOpt.limit = atoi (s); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | void set_d_opt (char *s) | ||
| 123 | { | ||
| 124 | s = getArg (s); | ||
| 125 | FileOpt.delay = atoi (s); | ||
| 126 | } | ||
| 127 | |||
| 128 | |||
| 129 | void set_v_opt (char *s) | ||
| 130 | { | ||
| 131 | s = getArg (s); | ||
| 132 | if (evaluateBoolArg (s)) | ||
| 133 | FileOpt.flags |= OPT_VERB; | ||
| 134 | } | ||
| 135 | |||
| 136 | void set_L_opt (char *s) | ||
| 137 | { | ||
| 138 | s = s + strlen ("addModule") + 1; | ||
| 139 | while (*s == ' ' || *s == '\t') | ||
| 140 | s++; | ||
| 141 | loadinit_mod (s); | ||
| 142 | } | ||
| 143 | |||
| 144 | %} | ||
| 145 | %% | ||
| 146 | |||
| 147 | ^{VOID_LINE}[\t !-?a-zA-Z0-9]* fprintf (stderr, "%s\n", yytext); | ||
| 148 | ^{LOCAL_IP}[\t .0-9]* set_s_opt (yytext); | ||
| 149 | ^{STATIC_MAC}[\t a-zA-Z0-9]* set_m_opt (yytext); | ||
| 150 | ^{SPOOF_MAC}[\t :a-fA-F0-9]* set_M_opt (yytext); | ||
| 151 | ^{INTERFACE}[\t a-zA-Z0-9]* set_i_opt (yytext); | ||
| 152 | ^{SPREADMODE}[\t a-zA-Z0-9]* set_X_opt (yytext); | ||
| 153 | ^{PACKETS_PS}[\t a-zA-Z0-9]* set_l_opt (yytext); | ||
| 154 | ^{PATIENCY}[\t a-zA-Z0-9]* set_d_opt (yytext); | ||
| 155 | ^{VERBOSE}[\t a-zA-Z0-9]* set_v_opt (yytext); | ||
| 156 | ^{LOAD_MOD}[\t !-?\-_.:,;a-zA-Z0-9]* set_L_opt (yytext); | ||
| 157 | |||
| 158 | [\n\t a-zA-Z0-9] | ||
| 159 | . | ||
| 160 | |||
| 161 | %% | ||
| 162 | |||
| 163 | int yywrap () { return (1);} | ||
| 164 | |||
| 165 | int | ||
| 166 | readConfFile (char *s) | ||
| 167 | { | ||
| 168 | if ((yyin = fopen (s, "r")) == NULL) | ||
| 169 | return 0; | ||
| 170 | yylex (); | ||
| 171 | return 1; | ||
| 172 | } | ||
diff --git a/other/b-scan/src/dcd_icmp.c b/other/b-scan/src/dcd_icmp.c new file mode 100644 index 0000000..c627a56 --- /dev/null +++ b/other/b-scan/src/dcd_icmp.c | |||
| @@ -0,0 +1,166 @@ | |||
| 1 | /* bscan - icmp decoder | ||
| 2 | * | ||
| 3 | * based on information from | ||
| 4 | * RFC792 - INTERNET CONTROL MESSAGE PROTOCOL | ||
| 5 | * RFC950 - Internet Standard Subnetting Procedure | ||
| 6 | * ??? "ICMP Usage in Scanning" (ICMP_Scanning_v2.5.pdf) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <stdio.h> | ||
| 10 | #include <bscan/dcd_icmp.h> | ||
| 11 | |||
| 12 | static char * icmp_echo_reply[] = { | ||
| 13 | "ICMP ECHOREPLY", | ||
| 14 | NULL | ||
| 15 | }; | ||
| 16 | |||
| 17 | static char * icmp_unreach[] = { | ||
| 18 | "ICMP UNREACH network unreachable", | ||
| 19 | "ICMP UNREACH host unreachable", | ||
| 20 | "ICMP UNREACH protocol unreachable", | ||
| 21 | "ICMP UNREACH port unreachable", | ||
| 22 | "ICMP UNREACH fragmentation needed but don't-fragment bit set", | ||
| 23 | "ICMP UNREACH source route failed", | ||
| 24 | "ICMP UNREACH destination network unknown", | ||
| 25 | "ICMP UNREACH destination host unknown", | ||
| 26 | "ICMP UNREACH source host isolated", | ||
| 27 | "ICMP UNREACH destination network administratively prohibited", | ||
| 28 | "ICMP UNREACH destination host administratively prohibited", | ||
| 29 | "ICMP UNREACH network unreachable for TOS", | ||
| 30 | "ICMP UNREACH host unreachable for TOS", | ||
| 31 | "ICMP UNREACH communication administratively prohibited by filtering", | ||
| 32 | "ICMP UNREACH host precedence violation", | ||
| 33 | "ICMP UNREACH precedence cutoff in effect", | ||
| 34 | NULL | ||
| 35 | }; | ||
| 36 | |||
| 37 | static char * icmp_quench[] = { | ||
| 38 | "ICMP QUENCH", | ||
| 39 | NULL | ||
| 40 | }; | ||
| 41 | |||
| 42 | static char * icmp_redirect[] = { | ||
| 43 | "ICMP REDIRECT Redirect datagrams for the Network", | ||
| 44 | "ICMP REDIRECT Redirect datagrams for the Host", | ||
| 45 | "ICMP REDIRECT Redirect datagrams for the Type of Service and Network", | ||
| 46 | "ICMP REDIRECT Redirect datagrams for the Type of Service and Host", | ||
| 47 | NULL | ||
| 48 | }; | ||
| 49 | |||
| 50 | static char * icmp_alternate[] = { | ||
| 51 | "ICMP ALTERNATEHOSTADDRESS", | ||
| 52 | NULL | ||
| 53 | }; | ||
| 54 | |||
| 55 | static char * icmp_echo[] = { | ||
| 56 | "ICMP ECHO", | ||
| 57 | NULL | ||
| 58 | }; | ||
| 59 | |||
| 60 | static char * icmp_routerad[] = { | ||
| 61 | "ICMP ROUTERADVERTISEMENT", | ||
| 62 | NULL | ||
| 63 | }; | ||
| 64 | |||
| 65 | static char * icmp_routersel[] = { | ||
| 66 | "ICMP ROUTERSELECTION", | ||
| 67 | NULL | ||
| 68 | }; | ||
| 69 | |||
| 70 | static char * icmp_timeexceed[] = { | ||
| 71 | "ICMP TIMEEXCEED time to live exceeded in transit", | ||
| 72 | "ICMP TIMEEXCEED fragment reassembly time exceeded", | ||
| 73 | NULL | ||
| 74 | }; | ||
| 75 | |||
| 76 | static char * icmp_parprob[] = { | ||
| 77 | "ICMP PARAMETER pointer indicates the error", | ||
| 78 | "ICMP PARAMETER missing a required option", | ||
| 79 | "ICMP PARAMETER bad length", | ||
| 80 | NULL | ||
| 81 | }; | ||
| 82 | |||
| 83 | static char * icmp_timestamp[] = { | ||
| 84 | "ICMP TIMESTAMP", | ||
| 85 | NULL | ||
| 86 | }; | ||
| 87 | |||
| 88 | static char * icmp_timestamp_reply[] = { | ||
| 89 | "ICMP TIMESTAMPREPLY", | ||
| 90 | NULL | ||
| 91 | }; | ||
| 92 | |||
| 93 | static char * icmp_information[] = { | ||
| 94 | "ICMP INFORMATION", | ||
| 95 | NULL | ||
| 96 | }; | ||
| 97 | |||
| 98 | static char * icmp_information_reply[] = { | ||
| 99 | "ICMP INFORMATIONREPLY", | ||
| 100 | NULL | ||
| 101 | }; | ||
| 102 | |||
| 103 | static char * icmp_addressmask[] = { | ||
| 104 | "ICMP ADDRESSMASK", | ||
| 105 | NULL | ||
| 106 | }; | ||
| 107 | |||
| 108 | static char * icmp_addressmask_reply[] = { | ||
| 109 | "ICMP ADDRESSMASKREPLY", | ||
| 110 | NULL | ||
| 111 | }; | ||
| 112 | |||
| 113 | static char * icmp_ERR[] = { | ||
| 114 | "ICMP invalid code", | ||
| 115 | NULL | ||
| 116 | }; | ||
| 117 | |||
| 118 | struct icmp_typeelem { | ||
| 119 | int count; | ||
| 120 | char ** tab; | ||
| 121 | }; | ||
| 122 | |||
| 123 | struct icmp_typeelem icmp_tab[] = { | ||
| 124 | { 1, icmp_echo_reply }, /* 0 Echo Reply */ | ||
| 125 | { 0, icmp_ERR }, /* 1 UNUSED */ | ||
| 126 | { 0, icmp_ERR }, /* 2 UNUSED */ | ||
| 127 | { 16, icmp_unreach }, /* 3 Destination Unreachable */ | ||
| 128 | { 1, icmp_quench }, /* 4 Source Quench */ | ||
| 129 | { 4, icmp_redirect }, /* 5 Redirect */ | ||
| 130 | { 1, icmp_alternate }, /* 6 Alternate Host Address */ | ||
| 131 | { 0, icmp_ERR }, /* 7 UNUSED */ | ||
| 132 | { 1, icmp_echo }, /* 8 Echo */ | ||
| 133 | { 1, icmp_routerad }, /* 9 Router Advertisement */ | ||
| 134 | { 1, icmp_routersel }, /* 10 Router Selection */ | ||
| 135 | { 2, icmp_timeexceed }, /* 11 Time Exceeded */ | ||
| 136 | { 3, icmp_parprob }, /* 12 Parameter Problem */ | ||
| 137 | { 1, icmp_timestamp }, /* 13 Timestamp */ | ||
| 138 | { 1, icmp_timestamp_reply }, /* 14 Timestamp Reply */ | ||
| 139 | { 1, icmp_information }, /* 15 Information Request */ | ||
| 140 | { 1, icmp_information_reply }, /* 16 Information Request */ | ||
| 141 | { 1, icmp_addressmask }, /* 17 RFC950: Address Mask Request */ | ||
| 142 | { 1, icmp_addressmask_reply }, /* 18 RFC950: Address Mask Reply */ | ||
| 143 | { 0, NULL }, /* EOList */ | ||
| 144 | }; | ||
| 145 | |||
| 146 | int icmp_type_max = (sizeof (icmp_tab) / sizeof (struct icmp_typeelem)) - 1; | ||
| 147 | |||
| 148 | const char * | ||
| 149 | icmp_str (int type, int code) | ||
| 150 | { | ||
| 151 | struct icmp_typeelem * it; | ||
| 152 | |||
| 153 | if (type < 0 || type >= icmp_type_max) | ||
| 154 | return ("ICMP invalid type"); | ||
| 155 | |||
| 156 | it = &icmp_tab[type]; | ||
| 157 | if (it->count == 0) | ||
| 158 | return (it->tab[0]); | ||
| 159 | |||
| 160 | if (code < 0 || code >= it->count) | ||
| 161 | return ("ICMP invalid code"); | ||
| 162 | |||
| 163 | return (it->tab[code]); | ||
| 164 | } | ||
| 165 | |||
| 166 | |||
diff --git a/other/b-scan/src/garage.c b/other/b-scan/src/garage.c new file mode 100644 index 0000000..4beba2d --- /dev/null +++ b/other/b-scan/src/garage.c | |||
| @@ -0,0 +1,508 @@ | |||
| 1 | /* bscan - garage.c - per IP storage functions | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | * by skyper / teso | ||
| 5 | * | ||
| 6 | * this module implements a per-IP storage method to allow other modules | ||
| 7 | * to store state information about hosts (ie for TCP fingerprinting or | ||
| 8 | * stateful protocols). | ||
| 9 | * | ||
| 10 | * 2000/12/31 version 1.0.1 - scut | ||
| 11 | * - added CIDR helper functions | ||
| 12 | * - added mg_cidr_getmask function to convert CIDR/netmask | ||
| 13 | * notation | ||
| 14 | * - added mg_cidr_maskcount to count max possible hosts in a mask | ||
| 15 | * - added mg_cidr_count function to count hosts in garage that | ||
| 16 | * match a mask | ||
| 17 | * - added ip based counter to the garage structure, this costs | ||
| 18 | * only few cycles when working with elements, but repays for | ||
| 19 | * the mg_count and some of the mg_cidr_* functions | ||
| 20 | * - changed mg_count to take advantage of the garage counter | ||
| 21 | * - added mg_cidr_match function | ||
| 22 | * - workaround for some size-dependant misoptimizations of gcc | ||
| 23 | * | ||
| 24 | * 2000/12/31 version 1.0.0 - scut | ||
| 25 | * - support for storage, retrieval and max-keep counter | ||
| 26 | * with automatic deallocation | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <stdio.h> | ||
| 31 | #include <stdlib.h> | ||
| 32 | #include <string.h> | ||
| 33 | #include <bscan/garage.h> | ||
| 34 | |||
| 35 | |||
| 36 | /* memory layout: | ||
| 37 | * | ||
| 38 | * each per-ip data is stored in a linked list element. the linked list | ||
| 39 | * can (theoretically) contain up to 2^16 elements, if the entire IP space | ||
| 40 | * is scanned at once. | ||
| 41 | * | ||
| 42 | * up to 2^16 of this linked lists can exist, hence 2^16*2^16 = 2^32 = whole | ||
| 43 | * IPv4 space. to access the correct linked list we calculate a hash value, | ||
| 44 | * to directly read from a one dimensional table of linked list root pointers. | ||
| 45 | * | ||
| 46 | * unsigned long int ip; | ||
| 47 | * | ||
| 48 | * h = ((ip >> 16) + ip) 0xffff) | ||
| 49 | * | ||
| 50 | * the linked list indexed by this two hash values is sorted in ascending | ||
| 51 | * order by the IP as unsigned long int. | ||
| 52 | */ | ||
| 53 | |||
| 54 | #define MG_H(ip) ((((ip) >> 16) + (ip)) & 0xffff) | ||
| 55 | |||
| 56 | |||
| 57 | #ifdef DEBUG | ||
| 58 | unsigned long long int tackall = 0; | ||
| 59 | unsigned long long int tackc = 0; | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #if 0 | ||
| 63 | /* unused code | ||
| 64 | */ | ||
| 65 | static unsigned long int | ||
| 66 | mg_count_slot (ip_list *list); | ||
| 67 | #endif | ||
| 68 | |||
| 69 | |||
| 70 | /* XXX/FIXME/TODO: shouldn't be here | ||
| 71 | */ | ||
| 72 | void * | ||
| 73 | xcalloc (unsigned int factor, unsigned int size) | ||
| 74 | { | ||
| 75 | void * foo = calloc (factor, size); | ||
| 76 | |||
| 77 | if (foo == NULL) { | ||
| 78 | perror ("xcalloc"); | ||
| 79 | |||
| 80 | exit (EXIT_FAILURE); | ||
| 81 | } | ||
| 82 | |||
| 83 | return (foo); | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | /* destroy the ip_list element given in `slot' | ||
| 88 | */ | ||
| 89 | static void | ||
| 90 | mg_destroy_slot (garage_hdlr *g, ip_list *slot, void (* cleaner)(ip_list *)); | ||
| 91 | |||
| 92 | |||
| 93 | garage_hdlr * | ||
| 94 | mg_init (char *name, unsigned long int max_hosts_in_list, | ||
| 95 | void (* cleaner)(ip_list *)) | ||
| 96 | { | ||
| 97 | garage_hdlr * new = xcalloc (1, sizeof (garage_hdlr)); | ||
| 98 | |||
| 99 | new->name = name; | ||
| 100 | new->garage = xcalloc (256 * 256, sizeof (ip_list *)); | ||
| 101 | new->cleaner = cleaner; | ||
| 102 | new->ip_count = 0; | ||
| 103 | |||
| 104 | if (max_hosts_in_list == 0) { | ||
| 105 | new->timeout_tbl = NULL; | ||
| 106 | new->timeout_max = 0; | ||
| 107 | new->timeout_idx = 0; | ||
| 108 | } else { | ||
| 109 | new->timeout_tbl = xcalloc (max_hosts_in_list, | ||
| 110 | sizeof (unsigned long int)); | ||
| 111 | new->timeout_max = max_hosts_in_list; | ||
| 112 | new->timeout_idx = 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | memset (new->garage, '\x00', 256 * 256 * sizeof (ip_list *)); | ||
| 116 | if (new->timeout_tbl != NULL) | ||
| 117 | memset (new->timeout_tbl, '\x00', max_hosts_in_list * | ||
| 118 | sizeof (unsigned long int)); | ||
| 119 | |||
| 120 | return (new); | ||
| 121 | } | ||
| 122 | |||
| 123 | |||
| 124 | void | ||
| 125 | mg_destroy (garage_hdlr *g, int do_handler) | ||
| 126 | { | ||
| 127 | int h; | ||
| 128 | |||
| 129 | |||
| 130 | #ifdef DEBUG | ||
| 131 | printf ("tackcount = %Lu\n", tackc); | ||
| 132 | printf ("tackall = %Lu\n", tackall); | ||
| 133 | printf ("tackmedian = %2.3f\n", (float) ((float) tackall / (float) tackc)); | ||
| 134 | #endif | ||
| 135 | |||
| 136 | for (h = 0 ; h < (256 * 256) ; ++h) { | ||
| 137 | if (g->garage[h] != NULL) { | ||
| 138 | /* the IP list structure for the IP will be free'd | ||
| 139 | * by mg_clean, too, so we don't have to do that | ||
| 140 | * manually | ||
| 141 | */ | ||
| 142 | mg_destroy_slot (g, g->garage[h], (do_handler == 0) ? | ||
| 143 | NULL : g->cleaner); | ||
| 144 | g->garage[h] = NULL; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | free (g->garage); | ||
| 149 | if (g->timeout_tbl == NULL) | ||
| 150 | free (g->timeout_tbl); | ||
| 151 | |||
| 152 | /* g->name is not to be free'd */ | ||
| 153 | |||
| 154 | free (g); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | static void | ||
| 159 | mg_destroy_slot (garage_hdlr *g, ip_list *slot, void (* cleaner)(ip_list *)) | ||
| 160 | { | ||
| 161 | ip_list * next; | ||
| 162 | |||
| 163 | do { | ||
| 164 | next = slot->next; | ||
| 165 | mg_clean (g, slot->ip, cleaner); | ||
| 166 | slot = next; | ||
| 167 | } while (slot != NULL); | ||
| 168 | |||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 172 | |||
| 173 | void | ||
| 174 | mg_write (garage_hdlr *g, unsigned long int ip, void *data, size_t data_len, | ||
| 175 | int data_free) | ||
| 176 | { | ||
| 177 | ip_list * il; | ||
| 178 | ip_elem * new = xcalloc (1, sizeof (ip_elem)); | ||
| 179 | |||
| 180 | |||
| 181 | new->next = NULL; | ||
| 182 | new->data_free = data_free; | ||
| 183 | new->data_len = data_len; | ||
| 184 | new->data = data; | ||
| 185 | |||
| 186 | |||
| 187 | il = g->garage[MG_H (ip)]; | ||
| 188 | if (il == NULL) { | ||
| 189 | il = xcalloc (1, sizeof (ip_list)); | ||
| 190 | il->next = NULL; | ||
| 191 | il->ip = ip; | ||
| 192 | il->data = new; | ||
| 193 | |||
| 194 | g->garage[MG_H (ip)] = il; | ||
| 195 | g->ip_count += 1; | ||
| 196 | } else { | ||
| 197 | ip_list ** cw = &g->garage[MG_H (ip)]; | ||
| 198 | |||
| 199 | while (il != NULL && ip > il->ip) { | ||
| 200 | cw = &il->next; | ||
| 201 | il = il->next; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (il != NULL && ip == il->ip) { | ||
| 205 | new->next = il->data; | ||
| 206 | il->data = new; | ||
| 207 | } else { | ||
| 208 | ip_list * il_tmp = xcalloc (1, sizeof (ip_list)); | ||
| 209 | |||
| 210 | il_tmp->next = il; | ||
| 211 | *cw = il_tmp; | ||
| 212 | il = il_tmp; | ||
| 213 | |||
| 214 | il->ip = ip; | ||
| 215 | il->data = new; | ||
| 216 | |||
| 217 | g->ip_count += 1; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | if (g->timeout_tbl != NULL) { | ||
| 222 | #ifdef DEBUG | ||
| 223 | printf ("tbl = 0x%08lx tbl_idx = %5lu tbl_max = %5lu tbl_count = %8lu\n", | ||
| 224 | (unsigned long int) g->timeout_tbl, | ||
| 225 | (unsigned long int) g->timeout_idx, | ||
| 226 | (unsigned long int) g->timeout_max, | ||
| 227 | (unsigned long int) mg_count (g)); | ||
| 228 | printf ("g->timeout_tbl[g->timeout_idx] = %lu\n", g->timeout_tbl[g->timeout_idx]); | ||
| 229 | printf ("condition = %s\n", (g->timeout_tbl[g->timeout_idx] != 0) ? "true" : "false"); | ||
| 230 | #endif | ||
| 231 | |||
| 232 | if (g->timeout_tbl[g->timeout_idx] != 0) | ||
| 233 | mg_clean (g, g->timeout_tbl[g->timeout_idx], NULL); | ||
| 234 | |||
| 235 | g->timeout_tbl[g->timeout_idx] = il->ip; | ||
| 236 | #ifdef DEBUG | ||
| 237 | printf ("g->timeout_idx = %5ld g->timeout_max = %5ld\n\n", | ||
| 238 | g->timeout_idx, g->timeout_max); | ||
| 239 | #endif | ||
| 240 | g->timeout_idx = (g->timeout_idx + 1) % g->timeout_max; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | |||
| 245 | ip_elem * | ||
| 246 | mg_read (garage_hdlr *g, unsigned long int ip) | ||
| 247 | { | ||
| 248 | #ifdef DEBUG | ||
| 249 | int tackcount = 0; | ||
| 250 | #endif | ||
| 251 | ip_list * il = g->garage[MG_H (ip)]; | ||
| 252 | |||
| 253 | /* no list for this hash value -> no IP stored | ||
| 254 | */ | ||
| 255 | if (il == NULL) | ||
| 256 | return (NULL); | ||
| 257 | |||
| 258 | /* walk the list | ||
| 259 | */ | ||
| 260 | do { | ||
| 261 | if (il->ip == ip) | ||
| 262 | #ifdef DEBUG | ||
| 263 | { | ||
| 264 | printf ("tackcount = %d\n", tackcount); | ||
| 265 | tackall += tackcount; | ||
| 266 | tackc += 1; | ||
| 267 | #endif | ||
| 268 | return (il->data); | ||
| 269 | #ifdef DEBUG | ||
| 270 | } else { | ||
| 271 | tackcount += 1; | ||
| 272 | } | ||
| 273 | #endif | ||
| 274 | |||
| 275 | il = il->next; | ||
| 276 | |||
| 277 | } while (il != NULL && il->ip <= ip); | ||
| 278 | |||
| 279 | return (NULL); | ||
| 280 | } | ||
| 281 | |||
| 282 | |||
| 283 | void | ||
| 284 | mg_clean (garage_hdlr *g, unsigned long int ip, void (* cleaner)(ip_list *)) | ||
| 285 | { | ||
| 286 | ip_elem * iel; | ||
| 287 | ip_elem * iel_tmp; | ||
| 288 | |||
| 289 | ip_list ** cw = &g->garage[MG_H (ip)]; | ||
| 290 | ip_list * il; | ||
| 291 | |||
| 292 | |||
| 293 | il = *cw; | ||
| 294 | |||
| 295 | /* walk the list | ||
| 296 | */ | ||
| 297 | while (il != NULL && il->ip < ip) { | ||
| 298 | cw = &il->next; | ||
| 299 | il = il->next; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (il == NULL || il->ip != ip) | ||
| 303 | return; | ||
| 304 | |||
| 305 | *cw = il->next; | ||
| 306 | |||
| 307 | /* if a cleaner has been given, or there is a default cleaner in the | ||
| 308 | * garage, then run it | ||
| 309 | */ | ||
| 310 | if (cleaner != NULL) { | ||
| 311 | cleaner (il); | ||
| 312 | } else if (g->cleaner != NULL) { | ||
| 313 | g->cleaner (il); | ||
| 314 | } | ||
| 315 | |||
| 316 | iel = il->data; | ||
| 317 | while (iel != NULL) { | ||
| 318 | iel_tmp = iel; | ||
| 319 | if (iel->data_free) | ||
| 320 | free (iel->data); | ||
| 321 | |||
| 322 | iel = iel->next; | ||
| 323 | free (iel_tmp); | ||
| 324 | } | ||
| 325 | |||
| 326 | g->ip_count -= 1; | ||
| 327 | |||
| 328 | free (il); | ||
| 329 | |||
| 330 | return; | ||
| 331 | } | ||
| 332 | |||
| 333 | |||
| 334 | void | ||
| 335 | mg_show (garage_hdlr *g) | ||
| 336 | { | ||
| 337 | int h1, h2; | ||
| 338 | int count; | ||
| 339 | |||
| 340 | char display[] = ".123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
| 341 | |||
| 342 | printf ("=== garage = %s === elements in garage = %lu\n", g->name, mg_count (g)); | ||
| 343 | printf ("0_________0_________0_________0_________0_________0_________0_________\n"); | ||
| 344 | |||
| 345 | for (h1 = 0 ; h1 < 256 ; ++h1) { | ||
| 346 | count = 0; | ||
| 347 | for (h2 = 0 ; h2 < 256 ; ++h2) { | ||
| 348 | if (g->garage[h1 * 256 + h2] != NULL) | ||
| 349 | count += 1; | ||
| 350 | } | ||
| 351 | |||
| 352 | printf ("%c", count >= (sizeof (display) - 1) ? '>' : display[count]); | ||
| 353 | if ((h1 + 1) % 70 == 0) { | ||
| 354 | printf ("\n"); | ||
| 355 | printf ("0_________0_________0_________0_________0_________0_________0_________\n"); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | printf ("\n"); | ||
| 359 | |||
| 360 | } | ||
| 361 | |||
| 362 | |||
| 363 | unsigned long int | ||
| 364 | mg_count (garage_hdlr *g) | ||
| 365 | { | ||
| 366 | return (g->ip_count); | ||
| 367 | } | ||
| 368 | |||
| 369 | |||
| 370 | #if 0 | ||
| 371 | /* unused code | ||
| 372 | */ | ||
| 373 | static unsigned long int | ||
| 374 | mg_count_slot (ip_list *list) | ||
| 375 | { | ||
| 376 | unsigned long int count = 0; | ||
| 377 | |||
| 378 | do { | ||
| 379 | count += 1; | ||
| 380 | list = list->next; | ||
| 381 | } while (list != NULL); | ||
| 382 | |||
| 383 | return (count); | ||
| 384 | } | ||
| 385 | #endif | ||
| 386 | |||
| 387 | |||
| 388 | int | ||
| 389 | mg_ip_isin (garage_hdlr *g, unsigned long int ip) | ||
| 390 | { | ||
| 391 | ip_list * il = g->garage[MG_H (ip)]; | ||
| 392 | |||
| 393 | if (il == NULL) | ||
| 394 | return (0); | ||
| 395 | |||
| 396 | while (il != NULL && ip < il->ip) { | ||
| 397 | il = il->next; | ||
| 398 | } | ||
| 399 | |||
| 400 | if (il != NULL && ip == il->ip) | ||
| 401 | return (1); | ||
| 402 | |||
| 403 | return (0); | ||
| 404 | } | ||
| 405 | |||
| 406 | |||
| 407 | |||
| 408 | /* CIDR routines | ||
| 409 | * | ||
| 410 | * XXX: maybe move some basic CIDR routines to an extra file for maintance | ||
| 411 | * XXX: beta code, please test | ||
| 412 | */ | ||
| 413 | |||
| 414 | unsigned long int | ||
| 415 | mg_cidr_getmask (unsigned long int mask) | ||
| 416 | { | ||
| 417 | /* work around to dumb gcc 'optimizations' (ie compiler bug) | ||
| 418 | */ | ||
| 419 | if (mask == 0) | ||
| 420 | return (0); | ||
| 421 | |||
| 422 | if (mask > 32) { | ||
| 423 | return (mask); | ||
| 424 | } else { | ||
| 425 | unsigned long int nm = 0xffffffff; | ||
| 426 | |||
| 427 | /* clear zero bits | ||
| 428 | */ | ||
| 429 | mask = 32 - mask; | ||
| 430 | nm >>= mask; | ||
| 431 | nm <<= mask; | ||
| 432 | |||
| 433 | return (nm); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | |||
| 438 | unsigned long int | ||
| 439 | mg_cidr_maskcount (unsigned long int mask) | ||
| 440 | { | ||
| 441 | return ((~mg_cidr_getmask (mask)) + 1); | ||
| 442 | } | ||
| 443 | |||
| 444 | |||
| 445 | int | ||
| 446 | mg_cidr_match (unsigned long int ip1, unsigned long int ip2, | ||
| 447 | unsigned long int mask) | ||
| 448 | { | ||
| 449 | mask = mg_cidr_getmask (mask); | ||
| 450 | ip1 &= mask; | ||
| 451 | ip2 &= mask; | ||
| 452 | |||
| 453 | return (ip1 == ip2); | ||
| 454 | } | ||
| 455 | |||
| 456 | |||
| 457 | unsigned long int | ||
| 458 | mg_cidr_count (garage_hdlr *g, unsigned long int ip, unsigned long int mask) | ||
| 459 | { | ||
| 460 | unsigned long int count = 0; | ||
| 461 | unsigned long int ip_start, | ||
| 462 | ip_end; | ||
| 463 | |||
| 464 | |||
| 465 | ip_start = ip & mg_cidr_getmask (mask); | ||
| 466 | ip_end = ip_start + mg_cidr_maskcount (mask); | ||
| 467 | |||
| 468 | /* workaround for /0 cidr mask (if sizeof (unsigned long int) == 4) | ||
| 469 | * it will make ip_end = 0, so we have to catch this case) | ||
| 470 | */ | ||
| 471 | if (ip_end == 0) | ||
| 472 | return (mg_count (g)); | ||
| 473 | |||
| 474 | if ((ip_end - ip_start) >= mg_count (g)) { | ||
| 475 | /* since there are less elements then the ip range contains, | ||
| 476 | * we go for a count-matching-elements-by-scanning-through- | ||
| 477 | * the-entire-array like technique | ||
| 478 | */ | ||
| 479 | unsigned long int h; | ||
| 480 | ip_list * il; | ||
| 481 | |||
| 482 | for (h = 0 ; h < (256 * 256) ; ++h) { | ||
| 483 | if (g->garage[h] != NULL) { | ||
| 484 | il = g->garage[h]; | ||
| 485 | |||
| 486 | do { | ||
| 487 | if (mg_cidr_match (il->ip, ip, mask)) | ||
| 488 | count += 1; | ||
| 489 | |||
| 490 | il = il->next; | ||
| 491 | } while (il != NULL); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | } else { | ||
| 495 | /* there are more elements in the garage then this range | ||
| 496 | * contains, so scam this range only | ||
| 497 | */ | ||
| 498 | do { | ||
| 499 | count += mg_ip_isin (g, ip_start); | ||
| 500 | |||
| 501 | ip_start += 1; | ||
| 502 | } while (ip_start < ip_end); | ||
| 503 | } | ||
| 504 | |||
| 505 | return (count); | ||
| 506 | } | ||
| 507 | |||
| 508 | |||
diff --git a/other/b-scan/src/module.c b/other/b-scan/src/module.c new file mode 100644 index 0000000..1748914 --- /dev/null +++ b/other/b-scan/src/module.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <dlfcn.h> | ||
| 4 | #include <string.h> | ||
| 5 | #include <bscan/module.h> | ||
| 6 | #include <bscan/system.h> | ||
| 7 | |||
| 8 | struct _mods mods[MAX_MODULES]; | ||
| 9 | /* modstructures not initialized */ | ||
| 10 | int modcount = -1; | ||
| 11 | |||
| 12 | /* | ||
| 13 | #ifdef HAVE_DLSYM | ||
| 14 | #define MAKE_DLSYM(x, y) mods[modcount].##x = dlsym(handle, ##y);\ | ||
| 15 | if ((error = dlerror()) != NULL) {\ | ||
| 16 | fprintf(stderr, ##y":%s\n", error); return(1); } | ||
| 17 | #endif | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* I think this is more correct, and also gets rid of some compile warnings. | ||
| 21 | * hope this doesn't break anything. -typo */ | ||
| 22 | #ifdef HAVE_DLSYM | ||
| 23 | #define MAKE_DLSYM(x, y) mods[modcount].x = dlsym(handle, y);\ | ||
| 24 | if ((error = dlerror()) != NULL) {\ | ||
| 25 | fprintf(stderr, y":%s\n", error); return(1); } | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* SunOS 4.1.3 support */ | ||
| 29 | #ifndef RTLD_NOW | ||
| 30 | #define RTLD_NOW 0x00001 | ||
| 31 | #endif | ||
| 32 | /* OpenBSD support */ | ||
| 33 | #ifndef RTLD_GLOBAL | ||
| 34 | #define RTLD_GLOBAL 0x00000 | ||
| 35 | #endif | ||
| 36 | |||
| 37 | /* we really hate theo for this shit of dl* work */ | ||
| 38 | #if defined(__OpenBSD__) | ||
| 39 | # if !(defined(__mips) || defined(__powerpc)) | ||
| 40 | # define DLSYM_AOUT 1 | ||
| 41 | # else | ||
| 42 | # define DLSYM_AOUT 0 | ||
| 43 | # endif | ||
| 44 | #endif | ||
| 45 | #if DLSYM_AOUT == 1 | ||
| 46 | # define DLSYM_UNDERSCORE "_" | ||
| 47 | #else | ||
| 48 | # define DLSYM_UNDERSCORE /**/ | ||
| 49 | #endif | ||
| 50 | |||
| 51 | |||
| 52 | /* | ||
| 53 | * init the module structures. NOT the modules! | ||
| 54 | */ | ||
| 55 | void | ||
| 56 | init_modules () | ||
| 57 | { | ||
| 58 | int c = 0; | ||
| 59 | |||
| 60 | while (c < MAX_MODULES) | ||
| 61 | { | ||
| 62 | mods[c].init = NULL; | ||
| 63 | mods[c].fini = NULL; | ||
| 64 | mods[c].musage = NULL; | ||
| 65 | mods[c].modname = NULL; | ||
| 66 | mods[c].modid = 0; | ||
| 67 | mods[c].modarg = NULL; | ||
| 68 | mods[c++].callmdl = NULL; | ||
| 69 | } | ||
| 70 | modcount = 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | /* | ||
| 75 | * Load a module | ||
| 76 | * Return 0 on success, != 0 on error [no space left, EACCESS, ...] | ||
| 77 | */ | ||
| 78 | int | ||
| 79 | add_module (char *fname, char *modarg) | ||
| 80 | { | ||
| 81 | #ifdef HAVE_DLSYM | ||
| 82 | void *handle; | ||
| 83 | char *error; | ||
| 84 | |||
| 85 | if (modcount == -1) | ||
| 86 | init_modules (); | ||
| 87 | |||
| 88 | if (modcount >= MAX_MODULES) | ||
| 89 | return (2); /* array to small! */ | ||
| 90 | |||
| 91 | handle = dlopen (fname, RTLD_NOW | RTLD_GLOBAL); | ||
| 92 | |||
| 93 | if ((error = dlerror ()) != NULL) | ||
| 94 | { | ||
| 95 | fprintf (stderr, "%s\n", error); | ||
| 96 | return (1); | ||
| 97 | } | ||
| 98 | |||
| 99 | MAKE_DLSYM (init, DLSYM_UNDERSCORE"init"); | ||
| 100 | MAKE_DLSYM (fini, DLSYM_UNDERSCORE"fini"); | ||
| 101 | MAKE_DLSYM (musage, DLSYM_UNDERSCORE"musage"); | ||
| 102 | MAKE_DLSYM (callmdl, DLSYM_UNDERSCORE"callmdl"); | ||
| 103 | |||
| 104 | mods[modcount].modid = modcount; | ||
| 105 | mods[modcount].modarg = modarg; /* not encoded arg */ | ||
| 106 | |||
| 107 | modcount++; | ||
| 108 | |||
| 109 | #endif | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* | ||
| 114 | * split a 'space seperated string' into many arguements | ||
| 115 | * decode esc-sequences | ||
| 116 | */ | ||
| 117 | void | ||
| 118 | split_margs (const char *moptarg, char ***margvp, int *margcp) | ||
| 119 | { | ||
| 120 | char *ptr, *opt; | ||
| 121 | int off; | ||
| 122 | char ch, ch2; | ||
| 123 | |||
| 124 | if (margcp == NULL) | ||
| 125 | return; | ||
| 126 | |||
| 127 | if (margvp == NULL) | ||
| 128 | return; | ||
| 129 | |||
| 130 | if (moptarg == NULL) | ||
| 131 | return; | ||
| 132 | |||
| 133 | moptarg = strdup(moptarg); | ||
| 134 | |||
| 135 | /* | ||
| 136 | * convert " modname -a arg1 -b arg2" to | ||
| 137 | * "modname -a arg1 -b arg2" | ||
| 138 | */ | ||
| 139 | opt = (char *) calloc (1, strlen (moptarg) + 1); | ||
| 140 | off = 0; | ||
| 141 | ch2 = ' '; | ||
| 142 | ptr = (char *) moptarg; | ||
| 143 | while ((ch = *ptr++) != '\0') | ||
| 144 | { | ||
| 145 | if ((ch == ' ') && (ch2 == ' ')) | ||
| 146 | continue; | ||
| 147 | opt[off++] = ch; | ||
| 148 | ch2 = ch; | ||
| 149 | } | ||
| 150 | if (ch2 == ' ') | ||
| 151 | opt[off - 1] = '\0'; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * split argument-string into char *argv[] array | ||
| 155 | */ | ||
| 156 | *margcp = 0; | ||
| 157 | while ((ptr = strchr (opt, ' ')) != NULL) | ||
| 158 | { | ||
| 159 | *ptr++ = '\0'; | ||
| 160 | |||
| 161 | (*margvp) = realloc (*margvp, ((*margcp) + 1) * sizeof (char *)); | ||
| 162 | |||
| 163 | ctoreal(opt, opt); /* decode esc-sequences */ | ||
| 164 | *(*margvp + *margcp) = opt; | ||
| 165 | (*margcp)++; | ||
| 166 | opt = ptr; | ||
| 167 | } | ||
| 168 | (*margvp) = realloc (*margvp, ((*margcp) + 2) * sizeof (char *)); | ||
| 169 | ctoreal(opt, opt); | ||
| 170 | *(*margvp + (*margcp)++) = opt; | ||
| 171 | *(*margvp + (*margcp)) = NULL; /* terminate the array */ | ||
| 172 | |||
| 173 | } | ||
| 174 | |||
| 175 | /* | ||
| 176 | * load and init the module. | ||
| 177 | * this function can exit | ||
| 178 | * return 0 on success | ||
| 179 | */ | ||
| 180 | int | ||
| 181 | loadinit_mod(char *optar) | ||
| 182 | { | ||
| 183 | char **margv = NULL; | ||
| 184 | int margc = 0; | ||
| 185 | extern int optind; | ||
| 186 | extern struct _opt *opt; | ||
| 187 | |||
| 188 | split_margs (optar, &margv, &margc); | ||
| 189 | if (add_module (margv[0], optar) == 0) | ||
| 190 | { | ||
| 191 | int oldoptind = optind; | ||
| 192 | int m = modcount - 1; | ||
| 193 | optind = 1; | ||
| 194 | |||
| 195 | if (mods[m].init ((char **) &mods[m].modname, margc, margv, opt) != 0) | ||
| 196 | { | ||
| 197 | fprintf (stderr, "- [%d]: '%s' init FAILED\n", | ||
| 198 | mods[m].modid, margv[0]); | ||
| 199 | mods[m].musage (); | ||
| 200 | exit (-1); | ||
| 201 | } else | ||
| 202 | fprintf (stderr, "+ [%d]: '%s' initialized\n", | ||
| 203 | mods[m].modid, mods[m].modname); | ||
| 204 | optind = oldoptind; /* restore old optind value */ | ||
| 205 | } else | ||
| 206 | { | ||
| 207 | fprintf (stderr, "+ [-]; '%s' failed\n", optar); | ||
| 208 | exit (-1); | ||
| 209 | } | ||
| 210 | |||
| 211 | return(0); | ||
| 212 | } | ||
| 213 | |||
| 214 | |||
diff --git a/other/b-scan/src/network_raw.c b/other/b-scan/src/network_raw.c new file mode 100644 index 0000000..1b87eaa --- /dev/null +++ b/other/b-scan/src/network_raw.c | |||
| @@ -0,0 +1,497 @@ | |||
| 1 | /* | ||
| 2 | * raw network routines | ||
| 3 | * libnet based (not yet ..but maybe in the future :> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <stdarg.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <sys/types.h> | ||
| 10 | #include <sys/socket.h> | ||
| 11 | #include <sys/wait.h> | ||
| 12 | #ifndef __FAVOR_BSD | ||
| 13 | #define __FAVOR_BSD | ||
| 14 | #endif | ||
| 15 | #ifndef __USE_BSD | ||
| 16 | #define __USE_BSD | ||
| 17 | #endif | ||
| 18 | #ifndef __BSD_SOURCE | ||
| 19 | #define __BSD_SOURCE | ||
| 20 | #endif | ||
| 21 | #include <libnet.h> | ||
| 22 | #include <bscan/network_raw.h> | ||
| 23 | |||
| 24 | static int netraw_lrand = 0; | ||
| 25 | #define LAME_RANDOM (netraw_lrand = (netraw_lrand + (netraw_lrand>>1))) | ||
| 26 | |||
| 27 | /* | ||
| 28 | * init all the network_raw stuff | ||
| 29 | * return 0 on success, -1 on error | ||
| 30 | */ | ||
| 31 | int | ||
| 32 | init_network_raw () | ||
| 33 | { | ||
| 34 | /* seeded by init_vars/bscan.c */ | ||
| 35 | netraw_lrand = 1 + (int) (65335.0 * rand () / (RAND_MAX + 1.0)); | ||
| 36 | return (0); | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | ||
| 40 | * calc. checksum WITH carry flag. | ||
| 41 | * call cksum = CKSUM_CARRY(sum); | ||
| 42 | * we calculate only the initial checksum here. | ||
| 43 | * we can use the result for all further packets | ||
| 44 | */ | ||
| 45 | int | ||
| 46 | in_cksum (unsigned short *addr, int len) | ||
| 47 | { | ||
| 48 | int nleft = len; | ||
| 49 | int sum = 0; | ||
| 50 | u_short *w = addr; | ||
| 51 | u_short answer = 0; | ||
| 52 | |||
| 53 | while (nleft > 1) | ||
| 54 | { | ||
| 55 | sum += *w++; | ||
| 56 | nleft -= 2; | ||
| 57 | } | ||
| 58 | |||
| 59 | if (nleft == 1) /* padding */ | ||
| 60 | { | ||
| 61 | *(u_char *) (&answer) = *(u_char *) w; | ||
| 62 | sum += answer; | ||
| 63 | } | ||
| 64 | |||
| 65 | return (sum); | ||
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | /* | ||
| 70 | * add ICMP_ECHO or ICMP_TSTAMP | ||
| 71 | * len = len of payload | ||
| 72 | * add ICMP-header to pkt | ||
| 73 | */ | ||
| 74 | void | ||
| 75 | add_icmpping (unsigned char *pkt, int len, int which) | ||
| 76 | { | ||
| 77 | struct icmp *icmp = (struct icmp *) pkt; | ||
| 78 | int sum; | ||
| 79 | struct timeval tv; | ||
| 80 | memset (icmp, 0, sizeof (*icmp)); /* sizeof(*icmp) = 28 */ | ||
| 81 | |||
| 82 | if (which == ICMP_ECHO) | ||
| 83 | { | ||
| 84 | icmp->icmp_type = ICMP_ECHO; | ||
| 85 | } | ||
| 86 | else if (which == ICMP_TSTAMP) | ||
| 87 | { | ||
| 88 | if (len < 13) | ||
| 89 | printf ("packet too small for timestamp request, lets blast the packets out anyway\n"); | ||
| 90 | icmp->icmp_type = ICMP_TSTAMP; | ||
| 91 | } | ||
| 92 | else | ||
| 93 | printf ("Your kung-fu is bad!\n"); | ||
| 94 | |||
| 95 | icmp->icmp_hun.ih_idseq.icd_id = LAME_RANDOM; | ||
| 96 | gettimeofday (&tv, NULL); | ||
| 97 | memcpy (icmp->icmp_dun.id_data, &tv, sizeof (tv)); | ||
| 98 | |||
| 99 | sum = in_cksum ((u_short *) icmp, ICMP_SIZE + len); | ||
| 100 | icmp->icmp_cksum = CKSUM_CARRY (sum); | ||
| 101 | } | ||
| 102 | |||
| 103 | |||
| 104 | /* | ||
| 105 | * add udp-header [no checksum] | ||
| 106 | * len = len of payload | ||
| 107 | */ | ||
| 108 | void | ||
| 109 | add_udphdr(unsigned char *pkt, struct net_tuple *nt, int len) | ||
| 110 | { | ||
| 111 | struct udphdr udp; | ||
| 112 | |||
| 113 | memset(&udp, 0, sizeof(udp)); | ||
| 114 | udp.uh_sport = nt->sport; | ||
| 115 | udp.uh_dport = nt->dport; | ||
| 116 | udp.uh_ulen = htons(len + UDP_SIZE); | ||
| 117 | udp.uh_sum = 0; /* no checksum !*/ | ||
| 118 | memcpy(pkt, &udp, sizeof(udp)); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | /* | ||
| 123 | * len = len of payload | ||
| 124 | */ | ||
| 125 | void | ||
| 126 | add_tcphdr (unsigned char *pkt, struct net_tuple *nt, uint8_t flags, int len, | ||
| 127 | tcp_seq * seq, tcp_seq * ack) | ||
| 128 | { | ||
| 129 | struct tcphdr tcp; | ||
| 130 | struct tcphdr *tcpptr; | ||
| 131 | struct _fakehead fakehead; | ||
| 132 | int sum; | ||
| 133 | |||
| 134 | memset (&tcp, 0, sizeof (tcp)); | ||
| 135 | memset (&fakehead, 0, sizeof (fakehead)); | ||
| 136 | tcp.th_dport = nt->dport; | ||
| 137 | tcp.th_sport = nt->sport; | ||
| 138 | fakehead.saddr = nt->src; | ||
| 139 | fakehead.daddr = nt->dst; | ||
| 140 | fakehead.zero = 0; | ||
| 141 | fakehead.protocol = IPPROTO_TCP; | ||
| 142 | fakehead.tot_len = htons (TCP_SIZE + len); | ||
| 143 | sum = in_cksum ((u_short *) & fakehead, sizeof (fakehead)); | ||
| 144 | tcp.th_off = TCP_SIZE >> 2; | ||
| 145 | if (seq != NULL) | ||
| 146 | tcp.th_seq = *seq; | ||
| 147 | else | ||
| 148 | tcp.th_seq = LAME_RANDOM; | ||
| 149 | if (ack != NULL) | ||
| 150 | tcp.th_ack = *ack; | ||
| 151 | tcp.th_flags |= flags; /* ADD the flags */ | ||
| 152 | tcp.th_win = htons (0x3fff); | ||
| 153 | memcpy (pkt, &tcp, sizeof (tcp)); | ||
| 154 | sum += in_cksum ((u_short *) pkt, sizeof (tcp) + len); | ||
| 155 | tcpptr = (struct tcphdr *)pkt; | ||
| 156 | tcpptr->th_sum = CKSUM_CARRY (sum); | ||
| 157 | } | ||
| 158 | |||
| 159 | |||
| 160 | /* | ||
| 161 | * add's ipv4-header of 20 bytes without any options | ||
| 162 | * - IPPROTO_TCP and 40 bytes total length | ||
| 163 | */ | ||
| 164 | void | ||
| 165 | add_iphdr (unsigned char *pkt, uint8_t ip_p, struct net_tuple *nt, int len) | ||
| 166 | { | ||
| 167 | struct ip ip; | ||
| 168 | memset (&ip, 0, IP_SIZE); | ||
| 169 | ip.ip_hl = sizeof (ip) >> 2; | ||
| 170 | ip.ip_v = 4; | ||
| 171 | /*ip->tos = 0; */ | ||
| 172 | ip.ip_len = htons (len + IP_SIZE); /* htons ? */ | ||
| 173 | /*ip->id = 0; done by kernel */ | ||
| 174 | /*ip->frag_off = 0; */ | ||
| 175 | ip.ip_ttl = 0xff; | ||
| 176 | ip.ip_p = ip_p; | ||
| 177 | /*.ip->check = 0; done by kernel */ | ||
| 178 | ip.ip_src.s_addr = nt->src; | ||
| 179 | ip.ip_dst.s_addr = nt->dst; | ||
| 180 | memcpy (pkt, &ip, sizeof (ip)); | ||
| 181 | } | ||
| 182 | |||
| 183 | /* | ||
| 184 | * send out ipv4-packet | ||
| 185 | * with data 'pkt' of length 'len' | ||
| 186 | * returns the number of characters sent, or -1 if an error occured | ||
| 187 | */ | ||
| 188 | int | ||
| 189 | send_ipv4 (int sox, u_char * pkt, size_t len) | ||
| 190 | { | ||
| 191 | struct sockaddr_in to; | ||
| 192 | to.sin_family = AF_INET; | ||
| 193 | memcpy (&to.sin_addr.s_addr, (pkt + 4 * 4), sizeof (u_long)); | ||
| 194 | return (sendto (sox, pkt, len, 0, (struct sockaddr *) &to, sizeof (to))); | ||
| 195 | } | ||
| 196 | |||
| 197 | |||
| 198 | /* | ||
| 199 | * small/lame tcp userland stack | ||
| 200 | * give 'best' tcp-answer to a tcp-packet | ||
| 201 | * return 0 on success | ||
| 202 | * payload + len are optional | ||
| 203 | */ | ||
| 204 | int | ||
| 205 | answer_tcp (int sox, struct ip *ip, struct tcphdr *tcp, uint8_t flags, | ||
| 206 | u_char * payload, uint len) | ||
| 207 | { | ||
| 208 | static u_char *outpkt = NULL; | ||
| 209 | static int msize = 0; | ||
| 210 | struct net_tuple nt; | ||
| 211 | tcp_seq outack; | ||
| 212 | |||
| 213 | if (TCP_SIZE + IP_SIZE + len > msize) | ||
| 214 | { | ||
| 215 | outpkt = realloc (outpkt, TCP_SIZE + IP_SIZE + len); | ||
| 216 | msize = TCP_SIZE + IP_SIZE + len; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (outpkt == NULL) | ||
| 220 | return (-1); | ||
| 221 | if (ip == NULL) | ||
| 222 | return (-1); | ||
| 223 | if (tcp == NULL) | ||
| 224 | return (-1); | ||
| 225 | |||
| 226 | memset (outpkt, 0, TCP_SIZE + IP_SIZE + len); | ||
| 227 | |||
| 228 | nt.sport = tcp->th_dport; | ||
| 229 | nt.dport = tcp->th_sport; | ||
| 230 | nt.src = ip->ip_dst.s_addr; | ||
| 231 | nt.dst = ip->ip_src.s_addr; | ||
| 232 | |||
| 233 | if (payload != NULL) | ||
| 234 | memcpy (outpkt + TCP_SIZE + IP_SIZE, payload, len); | ||
| 235 | |||
| 236 | outack = ntohl (tcp->th_seq) + ntohs (ip->ip_len) - (tcp->th_off << 2) - | ||
| 237 | (ip->ip_hl << 2); | ||
| 238 | if (tcp->th_flags & (TH_SYN | TH_FIN)) | ||
| 239 | outack++; | ||
| 240 | |||
| 241 | outack = htonl (outack); | ||
| 242 | add_tcphdr (outpkt + IP_SIZE, &nt, flags, len, &tcp->th_ack, &outack); | ||
| 243 | |||
| 244 | add_iphdr (outpkt, IPPROTO_TCP, &nt, TCP_SIZE + len); | ||
| 245 | |||
| 246 | send_ipv4 (sox, outpkt, IP_SIZE + TCP_SIZE + len); | ||
| 247 | |||
| 248 | return (0); | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | /* | ||
| 253 | * return 0 if ip-header is valid [length only] | ||
| 254 | * len = length from the begin of the ip-header [20 for normal ip header] | ||
| 255 | */ | ||
| 256 | int | ||
| 257 | vrfy_ip (struct ip *ip, uint32_t len, u_short * ip_options) | ||
| 258 | { | ||
| 259 | u_short _ip_options; | ||
| 260 | |||
| 261 | if (len < sizeof (*ip)) | ||
| 262 | return (-1); | ||
| 263 | |||
| 264 | _ip_options = ip->ip_hl << 2; | ||
| 265 | if (_ip_options > len) | ||
| 266 | return (-1); | ||
| 267 | |||
| 268 | if (_ip_options > 0xefff) | ||
| 269 | return -1; | ||
| 270 | |||
| 271 | if (_ip_options < sizeof (*ip)) | ||
| 272 | _ip_options = 0; | ||
| 273 | else | ||
| 274 | _ip_options -= sizeof (*ip); | ||
| 275 | |||
| 276 | *ip_options = _ip_options; | ||
| 277 | return (0); | ||
| 278 | } | ||
| 279 | |||
| 280 | |||
| 281 | /* | ||
| 282 | * len = len of tcp-header + tcp_options + tcp_data (from wire). | ||
| 283 | * returns 0 if tcp-header is valid [length check only] | ||
| 284 | * returns options | ||
| 285 | * != 0 if something went wrong [header size etc] | ||
| 286 | */ | ||
| 287 | int | ||
| 288 | vrfy_tcp (struct tcphdr *tcp, uint32_t plen, u_short * tcp_options) | ||
| 289 | { | ||
| 290 | u_short _tcp_options; | ||
| 291 | |||
| 292 | if (plen < sizeof (*tcp)) | ||
| 293 | return (-1); | ||
| 294 | |||
| 295 | _tcp_options = tcp->th_off << 2; | ||
| 296 | if (_tcp_options > plen) | ||
| 297 | return (-1); | ||
| 298 | if (_tcp_options > 0xefff) /* this is quite to large for me */ | ||
| 299 | return -1; | ||
| 300 | |||
| 301 | if (_tcp_options <= sizeof (*tcp)) | ||
| 302 | _tcp_options = 0; | ||
| 303 | else | ||
| 304 | _tcp_options -= sizeof (*tcp); | ||
| 305 | |||
| 306 | *tcp_options = _tcp_options; | ||
| 307 | |||
| 308 | return (0); | ||
| 309 | } | ||
| 310 | |||
| 311 | int | ||
| 312 | vrfy_udp (struct udphdr *udp, uint32_t len) | ||
| 313 | { | ||
| 314 | |||
| 315 | if (len < sizeof(*udp)) | ||
| 316 | return (-1); | ||
| 317 | |||
| 318 | return (0); | ||
| 319 | } | ||
| 320 | |||
| 321 | /* | ||
| 322 | * decode NetworkVirtualTerminal Data | ||
| 323 | * data = the raw (nvt)-input | ||
| 324 | * len = length of 'data' | ||
| 325 | * ans = the nvt-answer (IAC don't) | ||
| 326 | * anslen = the calculated anser length | ||
| 327 | * res = the decoded nvt data (login: prompt etc) | ||
| 328 | * reslen = the calculates decoded data length | ||
| 329 | * All parameters must be given (NULL is not allowed) | ||
| 330 | * and initialized | ||
| 331 | * return -1 on failure | ||
| 332 | * return 0 on success | ||
| 333 | * rfc-will: anslen, reslen < len | ||
| 334 | */ | ||
| 335 | #define IACFOUND 0x01 | ||
| 336 | #define DOFOUND 0x02 | ||
| 337 | #define UNKNOWNOPT 0x04 | ||
| 338 | #define SUBNEGO 0x08 | ||
| 339 | #define CRFOUND 0x10 | ||
| 340 | |||
| 341 | #define NVT_SE 0xf0 | ||
| 342 | #define NVT_SB 0xfa | ||
| 343 | #define NVT_WILL 0xfb | ||
| 344 | #define NVT_WONT 0xfc | ||
| 345 | #define NVT_DO 0xfd | ||
| 346 | #define NVT_DONT 0xfe | ||
| 347 | #define IAC 0xff | ||
| 348 | |||
| 349 | int | ||
| 350 | decode_nvt(u_char *data, uint len, u_char *ans, uint *anslen, | ||
| 351 | u_char *res, uint *reslen) | ||
| 352 | { | ||
| 353 | u_char *ptr = data; | ||
| 354 | u_char *ansptr = ans; | ||
| 355 | u_char *resptr = res; | ||
| 356 | u_char flags = 0; | ||
| 357 | int i = 0; | ||
| 358 | u_char c; | ||
| 359 | |||
| 360 | if ( (data == NULL) || (ans == NULL) || (res == NULL)) | ||
| 361 | return(0); | ||
| 362 | |||
| 363 | *anslen = 0; | ||
| 364 | *reslen = 0; | ||
| 365 | |||
| 366 | while (1) | ||
| 367 | { | ||
| 368 | if (i++ >= len) | ||
| 369 | break; | ||
| 370 | c = *ptr++; | ||
| 371 | |||
| 372 | if (flags & UNKNOWNOPT) | ||
| 373 | { | ||
| 374 | flags = 0; | ||
| 375 | continue; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (flags & IACFOUND) | ||
| 379 | { | ||
| 380 | if (c == IAC) /* IAC IAC */ | ||
| 381 | { | ||
| 382 | *resptr++ = IAC; | ||
| 383 | flags = 0; /* reset */ | ||
| 384 | continue; | ||
| 385 | } | ||
| 386 | |||
| 387 | if (flags & SUBNEGO) | ||
| 388 | { | ||
| 389 | if (c == NVT_SE) /* subnegotiation end */ | ||
| 390 | flags = 0; | ||
| 391 | continue; | ||
| 392 | } | ||
| 393 | |||
| 394 | if (flags & DOFOUND) | ||
| 395 | { | ||
| 396 | /* 3com switch test if (c == 0x03) | ||
| 397 | { | ||
| 398 | *ansptr++ = IAC; | ||
| 399 | *ansptr++ = NVT_DO; | ||
| 400 | *ansptr++ = 0x03; | ||
| 401 | *ansptr++ = IAC; | ||
| 402 | *ansptr++ = NVT_WILL; | ||
| 403 | *ansptr++ = 0x18; | ||
| 404 | *ansptr++ = IAC; | ||
| 405 | *ansptr++ = NVT_WILL; | ||
| 406 | *ansptr++ = 0x1f; | ||
| 407 | *ansptr++ = IAC; | ||
| 408 | *ansptr++ = NVT_WILL; | ||
| 409 | *ansptr++ = 0x20; | ||
| 410 | *ansptr++ = IAC; | ||
| 411 | *ansptr++ = NVT_WILL; | ||
| 412 | *ansptr++ = 0x21; | ||
| 413 | *ansptr++ = IAC; | ||
| 414 | *ansptr++ = NVT_WILL; | ||
| 415 | *ansptr++ = 0x22; | ||
| 416 | *ansptr++ = IAC; | ||
| 417 | *ansptr++ = NVT_WILL; | ||
| 418 | *ansptr++ = 0x27; | ||
| 419 | *ansptr++ = IAC; | ||
| 420 | *ansptr++ = NVT_DO; | ||
| 421 | *ansptr++ = 0x05; | ||
| 422 | *ansptr++ = IAC; | ||
| 423 | *ansptr++ = NVT_WILL; | ||
| 424 | *ansptr++ = 0x23; | ||
| 425 | *anslen = *anslen + 24; | ||
| 426 | |||
| 427 | } | ||
| 428 | */ | ||
| 429 | *ansptr++ = IAC; | ||
| 430 | *ansptr++ = NVT_WONT; /* me is dump - im a kid */ | ||
| 431 | *ansptr++ = c; | ||
| 432 | *anslen = *anslen + 3; | ||
| 433 | flags = 0; | ||
| 434 | continue; | ||
| 435 | } | ||
| 436 | |||
| 437 | if (c == NVT_SB) /* subnegotiation */ | ||
| 438 | { | ||
| 439 | flags = SUBNEGO; | ||
| 440 | continue; | ||
| 441 | } | ||
| 442 | |||
| 443 | if (c == NVT_DO) /* DO ... */ | ||
| 444 | { | ||
| 445 | flags |= DOFOUND; | ||
| 446 | continue; | ||
| 447 | } else { | ||
| 448 | flags = ~(IACFOUND | DOFOUND); | ||
| 449 | flags |= UNKNOWNOPT; /* skip next */ | ||
| 450 | continue; | ||
| 451 | } | ||
| 452 | |||
| 453 | } | ||
| 454 | |||
| 455 | if (flags & SUBNEGO) | ||
| 456 | continue; | ||
| 457 | |||
| 458 | if (c == IAC) | ||
| 459 | { | ||
| 460 | flags = IACFOUND; /* just IAC */ | ||
| 461 | continue; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (flags & CRFOUND) | ||
| 465 | { | ||
| 466 | if (c == '\0') | ||
| 467 | { | ||
| 468 | flags &= ~CRFOUND; | ||
| 469 | *res++ = '\r'; | ||
| 470 | *reslen = *reslen + 1; | ||
| 471 | continue; | ||
| 472 | } | ||
| 473 | if (c == '\n') | ||
| 474 | { | ||
| 475 | flags &= ~CRFOUND; | ||
| 476 | *res++ = '\n'; | ||
| 477 | *reslen = *reslen + 1; | ||
| 478 | continue; | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | if (c == '\r') | ||
| 483 | { | ||
| 484 | flags |= CRFOUND; | ||
| 485 | continue; | ||
| 486 | } | ||
| 487 | |||
| 488 | *res++ = c; | ||
| 489 | *reslen = *reslen + 1; | ||
| 490 | |||
| 491 | } | ||
| 492 | |||
| 493 | return(0); | ||
| 494 | } | ||
| 495 | |||
| 496 | |||
| 497 | |||
diff --git a/other/b-scan/src/restore.c b/other/b-scan/src/restore.c new file mode 100644 index 0000000..45edbb8 --- /dev/null +++ b/other/b-scan/src/restore.c | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | /* | ||
| 2 | * bscan, restore.c | ||
| 3 | * this is the buggies part of the entire scanner :> | ||
| 4 | * many buffer overflows in here | ||
| 5 | */ | ||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/system.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | |||
| 12 | extern struct _opt *opt; | ||
| 13 | |||
| 14 | #define RESTORE_FILE "restore.bscan" | ||
| 15 | |||
| 16 | #define R_ARGVLIST "argvlist" | ||
| 17 | #define R_MODARG "modarg" | ||
| 18 | #define R_LIMIT "limit" | ||
| 19 | #define R_FLAGS "flags" | ||
| 20 | #define R_DELAY "delay" | ||
| 21 | #define R_PSCANSTAT "pscanstat" | ||
| 22 | #define R_IPSCAN_COUNT "ipscan_count" | ||
| 23 | #define R_IPTOTSCAN_C "iptotscan_count" | ||
| 24 | #define R_BSENT_COUNT "bsent_count" | ||
| 25 | #define R_IP_OFFSET "ip_offset" | ||
| 26 | #define R_IP_BLKLEN "ip_blklen" | ||
| 27 | #define R_IP_POS "ip_pos" | ||
| 28 | #define R_SCAN_TIME "scan_time" | ||
| 29 | #define R_SPF_SIP "spf_sip" | ||
| 30 | #define R_SPF_SMAC "spf_smac" | ||
| 31 | #define R_SNARFICMP_C "snarf.icmp_c" | ||
| 32 | #define R_SNARFCLOSE_C "snarf.close_c" | ||
| 33 | #define R_SNARFOPEN_C "snarf.open_c" | ||
| 34 | #define R_SNARFREFUSED_C "snarf.refused_c" | ||
| 35 | #define R_IDEV "lnet.device" | ||
| 36 | #define R_HOSTFILE "hostfile" | ||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * save everything that is required to restore/restart an inter session | ||
| 41 | */ | ||
| 42 | int | ||
| 43 | write_restore () | ||
| 44 | { | ||
| 45 | u_char *p = (u_char *) opt->spf_smac; | ||
| 46 | FILE *fptr; | ||
| 47 | char **myargv = opt->argvlist; | ||
| 48 | struct timeval tv; | ||
| 49 | #ifdef HAVE_DLSYM | ||
| 50 | int c=0; | ||
| 51 | extern const int modcount; | ||
| 52 | extern const struct _mods mods[MAX_MODULES]; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | if (opt->flags & OPT_VERB) | ||
| 56 | fprintf (stderr, "Writing restore file '%s'\n", RESTORE_FILE); | ||
| 57 | |||
| 58 | if ((fptr = fopen (RESTORE_FILE, "w+")) == NULL) | ||
| 59 | return (-1); | ||
| 60 | |||
| 61 | fprintf (fptr, "# bscan restore file. This is an automatic generated\n"); | ||
| 62 | fprintf (fptr, "# file. Don't edit.\n"); | ||
| 63 | fprintf (fptr, "#\n"); | ||
| 64 | |||
| 65 | fprintf (fptr, R_ARGVLIST ": "); | ||
| 66 | if ((opt->target != NULL) && !(opt->flags & OPT_HOSTFILE)) | ||
| 67 | fprintf (fptr, "\"%s\" ", opt->target); | ||
| 68 | while (*myargv != NULL) | ||
| 69 | fprintf (fptr, "\"%s\" ", *myargv++); | ||
| 70 | fprintf (fptr, "\n"); | ||
| 71 | |||
| 72 | #ifdef HAVE_DLSYM | ||
| 73 | for (c = 0; c < modcount; c++) | ||
| 74 | fprintf(fptr, R_MODARG ": %s\n", mods[c].modarg); | ||
| 75 | #endif | ||
| 76 | |||
| 77 | fprintf (fptr, R_LIMIT ": %u\n", opt->limit); | ||
| 78 | fprintf (fptr, R_DELAY ": %u\n", opt->delay); | ||
| 79 | fprintf (fptr, R_PSCANSTAT ": %u\n", opt->pscanstat); | ||
| 80 | fprintf (fptr, R_IPSCAN_COUNT ": %lu\n", opt->ipscan_count); | ||
| 81 | fprintf (fptr, R_IPTOTSCAN_C ": %lu\n", opt->iptotscan_count); | ||
| 82 | fprintf (fptr, R_BSENT_COUNT ": %lu\n", opt->bsent_count); | ||
| 83 | fprintf (fptr, R_IP_OFFSET ": %lu\n", opt->ip_offset); | ||
| 84 | fprintf (fptr, R_IP_BLKLEN ": %lu\n", opt->ip_blklen); | ||
| 85 | fprintf (fptr, R_IP_POS ": %lu\n", opt->ip_pos); | ||
| 86 | fprintf (fptr, R_FLAGS ": %4.4x\n", opt->flags); | ||
| 87 | memcpy(&tv, &opt->tv2, sizeof(tv)); | ||
| 88 | time_diff (&opt->scan_start, &tv); | ||
| 89 | fprintf (fptr, R_SCAN_TIME ": %ld\n", (long)tv.tv_sec); | ||
| 90 | fprintf (fptr, R_SPF_SIP ": %s\n", int_ntoa (opt->nt.src)); | ||
| 91 | fprintf (fptr, R_SPF_SMAC ": %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
| 92 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 93 | fprintf (fptr, R_SNARFICMP_C ": %lu\n", opt->snarf.icmp_c); | ||
| 94 | fprintf (fptr, R_SNARFCLOSE_C ": %lu\n", opt->snarf.close_c); | ||
| 95 | fprintf (fptr, R_SNARFOPEN_C ": %lu\n", opt->snarf.open_c); | ||
| 96 | fprintf (fptr, R_SNARFREFUSED_C ": %lu\n", opt->snarf.refused_c); | ||
| 97 | if (opt->lnet.device != NULL) | ||
| 98 | fprintf (fptr, R_IDEV ": %s\n", opt->lnet.device); | ||
| 99 | else | ||
| 100 | fprintf (fptr, R_IDEV ": \n"); | ||
| 101 | |||
| 102 | if (opt->hostfile != NULL) | ||
| 103 | fprintf (fptr, R_HOSTFILE ": %s\n", opt->hostfile); | ||
| 104 | else | ||
| 105 | fprintf (fptr, R_HOSTFILE ": \n"); | ||
| 106 | |||
| 107 | fclose (fptr); | ||
| 108 | |||
| 109 | return (0); | ||
| 110 | } | ||
| 111 | |||
| 112 | int | ||
| 113 | restore_processtag (char *tag, char *arg) | ||
| 114 | { | ||
| 115 | char *ptr = arg; | ||
| 116 | int c = 0; | ||
| 117 | |||
| 118 | if ((arg == NULL) || (tag == NULL)) | ||
| 119 | return (-1); | ||
| 120 | |||
| 121 | if (!strcmp (R_ARGVLIST, tag)) | ||
| 122 | if (strlen (arg) > 0) | ||
| 123 | { | ||
| 124 | int toggle = 0; | ||
| 125 | while (*ptr != '\0') | ||
| 126 | if (*ptr++ == '"') | ||
| 127 | c++; | ||
| 128 | ptr = arg; | ||
| 129 | c = c / 2; | ||
| 130 | if (c <= 0) | ||
| 131 | return (-1); /* this should not happen */ | ||
| 132 | if ((opt->argvlist = malloc ((c + 1) * sizeof (char *))) == NULL) | ||
| 133 | return (-1); | ||
| 134 | for (toggle = 0; toggle < c + 1; toggle++) | ||
| 135 | opt->argvlist[toggle] = NULL; | ||
| 136 | |||
| 137 | toggle = 0; | ||
| 138 | ptr = arg; | ||
| 139 | c = 0; | ||
| 140 | while (*ptr != '\0') | ||
| 141 | if (*ptr++ == '"') | ||
| 142 | { | ||
| 143 | *(ptr - 1) = '\0'; | ||
| 144 | if (toggle++ == 1) | ||
| 145 | { | ||
| 146 | toggle = 0; | ||
| 147 | continue; | ||
| 148 | } | ||
| 149 | opt->argvlist[c++] = ptr; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* strings are ready + \0 terminated here */ | ||
| 153 | |||
| 154 | for (toggle = 0; toggle < c; toggle++) | ||
| 155 | opt->argvlist[toggle] = strdup (opt->argvlist[toggle]); | ||
| 156 | |||
| 157 | return (0); | ||
| 158 | } | ||
| 159 | |||
| 160 | if (!strcmp (R_MODARG, tag)) | ||
| 161 | loadinit_mod(arg); | ||
| 162 | |||
| 163 | if (!strcmp (R_DELAY, tag)) | ||
| 164 | opt->delay = atoi (arg); | ||
| 165 | if (!strcmp (R_LIMIT, tag)) | ||
| 166 | opt->limit = atoi (arg); | ||
| 167 | if (!strcmp (R_PSCANSTAT, tag)) | ||
| 168 | opt->pscanstat = atoi (arg); | ||
| 169 | if (!strcmp (R_IPSCAN_COUNT, tag)) | ||
| 170 | opt->ipscan_count = strtoul (arg, NULL, 10); | ||
| 171 | if (!strcmp (R_IPTOTSCAN_C, tag)) | ||
| 172 | opt->iptotscan_count = strtoul (arg, NULL, 10); | ||
| 173 | if (!strcmp (R_BSENT_COUNT, tag)) | ||
| 174 | opt->bsent_count = strtoul (arg, NULL, 10); | ||
| 175 | if (!strcmp (R_IP_OFFSET, tag)) | ||
| 176 | opt->ip_offset = strtoul (arg, NULL, 10); | ||
| 177 | if (!strcmp (R_IP_BLKLEN, tag)) | ||
| 178 | opt->ip_blklen = strtoul (arg, NULL, 10); | ||
| 179 | if (!strcmp (R_IP_POS, tag)) | ||
| 180 | opt->ip_pos = strtoul (arg, NULL, 10); | ||
| 181 | if (!strcmp (R_SCAN_TIME, tag)) | ||
| 182 | { /* doing the date trick ..we had a scannerdowntime.. */ | ||
| 183 | gettimeofday (&opt->scan_start, NULL); | ||
| 184 | opt->scan_start.tv_sec = | ||
| 185 | opt->scan_start.tv_sec - strtoul (arg, NULL, 10); | ||
| 186 | } | ||
| 187 | if (!strcmp (R_SPF_SIP, tag)) | ||
| 188 | opt->nt.src = inet_addr (arg); | ||
| 189 | if (!strcmp (R_SPF_SMAC, tag)) | ||
| 190 | { | ||
| 191 | unsigned short int sp[6]; | ||
| 192 | sscanf (arg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 193 | &sp[3], &sp[4], &sp[5]); | ||
| 194 | for (c = 0; c < 6; c++) | ||
| 195 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 196 | |||
| 197 | } | ||
| 198 | if (!strcmp (R_FLAGS, tag)) | ||
| 199 | { | ||
| 200 | sscanf (arg, "%hx", &opt->flags); | ||
| 201 | opt->flags &= ~OPT_ABRT; | ||
| 202 | opt->flags &= ~OPT_REST; | ||
| 203 | } | ||
| 204 | if (!strcmp (R_SNARFICMP_C, tag)) | ||
| 205 | opt->snarf.icmp_c = strtoul (arg, NULL, 10); | ||
| 206 | if (!strcmp (R_SNARFCLOSE_C, tag)) | ||
| 207 | opt->snarf.close_c = strtoul (arg, NULL, 10); | ||
| 208 | if (!strcmp (R_SNARFOPEN_C, tag)) | ||
| 209 | opt->snarf.open_c = strtoul (arg, NULL, 10); | ||
| 210 | if (!strcmp (R_SNARFREFUSED_C, tag)) | ||
| 211 | opt->snarf.refused_c = strtoul (arg, NULL, 10); | ||
| 212 | if (!strcmp (R_IDEV, tag)) | ||
| 213 | if (strlen (arg) > 0) | ||
| 214 | opt->lnet.device = strdup (arg); | ||
| 215 | if (!strcmp (R_HOSTFILE, tag)) | ||
| 216 | if (strlen (arg) > 0) | ||
| 217 | opt->hostfile = strdup (arg); | ||
| 218 | |||
| 219 | return (0); | ||
| 220 | } | ||
| 221 | |||
| 222 | |||
| 223 | /* | ||
| 224 | * read restore-file | ||
| 225 | * return 0 on success, -1 on failure | ||
| 226 | * sscanf is exploitable. have fun. What kind of stupid admin | ||
| 227 | * who set a +s on this programm. harhar | ||
| 228 | */ | ||
| 229 | int | ||
| 230 | read_restore (char *filename) | ||
| 231 | { | ||
| 232 | FILE *fptr; | ||
| 233 | char buf[1024]; | ||
| 234 | char tag[1024], arg[1024]; | ||
| 235 | |||
| 236 | if (opt->flags & OPT_VERB) | ||
| 237 | fprintf (stderr, "Reading restore file '%s'.\n", filename); | ||
| 238 | |||
| 239 | if ((fptr = fopen (filename, "rb")) == NULL) | ||
| 240 | { | ||
| 241 | printf ("OPEN FAILED\n"); | ||
| 242 | return (-1); | ||
| 243 | } | ||
| 244 | |||
| 245 | while (fgets (buf, sizeof (buf), fptr) != NULL) | ||
| 246 | { | ||
| 247 | if (strchr (buf, '#') != NULL) | ||
| 248 | continue; | ||
| 249 | |||
| 250 | tag[0] = arg[0] = '\0'; | ||
| 251 | sscanf (buf, "%[^: ]%*[: \t]%[^#\n]%*[\n]", tag, arg); | ||
| 252 | |||
| 253 | if (restore_processtag (tag, arg) == -1) | ||
| 254 | { | ||
| 255 | fprintf (stderr, "error while processing restore file with '%s:%s' \n ", tag, arg); | ||
| 256 | exit (-1); | ||
| 257 | } | ||
| 258 | |||
| 259 | } | ||
| 260 | |||
| 261 | fclose (fptr); | ||
| 262 | return (0); | ||
| 263 | } | ||
diff --git a/other/b-scan/src/signal.c b/other/b-scan/src/signal.c new file mode 100644 index 0000000..a2af01f --- /dev/null +++ b/other/b-scan/src/signal.c | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #include <signal.h> | ||
| 2 | #include <bscan/signal.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * add the signals that you want to be set to default-action | ||
| 6 | */ | ||
| 7 | int | ||
| 8 | do_sig_setall (sighandler_t action) | ||
| 9 | { | ||
| 10 | #ifdef SIGHUP | ||
| 11 | signal (SIGHUP, action); | ||
| 12 | #endif | ||
| 13 | #ifdef SIGINT | ||
| 14 | signal (SIGINT, action); | ||
| 15 | #endif | ||
| 16 | #ifdef SIGQUIT | ||
| 17 | signal (SIGQUIT, action); | ||
| 18 | #endif | ||
| 19 | #ifdef SIGABRT | ||
| 20 | signal (SIGABRT, action); | ||
| 21 | #endif | ||
| 22 | #ifdef SIGPIPE | ||
| 23 | signal (SIGPIPE, action); | ||
| 24 | #endif | ||
| 25 | #ifdef SIGALRM | ||
| 26 | signal (SIGALRM, action); | ||
| 27 | #endif | ||
| 28 | #ifdef SIGTERM | ||
| 29 | signal (SIGTERM, action); | ||
| 30 | #endif | ||
| 31 | #ifdef SIGUSR1 | ||
| 32 | signal (SIGUSR1, action); | ||
| 33 | #endif | ||
| 34 | #ifdef SIGUSR1 | ||
| 35 | signal (SIGUSR1, action); | ||
| 36 | #endif | ||
| 37 | #ifdef SIGCHLD | ||
| 38 | signal (SIGCHLD, action); | ||
| 39 | #endif | ||
| 40 | #ifdef SIGCOMT | ||
| 41 | signal (SIGCOMT, action); | ||
| 42 | #endif | ||
| 43 | #ifdef SIGSTOP | ||
| 44 | signal (SIGSTOP, action); | ||
| 45 | #endif | ||
| 46 | #ifdef SIGTSTP | ||
| 47 | signal (SIGTSTP, action); | ||
| 48 | #endif | ||
| 49 | #ifdef SIGTTIM | ||
| 50 | signal (SIGTTIM, action); | ||
| 51 | #endif | ||
| 52 | #ifdef SIGTTOU | ||
| 53 | signal (SIGTTOU, action); | ||
| 54 | #endif | ||
| 55 | |||
| 56 | return (0); | ||
| 57 | } | ||
| 58 | |||
| 59 | /* | ||
| 60 | * sig-ctl function. | ||
| 61 | * atm only SIG_DFL implemented.... | ||
| 62 | */ | ||
| 63 | int | ||
| 64 | sigctl (int flags, sighandler_t action) | ||
| 65 | { | ||
| 66 | int ret = 0; | ||
| 67 | |||
| 68 | if (flags & SIG_SETALL) | ||
| 69 | ret = do_sig_setall (action); | ||
| 70 | |||
| 71 | return (ret); | ||
| 72 | } | ||
diff --git a/other/b-scan/src/snarf.c b/other/b-scan/src/snarf.c new file mode 100644 index 0000000..fce8b9e --- /dev/null +++ b/other/b-scan/src/snarf.c | |||
| @@ -0,0 +1,211 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | |||
| 3 | #include <sys/types.h> | ||
| 4 | #include <sys/socket.h> | ||
| 5 | #ifndef __FAVOR_BSD | ||
| 6 | #define __FAVOR_BSD | ||
| 7 | #endif | ||
| 8 | #ifndef __USE_BSD | ||
| 9 | #define __USE_BSD | ||
| 10 | #endif | ||
| 11 | #ifndef __BSD_SOURCE | ||
| 12 | #define __BSD_SOURCE | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #include <pcap.h> | ||
| 16 | #include <bscan/bscan.h> | ||
| 17 | #include <bscan/snarf.h> | ||
| 18 | #include <bscan/module.h> | ||
| 19 | #include <bscan/signal.h> | ||
| 20 | |||
| 21 | pcap_t *ip_socket; | ||
| 22 | |||
| 23 | /* | ||
| 24 | * some global variables (modules need access etc) | ||
| 25 | */ | ||
| 26 | int dlt_len; | ||
| 27 | u_char *align_buf = NULL; | ||
| 28 | unsigned short ip_options = 0; | ||
| 29 | struct ip *ip; | ||
| 30 | struct Ether_header *eth; | ||
| 31 | u_int pcaplen, plen; | ||
| 32 | struct timeval *pts; | ||
| 33 | |||
| 34 | extern struct _opt *opt; | ||
| 35 | #ifdef HAVE_DLSYM | ||
| 36 | extern const int modcount; | ||
| 37 | extern const struct _mods mods[MAX_MODULES]; | ||
| 38 | #endif | ||
| 39 | |||
| 40 | |||
| 41 | /* | ||
| 42 | * answer on arp-request. | ||
| 43 | */ | ||
| 44 | static void | ||
| 45 | handle_arp (struct pcap_pkthdr *p, struct Ether_header *eth, | ||
| 46 | struct Arphdr *arp) | ||
| 47 | { | ||
| 48 | u_long *ipdummy = (u_long *) arp->ar_tip; | ||
| 49 | |||
| 50 | if (ntohs (arp->ar_op) != ARPOP_REQUEST) | ||
| 51 | return; | ||
| 52 | |||
| 53 | #ifdef DEBUG | ||
| 54 | printf ("ARPG request for %s\n", int_ntoa ((u_long) * ipdummy)); | ||
| 55 | #endif | ||
| 56 | if (*ipdummy == opt->nt.src) | ||
| 57 | play_arpg (&opt->lnet, arp->ar_tip, (u_char *) opt->spf_smac, | ||
| 58 | (u_char *) arp->ar_sip, eth->ether_shost); | ||
| 59 | } | ||
| 60 | |||
| 61 | |||
| 62 | /* | ||
| 63 | * called by libpcap | ||
| 64 | */ | ||
| 65 | static void | ||
| 66 | filter_packet (u_char * u, struct pcap_pkthdr *p, u_char * packet) | ||
| 67 | { | ||
| 68 | int c; | ||
| 69 | static u_char *align_eth = NULL; | ||
| 70 | |||
| 71 | if (p->len < (dlt_len + sizeof (struct Arphdr))) | ||
| 72 | return; | ||
| 73 | if (align_buf == NULL) | ||
| 74 | align_buf = (u_char *) malloc (2048); | ||
| 75 | if (align_eth == NULL) | ||
| 76 | align_eth = (u_char *) malloc (42); | ||
| 77 | |||
| 78 | memcpy ((char *) align_buf, (char *) (packet + dlt_len), p->caplen); | ||
| 79 | memcpy ((char *) align_eth, (char *) packet, 42); | ||
| 80 | eth = (struct Ether_header *) (align_eth); | ||
| 81 | ip = (struct ip *) (align_buf); | ||
| 82 | |||
| 83 | if (ntohs (eth->ether_type) == ETHERTYPE_ARP) | ||
| 84 | { | ||
| 85 | handle_arp (p, eth, (struct Arphdr *) (align_buf)); | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | if (ntohs (eth->ether_type) != ETHERTYPE_IP) | ||
| 91 | return; | ||
| 92 | if (vrfy_ip (ip, p->len - dlt_len, &ip_options) != 0) | ||
| 93 | return; | ||
| 94 | if (ip->ip_dst.s_addr != opt->nt.src) | ||
| 95 | return; | ||
| 96 | if (p->len < (dlt_len + sizeof (*ip) + ip_options)) | ||
| 97 | return; | ||
| 98 | |||
| 99 | /* here only 'my-ip' packets */ | ||
| 100 | |||
| 101 | /* module entry point TWO */ | ||
| 102 | /* packet is verifite, belongs to us + valid size */ | ||
| 103 | /* return of module tell us if we should procced as usual or not */ | ||
| 104 | /* DROP is valid here ! */ | ||
| 105 | |||
| 106 | plen = p->len; | ||
| 107 | pcaplen = p->caplen; | ||
| 108 | pts = &p->ts; | ||
| 109 | |||
| 110 | #ifdef HAVE_DLSYM | ||
| 111 | c = 0; | ||
| 112 | while (c < modcount) | ||
| 113 | mods[c++].callmdl (MOD_RCV, opt); | ||
| 114 | #endif | ||
| 115 | |||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | * init pcap network stuff | ||
| 120 | * only called once on startup. | ||
| 121 | * -1 = error | ||
| 122 | * 0 = success | ||
| 123 | */ | ||
| 124 | int | ||
| 125 | pcap_init_net (char *iface, int promisc, char *filter, int *dltlen) | ||
| 126 | { | ||
| 127 | char errbuf[PCAP_ERRBUF_SIZE]; | ||
| 128 | struct bpf_program prog; | ||
| 129 | bpf_u_int32 network, netmask; | ||
| 130 | |||
| 131 | if (iface == NULL) | ||
| 132 | { | ||
| 133 | iface = pcap_lookupdev (errbuf); | ||
| 134 | if (iface == NULL) | ||
| 135 | { | ||
| 136 | fprintf (stderr, "pcap_lookupdev: %s\n", errbuf); | ||
| 137 | return (-1); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | if (pcap_lookupnet (iface, &network, &netmask, errbuf) < 0) | ||
| 141 | { | ||
| 142 | fprintf (stderr, "pcap_lookupnet: %s\n", errbuf); | ||
| 143 | return (-1); | ||
| 144 | } | ||
| 145 | ip_socket = pcap_open_live (iface, 1024, promisc, 1024, errbuf); | ||
| 146 | if (ip_socket == NULL) | ||
| 147 | { | ||
| 148 | fprintf (stderr, "pcap_open_live: %s\n", errbuf); | ||
| 149 | return (-1); | ||
| 150 | } | ||
| 151 | switch (pcap_datalink (ip_socket)) | ||
| 152 | { | ||
| 153 | case DLT_EN10MB: | ||
| 154 | *dltlen = 14; | ||
| 155 | break; | ||
| 156 | case DLT_SLIP: | ||
| 157 | *dltlen = 16; | ||
| 158 | break; | ||
| 159 | default: | ||
| 160 | *dltlen = 4; | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | if (pcap_compile (ip_socket, &prog, filter, 1, netmask) < 0) | ||
| 164 | { | ||
| 165 | fprintf (stderr, "pcap_compile: %s\n", errbuf); | ||
| 166 | return (-1); | ||
| 167 | } | ||
| 168 | if (pcap_setfilter (ip_socket, &prog) < 0) | ||
| 169 | { | ||
| 170 | fprintf (stderr, "pcap_setfilter: %s\n", errbuf); | ||
| 171 | return (-1); | ||
| 172 | } | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | /* | ||
| 179 | * called by main-thread. | ||
| 180 | * doing all the snarf, arp-reply, tcp-stack stuff from here | ||
| 181 | */ | ||
| 182 | void * | ||
| 183 | do_snarf (void *iface) | ||
| 184 | { | ||
| 185 | /* sigctl (SIG_SETALL, SIG_DFL); | ||
| 186 | signal (SIGINT, SIG_IGN); | ||
| 187 | */ | ||
| 188 | |||
| 189 | pcap_init_net (iface, 1, PCAP_FILTER, &dlt_len); | ||
| 190 | |||
| 191 | /* the parent thread should at least w8 until we are ready to rumble */ | ||
| 192 | opt->flags &= ~OPT_W8SEMA; | ||
| 193 | |||
| 194 | while (1) | ||
| 195 | pcap_loop (ip_socket, -1, (pcap_handler) filter_packet, NULL); | ||
| 196 | |||
| 197 | undo_snarf(); /*### fixme, somewhere else */ | ||
| 198 | |||
| 199 | pthread_exit(NULL); /* no return values needed */ | ||
| 200 | return NULL; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* | ||
| 204 | * close everything that was initialized with do_snarf | ||
| 205 | */ | ||
| 206 | void | ||
| 207 | undo_snarf () | ||
| 208 | { | ||
| 209 | pcap_close (ip_socket); | ||
| 210 | } | ||
| 211 | |||
diff --git a/other/b-scan/src/system.c b/other/b-scan/src/system.c new file mode 100644 index 0000000..a3ccc94 --- /dev/null +++ b/other/b-scan/src/system.c | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <sys/ipc.h> | ||
| 3 | #include <sys/shm.h> | ||
| 4 | #include <sys/mman.h> | ||
| 5 | #include <sys/time.h> | ||
| 6 | #include <stdio.h> | ||
| 7 | #include <unistd.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <ctype.h> | ||
| 11 | #include <fcntl.h> | ||
| 12 | #include <time.h> | ||
| 13 | |||
| 14 | #ifndef SHMMNI | ||
| 15 | #define SHMMNI 100 | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #define MAXSHM 4 /* its bscan. we need <4 shm's */ | ||
| 19 | |||
| 20 | static int shm_id = -1; /* last used id */ | ||
| 21 | static int shm_c = -1; /* shm_alloc counter */ | ||
| 22 | |||
| 23 | static struct _shm | ||
| 24 | { | ||
| 25 | int id; | ||
| 26 | void *ptr; | ||
| 27 | } | ||
| 28 | shm[MAXSHM]; | ||
| 29 | |||
| 30 | |||
| 31 | /* | ||
| 32 | * uhm. hard job for the process coz the process | ||
| 33 | * does not get the shm_id. uhm. i should make a static traking list | ||
| 34 | * of all shared memory segments (addr <-> id mapping maybe ?) | ||
| 35 | * on the other hand...since an attachment count is maintained for | ||
| 36 | * the shared memory segment the segment gets removed when the last | ||
| 37 | * process using the segment terminates or detaches it. | ||
| 38 | * hmm. Seems the following function is completly useless....:> | ||
| 39 | * Hey. why are you reading my comments ? write me: anonymous@segfault.net! | ||
| 40 | */ | ||
| 41 | int | ||
| 42 | shmfree (int shm_id) | ||
| 43 | { | ||
| 44 | if (shm_id < 0) | ||
| 45 | return (-1); | ||
| 46 | return (shmctl (shm_id, IPC_RMID, 0)); | ||
| 47 | } | ||
| 48 | |||
| 49 | /* | ||
| 50 | * kill ALL shm's | ||
| 51 | * uhm. this is brutal. but shm is risky. you can bring | ||
| 52 | * down ANY system if you waste all shm's. Shm's dont get | ||
| 53 | * freed on process-exit !!! syslog will fail, inetd will fail, .. | ||
| 54 | * any program that tries to alloc shared memory...nono good :> | ||
| 55 | * root can use 'ipcrm shm <id>' do free the shm's. | ||
| 56 | * that's why we use this brutal "killall"-method. | ||
| 57 | * something else: killall-method is realy BRUTAL. believe me! | ||
| 58 | * If you have other functions registered on exit (atexit) | ||
| 59 | * and you try to reference to a shm within these function...you are lost | ||
| 60 | * Unexpected things will happen.... | ||
| 61 | */ | ||
| 62 | void | ||
| 63 | shmkillall () | ||
| 64 | { | ||
| 65 | int c; | ||
| 66 | |||
| 67 | for (c = 0; c < shm_c; c++) | ||
| 68 | shmfree (shm[c].id); | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * allocate shared memory (poor but fast IPC) | ||
| 73 | * the value returned is a pointer to the allocated | ||
| 74 | * memory, which is suitably aligned for any kind of | ||
| 75 | * variable, or NULL if the request fails. | ||
| 76 | * | ||
| 77 | * TODO: on SVR4 use open("/dev/zero", O_RDWR); and mmap trick for speedup | ||
| 78 | */ | ||
| 79 | void * | ||
| 80 | shmalloc (int flag, size_t length) | ||
| 81 | { | ||
| 82 | void *shm_addr; | ||
| 83 | int c = 0; | ||
| 84 | |||
| 85 | if (shm_c == -1) /* init all the internal shm stuff */ | ||
| 86 | { | ||
| 87 | atexit (shmkillall); | ||
| 88 | shm_c = 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (shm_c >= MAXSHM) | ||
| 92 | return (NULL); /* no space left in list. no bscan ?? */ | ||
| 93 | |||
| 94 | if (flag == 0) | ||
| 95 | flag = (IPC_CREAT | IPC_EXCL | SHM_R | SHM_W); | ||
| 96 | |||
| 97 | while (c < SHMMNI) /* brute force a NEW shared memory section */ | ||
| 98 | if ((shm_id = shmget (getpid () + c++, length, flag)) != -1) | ||
| 99 | break; | ||
| 100 | else | ||
| 101 | return (NULL); | ||
| 102 | |||
| 103 | if ((shm_addr = shmat (shm_id, NULL, 0)) == NULL) | ||
| 104 | return (NULL); | ||
| 105 | |||
| 106 | shm[shm_c].id = shm_id; | ||
| 107 | shm[shm_c].ptr = shm_addr; | ||
| 108 | shm_c++; /* increase shm-counter */ | ||
| 109 | |||
| 110 | return (shm_addr); | ||
| 111 | } | ||
| 112 | |||
| 113 | #ifdef WITH_NANOSLEEP | ||
| 114 | /* add lib '-lrt' */ | ||
| 115 | /* | ||
| 116 | * nanosec must be in the range 0 to 999 999 999 | ||
| 117 | * ..we dont care about signals here... | ||
| 118 | */ | ||
| 119 | void | ||
| 120 | do_nanosleep (time_t sec, long nsec) | ||
| 121 | { | ||
| 122 | struct timespec mynano; | ||
| 123 | mynano.tv_sec = sec; | ||
| 124 | mynano.tv_nsec = nsec; | ||
| 125 | nanosleep (&mynano, NULL); | ||
| 126 | } | ||
| 127 | #endif | ||
| 128 | |||
| 129 | |||
| 130 | /* | ||
| 131 | * xchange data p1 <-> p2 of length len | ||
| 132 | */ | ||
| 133 | void | ||
| 134 | xchange (void *p1, void *p2, int len) | ||
| 135 | { | ||
| 136 | unsigned char buf[len]; | ||
| 137 | |||
| 138 | memcpy (buf, p1, len); | ||
| 139 | memcpy (p1, p2, len); | ||
| 140 | memcpy (p2, buf, len); | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * calculate time-difference now - in | ||
| 145 | * and return diff in 'now' | ||
| 146 | */ | ||
| 147 | void | ||
| 148 | time_diff (struct timeval *in, struct timeval *now) | ||
| 149 | { | ||
| 150 | if ((now->tv_usec -= in->tv_usec) < 0) | ||
| 151 | { | ||
| 152 | now->tv_sec--; | ||
| 153 | now->tv_usec += 1000000; | ||
| 154 | } | ||
| 155 | now->tv_sec -= in->tv_sec; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* | ||
| 159 | * converts a 'esc-sequenced' string to normal string | ||
| 160 | * return string in dst. | ||
| 161 | * returns 0 on success | ||
| 162 | * todo: \ddd decoding | ||
| 163 | */ | ||
| 164 | int | ||
| 165 | ctoreal(char *src, char *dst) | ||
| 166 | { | ||
| 167 | char c; | ||
| 168 | |||
| 169 | if ((src == NULL) || (dst == NULL)) | ||
| 170 | { | ||
| 171 | dst = NULL; | ||
| 172 | return(0); /* yes, its ok. */ | ||
| 173 | } | ||
| 174 | |||
| 175 | while (*src != '\0') | ||
| 176 | if (*src == '\\') | ||
| 177 | { | ||
| 178 | switch((c = *++src)) | ||
| 179 | { | ||
| 180 | case 'n': | ||
| 181 | *dst++ = '\n'; | ||
| 182 | break; | ||
| 183 | case 'r': | ||
| 184 | *dst++ = '\r'; | ||
| 185 | break; | ||
| 186 | case 't': | ||
| 187 | *dst++ = '\t'; | ||
| 188 | break; | ||
| 189 | case '\\': | ||
| 190 | *dst++ = '\\'; | ||
| 191 | break; | ||
| 192 | case 's': | ||
| 193 | *dst++ = ' '; | ||
| 194 | break; | ||
| 195 | default: | ||
| 196 | *dst++ = c; | ||
| 197 | /* printf("unknown escape sequence 0x%2.2x\n", c);*/ | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | src++; | ||
| 201 | } else | ||
| 202 | { | ||
| 203 | *dst++ = *src++; | ||
| 204 | } | ||
| 205 | *dst = '\0'; | ||
| 206 | return(0); | ||
| 207 | } | ||
| 208 | |||
| 209 | |||
| 210 | /* | ||
| 211 | * parse data, format data and print to fd (only prinatable chars) | ||
| 212 | * supress \r, nonprintable -> '_'; | ||
| 213 | * output line by line [\n] with 'prefix' before each line. | ||
| 214 | * prefix is a 0-terminated string | ||
| 215 | */ | ||
| 216 | void | ||
| 217 | save_write(FILE *fd, char *prefix, unsigned char *data, int data_len) | ||
| 218 | { | ||
| 219 | int c; | ||
| 220 | unsigned char *ptr = data; | ||
| 221 | unsigned char *startptr = data; | ||
| 222 | const char trans[] = | ||
| 223 | "................................ !\"#$%&'()*+,-./0123456789" | ||
| 224 | ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" | ||
| 225 | "nopqrstuvwxyz{|}~...................................." | ||
| 226 | "....................................................." | ||
| 227 | "........................................"; | ||
| 228 | |||
| 229 | |||
| 230 | if (prefix == NULL) | ||
| 231 | prefix = ""; | ||
| 232 | |||
| 233 | for (c = 0; c < data_len; c++) | ||
| 234 | { | ||
| 235 | if (*data == '\r') /* i dont like these */ | ||
| 236 | { | ||
| 237 | data++; | ||
| 238 | continue; | ||
| 239 | } | ||
| 240 | if (*data == '\n') | ||
| 241 | { | ||
| 242 | *ptr = '\0'; | ||
| 243 | fprintf (fd, "%s%s\n", prefix, startptr); | ||
| 244 | startptr = ++data; | ||
| 245 | ptr = startptr; | ||
| 246 | continue; | ||
| 247 | } | ||
| 248 | |||
| 249 | *ptr++ = trans[*data++]; | ||
| 250 | |||
| 251 | } | ||
| 252 | |||
| 253 | if (ptr != startptr) | ||
| 254 | { | ||
| 255 | *ptr = '\0'; | ||
| 256 | fprintf (fd, "%s%s\n", prefix, startptr); | ||
| 257 | } | ||
| 258 | |||
| 259 | } | ||
| 260 | |||
| 261 | /* | ||
| 262 | * check if data contains any non-printable chars [except \n] | ||
| 263 | * return 0 if yes,,,,1 if not. | ||
| 264 | */ | ||
| 265 | int | ||
| 266 | isprintdata(char *ptr, int len) | ||
| 267 | { | ||
| 268 | char c; | ||
| 269 | |||
| 270 | while(len-- > 0) | ||
| 271 | { | ||
| 272 | c = *ptr++; | ||
| 273 | if (c == '\n') | ||
| 274 | continue; | ||
| 275 | if (!isprint((int)c)) | ||
| 276 | return(0); | ||
| 277 | } | ||
| 278 | |||
| 279 | return(1); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* | ||
| 283 | * convert some data into hex string | ||
| 284 | * We DO 0 terminate the string. | ||
| 285 | * dest = destination | ||
| 286 | * destlen = max. length of dest (size of allocated memory) | ||
| 287 | * data = (non)printable input data | ||
| 288 | * len = input data len | ||
| 289 | * return 0 on success, 1 if data does not fit into dest, -1 on error | ||
| 290 | */ | ||
| 291 | int | ||
| 292 | dat2hexstr(unsigned char *dest, unsigned int destlen, unsigned char *data, | ||
| 293 | unsigned int len) | ||
| 294 | { | ||
| 295 | unsigned int i = 0; | ||
| 296 | unsigned int slen = 0; | ||
| 297 | unsigned char *ptr = dest; | ||
| 298 | unsigned char c; | ||
| 299 | char hex[] = "0123456789ABCDEF"; | ||
| 300 | |||
| 301 | memset(dest, '\0', destlen); | ||
| 302 | |||
| 303 | while (i++ < len) | ||
| 304 | { | ||
| 305 | c = *data++; | ||
| 306 | if (slen + 3 < destlen) | ||
| 307 | { | ||
| 308 | *dest++ = hex[c / 16]; | ||
| 309 | *dest++ = hex[c % 16]; | ||
| 310 | *dest++ = ' '; | ||
| 311 | slen += 3; | ||
| 312 | ptr += 3; | ||
| 313 | } else { | ||
| 314 | return(1); | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | return(0); | ||
| 319 | } | ||
| 320 | |||
| 321 | |||
| 322 | /* dat2strip | ||
| 323 | * | ||
| 324 | * print the data at `data', which is `len' bytes long to the char | ||
| 325 | * array `dest', which is `destlen' characters long. filter out any | ||
| 326 | * non-printables. NUL terminate the dest array in every case. | ||
| 327 | * | ||
| 328 | * return the number of characters written | ||
| 329 | */ | ||
| 330 | |||
| 331 | int | ||
| 332 | dat2strip(unsigned char *dest, unsigned int destlen, unsigned char *data, | ||
| 333 | unsigned int len) | ||
| 334 | { | ||
| 335 | unsigned char *dp; | ||
| 336 | |||
| 337 | for (dp = dest ; dp - dest < destlen && len > 0 ; --len, ++data, ++dp) { | ||
| 338 | if (isprint (*data)) | ||
| 339 | *dp = *data; | ||
| 340 | } | ||
| 341 | |||
| 342 | if (dp - dest < destlen) | ||
| 343 | *dp = '\0'; | ||
| 344 | dest[destlen - 1] = '\0'; | ||
| 345 | |||
| 346 | return (dp - dest); | ||
| 347 | } | ||
| 348 | |||
| 349 | |||
diff --git a/other/b-scan/src/test_garage.c b/other/b-scan/src/test_garage.c new file mode 100644 index 0000000..06acf61 --- /dev/null +++ b/other/b-scan/src/test_garage.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* test_garage.c - test program for the garage module | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <time.h> | ||
| 10 | #include <garage.h> | ||
| 11 | |||
| 12 | |||
| 13 | void | ||
| 14 | cleaner_t (ip_list *il); | ||
| 15 | |||
| 16 | int | ||
| 17 | main (int argc, char *argv[]) | ||
| 18 | { | ||
| 19 | int data_len; | ||
| 20 | unsigned char * data; | ||
| 21 | unsigned long int ip, | ||
| 22 | gip = 0; | ||
| 23 | unsigned long int ips; | ||
| 24 | garage_hdlr * hdl; | ||
| 25 | unsigned long int maxkeep; | ||
| 26 | |||
| 27 | printf ("mg_cidr_getmask (20) = 0x%08lx\n", mg_cidr_getmask (20)); | ||
| 28 | printf ("mg_cidr_getmask (0xffffffc0) = 0x%08lx\n", mg_cidr_getmask (0xffffffc0)); | ||
| 29 | |||
| 30 | if (argc < 2 || sscanf (argv[1], "%lu", &ips) != 1) { | ||
| 31 | printf ("usage: %s <number-of-ips> [maxkeep]\n\n", argv[0]); | ||
| 32 | |||
| 33 | exit (EXIT_FAILURE); | ||
| 34 | } | ||
| 35 | if (argc == 3 && sscanf (argv[2], "%lu", &maxkeep) != 1) | ||
| 36 | exit (EXIT_FAILURE); | ||
| 37 | |||
| 38 | srand (time (NULL)); | ||
| 39 | hdl = mg_init ("footest", maxkeep, cleaner_t); | ||
| 40 | |||
| 41 | printf ("mg_cidr_getmask (0) = 0x%08lx\n", mg_cidr_getmask (0)); | ||
| 42 | |||
| 43 | mg_write (hdl, 2048, "foobar", 7, 0); | ||
| 44 | mg_write (hdl, 2050, "foobar", 7, 0); | ||
| 45 | mg_write (hdl, 101911, "foobar", 7, 0); | ||
| 46 | mg_write (hdl, 28914191, "foobar", 7, 0); | ||
| 47 | printf ("mg_cidr_count (hdl, 2048, 32) = %lu\n", mg_cidr_count (hdl, 2048, 32)); | ||
| 48 | printf ("mg_cidr_count (hdl, 2048, 31) = %lu\n", mg_cidr_count (hdl, 2048, 31)); | ||
| 49 | printf ("mg_cidr_count (hdl, 2048, 30) = %lu\n", mg_cidr_count (hdl, 2048, 30)); | ||
| 50 | printf ("mg_cidr_count (hdl, 2048, 13) = %lu\n", mg_cidr_count (hdl, 2048, 13)); | ||
| 51 | printf ("mg_cidr_count (hdl, 2048, 0) = %lu\n", mg_cidr_count (hdl, 2048, 0)); | ||
| 52 | |||
| 53 | |||
| 54 | ip = 123; | ||
| 55 | mg_write (hdl, ip, "foo", 4, 0); | ||
| 56 | mg_read (hdl, ip); | ||
| 57 | mg_clean (hdl, ip, NULL); | ||
| 58 | |||
| 59 | do { | ||
| 60 | ip = rand (); | ||
| 61 | |||
| 62 | data_len = rand () % 64; | ||
| 63 | data_len += 1; /* avoid allocating zero bytes */ | ||
| 64 | data = malloc (data_len); | ||
| 65 | memset (data, '\x73', data_len); | ||
| 66 | data[data_len - 1] = '\0'; | ||
| 67 | |||
| 68 | mg_write (hdl, ip, (void *) data, data_len, 1); | ||
| 69 | if (ips % 137 == 0) | ||
| 70 | gip = ip; | ||
| 71 | |||
| 72 | if (ips % 139 == 0) | ||
| 73 | (void) mg_read (hdl, gip); | ||
| 74 | |||
| 75 | ips -= 1; | ||
| 76 | if (ips % 5000 == 0) | ||
| 77 | mg_show (hdl); | ||
| 78 | |||
| 79 | } while (ips > 0); | ||
| 80 | |||
| 81 | mg_show (hdl); | ||
| 82 | mg_destroy (hdl, 0); | ||
| 83 | |||
| 84 | exit (EXIT_SUCCESS); | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | void | ||
| 89 | cleaner_t (ip_list *il) | ||
| 90 | { | ||
| 91 | if ((rand () % 20000) == 0) | ||
| 92 | printf ("cleaner_t: il = 0x%08lx IP = 0x%08lx\n", | ||
| 93 | (unsigned long int) il, | ||
| 94 | il->ip); | ||
| 95 | |||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
diff --git a/other/b-scan/src/tty.c b/other/b-scan/src/tty.c new file mode 100644 index 0000000..5c99b7f --- /dev/null +++ b/other/b-scan/src/tty.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | /* | ||
| 2 | * most of this stuff is ripped from solar's excelent john-1.6 source | ||
| 3 | */ | ||
| 4 | #include <sys/types.h> | ||
| 5 | #include <sys/stat.h> | ||
| 6 | #include <fcntl.h> | ||
| 7 | |||
| 8 | #include <unistd.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | #include <termios.h> | ||
| 11 | |||
| 12 | static int tty_fd = 0; | ||
| 13 | static int tty_buf = -1; | ||
| 14 | static struct termios saved_ti; | ||
| 15 | |||
| 16 | |||
| 17 | /* | ||
| 18 | * Reads a character, returns -1 if no data available or on error. | ||
| 19 | */ | ||
| 20 | int | ||
| 21 | tty_getchar () | ||
| 22 | { | ||
| 23 | int c; | ||
| 24 | |||
| 25 | /* | ||
| 26 | * process buffer first | ||
| 27 | */ | ||
| 28 | if (tty_buf != -1) | ||
| 29 | { | ||
| 30 | c = tty_buf; | ||
| 31 | tty_buf = -1; | ||
| 32 | return (c); | ||
| 33 | } | ||
| 34 | |||
| 35 | if (tty_fd) | ||
| 36 | { | ||
| 37 | c = 0; | ||
| 38 | if (read (tty_fd, &c, 1) > 0) | ||
| 39 | return c; | ||
| 40 | } | ||
| 41 | |||
| 42 | return (-1); | ||
| 43 | } | ||
| 44 | |||
| 45 | /* | ||
| 46 | * check if someone pressed a key | ||
| 47 | * Actually we do a read on the fd and store the result in a buffer | ||
| 48 | * todo: check with ioctl if data is pending | ||
| 49 | * return 1 is data is pending, 0 if not | ||
| 50 | */ | ||
| 51 | int | ||
| 52 | tty_ischar () | ||
| 53 | { | ||
| 54 | if (tty_buf != -1) | ||
| 55 | return (1); | ||
| 56 | |||
| 57 | if ((tty_buf = tty_getchar ()) != -1) | ||
| 58 | return (1); | ||
| 59 | |||
| 60 | return (0); | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | /* | ||
| 65 | * Restores the terminal parameters and closes the file descriptor. | ||
| 66 | */ | ||
| 67 | void | ||
| 68 | tty_done () | ||
| 69 | { | ||
| 70 | int fd; | ||
| 71 | |||
| 72 | if (!tty_fd) | ||
| 73 | return; | ||
| 74 | |||
| 75 | fd = tty_fd; | ||
| 76 | tty_fd = 0; | ||
| 77 | tcsetattr (fd, TCSANOW, &saved_ti); | ||
| 78 | |||
| 79 | close (fd); | ||
| 80 | } | ||
| 81 | |||
| 82 | |||
| 83 | /* | ||
| 84 | * Initializes the terminal for unbuffered non-blocking input. Also registers | ||
| 85 | * tty_done() via atexit(). | ||
| 86 | */ | ||
| 87 | void | ||
| 88 | tty_init () | ||
| 89 | { | ||
| 90 | int fd; | ||
| 91 | struct termios ti; | ||
| 92 | |||
| 93 | if (tty_fd) | ||
| 94 | return; | ||
| 95 | |||
| 96 | if ((fd = open ("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) | ||
| 97 | return; | ||
| 98 | |||
| 99 | if (tcgetpgrp (fd) != getpid ()) | ||
| 100 | { | ||
| 101 | close (fd); | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | tcgetattr (fd, &ti); | ||
| 106 | saved_ti = ti; | ||
| 107 | ti.c_lflag &= ~(ICANON | ECHO); | ||
| 108 | ti.c_cc[VINTR] = 3; /* CTRL-C is INTR */ | ||
| 109 | ti.c_cc[VMIN] = 1; | ||
| 110 | ti.c_cc[VTIME] = 0; | ||
| 111 | tcsetattr (fd, TCSANOW, &ti); | ||
| 112 | |||
| 113 | tty_fd = fd; | ||
| 114 | |||
| 115 | atexit (tty_done); | ||
| 116 | } | ||
diff --git a/other/b-scan/support/Makefile b/other/b-scan/support/Makefile new file mode 100644 index 0000000..4025e1f --- /dev/null +++ b/other/b-scan/support/Makefile | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | CC=gcc | ||
| 2 | COPT=-Wall -ggdb -I../include | ||
| 3 | DEFS=#-DDEBUG | ||
| 4 | OBJ=hpuxdl.o snprintf.o | ||
| 5 | |||
| 6 | # HPUX 11.00 | ||
| 7 | # DEFS=-DNEED_SNPRINTF -DHAVE_SHL_LOAD #-DDEBUG | ||
| 8 | |||
| 9 | # HPUX 10.20 | ||
| 10 | # DEFS=-DHP10 -DNEED_SNPRINTF -DHAVE_SHL_LOAD #-DDEBUG | ||
| 11 | |||
| 12 | all: $(OBJ) | ||
| 13 | |||
| 14 | .c.o: | ||
| 15 | $(CC) $(COPT) $(DEFS) -c $< | ||
| 16 | |||
| 17 | clean: | ||
| 18 | rm -f $(OBJ) core *~ | ||
| 19 | |||
| 20 | |||
diff --git a/other/b-scan/support/hpuxdl.c b/other/b-scan/support/hpuxdl.c new file mode 100644 index 0000000..accaed9 --- /dev/null +++ b/other/b-scan/support/hpuxdl.c | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | #ifdef HAVE_SHL_LOAD | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <errno.h> | ||
| 5 | #include <dl.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This is a minimal implementation of the ELF dlopen, dlclose, dlsym | ||
| 9 | * and dlerror routines based on HP's shl_load, shl_unload and | ||
| 10 | * shl_findsym. */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Reference Counting. | ||
| 14 | * | ||
| 15 | * Empirically it looks like the HP routines do not maintain a | ||
| 16 | * reference count, so I maintain one here. | ||
| 17 | */ | ||
| 18 | |||
| 19 | typedef struct lib_entry { | ||
| 20 | shl_t handle; | ||
| 21 | int count; | ||
| 22 | struct lib_entry *next; | ||
| 23 | } *LibEntry; | ||
| 24 | |||
| 25 | #define lib_entry_handle(e) ((e)->handle) | ||
| 26 | #define lib_entry_count(e) ((e)->count) | ||
| 27 | #define lib_entry_next(e) ((e)->next) | ||
| 28 | #define set_lib_entry_handle(e,v) ((e)->handle = (v)) | ||
| 29 | #define set_lib_entry_count(e,v) ((e)->count = (v)) | ||
| 30 | #define set_lib_entry_next(e,v) ((e)->next = (v)) | ||
| 31 | #define increment_lib_entry_count(e) ((e)->count++) | ||
| 32 | #define decrement_lib_entry_count(e) ((e)->count--) | ||
| 33 | |||
| 34 | static LibEntry Entries = NULL; | ||
| 35 | |||
| 36 | static LibEntry find_lib_entry(shl_t handle) | ||
| 37 | { | ||
| 38 | LibEntry entry; | ||
| 39 | |||
| 40 | for (entry = Entries; entry != NULL; entry = lib_entry_next(entry)) | ||
| 41 | if (lib_entry_handle(entry) == handle) | ||
| 42 | return entry; | ||
| 43 | return NULL; | ||
| 44 | } | ||
| 45 | |||
| 46 | static LibEntry new_lib_entry(shl_t handle) | ||
| 47 | { | ||
| 48 | LibEntry entry; | ||
| 49 | |||
| 50 | if ((entry = (LibEntry) malloc(sizeof(struct lib_entry))) != NULL) { | ||
| 51 | set_lib_entry_handle(entry, handle); | ||
| 52 | set_lib_entry_count(entry, 1); | ||
| 53 | set_lib_entry_next(entry, Entries); | ||
| 54 | Entries = entry; | ||
| 55 | } | ||
| 56 | return entry; | ||
| 57 | } | ||
| 58 | |||
| 59 | static void free_lib_entry(LibEntry entry) | ||
| 60 | { | ||
| 61 | if (entry == Entries) | ||
| 62 | Entries = lib_entry_next(entry); | ||
| 63 | else { | ||
| 64 | LibEntry last, next; | ||
| 65 | for (last = Entries, next = lib_entry_next(last); | ||
| 66 | next != NULL; | ||
| 67 | last = next, next = lib_entry_next(last)) { | ||
| 68 | if (entry == next) { | ||
| 69 | set_lib_entry_next(last, lib_entry_next(entry)); | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | free(entry); | ||
| 75 | } | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Error Handling. | ||
| 79 | */ | ||
| 80 | |||
| 81 | #define ERRBUFSIZE 1000 | ||
| 82 | |||
| 83 | static char errbuf[ERRBUFSIZE]; | ||
| 84 | static int dlerrno = 0; | ||
| 85 | |||
| 86 | char *dlerror(void) | ||
| 87 | { | ||
| 88 | return dlerrno ? errbuf : NULL; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Opening and Closing Liraries. | ||
| 93 | */ | ||
| 94 | |||
| 95 | void *dlopen(const char *fname, int mode) | ||
| 96 | { | ||
| 97 | shl_t handle; | ||
| 98 | LibEntry entry = NULL; | ||
| 99 | |||
| 100 | dlerrno = 0; | ||
| 101 | if (fname == NULL) | ||
| 102 | handle = PROG_HANDLE; | ||
| 103 | else { | ||
| 104 | handle = shl_load(fname, mode, 0L); | ||
| 105 | if (handle != NULL) { | ||
| 106 | if ((entry = find_lib_entry(handle)) == NULL) { | ||
| 107 | if ((entry = new_lib_entry(handle)) == NULL) { | ||
| 108 | shl_unload(handle); | ||
| 109 | handle = NULL; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | else | ||
| 113 | increment_lib_entry_count(entry); | ||
| 114 | } | ||
| 115 | if (handle == NULL) { | ||
| 116 | char *errstr; | ||
| 117 | dlerrno = errno; | ||
| 118 | errstr = strerror(errno); | ||
| 119 | if (errno == NULL) errstr = "???"; | ||
| 120 | sprintf(errbuf, "can't open %s: %s", fname, errstr); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | #ifdef DEBUG | ||
| 124 | printf("opening library %s, handle = %x, count = %d\n", | ||
| 125 | fname, handle, entry ? lib_entry_count(entry) : -1); | ||
| 126 | if (dlerrno) printf("%s\n", dlerror()); | ||
| 127 | #endif | ||
| 128 | return (void *) handle; | ||
| 129 | } | ||
| 130 | |||
| 131 | int dlclose(void *handle) | ||
| 132 | { | ||
| 133 | LibEntry entry; | ||
| 134 | #ifdef DEBUG | ||
| 135 | entry = find_lib_entry(handle); | ||
| 136 | printf("closing library handle = %x, count = %d\n", | ||
| 137 | handle, entry ? lib_entry_count(entry) : -1); | ||
| 138 | #endif | ||
| 139 | |||
| 140 | dlerrno = 0; | ||
| 141 | if ((shl_t) handle == PROG_HANDLE) | ||
| 142 | return 0; /* ignore attempts to close main program */ | ||
| 143 | else { | ||
| 144 | |||
| 145 | if ((entry = find_lib_entry((shl_t) handle)) != NULL) { | ||
| 146 | decrement_lib_entry_count(entry); | ||
| 147 | if (lib_entry_count(entry) > 0) | ||
| 148 | return 0; | ||
| 149 | else { | ||
| 150 | /* unload once reference count reaches zero */ | ||
| 151 | free_lib_entry(entry); | ||
| 152 | if (shl_unload((shl_t) handle) == 0) | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | } | ||
| 156 | /* if you get to here, an error has occurred */ | ||
| 157 | dlerrno = 1; | ||
| 158 | sprintf(errbuf, "attempt to close library failed"); | ||
| 159 | #ifdef DEBUG | ||
| 160 | printf("%s\n", dlerror()); | ||
| 161 | #endif | ||
| 162 | return -1; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Symbol Lookup. | ||
| 168 | */ | ||
| 169 | |||
| 170 | void *dlsym(void *handle, const char *name) | ||
| 171 | { | ||
| 172 | void *f; | ||
| 173 | shl_t myhandle; | ||
| 174 | |||
| 175 | dlerrno = 0; | ||
| 176 | myhandle = (handle == NULL) ? PROG_HANDLE : (shl_t) handle; | ||
| 177 | |||
| 178 | if (shl_findsym(&myhandle, name, TYPE_PROCEDURE, &f) != 0) { | ||
| 179 | dlerrno = 1; | ||
| 180 | sprintf(errbuf, "symbol %s not found", name); | ||
| 181 | f = NULL; | ||
| 182 | } | ||
| 183 | |||
| 184 | return(f); | ||
| 185 | } | ||
| 186 | |||
| 187 | #endif | ||
diff --git a/other/b-scan/support/snprintf.c b/other/b-scan/support/snprintf.c new file mode 100644 index 0000000..f6a7a40 --- /dev/null +++ b/other/b-scan/support/snprintf.c | |||
| @@ -0,0 +1,331 @@ | |||
| 1 | #ifdef NEED_SNPRINTF | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | #include <string.h> | ||
| 6 | |||
| 7 | #ifndef __P | ||
| 8 | #define __P(p) p | ||
| 9 | #endif | ||
| 10 | |||
| 11 | #include <stdarg.h> | ||
| 12 | #define VA_LOCAL_DECL va_list ap; | ||
| 13 | #define VA_START(f) va_start(ap, f) | ||
| 14 | #define VA_END va_end(ap) | ||
| 15 | |||
| 16 | #ifdef SOLARIS2 | ||
| 17 | #ifdef _FILE_OFFSET_BITS | ||
| 18 | #define SOLARIS26 | ||
| 19 | #endif | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #ifdef SOLARIS26 | ||
| 23 | #define HAS_SNPRINTF | ||
| 24 | #define HAS_VSNPRINTF | ||
| 25 | #endif | ||
| 26 | #ifdef _SCO_DS_ | ||
| 27 | #define HAS_SNPRINTF | ||
| 28 | #endif | ||
| 29 | #ifdef luna2 | ||
| 30 | #define HAS_VSNPRINTF | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /************************************************************** | ||
| 34 | * Original: | ||
| 35 | * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 | ||
| 36 | * A bombproof version of doprnt (dopr) included. | ||
| 37 | * Sigh. This sort of thing is always nasty do deal with. Note that | ||
| 38 | * the version here does not include floating point... | ||
| 39 | * | ||
| 40 | * snprintf() is used instead of sprintf() as it does limit checks | ||
| 41 | * for string length. This covers a nasty loophole. | ||
| 42 | * | ||
| 43 | * The other functions are there to prevent NULL pointers from | ||
| 44 | * causing nast effects. | ||
| 45 | **************************************************************/ | ||
| 46 | |||
| 47 | static void dopr(char *, const char *, va_list); | ||
| 48 | static char *end; | ||
| 49 | |||
| 50 | #ifndef HAS_VSNPRINTF | ||
| 51 | int vsnprintf(char *str, size_t count, const char *fmt, va_list args) | ||
| 52 | { | ||
| 53 | str[0] = 0; | ||
| 54 | end = str + count - 1; | ||
| 55 | dopr(str, fmt, args); | ||
| 56 | if (count > 0) | ||
| 57 | end[0] = 0; | ||
| 58 | return strlen(str); | ||
| 59 | } | ||
| 60 | |||
| 61 | #ifndef HAS_SNPRINTF | ||
| 62 | /* VARARGS3 */ | ||
| 63 | int snprintf(char *str, size_t count, const char *fmt,...) | ||
| 64 | { | ||
| 65 | int len; | ||
| 66 | VA_LOCAL_DECL | ||
| 67 | |||
| 68 | VA_START(fmt); | ||
| 69 | len = vsnprintf(str, count, fmt, ap); | ||
| 70 | VA_END; | ||
| 71 | return len; | ||
| 72 | } | ||
| 73 | #endif | ||
| 74 | |||
| 75 | /* | ||
| 76 | * dopr(): poor man's version of doprintf | ||
| 77 | */ | ||
| 78 | |||
| 79 | static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth)); | ||
| 80 | static void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad)); | ||
| 81 | static void dostr __P((char *, int)); | ||
| 82 | static char *output; | ||
| 83 | static void dopr_outch __P((int c)); | ||
| 84 | |||
| 85 | static void dopr(char *buffer, const char *format, va_list args) | ||
| 86 | { | ||
| 87 | int ch; | ||
| 88 | long value; | ||
| 89 | int longflag = 0; | ||
| 90 | int pointflag = 0; | ||
| 91 | int maxwidth = 0; | ||
| 92 | char *strvalue; | ||
| 93 | int ljust; | ||
| 94 | int len; | ||
| 95 | int zpad; | ||
| 96 | |||
| 97 | output = buffer; | ||
| 98 | while ((ch = *format++)) { | ||
| 99 | switch (ch) { | ||
| 100 | case '%': | ||
| 101 | ljust = len = zpad = maxwidth = 0; | ||
| 102 | longflag = pointflag = 0; | ||
| 103 | nextch: | ||
| 104 | ch = *format++; | ||
| 105 | switch (ch) { | ||
| 106 | case 0: | ||
| 107 | dostr("**end of format**", 0); | ||
| 108 | return; | ||
| 109 | case '-': | ||
| 110 | ljust = 1; | ||
| 111 | goto nextch; | ||
| 112 | case '0': /* set zero padding if len not set */ | ||
| 113 | if (len == 0 && !pointflag) | ||
| 114 | zpad = '0'; | ||
| 115 | case '1': | ||
| 116 | case '2': | ||
| 117 | case '3': | ||
| 118 | case '4': | ||
| 119 | case '5': | ||
| 120 | case '6': | ||
| 121 | case '7': | ||
| 122 | case '8': | ||
| 123 | case '9': | ||
| 124 | if (pointflag) | ||
| 125 | maxwidth = maxwidth * 10 + ch - '0'; | ||
| 126 | else | ||
| 127 | len = len * 10 + ch - '0'; | ||
| 128 | goto nextch; | ||
| 129 | case '*': | ||
| 130 | if (pointflag) | ||
| 131 | maxwidth = va_arg(args, int); | ||
| 132 | else | ||
| 133 | len = va_arg(args, int); | ||
| 134 | goto nextch; | ||
| 135 | case '.': | ||
| 136 | pointflag = 1; | ||
| 137 | goto nextch; | ||
| 138 | case 'l': | ||
| 139 | longflag = 1; | ||
| 140 | goto nextch; | ||
| 141 | case 'u': | ||
| 142 | case 'U': | ||
| 143 | /*fmtnum(value,base,dosign,ljust,len,zpad) */ | ||
| 144 | if (longflag) { | ||
| 145 | value = va_arg(args, long); | ||
| 146 | } | ||
| 147 | else { | ||
| 148 | value = va_arg(args, int); | ||
| 149 | } | ||
| 150 | fmtnum(value, 10, 0, ljust, len, zpad); | ||
| 151 | break; | ||
| 152 | case 'o': | ||
| 153 | case 'O': | ||
| 154 | /*fmtnum(value,base,dosign,ljust,len,zpad) */ | ||
| 155 | if (longflag) { | ||
| 156 | value = va_arg(args, long); | ||
| 157 | } | ||
| 158 | else { | ||
| 159 | value = va_arg(args, int); | ||
| 160 | } | ||
| 161 | fmtnum(value, 8, 0, ljust, len, zpad); | ||
| 162 | break; | ||
| 163 | case 'd': | ||
| 164 | case 'D': | ||
| 165 | if (longflag) { | ||
| 166 | value = va_arg(args, long); | ||
| 167 | } | ||
| 168 | else { | ||
| 169 | value = va_arg(args, int); | ||
| 170 | } | ||
| 171 | fmtnum(value, 10, 1, ljust, len, zpad); | ||
| 172 | break; | ||
| 173 | case 'x': | ||
| 174 | if (longflag) { | ||
| 175 | value = va_arg(args, long); | ||
| 176 | } | ||
| 177 | else { | ||
| 178 | value = va_arg(args, int); | ||
| 179 | } | ||
| 180 | fmtnum(value, 16, 0, ljust, len, zpad); | ||
| 181 | break; | ||
| 182 | case 'X': | ||
| 183 | if (longflag) { | ||
| 184 | value = va_arg(args, long); | ||
| 185 | } | ||
| 186 | else { | ||
| 187 | value = va_arg(args, int); | ||
| 188 | } | ||
| 189 | fmtnum(value, -16, 0, ljust, len, zpad); | ||
| 190 | break; | ||
| 191 | case 's': | ||
| 192 | strvalue = va_arg(args, char *); | ||
| 193 | if (maxwidth > 0 || !pointflag) { | ||
| 194 | if (pointflag && len > maxwidth) | ||
| 195 | len = maxwidth; /* Adjust padding */ | ||
| 196 | fmtstr(strvalue, ljust, len, zpad, maxwidth); | ||
| 197 | } | ||
| 198 | break; | ||
| 199 | case 'c': | ||
| 200 | ch = va_arg(args, int); | ||
| 201 | dopr_outch(ch); | ||
| 202 | break; | ||
| 203 | case '%': | ||
| 204 | dopr_outch(ch); | ||
| 205 | continue; | ||
| 206 | default: | ||
| 207 | dostr("???????", 0); | ||
| 208 | } | ||
| 209 | break; | ||
| 210 | default: | ||
| 211 | dopr_outch(ch); | ||
| 212 | break; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | *output = 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth) | ||
| 219 | { | ||
| 220 | int padlen, strlen; /* amount to pad */ | ||
| 221 | |||
| 222 | if (value == 0) { | ||
| 223 | value = "<NULL>"; | ||
| 224 | } | ||
| 225 | for (strlen = 0; value[strlen]; ++strlen); /* strlen */ | ||
| 226 | if (strlen > maxwidth && maxwidth) | ||
| 227 | strlen = maxwidth; | ||
| 228 | padlen = len - strlen; | ||
| 229 | if (padlen < 0) | ||
| 230 | padlen = 0; | ||
| 231 | if (ljust) | ||
| 232 | padlen = -padlen; | ||
| 233 | while (padlen > 0) { | ||
| 234 | dopr_outch(' '); | ||
| 235 | --padlen; | ||
| 236 | } | ||
| 237 | dostr(value, maxwidth); | ||
| 238 | while (padlen < 0) { | ||
| 239 | dopr_outch(' '); | ||
| 240 | ++padlen; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | static void fmtnum(long value, int base, int dosign, int ljust, int len, int zpad) | ||
| 245 | { | ||
| 246 | int signvalue = 0; | ||
| 247 | unsigned long uvalue; | ||
| 248 | char convert[20]; | ||
| 249 | int place = 0; | ||
| 250 | int padlen = 0; /* amount to pad */ | ||
| 251 | int caps = 0; | ||
| 252 | |||
| 253 | /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", | ||
| 254 | value, base, dosign, ljust, len, zpad )); */ | ||
| 255 | uvalue = value; | ||
| 256 | if (dosign) { | ||
| 257 | if (value < 0) { | ||
| 258 | signvalue = '-'; | ||
| 259 | uvalue = -value; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | if (base < 0) { | ||
| 263 | caps = 1; | ||
| 264 | base = -base; | ||
| 265 | } | ||
| 266 | do { | ||
| 267 | convert[place++] = | ||
| 268 | (caps ? "0123456789ABCDEF" : "0123456789abcdef") | ||
| 269 | [uvalue % (unsigned) base]; | ||
| 270 | uvalue = (uvalue / (unsigned) base); | ||
| 271 | } while (uvalue); | ||
| 272 | convert[place] = 0; | ||
| 273 | padlen = len - place; | ||
| 274 | if (padlen < 0) | ||
| 275 | padlen = 0; | ||
| 276 | if (ljust) | ||
| 277 | padlen = -padlen; | ||
| 278 | /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", | ||
| 279 | convert,place,signvalue,padlen)); */ | ||
| 280 | if (zpad && padlen > 0) { | ||
| 281 | if (signvalue) { | ||
| 282 | dopr_outch(signvalue); | ||
| 283 | --padlen; | ||
| 284 | signvalue = 0; | ||
| 285 | } | ||
| 286 | while (padlen > 0) { | ||
| 287 | dopr_outch(zpad); | ||
| 288 | --padlen; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | while (padlen > 0) { | ||
| 292 | dopr_outch(' '); | ||
| 293 | --padlen; | ||
| 294 | } | ||
| 295 | if (signvalue) | ||
| 296 | dopr_outch(signvalue); | ||
| 297 | while (place > 0) | ||
| 298 | dopr_outch(convert[--place]); | ||
| 299 | while (padlen < 0) { | ||
| 300 | dopr_outch(' '); | ||
| 301 | ++padlen; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | static void dostr(char *str, int cut) | ||
| 306 | { | ||
| 307 | if (cut) { | ||
| 308 | while (*str && cut-- > 0) | ||
| 309 | dopr_outch(*str++); | ||
| 310 | } | ||
| 311 | else { | ||
| 312 | while (*str) | ||
| 313 | dopr_outch(*str++); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | static void dopr_outch(int c) | ||
| 318 | { | ||
| 319 | #if 0 | ||
| 320 | if (iscntrl(c) && c != '\n' && c != '\t') { | ||
| 321 | c = '@' + (c & 0x1F); | ||
| 322 | if (end == 0 || output < end) | ||
| 323 | *output++ = '^'; | ||
| 324 | } | ||
| 325 | #endif | ||
| 326 | if (end == 0 || output < end) | ||
| 327 | *output++ = c; | ||
| 328 | } | ||
| 329 | |||
| 330 | #endif /* HAVE_VSNPRINTF */ | ||
| 331 | #endif /*n NEED_SNPRINTF */ | ||
diff --git a/other/b-scan/test_garage.c b/other/b-scan/test_garage.c new file mode 100644 index 0000000..06acf61 --- /dev/null +++ b/other/b-scan/test_garage.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* test_garage.c - test program for the garage module | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <time.h> | ||
| 10 | #include <garage.h> | ||
| 11 | |||
| 12 | |||
| 13 | void | ||
| 14 | cleaner_t (ip_list *il); | ||
| 15 | |||
| 16 | int | ||
| 17 | main (int argc, char *argv[]) | ||
| 18 | { | ||
| 19 | int data_len; | ||
| 20 | unsigned char * data; | ||
| 21 | unsigned long int ip, | ||
| 22 | gip = 0; | ||
| 23 | unsigned long int ips; | ||
| 24 | garage_hdlr * hdl; | ||
| 25 | unsigned long int maxkeep; | ||
| 26 | |||
| 27 | printf ("mg_cidr_getmask (20) = 0x%08lx\n", mg_cidr_getmask (20)); | ||
| 28 | printf ("mg_cidr_getmask (0xffffffc0) = 0x%08lx\n", mg_cidr_getmask (0xffffffc0)); | ||
| 29 | |||
| 30 | if (argc < 2 || sscanf (argv[1], "%lu", &ips) != 1) { | ||
| 31 | printf ("usage: %s <number-of-ips> [maxkeep]\n\n", argv[0]); | ||
| 32 | |||
| 33 | exit (EXIT_FAILURE); | ||
| 34 | } | ||
| 35 | if (argc == 3 && sscanf (argv[2], "%lu", &maxkeep) != 1) | ||
| 36 | exit (EXIT_FAILURE); | ||
| 37 | |||
| 38 | srand (time (NULL)); | ||
| 39 | hdl = mg_init ("footest", maxkeep, cleaner_t); | ||
| 40 | |||
| 41 | printf ("mg_cidr_getmask (0) = 0x%08lx\n", mg_cidr_getmask (0)); | ||
| 42 | |||
| 43 | mg_write (hdl, 2048, "foobar", 7, 0); | ||
| 44 | mg_write (hdl, 2050, "foobar", 7, 0); | ||
| 45 | mg_write (hdl, 101911, "foobar", 7, 0); | ||
| 46 | mg_write (hdl, 28914191, "foobar", 7, 0); | ||
| 47 | printf ("mg_cidr_count (hdl, 2048, 32) = %lu\n", mg_cidr_count (hdl, 2048, 32)); | ||
| 48 | printf ("mg_cidr_count (hdl, 2048, 31) = %lu\n", mg_cidr_count (hdl, 2048, 31)); | ||
| 49 | printf ("mg_cidr_count (hdl, 2048, 30) = %lu\n", mg_cidr_count (hdl, 2048, 30)); | ||
| 50 | printf ("mg_cidr_count (hdl, 2048, 13) = %lu\n", mg_cidr_count (hdl, 2048, 13)); | ||
| 51 | printf ("mg_cidr_count (hdl, 2048, 0) = %lu\n", mg_cidr_count (hdl, 2048, 0)); | ||
| 52 | |||
| 53 | |||
| 54 | ip = 123; | ||
| 55 | mg_write (hdl, ip, "foo", 4, 0); | ||
| 56 | mg_read (hdl, ip); | ||
| 57 | mg_clean (hdl, ip, NULL); | ||
| 58 | |||
| 59 | do { | ||
| 60 | ip = rand (); | ||
| 61 | |||
| 62 | data_len = rand () % 64; | ||
| 63 | data_len += 1; /* avoid allocating zero bytes */ | ||
| 64 | data = malloc (data_len); | ||
| 65 | memset (data, '\x73', data_len); | ||
| 66 | data[data_len - 1] = '\0'; | ||
| 67 | |||
| 68 | mg_write (hdl, ip, (void *) data, data_len, 1); | ||
| 69 | if (ips % 137 == 0) | ||
| 70 | gip = ip; | ||
| 71 | |||
| 72 | if (ips % 139 == 0) | ||
| 73 | (void) mg_read (hdl, gip); | ||
| 74 | |||
| 75 | ips -= 1; | ||
| 76 | if (ips % 5000 == 0) | ||
| 77 | mg_show (hdl); | ||
| 78 | |||
| 79 | } while (ips > 0); | ||
| 80 | |||
| 81 | mg_show (hdl); | ||
| 82 | mg_destroy (hdl, 0); | ||
| 83 | |||
| 84 | exit (EXIT_SUCCESS); | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | void | ||
| 89 | cleaner_t (ip_list *il) | ||
| 90 | { | ||
| 91 | if ((rand () % 20000) == 0) | ||
| 92 | printf ("cleaner_t: il = 0x%08lx IP = 0x%08lx\n", | ||
| 93 | (unsigned long int) il, | ||
| 94 | il->ip); | ||
| 95 | |||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
diff --git a/other/b-scan/tmp/Makefile b/other/b-scan/tmp/Makefile new file mode 100644 index 0000000..8306b6c --- /dev/null +++ b/other/b-scan/tmp/Makefile | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | # | ||
| 2 | # Makefile of (m)bscan v0.0, skyper | ||
| 3 | # Massiv Banner Scanner | ||
| 4 | # | ||
| 5 | # GNU-make mandatory! | ||
| 6 | |||
| 7 | SUBDIRS=support src modules | ||
| 8 | |||
| 9 | # edit support/Makefile | ||
| 10 | # edit src/Makefile | ||
| 11 | # edit modules/Makefile | ||
| 12 | |||
| 13 | all: | ||
| 14 | for dir in $(SUBDIRS); do \ | ||
| 15 | $(MAKE) -C $$dir; \ | ||
| 16 | done | ||
| 17 | |||
| 18 | clean: | ||
| 19 | for dir in $(SUBDIRS); do \ | ||
| 20 | $(MAKE) -C $$dir clean; \ | ||
| 21 | done | ||
| 22 | |||
| 23 | pack: | ||
| 24 | rm -f bscan.tar.gz | ||
| 25 | tar cfvz bscan.tar.gz support/*.c support/Makefile src/*.c src/*.l src/Makefile include/bscan/*.h Makefile MODULES PROBLEMS INSTALL README modules/*.c modules/Makefile | ||
| 26 | |||
| 27 | |||
diff --git a/other/b-scan/tmp/include/bscan/arpg.h b/other/b-scan/tmp/include/bscan/arpg.h new file mode 100644 index 0000000..19ebddc --- /dev/null +++ b/other/b-scan/tmp/include/bscan/arpg.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #include <libnet.h> | ||
| 2 | |||
| 3 | struct _libnet | ||
| 4 | { | ||
| 5 | int packet_size; | ||
| 6 | u_char *packet; | ||
| 7 | char err_buf[LIBNET_ERRBUF_SIZE]; | ||
| 8 | u_char *device; | ||
| 9 | struct libnet_link_int *network; | ||
| 10 | }; | ||
| 11 | |||
| 12 | void prepare_libnet (struct _libnet *lnet); | ||
| 13 | int play_arpg (struct _libnet *, u_char *, u_char *, u_char *, u_char *); | ||
diff --git a/other/b-scan/tmp/include/bscan/bscan.h b/other/b-scan/tmp/include/bscan/bscan.h new file mode 100644 index 0000000..c1ad9bb --- /dev/null +++ b/other/b-scan/tmp/include/bscan/bscan.h | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* | ||
| 2 | * bscan, lame (and hopefully fast) banner scanner [port 21,25,110,...] | ||
| 3 | * | ||
| 4 | * "<es> skyper its a cool idea" | ||
| 5 | * "<es> i'd like to see the k0ad when ur finished" | ||
| 6 | * HI ES :) | ||
| 7 | * greetings to all my !el8 brothers :)) | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <stdio.h> | ||
| 11 | #include <stdarg.h> | ||
| 12 | #include <sys/socket.h> | ||
| 13 | #include <sys/wait.h> | ||
| 14 | #include <pthread.h> | ||
| 15 | #ifndef __FAVOR_BSD | ||
| 16 | #define __FAVOR_BSD | ||
| 17 | #endif | ||
| 18 | #ifndef __USE_BSD | ||
| 19 | #define __USE_BSD | ||
| 20 | #endif | ||
| 21 | #ifndef __BSD_SOURCE | ||
| 22 | #define __BSD_SOURCE | ||
| 23 | #endif | ||
| 24 | #include "arpg.h" | ||
| 25 | #include "network_raw.h" | ||
| 26 | |||
| 27 | |||
| 28 | #define SPF_SMAC "\x00\x20\xAF\xA3\x13\x37" | ||
| 29 | |||
| 30 | #define OPT_VERB 0x1 | ||
| 31 | #define OPT_RESERV1 0x2 | ||
| 32 | #define OPT_SETARP 0x4 | ||
| 33 | #define OPT_SPREADSCAN 0x8 | ||
| 34 | #define OPT_OUTONLY 0x10 | ||
| 35 | |||
| 36 | #define OPT_ABRT 0x20 | ||
| 37 | #define OPT_REST 0x40 | ||
| 38 | #define OPT_HOSTFILE 0x80 | ||
| 39 | #define OPT_W8SEMA 0x100 | ||
| 40 | |||
| 41 | |||
| 42 | struct _opt | ||
| 43 | { | ||
| 44 | int (*getnextip) (); | ||
| 45 | int sox; | ||
| 46 | u_char *packet; | ||
| 47 | int pkg_maxlen; | ||
| 48 | int pkg_len; /* actual length of contructed packet */ | ||
| 49 | char *hostfile; | ||
| 50 | char **argvlist; | ||
| 51 | FILE *ffd; /* e.g. input file */ | ||
| 52 | char *target; | ||
| 53 | unsigned long netmask; /* depricated */ | ||
| 54 | unsigned long network; /* depricated */ | ||
| 55 | unsigned int limit; | ||
| 56 | unsigned short flags; | ||
| 57 | unsigned long random_maxcount; | ||
| 58 | u_int delay; /* w8 for outstanding packets */ | ||
| 59 | u_int pscanstat; /* scan stats every x pkts, default NEVER */ | ||
| 60 | u_long start_ip; /* in HBO */ | ||
| 61 | u_long end_ip; /* in HBO */ | ||
| 62 | u_long ipscan_count; /* scanned ip's of a SPECIFIC range [temp!] */ | ||
| 63 | u_long iptotscan_count; /* total scan_count over all ranges */ | ||
| 64 | /* used for flood protection */ | ||
| 65 | u_long bsent_count; /* byte-sent counter. TMP (!) variable */ | ||
| 66 | u_long ip_offset; /* spread scan offset */ | ||
| 67 | u_long ip_blklen; /* block-length for spread-scan */ | ||
| 68 | u_long ip_pos; /* position for SPREAD scan, non-linear */ | ||
| 69 | struct timeval scan_start; /* scan start for ALL ranges */ | ||
| 70 | /* the real beginning */ | ||
| 71 | struct timeval tv2; /* flood protection timer 2 + restore */ | ||
| 72 | /* must be the last gettimeofday() from scan */ | ||
| 73 | float sec; /* flood protection distance time */ | ||
| 74 | struct _libnet lnet; | ||
| 75 | u_char spf_smac[6]; /* spoofed ethernet sender mac */ | ||
| 76 | pthread_t bscantid; /* 'parent' thread id */ | ||
| 77 | pthread_t snarftid; /* snarf thread id */ | ||
| 78 | struct _snarf | ||
| 79 | { | ||
| 80 | u_long icmp_c; | ||
| 81 | u_long close_c; | ||
| 82 | u_long open_c; | ||
| 83 | u_long refused_c; | ||
| 84 | } | ||
| 85 | snarf; | ||
| 86 | struct net_tuple nt; | ||
| 87 | }; | ||
| 88 | |||
| 89 | |||
| 90 | void make_iprange (u_long *, u_long *, u_long *, u_long *, char *); | ||
| 91 | void init_spreadscan (u_long diff); | ||
| 92 | void sigdriver (int); | ||
| 93 | void print_scanstat (FILE *); | ||
| 94 | void die (int); | ||
diff --git a/other/b-scan/tmp/include/bscan/cf_prse.h b/other/b-scan/tmp/include/bscan/cf_prse.h new file mode 100644 index 0000000..6185ab3 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/cf_prse.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | struct confFileOpt | ||
| 2 | { | ||
| 3 | unsigned short flags; | ||
| 4 | unsigned int limit; | ||
| 5 | char *device; | ||
| 6 | unsigned long int delay; | ||
| 7 | unsigned long srcAddr; | ||
| 8 | unsigned short mac[5]; | ||
| 9 | } FileOpt; | ||
| 10 | |||
| 11 | int readConfFile (char *); | ||
diff --git a/other/b-scan/tmp/include/bscan/dcd_icmp.h b/other/b-scan/tmp/include/bscan/dcd_icmp.h new file mode 100644 index 0000000..215d0c8 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/dcd_icmp.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* bscan - icmp include file | ||
| 2 | */ | ||
| 3 | |||
| 4 | #ifndef BS_DCD_ICMP_H | ||
| 5 | #define BS_DCD_ICMP_H | ||
| 6 | |||
| 7 | #define ICMP_HDRSIZE 8 | ||
| 8 | |||
| 9 | const char * | ||
| 10 | icmp_str (int type, int code); | ||
| 11 | |||
| 12 | #endif | ||
| 13 | |||
diff --git a/other/b-scan/tmp/include/bscan/garage.h b/other/b-scan/tmp/include/bscan/garage.h new file mode 100644 index 0000000..0d63774 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/garage.h | |||
| @@ -0,0 +1,178 @@ | |||
| 1 | /* bscan - mod_garage.h - per IP storage functions include file | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef _MOD_GARAGE_H | ||
| 7 | #define _MOD_GARAGE_H | ||
| 8 | |||
| 9 | #include <sys/types.h> | ||
| 10 | |||
| 11 | #define GARAGE_VERSION "1.0.1" | ||
| 12 | |||
| 13 | |||
| 14 | typedef struct ip_elem { | ||
| 15 | struct ip_elem * next; /* more then one data stored */ | ||
| 16 | |||
| 17 | int data_free; /* 1 = do free() on destroy */ | ||
| 18 | size_t data_len; | ||
| 19 | void * data; /* must be free() able */ | ||
| 20 | } ip_elem; | ||
| 21 | |||
| 22 | |||
| 23 | typedef struct ip_list { | ||
| 24 | struct ip_list * next; /* another IP, always greater then this ! */ | ||
| 25 | unsigned long int ip; | ||
| 26 | |||
| 27 | ip_elem * data; | ||
| 28 | } ip_list; | ||
| 29 | |||
| 30 | |||
| 31 | /* not for use in other code then garage.c | ||
| 32 | */ | ||
| 33 | typedef struct { | ||
| 34 | char * name; | ||
| 35 | ip_list ** garage; | ||
| 36 | |||
| 37 | void (* cleaner)(ip_list *); | ||
| 38 | |||
| 39 | unsigned long int ip_count; | ||
| 40 | |||
| 41 | unsigned long int timeout_max; | ||
| 42 | unsigned long int timeout_idx; | ||
| 43 | unsigned long int * timeout_tbl; | ||
| 44 | } garage_hdlr; | ||
| 45 | |||
| 46 | |||
| 47 | /* mg_init | ||
| 48 | * | ||
| 49 | * setup the required structures for the garage | ||
| 50 | * | ||
| 51 | * return 0 on success | ||
| 52 | * return 1 on failure | ||
| 53 | */ | ||
| 54 | |||
| 55 | garage_hdlr * | ||
| 56 | mg_init (char *name, unsigned long int max_hosts_in_list, | ||
| 57 | void (* cleaner)(ip_list *)); | ||
| 58 | |||
| 59 | |||
| 60 | /* mg_destroy | ||
| 61 | * | ||
| 62 | * destroy all data in the garage `g', use the standard handler in case | ||
| 63 | * `do_handler' is not zero, otherwise just free. | ||
| 64 | */ | ||
| 65 | |||
| 66 | void | ||
| 67 | mg_destroy (garage_hdlr *g, int do_handler); | ||
| 68 | |||
| 69 | |||
| 70 | /* mg_write | ||
| 71 | * | ||
| 72 | * store pointer `data' with len `data_len' to the garage for IP `ip' | ||
| 73 | * if `data_free' is non-zero the `data' pointer will be freed if mg_clean | ||
| 74 | * or mg_destroy is called. | ||
| 75 | */ | ||
| 76 | |||
| 77 | void | ||
| 78 | mg_write (garage_hdlr *g, unsigned long int ip, void *data, size_t data_len, | ||
| 79 | int data_free); | ||
| 80 | |||
| 81 | |||
| 82 | /* mg_read | ||
| 83 | * | ||
| 84 | * return first ip_elem for ip `ip' on success (it is not removed from garage) | ||
| 85 | * return NULL on failure | ||
| 86 | */ | ||
| 87 | |||
| 88 | ip_elem * | ||
| 89 | mg_read (garage_hdlr *g, unsigned long int ip); | ||
| 90 | |||
| 91 | |||
| 92 | /* mg_clean | ||
| 93 | * | ||
| 94 | * clean everything stored in the garage for IP `ip' | ||
| 95 | */ | ||
| 96 | |||
| 97 | void | ||
| 98 | mg_clean (garage_hdlr *g, unsigned long int ip, void (*cleaner)(ip_list *)); | ||
| 99 | |||
| 100 | |||
| 101 | /* mg_show | ||
| 102 | * | ||
| 103 | * DEBUG function, to show IP distribution in garage | ||
| 104 | */ | ||
| 105 | |||
| 106 | void | ||
| 107 | mg_show (garage_hdlr *g); | ||
| 108 | |||
| 109 | |||
| 110 | /* mg_count | ||
| 111 | * | ||
| 112 | * count elements in garage | ||
| 113 | */ | ||
| 114 | |||
| 115 | unsigned long int | ||
| 116 | mg_count (garage_hdlr *g); | ||
| 117 | |||
| 118 | |||
| 119 | /* mg_ip_isin | ||
| 120 | * | ||
| 121 | * check whether the ip `ip' is stored in the garage pointed to by `g'. | ||
| 122 | * | ||
| 123 | * return zero in case it is not | ||
| 124 | * return != zero if it is | ||
| 125 | */ | ||
| 126 | |||
| 127 | int | ||
| 128 | mg_ip_isin (garage_hdlr *g, unsigned long int ip); | ||
| 129 | |||
| 130 | |||
| 131 | /* CIDR routines | ||
| 132 | */ | ||
| 133 | |||
| 134 | /* mg_cidr_getmask | ||
| 135 | * | ||
| 136 | * convert a netmask (eg 0xfffffc00) or a cidr notation (eg 24) given in | ||
| 137 | * `mask' to a netmask. | ||
| 138 | */ | ||
| 139 | |||
| 140 | unsigned long int | ||
| 141 | mg_cidr_getmask (unsigned long int mask); | ||
| 142 | |||
| 143 | |||
| 144 | /* mg_cidr_maskcount | ||
| 145 | * | ||
| 146 | * return the number of hosts that are possible using a mask `mask' in | ||
| 147 | * either CIDR or netmask notation | ||
| 148 | */ | ||
| 149 | |||
| 150 | unsigned long int | ||
| 151 | mg_cidr_maskcount (unsigned long int mask); | ||
| 152 | |||
| 153 | |||
| 154 | /* mg_cidr_match | ||
| 155 | * | ||
| 156 | * check whether `ip1' and `ip2' are in the same network, given the network | ||
| 157 | * size by `mask' (CIDR or netmask notation) | ||
| 158 | */ | ||
| 159 | |||
| 160 | int | ||
| 161 | mg_cidr_match (unsigned long int ip1, unsigned long int ip2, | ||
| 162 | unsigned long int mask); | ||
| 163 | |||
| 164 | |||
| 165 | /* mg_cidr_count | ||
| 166 | * | ||
| 167 | * count elements in garage `g', that are within the CIDR range build from | ||
| 168 | * ip `ip' and netmask `mask'. `mask' is either the number of bits, if it's in | ||
| 169 | * the range of 0-32, or the real mask, if it is greater then 32. (for the | ||
| 170 | * zero case the netmask is equal to the cidr notation). | ||
| 171 | */ | ||
| 172 | |||
| 173 | unsigned long int | ||
| 174 | mg_cidr_count (garage_hdlr *g, unsigned long int ip, unsigned long int mask); | ||
| 175 | |||
| 176 | |||
| 177 | #endif | ||
| 178 | |||
diff --git a/other/b-scan/tmp/include/bscan/module.h b/other/b-scan/tmp/include/bscan/module.h new file mode 100644 index 0000000..3ad316b --- /dev/null +++ b/other/b-scan/tmp/include/bscan/module.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | |||
| 2 | #define MAX_MODULES 8 | ||
| 3 | |||
| 4 | #define MOD_FIRSTPKG 0x00 | ||
| 5 | #define MOD_RCV 0x01 | ||
| 6 | |||
| 7 | #define RMOD_OK 0x00 | ||
| 8 | #define RMOD_SKIP 0x01 | ||
| 9 | #define RMOD_ERROR 0x02 | ||
| 10 | #define RMOD_ABRT 0x04 | ||
| 11 | |||
| 12 | struct _mods | ||
| 13 | { | ||
| 14 | int (*init) (char **, int, char **, void *); /* init the module stuff */ | ||
| 15 | int (*fini) (); /* finish the module */ | ||
| 16 | void (*musage) (); /* print out usage informations */ | ||
| 17 | int (*callmdl) (int, void *); /* call a function */ | ||
| 18 | const char *modname; /* name of the module after init */ | ||
| 19 | int modid; /* id of the module. who needs this ? */ | ||
| 20 | char *modarg; /* arg to module */ | ||
| 21 | }; | ||
| 22 | |||
| 23 | int add_module (char *, char *); | ||
| 24 | void split_margs (const char *, char ***, int *); | ||
| 25 | int loadinit_mod (char *); | ||
| 26 | |||
diff --git a/other/b-scan/tmp/include/bscan/network_raw.h b/other/b-scan/tmp/include/bscan/network_raw.h new file mode 100644 index 0000000..9ffed74 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/network_raw.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * network_raw.h, depends on libnet.h | ||
| 4 | */ | ||
| 5 | |||
| 6 | |||
| 7 | #define ETH_SIZE 14 | ||
| 8 | #define IP_SIZE 20 | ||
| 9 | #define TCP_SIZE 20 | ||
| 10 | #define ICMP_SIZE 8 | ||
| 11 | #define UDP_SIZE 8 | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Checksum stuff | ||
| 15 | */ | ||
| 16 | #define CKSUM_CARRY(x) \ | ||
| 17 | (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) | ||
| 18 | #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) | ||
| 19 | |||
| 20 | |||
| 21 | /* | ||
| 22 | * leet net tuple | ||
| 23 | */ | ||
| 24 | struct net_tuple | ||
| 25 | { | ||
| 26 | uint32_t src; | ||
| 27 | unsigned short int sport; | ||
| 28 | uint32_t dst; | ||
| 29 | unsigned short int dport; | ||
| 30 | }; | ||
| 31 | |||
| 32 | |||
| 33 | /* | ||
| 34 | * pseudo TCP header for calculating the chksum | ||
| 35 | */ | ||
| 36 | struct _fakehead | ||
| 37 | { | ||
| 38 | uint32_t saddr; | ||
| 39 | uint32_t daddr; | ||
| 40 | uint8_t zero; | ||
| 41 | uint8_t protocol; | ||
| 42 | uint16_t tot_len; | ||
| 43 | }; | ||
| 44 | |||
| 45 | int init_network_raw (void); | ||
| 46 | int in_cksum (unsigned short *, int); | ||
| 47 | int send_ipv4 (int, u_char *, size_t); | ||
| 48 | void add_udphdr (unsigned char *, struct net_tuple *, int); | ||
| 49 | void add_tcphdr (unsigned char *, struct net_tuple *, uint8_t, int, | ||
| 50 | tcp_seq *, tcp_seq *); | ||
| 51 | void add_icmpping (unsigned char *, int, int); | ||
| 52 | void add_iphdr (unsigned char *, uint8_t ip_p, struct net_tuple *, int); | ||
| 53 | int answer_tcp (int, struct ip *, struct tcphdr *, uint8_t, u_char *, uint); | ||
| 54 | int vrfy_ip (struct ip *, uint32_t, u_short *); | ||
| 55 | int vrfy_tcp (struct tcphdr *, uint32_t, u_short *); | ||
| 56 | int decode_nvt(u_char *, uint, u_char *, uint *, u_char *, uint *); | ||
| 57 | |||
diff --git a/other/b-scan/tmp/include/bscan/restore.h b/other/b-scan/tmp/include/bscan/restore.h new file mode 100644 index 0000000..960efe6 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/restore.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | /* | ||
| 2 | * restore.h | ||
| 3 | */ | ||
| 4 | |||
| 5 | int write_restore (void); | ||
| 6 | int read_restore (char *); | ||
diff --git a/other/b-scan/tmp/include/bscan/signal.h b/other/b-scan/tmp/include/bscan/signal.h new file mode 100644 index 0000000..fab56f6 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/signal.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* | ||
| 2 | * this space for rent.... | ||
| 3 | */ | ||
| 4 | |||
| 5 | typedef void (*sighandler_t) (int); | ||
| 6 | |||
| 7 | #define SIG_SETALL 0x01 | ||
| 8 | |||
| 9 | |||
| 10 | int sigctl (int, sighandler_t); | ||
diff --git a/other/b-scan/tmp/include/bscan/snarf.h b/other/b-scan/tmp/include/bscan/snarf.h new file mode 100644 index 0000000..fee7047 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/snarf.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | |||
| 2 | #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) | ||
| 3 | |||
| 4 | #define ETH_ALEN 6 | ||
| 5 | #define PCAP_FILTER "arp or tcp or icmp or udp" | ||
| 6 | |||
| 7 | struct Ether_header | ||
| 8 | { | ||
| 9 | uint8_t ether_dhost[ETH_ALEN]; | ||
| 10 | uint8_t ether_shost[ETH_ALEN]; | ||
| 11 | uint16_t ether_type; | ||
| 12 | }; | ||
| 13 | |||
| 14 | struct Arphdr | ||
| 15 | { | ||
| 16 | unsigned short int ar_hrd; /* Format of hardware address. */ | ||
| 17 | unsigned short int ar_pro; /* Format of protocol address. */ | ||
| 18 | unsigned char ar_hln; /* Length of hardware address. */ | ||
| 19 | unsigned char ar_pln; /* Length of protocol address. */ | ||
| 20 | unsigned short int ar_op; /* ARP opcode (command). */ | ||
| 21 | /* Ethernet looks like this : This bit is variable sized | ||
| 22 | however... */ | ||
| 23 | unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */ | ||
| 24 | unsigned char ar_sip[4]; /* Sender IP address. */ | ||
| 25 | unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */ | ||
| 26 | unsigned char ar_tip[4]; /* Target IP address. */ | ||
| 27 | }; | ||
| 28 | |||
| 29 | |||
| 30 | void *do_snarf (void *); | ||
| 31 | void undo_snarf (); | ||
diff --git a/other/b-scan/tmp/include/bscan/system.h b/other/b-scan/tmp/include/bscan/system.h new file mode 100644 index 0000000..6eed6d8 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/system.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * generic system functions | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <sys/time.h> | ||
| 6 | #include <unistd.h> | ||
| 7 | #include <errno.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | #define DEV_ZERO "/dev/zero" | ||
| 12 | |||
| 13 | /* | ||
| 14 | * we use the 'do while' trick to use err_abort as if they were functions | ||
| 15 | */ | ||
| 16 | #define err_abort(code,text) do { \ | ||
| 17 | fprintf (stderr, "%s at \"%s\":%d: %s\n", \ | ||
| 18 | text, __FILE__, __LINE__, strerror (code)); \ | ||
| 19 | abort(); \ | ||
| 20 | } while (0) | ||
| 21 | |||
| 22 | #define errno_abort(text) do { \ | ||
| 23 | fprintf(stderr, "%s at \"%s\":%d: %s\n", \ | ||
| 24 | text, __FILE__, __LINE__, strerror (errno)); \ | ||
| 25 | abort(); \ | ||
| 26 | } while (0) | ||
| 27 | |||
| 28 | |||
| 29 | void *shmalloc (int, size_t); | ||
| 30 | void do_nanosleep (time_t, long); | ||
| 31 | void xchange (void *, void *, int); | ||
| 32 | void time_diff (struct timeval *, struct timeval *); | ||
| 33 | int ctoreal(char *, char *); | ||
| 34 | void save_write(FILE *, char *, unsigned char *, int); | ||
| 35 | int isprintdata(char *, int); | ||
| 36 | int dat2hexstr(unsigned char *, unsigned int, unsigned char *, unsigned int); | ||
| 37 | int dat2strip(unsigned char *, unsigned int, unsigned char *, unsigned int); | ||
| 38 | |||
diff --git a/other/b-scan/tmp/include/bscan/tty.h b/other/b-scan/tmp/include/bscan/tty.h new file mode 100644 index 0000000..09d73c0 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/tty.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | /* | ||
| 2 | * tty support functions | ||
| 3 | */ | ||
| 4 | |||
| 5 | void tty_done (); | ||
| 6 | void tty_init (); | ||
| 7 | int tty_getchar (); | ||
diff --git a/other/b-scan/tmp/include/bscan/version.h b/other/b-scan/tmp/include/bscan/version.h new file mode 100644 index 0000000..39b1298 --- /dev/null +++ b/other/b-scan/tmp/include/bscan/version.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #define VER_MAJOR 0 | ||
| 2 | #define VER_MINOR 7 | ||
| 3 | #define VER_SUFFIX d | ||
| 4 | #define VER_EMAIL "anonymous@segfault.net" | ||
| 5 | #define VERSION "bscan v0.7-dev, anonymous@segfault.net" | ||
diff --git a/other/b-scan/tmp/modules/Makefile b/other/b-scan/tmp/modules/Makefile new file mode 100644 index 0000000..ccac359 --- /dev/null +++ b/other/b-scan/tmp/modules/Makefile | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | CC=gcc | ||
| 2 | COPT=-Wall -ggdb -shared -fPIC -I../include | ||
| 3 | DEFS=`libnet-config --defines` -DUSE_LIBNET #-DDEBUG | ||
| 4 | LIBS= | ||
| 5 | TARGETS=mod_snmp mod_banner mod_httpd mod_ping mod_bind | ||
| 6 | |||
| 7 | # HPUX 10.20 | ||
| 8 | # DEFS=`libnet-config --defines` -DUSE_LIBNET -DHP10 #-DDEBUG | ||
| 9 | |||
| 10 | all: | ||
| 11 | for trgt in $(TARGETS); do \ | ||
| 12 | $(CC) $(COPT) $(DEFS) -o $$trgt.so $$trgt.c; \ | ||
| 13 | done | ||
| 14 | |||
| 15 | |||
| 16 | clean: | ||
| 17 | for trgt in $(TARGETS); do \ | ||
| 18 | rm -f $$trgt.so; \ | ||
| 19 | done | ||
| 20 | rm -f core *~ | ||
| 21 | |||
| 22 | |||
diff --git a/other/b-scan/tmp/modules/mod_banner.c b/other/b-scan/tmp/modules/mod_banner.c new file mode 100644 index 0000000..6f02a39 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_banner.c | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | /* | ||
| 2 | * mod_example.c | ||
| 3 | * Example module for bscan. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/module.h> | ||
| 8 | #include <bscan/dcd_icmp.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | #include <unistd.h> | ||
| 12 | |||
| 13 | |||
| 14 | #ifndef MOD_NAME | ||
| 15 | #define MOD_NAME "mod_banner" | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #define SCN_NVT 0x00000001 | ||
| 19 | #define SCN_HALFOPEN 0x00000002 | ||
| 20 | #define SCN_XMAS 0x00000004 | ||
| 21 | #define SCN_FIN 0x00000008 | ||
| 22 | #define SCN_NULL 0x00000010 | ||
| 23 | #define SCN_PUSH 0x00000020 | ||
| 24 | #define SCN_LETOPEN 0x00000040 | ||
| 25 | #define SCN_NOSCAN 0x00000080 | ||
| 26 | #define SCN_NOICMP 0x00000100 | ||
| 27 | |||
| 28 | |||
| 29 | static int isinit=0; | ||
| 30 | /* | ||
| 31 | * some variables from the binary-process | ||
| 32 | */ | ||
| 33 | extern int dlt_len; | ||
| 34 | extern u_char *align_buf; | ||
| 35 | extern unsigned short ip_options; | ||
| 36 | extern struct ip *ip; | ||
| 37 | extern struct Ether_header *eth; | ||
| 38 | extern u_int plen, pcaplen; | ||
| 39 | |||
| 40 | |||
| 41 | struct _mopt | ||
| 42 | { | ||
| 43 | u_int scanflags; | ||
| 44 | uint8_t th_flags; | ||
| 45 | } static mopt; | ||
| 46 | |||
| 47 | |||
| 48 | /* | ||
| 49 | * static functions prototypes | ||
| 50 | */ | ||
| 51 | static int mdo_opt(int, char **, struct _opt *); | ||
| 52 | static void init_vars(struct _opt *); | ||
| 53 | static int process_rcv(struct _opt *); | ||
| 54 | static void handle_icmp (); | ||
| 55 | |||
| 56 | |||
| 57 | |||
| 58 | /* | ||
| 59 | * print out usage informations | ||
| 60 | */ | ||
| 61 | void | ||
| 62 | musage() | ||
| 63 | { | ||
| 64 | printf ("\n"MOD_NAME"\n"); | ||
| 65 | printf (" -o <source port>, default 20\n"); | ||
| 66 | printf (" -p <port to scan>, default 21\n"); | ||
| 67 | printf (" -a grab all data and let the connecten established\n"); | ||
| 68 | printf (" -n NVT terminal support (use this for telnetd-scans)\n"); | ||
| 69 | printf (" -I dont report ICMP-errors\n"); | ||
| 70 | printf (" -q quite, dont send out any initial packages [first-pkg]\n"); | ||
| 71 | printf (" "MOD_NAME" only reports ICMP errors and doesn't start\n"); | ||
| 72 | printf (" scanning. It will still simulate the tcp-stack.\n"); | ||
| 73 | printf | ||
| 74 | (" -sS,-sF,-sX,-sN,-sP TCP SYN stealth, Fin, Xmas, Null, !Push scan\n"); | ||
| 75 | |||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | /* | ||
| 80 | * return 0 on success, != 0 on failure | ||
| 81 | */ | ||
| 82 | int | ||
| 83 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 84 | { | ||
| 85 | #ifdef DEBUG | ||
| 86 | printf("MODULE INIT\n"); | ||
| 87 | #endif | ||
| 88 | if (isinit) | ||
| 89 | return(-1); | ||
| 90 | |||
| 91 | *modname = MOD_NAME; | ||
| 92 | isinit = 1; | ||
| 93 | init_vars(opt); | ||
| 94 | |||
| 95 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 96 | return(-1); | ||
| 97 | |||
| 98 | return(0); | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | ||
| 102 | * fini-routine. called on cleanup | ||
| 103 | */ | ||
| 104 | int | ||
| 105 | fini() | ||
| 106 | { | ||
| 107 | #ifdef DEBUG | ||
| 108 | printf("MODULE FINI\n"); | ||
| 109 | #endif | ||
| 110 | return(0); | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | /* | ||
| 115 | * | ||
| 116 | */ | ||
| 117 | int | ||
| 118 | callmdl(int entry, struct _opt *opt) | ||
| 119 | { | ||
| 120 | #ifdef DEBUG | ||
| 121 | printf("MODULE CALLMDL\n"); | ||
| 122 | #endif | ||
| 123 | if (entry == MOD_FIRSTPKG) | ||
| 124 | { | ||
| 125 | if (mopt.scanflags & SCN_NOSCAN) | ||
| 126 | return(RMOD_SKIP); | ||
| 127 | |||
| 128 | add_tcphdr(opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, mopt.th_flags, 0, NULL, NULL); | ||
| 129 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_TCP, &opt->nt, TCP_SIZE); | ||
| 130 | opt->pkg_len = TCP_SIZE + IP_SIZE; | ||
| 131 | return(RMOD_OK); | ||
| 132 | } | ||
| 133 | |||
| 134 | if (entry == MOD_RCV) | ||
| 135 | process_rcv(opt); | ||
| 136 | |||
| 137 | return(RMOD_OK); | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | /* | ||
| 142 | *********************************************************** | ||
| 143 | * Our OWN/static functions for THIS module * | ||
| 144 | *********************************************************** | ||
| 145 | */ | ||
| 146 | |||
| 147 | /* | ||
| 148 | * initialize all local variables. | ||
| 149 | * We use some 'unused' variables of the masterprogramm | ||
| 150 | */ | ||
| 151 | static void | ||
| 152 | init_vars(struct _opt *opt) | ||
| 153 | { | ||
| 154 | opt->nt.sport = htons(20); /* not used by master programm */ | ||
| 155 | opt->nt.dport = htons(21); /* not used by master programm */ | ||
| 156 | |||
| 157 | mopt.scanflags = 0; | ||
| 158 | mopt.th_flags = TH_SYN; | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | /* | ||
| 163 | * LOCAL/STATIC function, only available in the module | ||
| 164 | * return 0 on success, != 0 on failure | ||
| 165 | */ | ||
| 166 | static int | ||
| 167 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 168 | { | ||
| 169 | extern char *optarg; | ||
| 170 | /*extern int optind, opterr, optopt;*/ | ||
| 171 | int c; | ||
| 172 | |||
| 173 | while ((c = getopt (argc, argv, "Iqans:p:o:")) != -1) | ||
| 174 | { | ||
| 175 | switch (c) | ||
| 176 | { | ||
| 177 | case 'I': | ||
| 178 | mopt.scanflags |= SCN_NOICMP; | ||
| 179 | break; | ||
| 180 | case 'q': | ||
| 181 | mopt.scanflags |= SCN_NOSCAN; | ||
| 182 | break; | ||
| 183 | case 'p': | ||
| 184 | opt->nt.dport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 185 | break; | ||
| 186 | case 'o': | ||
| 187 | opt->nt.sport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 188 | break; | ||
| 189 | case 'a': | ||
| 190 | mopt.scanflags |= SCN_LETOPEN; | ||
| 191 | break; | ||
| 192 | case 'n': | ||
| 193 | mopt.scanflags |= SCN_NVT; /* NVT parsing */ | ||
| 194 | break; | ||
| 195 | case 's': | ||
| 196 | switch (optarg[0]) | ||
| 197 | { | ||
| 198 | case 'S': | ||
| 199 | mopt.scanflags |= SCN_HALFOPEN; | ||
| 200 | mopt.th_flags = TH_SYN; | ||
| 201 | break; | ||
| 202 | case 'X': | ||
| 203 | mopt.scanflags |= SCN_XMAS; | ||
| 204 | mopt.th_flags = (TH_FIN | TH_PUSH | TH_URG); | ||
| 205 | break; | ||
| 206 | case 'F': | ||
| 207 | mopt.scanflags |= SCN_FIN; | ||
| 208 | mopt.th_flags = TH_FIN; | ||
| 209 | break; | ||
| 210 | case 'N': | ||
| 211 | mopt.scanflags |= SCN_NULL; | ||
| 212 | mopt.th_flags = 0; | ||
| 213 | break; | ||
| 214 | case 'P': | ||
| 215 | mopt.scanflags |= SCN_PUSH; | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | fprintf(stderr, "unrecognized option -s%c\n", optarg[0]); | ||
| 219 | return(-1); | ||
| 220 | } | ||
| 221 | break; | ||
| 222 | case ':': | ||
| 223 | fprintf(stderr, "missing parameter\n"); | ||
| 224 | return(-1); | ||
| 225 | default: | ||
| 226 | return(-1); | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | if ((mopt.scanflags & SCN_NVT) && !(mopt.scanflags & SCN_LETOPEN)) | ||
| 231 | fprintf(stderr, "WARNING: NVT used without -a. This is probably not what you want!\n"); | ||
| 232 | |||
| 233 | return(0); | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | /* | ||
| 238 | * vrfy the icmp packet and print out 'human readable'-icmp code | ||
| 239 | * dest-unreachable packages only! | ||
| 240 | */ | ||
| 241 | static void | ||
| 242 | handle_icmp (int offset) | ||
| 243 | { | ||
| 244 | struct icmp *icmp = (struct icmp *) (align_buf + offset); | ||
| 245 | struct ip *icmpip; | ||
| 246 | |||
| 247 | if (plen < offset + sizeof (*icmp) + dlt_len) | ||
| 248 | return; | ||
| 249 | |||
| 250 | icmpip = (struct ip *) (align_buf + offset + ICMP_HDRSIZE); | ||
| 251 | |||
| 252 | printf ("%s (%d/%d) %s", int_ntoa (icmpip->ip_dst.s_addr), | ||
| 253 | icmp->icmp_type, icmp->icmp_code, | ||
| 254 | icmp_str (icmp->icmp_type, icmp->icmp_code)); | ||
| 255 | printf ("(from %s)\n", int_ntoa (ip->ip_src.s_addr)); | ||
| 256 | } | ||
| 257 | |||
| 258 | |||
| 259 | /* | ||
| 260 | * process incoming packets | ||
| 261 | * IP-packet is verified and variables valid (ip_options, *ip) | ||
| 262 | */ | ||
| 263 | static int | ||
| 264 | process_rcv(struct _opt *opt) | ||
| 265 | { | ||
| 266 | struct tcphdr *tcp; | ||
| 267 | unsigned short tcp_options = 0; | ||
| 268 | u_char *data = NULL; | ||
| 269 | u_char *ans = NULL; /* tcpdata answer */ | ||
| 270 | u_char prefix[32]; | ||
| 271 | int data_len = 0; | ||
| 272 | uint ans_len = 0; | ||
| 273 | uint res_len = 0; | ||
| 274 | uint tcphdr_len = 0; | ||
| 275 | uint iphdr_len = 0; | ||
| 276 | |||
| 277 | |||
| 278 | if (ip->ip_p == IPPROTO_ICMP) | ||
| 279 | { | ||
| 280 | opt->snarf.icmp_c++; /* for statistics */ | ||
| 281 | if (!(mopt.scanflags & SCN_NOICMP)) | ||
| 282 | handle_icmp (sizeof (*ip) + ip_options); | ||
| 283 | |||
| 284 | return(0); | ||
| 285 | } | ||
| 286 | |||
| 287 | if (ip->ip_p != IPPROTO_TCP) | ||
| 288 | return(0); | ||
| 289 | |||
| 290 | iphdr_len = sizeof(*ip) + ip_options; | ||
| 291 | tcp = (struct tcphdr *) (align_buf + iphdr_len); | ||
| 292 | |||
| 293 | if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len , &tcp_options) != 0) | ||
| 294 | return(0); | ||
| 295 | |||
| 296 | if (tcp->th_flags & TH_RST) | ||
| 297 | { | ||
| 298 | opt->snarf.refused_c++; | ||
| 299 | printf ("%s:%d refused\n", int_ntoa (ip->ip_src.s_addr), | ||
| 300 | ntohs (tcp->th_sport)); | ||
| 301 | } | ||
| 302 | else if (tcp->th_flags & TH_FIN) | ||
| 303 | { | ||
| 304 | opt->snarf.close_c++; | ||
| 305 | answer_tcp (opt->sox, ip, tcp, TH_FIN | TH_ACK, NULL, 0); | ||
| 306 | printf ("%s:%d connection closed by foreig host\n", | ||
| 307 | int_ntoa (ip->ip_src.s_addr), ntohs (tcp->th_sport)); | ||
| 308 | } | ||
| 309 | else if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) | ||
| 310 | { | ||
| 311 | |||
| 312 | if (mopt.scanflags & SCN_HALFOPEN) | ||
| 313 | { | ||
| 314 | if (!(mopt.scanflags & SCN_LETOPEN)) | ||
| 315 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, NULL, 0); | ||
| 316 | return(0); | ||
| 317 | } | ||
| 318 | else | ||
| 319 | answer_tcp (opt->sox, ip, tcp, TH_ACK, NULL, 0); | ||
| 320 | |||
| 321 | opt->snarf.open_c++; | ||
| 322 | printf ("%s:%d open\n", int_ntoa (ip->ip_src.s_addr), | ||
| 323 | ntohs (tcp->th_sport)); | ||
| 324 | } | ||
| 325 | |||
| 326 | /* banner scanner output */ | ||
| 327 | tcphdr_len = sizeof(*tcp) + tcp_options; | ||
| 328 | if (plen - dlt_len > ntohs(ip->ip_len)) | ||
| 329 | data_len = ntohs(ip->ip_len) - iphdr_len - tcphdr_len; | ||
| 330 | else | ||
| 331 | data_len = plen - dlt_len - iphdr_len - tcphdr_len; | ||
| 332 | |||
| 333 | if (data_len <= 0) | ||
| 334 | return(0); | ||
| 335 | |||
| 336 | if ( (data = alloca(data_len + 1)) == NULL) | ||
| 337 | return(-1); | ||
| 338 | |||
| 339 | memcpy(data, align_buf + iphdr_len + tcphdr_len, data_len); | ||
| 340 | |||
| 341 | if (mopt.scanflags & SCN_NVT) | ||
| 342 | { | ||
| 343 | if ((ans = alloca(data_len)) == NULL) | ||
| 344 | return(-1); | ||
| 345 | |||
| 346 | decode_nvt(data, data_len, ans, &ans_len, data, &res_len); | ||
| 347 | data_len = res_len; /* we wrote everything into data */ | ||
| 348 | } | ||
| 349 | |||
| 350 | snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), | ||
| 351 | ntohs (tcp->th_sport)); | ||
| 352 | save_write(stdout, prefix, data, data_len); | ||
| 353 | |||
| 354 | if (tcp->th_flags & TH_RST) /* data_len != 0 */ | ||
| 355 | return(0); /* evil peer resetted our connection */ | ||
| 356 | |||
| 357 | /* close after first data package or ack last RST if data_len >0 */ | ||
| 358 | if (!(mopt.scanflags & SCN_LETOPEN) || (tcp->th_flags & TH_RST)) | ||
| 359 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, ans, ans_len); | ||
| 360 | else | ||
| 361 | answer_tcp (opt->sox, ip, tcp, TH_ACK, ans, ans_len); | ||
| 362 | |||
| 363 | |||
| 364 | return(0); | ||
| 365 | } | ||
diff --git a/other/b-scan/tmp/modules/mod_bind.c b/other/b-scan/tmp/modules/mod_bind.c new file mode 100644 index 0000000..2a09f49 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_bind.c | |||
| @@ -0,0 +1,302 @@ | |||
| 1 | /* | ||
| 2 | * ping-module for bscan. | ||
| 3 | * IDEA: add record-route and source-route feature | ||
| 4 | * and -p pattern [where can we save our time-struct then ? | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <bscan/bscan.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef MOD_NAME | ||
| 14 | #define MOD_NAME "mod_bind" | ||
| 15 | #endif | ||
| 16 | |||
| 17 | /* | ||
| 18 | * this is our query. This is a DNS-formated string | ||
| 19 | * <length1><string1><length2><string2><0> | ||
| 20 | */ | ||
| 21 | #define DNSTXTREQ "\007version\004bind" | ||
| 22 | |||
| 23 | static int process_rcv(struct _opt *); | ||
| 24 | static void add_dnshdr(unsigned char *); | ||
| 25 | static void add_dnstxthdr(unsigned char *, char *, u_int *); | ||
| 26 | |||
| 27 | static int isinit=0; | ||
| 28 | /* | ||
| 29 | * some variables from the binary-process | ||
| 30 | */ | ||
| 31 | extern int dlt_len; | ||
| 32 | extern u_char *align_buf; | ||
| 33 | extern unsigned short ip_options; | ||
| 34 | extern struct ip *ip; | ||
| 35 | extern struct Ether_header *eth; | ||
| 36 | extern u_int plen, pcaplen; | ||
| 37 | extern struct timeval *pts; | ||
| 38 | |||
| 39 | |||
| 40 | struct _dnshdr | ||
| 41 | { | ||
| 42 | u_short id; /* DNS packet ID */ | ||
| 43 | u_short flags; /* DNS flags */ | ||
| 44 | u_short num_q; /* Number of questions */ | ||
| 45 | u_short num_answ_rr; /* Number of answer resource records */ | ||
| 46 | u_short num_auth_rr; /* Number of authority resource records */ | ||
| 47 | u_short num_addi_rr; /* Number of additional resource records */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct _dnsanswr | ||
| 51 | { | ||
| 52 | u_short type; | ||
| 53 | u_short class; | ||
| 54 | u_short ttl1; | ||
| 55 | u_short ttl2; | ||
| 56 | u_short len; | ||
| 57 | }; | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | /* | ||
| 62 | * static functions prototypes | ||
| 63 | */ | ||
| 64 | static int mdo_opt(int, char **, struct _opt *); | ||
| 65 | static void init_vars(struct _opt *); | ||
| 66 | |||
| 67 | /* | ||
| 68 | * print out usage informations | ||
| 69 | */ | ||
| 70 | void | ||
| 71 | musage() | ||
| 72 | { | ||
| 73 | printf ("\n"MOD_NAME"\n"); | ||
| 74 | printf ("verson.bind chaos txt module\n"); | ||
| 75 | printf (" -p <port>, destination port, default 53\n"); | ||
| 76 | printf (" -o <port>, source port, default 53\n"); | ||
| 77 | } | ||
| 78 | |||
| 79 | |||
| 80 | /* | ||
| 81 | * return 0 on success, != 0 on failure | ||
| 82 | */ | ||
| 83 | int | ||
| 84 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 85 | { | ||
| 86 | #ifdef DEBUG | ||
| 87 | printf("MODULE INIT\n"); | ||
| 88 | #endif | ||
| 89 | if (isinit) | ||
| 90 | return(-1); | ||
| 91 | |||
| 92 | *modname = MOD_NAME; | ||
| 93 | isinit = 1; | ||
| 94 | init_vars(opt); | ||
| 95 | |||
| 96 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 97 | return(-1); | ||
| 98 | |||
| 99 | return(0); | ||
| 100 | } | ||
| 101 | |||
| 102 | /* | ||
| 103 | * fini-routine. called on cleanup | ||
| 104 | */ | ||
| 105 | int | ||
| 106 | fini() | ||
| 107 | { | ||
| 108 | #ifdef DEBUG | ||
| 109 | printf("MODULE FINI\n"); | ||
| 110 | #endif | ||
| 111 | return(0); | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | * Module entry point [entry] | ||
| 117 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 118 | * or do nothing [MOD_RCV]. | ||
| 119 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 120 | */ | ||
| 121 | int | ||
| 122 | callmdl(int entry, struct _opt *opt) | ||
| 123 | { | ||
| 124 | #ifdef DEBUG | ||
| 125 | printf("MODULE CALLMDL\n"); | ||
| 126 | #endif | ||
| 127 | if (entry == MOD_FIRSTPKG) | ||
| 128 | { | ||
| 129 | add_dnstxthdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr), DNSTXTREQ, &opt->pkg_len); | ||
| 130 | add_dnshdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE); | ||
| 131 | add_udphdr (opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, opt->pkg_len + sizeof(struct _dnshdr)); | ||
| 132 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE + sizeof(struct _dnshdr)); | ||
| 133 | opt->pkg_len += IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr); | ||
| 134 | return(RMOD_OK); | ||
| 135 | } | ||
| 136 | |||
| 137 | if (entry == MOD_RCV) | ||
| 138 | process_rcv(opt); | ||
| 139 | |||
| 140 | return(RMOD_OK); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | /* | ||
| 145 | *********************************************************** | ||
| 146 | * Our OWN/static functions for THIS module * | ||
| 147 | *********************************************************** | ||
| 148 | */ | ||
| 149 | |||
| 150 | /* | ||
| 151 | * initialize all local variables. | ||
| 152 | * We use some 'unused' variables of the masterprogramm | ||
| 153 | */ | ||
| 154 | static void | ||
| 155 | init_vars(struct _opt *opt) | ||
| 156 | { | ||
| 157 | opt->nt.sport = htons(53); | ||
| 158 | opt->nt.dport = htons(53); | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | /* | ||
| 163 | * LOCAL/STATIC function, only available in the module | ||
| 164 | * return 0 on success, != 0 on failure | ||
| 165 | */ | ||
| 166 | static int | ||
| 167 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 168 | { | ||
| 169 | extern char *optarg; | ||
| 170 | /*extern int optind, opterr, optopt;*/ | ||
| 171 | int c; | ||
| 172 | |||
| 173 | while ((c = getopt (argc, argv, "p:o:")) != -1) | ||
| 174 | { | ||
| 175 | switch (c) | ||
| 176 | { | ||
| 177 | case 'p': | ||
| 178 | opt->nt.dport = htons(atoi(optarg)); | ||
| 179 | break; | ||
| 180 | case 'o': | ||
| 181 | opt->nt.sport = htons(atoi(optarg)); | ||
| 182 | break; | ||
| 183 | case ':': | ||
| 184 | fprintf(stderr, "missing parameter\n"); | ||
| 185 | return(-1); | ||
| 186 | default: | ||
| 187 | return(-1); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | return(0); | ||
| 191 | } | ||
| 192 | |||
| 193 | |||
| 194 | /* | ||
| 195 | * add a DNS header | ||
| 196 | */ | ||
| 197 | static void | ||
| 198 | add_dnshdr(unsigned char *pkt) | ||
| 199 | { | ||
| 200 | struct _dnshdr *dnshdr = (struct _dnshdr *)pkt; | ||
| 201 | |||
| 202 | dnshdr->id = htons(6); /* could be random */ | ||
| 203 | dnshdr->flags = htons(0x0100); /* do query recursivly */ | ||
| 204 | dnshdr->num_q = htons(1); | ||
| 205 | dnshdr->num_answ_rr = 0; | ||
| 206 | dnshdr->num_auth_rr = 0; | ||
| 207 | dnshdr->num_addi_rr = 0; | ||
| 208 | /* add request here. class TXT etc */ | ||
| 209 | } | ||
| 210 | |||
| 211 | /* | ||
| 212 | * add DNS-TXT header here | ||
| 213 | * returns length in *len | ||
| 214 | */ | ||
| 215 | static void | ||
| 216 | add_dnstxthdr(unsigned char *pkt, char *name, u_int *len) | ||
| 217 | { | ||
| 218 | u_short *type; | ||
| 219 | u_short *class; | ||
| 220 | |||
| 221 | if (name == NULL) | ||
| 222 | return; /* nah! specifiy "". we need \0 termination */ | ||
| 223 | |||
| 224 | memcpy(pkt, name, strlen(name)+1); | ||
| 225 | type = (u_short *)(pkt + strlen(name) + 1); | ||
| 226 | class = (u_short *)(pkt + strlen(name) + 1 + sizeof(*class)); | ||
| 227 | |||
| 228 | *type = htons(0x10); /* TEXT string */ | ||
| 229 | *class = htons(0x03); /* chaos */ | ||
| 230 | *len = strlen(name) + 1 + sizeof(*type) + sizeof(*class); | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | /* | ||
| 235 | * handle incoming DNS udp answers | ||
| 236 | */ | ||
| 237 | static int | ||
| 238 | process_rcv(struct _opt *opt) | ||
| 239 | { | ||
| 240 | struct _dnshdr *dns; | ||
| 241 | struct _dnsanswr *dnsanswr; | ||
| 242 | struct udphdr *udp; | ||
| 243 | char *ptr; | ||
| 244 | char buf[128]; | ||
| 245 | int len, dnstxtlen; | ||
| 246 | uint iphdr_len = 0; | ||
| 247 | |||
| 248 | if (ip->ip_p != IPPROTO_UDP) | ||
| 249 | return(0); | ||
| 250 | |||
| 251 | iphdr_len = IP_SIZE + ip_options; | ||
| 252 | if (plen < dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns)) | ||
| 253 | return(-1); /* invalid size */ | ||
| 254 | |||
| 255 | dns = (struct _dnshdr *) (align_buf + iphdr_len + sizeof(*udp)); | ||
| 256 | if (ntohs(dns->flags) & 0x000F) /* dns-error? query refused ? */ | ||
| 257 | return(-1); | ||
| 258 | |||
| 259 | ptr = (char *) (align_buf + iphdr_len + sizeof(*udp) + sizeof(*dns)); | ||
| 260 | len = dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns); | ||
| 261 | |||
| 262 | while (len++ < plen) | ||
| 263 | if (*ptr++ == '\0') | ||
| 264 | break; | ||
| 265 | |||
| 266 | if (len >= plen) | ||
| 267 | return(-1); | ||
| 268 | |||
| 269 | len += 4; | ||
| 270 | ptr += 4; | ||
| 271 | |||
| 272 | while (len++ < plen) /* skip VERSION.BIND answer string */ | ||
| 273 | if (*ptr++ == '\0') | ||
| 274 | break; | ||
| 275 | |||
| 276 | len += sizeof(*dnsanswr); | ||
| 277 | if (len >= plen) | ||
| 278 | return(-1); | ||
| 279 | |||
| 280 | dnsanswr = (struct _dnsanswr *) (ptr); | ||
| 281 | dnstxtlen = ntohs(dnsanswr->len); | ||
| 282 | if (len + dnstxtlen > plen) | ||
| 283 | return(0); | ||
| 284 | |||
| 285 | if ((dnstxtlen == 0) || (dnstxtlen > 128)) | ||
| 286 | return(-1); | ||
| 287 | |||
| 288 | memcpy(buf, ptr + sizeof(*dnsanswr) +1, dnstxtlen - 1); | ||
| 289 | buf[dnstxtlen - 1] = '\0'; | ||
| 290 | |||
| 291 | ptr = buf; /* evil hax0rs sending messed up strings ? */ | ||
| 292 | while (*++ptr != '\0') | ||
| 293 | if (!isprint((int)*ptr)) | ||
| 294 | *ptr = '_'; | ||
| 295 | |||
| 296 | printf("%s VERSION.BIND. \"%s\"\n", int_ntoa(ip->ip_src.s_addr), buf); | ||
| 297 | |||
| 298 | return(0); | ||
| 299 | |||
| 300 | } | ||
| 301 | |||
| 302 | |||
diff --git a/other/b-scan/tmp/modules/mod_httpd.c b/other/b-scan/tmp/modules/mod_httpd.c new file mode 100644 index 0000000..275125c --- /dev/null +++ b/other/b-scan/tmp/modules/mod_httpd.c | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* | ||
| 2 | * mod_example.c | ||
| 3 | * Example module for bscan. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/module.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | |||
| 10 | |||
| 11 | #ifndef MOD_NAME | ||
| 12 | #define MOD_NAME "mod_httpd" | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #define HEADREQ "HEAD / HTTP/1.0\r\n\r\n" | ||
| 16 | |||
| 17 | |||
| 18 | static int isinit=0; | ||
| 19 | /* | ||
| 20 | * some variables from the binary-process | ||
| 21 | */ | ||
| 22 | extern int dlt_len; | ||
| 23 | extern u_char *align_buf; | ||
| 24 | extern unsigned short ip_options; | ||
| 25 | extern struct ip *ip; | ||
| 26 | extern struct Ether_header *eth; | ||
| 27 | extern u_int plen, pcaplen; | ||
| 28 | |||
| 29 | struct _mopt | ||
| 30 | { | ||
| 31 | unsigned short int dport; /* dport in NBO */ | ||
| 32 | char *request; /* the http-request */ | ||
| 33 | } static mopt; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * static functions prototypes | ||
| 37 | */ | ||
| 38 | static int mdo_opt(int, char **, struct _opt *); | ||
| 39 | static void init_vars(struct _opt *); | ||
| 40 | static int process_rcv(struct _opt *); | ||
| 41 | |||
| 42 | /* | ||
| 43 | * print out usage informations | ||
| 44 | */ | ||
| 45 | void | ||
| 46 | musage() | ||
| 47 | { | ||
| 48 | printf ("\n"MOD_NAME"\n"); | ||
| 49 | printf (" -p <port>, default 80\n"); | ||
| 50 | printf (" -r <request>, default 'HEAD / HTTP/1.0'\n"); | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | /* | ||
| 55 | * return 0 on success, != 0 on failure | ||
| 56 | */ | ||
| 57 | int | ||
| 58 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 59 | { | ||
| 60 | #ifdef DEBUG | ||
| 61 | printf("MODULE INIT\n"); | ||
| 62 | #endif | ||
| 63 | if (isinit) | ||
| 64 | return(-1); | ||
| 65 | |||
| 66 | *modname = MOD_NAME; | ||
| 67 | isinit = 1; | ||
| 68 | init_vars(opt); | ||
| 69 | |||
| 70 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 71 | return(-1); | ||
| 72 | |||
| 73 | return(0); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* | ||
| 77 | * fini-routine. called on cleanup | ||
| 78 | */ | ||
| 79 | int | ||
| 80 | fini() | ||
| 81 | { | ||
| 82 | #ifdef DEBUG | ||
| 83 | printf("MODULE FINI\n"); | ||
| 84 | #endif | ||
| 85 | return(0); | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /* | ||
| 90 | * | ||
| 91 | */ | ||
| 92 | int | ||
| 93 | callmdl(int entry, struct _opt *opt) | ||
| 94 | { | ||
| 95 | #ifdef DEBUG | ||
| 96 | printf("MODULE CALLMDL\n"); | ||
| 97 | #endif | ||
| 98 | if (entry == MOD_FIRSTPKG) | ||
| 99 | return(RMOD_SKIP); | ||
| 100 | |||
| 101 | if (entry == MOD_RCV) | ||
| 102 | process_rcv(opt); | ||
| 103 | |||
| 104 | return(RMOD_OK); | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 108 | /* | ||
| 109 | *********************************************************** | ||
| 110 | * Our OWN/static functions for THIS module * | ||
| 111 | *********************************************************** | ||
| 112 | */ | ||
| 113 | |||
| 114 | /* | ||
| 115 | * initialize all local variables. | ||
| 116 | * We use some 'unused' variables of the masterprogramm | ||
| 117 | */ | ||
| 118 | static void | ||
| 119 | init_vars(struct _opt *opt) | ||
| 120 | { | ||
| 121 | mopt.dport = htons(80); | ||
| 122 | mopt.request = HEADREQ; | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | /* | ||
| 127 | * LOCAL/STATIC function, only available in the module | ||
| 128 | * return 0 on success, != 0 on failure | ||
| 129 | */ | ||
| 130 | static int | ||
| 131 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 132 | { | ||
| 133 | extern char *optarg; | ||
| 134 | /*extern int optind, opterr, optopt;*/ | ||
| 135 | int c; | ||
| 136 | |||
| 137 | while ((c = getopt (argc, argv, "p:r:")) != -1) | ||
| 138 | { | ||
| 139 | switch (c) | ||
| 140 | { | ||
| 141 | case 'p': | ||
| 142 | mopt.dport = htons(strtoul (optarg, (char **) NULL, 10)); | ||
| 143 | break; | ||
| 144 | case 'r': | ||
| 145 | mopt.request = optarg; | ||
| 146 | fprintf(stderr, MOD_NAME ": requesting \"%s\"\n", optarg); | ||
| 147 | break; | ||
| 148 | case ':': | ||
| 149 | fprintf(stderr, "missing parameter\n"); | ||
| 150 | return(-1); | ||
| 151 | default: | ||
| 152 | return(-1); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | return(0); | ||
| 156 | } | ||
| 157 | |||
| 158 | |||
| 159 | /* | ||
| 160 | * process incoming packets | ||
| 161 | * IP-packet is verified and variables valid (ip_options, *ip) | ||
| 162 | */ | ||
| 163 | static int | ||
| 164 | process_rcv(struct _opt *opt) | ||
| 165 | { | ||
| 166 | struct tcphdr *tcp; | ||
| 167 | unsigned short tcp_options = 0; | ||
| 168 | uint iphdr_len = 0; | ||
| 169 | |||
| 170 | |||
| 171 | if (ip->ip_p != IPPROTO_TCP) | ||
| 172 | return(0); | ||
| 173 | |||
| 174 | iphdr_len = sizeof(*ip) + ip_options; | ||
| 175 | tcp = (struct tcphdr *) (align_buf + iphdr_len); | ||
| 176 | |||
| 177 | if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len, &tcp_options) != 0) | ||
| 178 | return(0); | ||
| 179 | |||
| 180 | if (tcp->th_sport != mopt.dport) | ||
| 181 | return(0); | ||
| 182 | |||
| 183 | if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) | ||
| 184 | answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_PUSH, mopt.request, strlen(mopt.request)); | ||
| 185 | |||
| 186 | return(0); | ||
| 187 | } | ||
| 188 | |||
diff --git a/other/b-scan/tmp/modules/mod_ping.c b/other/b-scan/tmp/modules/mod_ping.c new file mode 100644 index 0000000..73a90a4 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_ping.c | |||
| @@ -0,0 +1,205 @@ | |||
| 1 | /* | ||
| 2 | * ping-module for bscan. | ||
| 3 | * IDEA: add record-route and source-route feature | ||
| 4 | * and -p pattern [where can we save our time-struct then ? | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <bscan/bscan.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <bscan/system.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef MOD_NAME | ||
| 14 | #define MOD_NAME "mod_ping" | ||
| 15 | #endif | ||
| 16 | |||
| 17 | static int process_rcv(struct _opt *); | ||
| 18 | |||
| 19 | static int isinit=0; | ||
| 20 | /* | ||
| 21 | * some variables from the binary-process | ||
| 22 | */ | ||
| 23 | extern int dlt_len; | ||
| 24 | extern u_char *align_buf; | ||
| 25 | extern unsigned short ip_options; | ||
| 26 | extern struct ip *ip; | ||
| 27 | extern struct Ether_header *eth; | ||
| 28 | extern u_int plen, pcaplen; | ||
| 29 | extern struct timeval *pts; | ||
| 30 | |||
| 31 | struct _mopt | ||
| 32 | { | ||
| 33 | int type; | ||
| 34 | int size; | ||
| 35 | } static mopt; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * static functions prototypes | ||
| 39 | */ | ||
| 40 | static int mdo_opt(int, char **, struct _opt *); | ||
| 41 | static void init_vars(struct _opt *); | ||
| 42 | |||
| 43 | /* | ||
| 44 | * print out usage informations | ||
| 45 | */ | ||
| 46 | void | ||
| 47 | musage() | ||
| 48 | { | ||
| 49 | printf ("\n"MOD_NAME"\n"); | ||
| 50 | printf (" -t (echo|time) -s <size>, size of ping-data [default 56].\n"); | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | /* | ||
| 55 | * return 0 on success, != 0 on failure | ||
| 56 | */ | ||
| 57 | int | ||
| 58 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 59 | { | ||
| 60 | #ifdef DEBUG | ||
| 61 | printf("MODULE INIT\n"); | ||
| 62 | #endif | ||
| 63 | if (isinit) | ||
| 64 | return(-1); | ||
| 65 | |||
| 66 | *modname = MOD_NAME; | ||
| 67 | isinit = 1; | ||
| 68 | init_vars(opt); | ||
| 69 | |||
| 70 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 71 | return(-1); | ||
| 72 | |||
| 73 | return(0); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* | ||
| 77 | * fini-routine. called on cleanup | ||
| 78 | */ | ||
| 79 | int | ||
| 80 | fini() | ||
| 81 | { | ||
| 82 | #ifdef DEBUG | ||
| 83 | printf("MODULE FINI\n"); | ||
| 84 | #endif | ||
| 85 | return(0); | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /* | ||
| 90 | * Module entry point [entry] | ||
| 91 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 92 | * or do nothing [MOD_RCV]. | ||
| 93 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 94 | */ | ||
| 95 | int | ||
| 96 | callmdl(int entry, struct _opt *opt) | ||
| 97 | { | ||
| 98 | #ifdef DEBUG | ||
| 99 | printf("MODULE CALLMDL\n"); | ||
| 100 | #endif | ||
| 101 | if (entry == MOD_FIRSTPKG) | ||
| 102 | { | ||
| 103 | add_icmpping (opt->packet + ETH_SIZE + IP_SIZE, mopt.size, mopt.type); | ||
| 104 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_ICMP, &opt->nt, ICMP_SIZE + mopt.size); | ||
| 105 | opt->pkg_len = IP_SIZE + ICMP_SIZE + mopt.size; | ||
| 106 | return(RMOD_OK); | ||
| 107 | } | ||
| 108 | |||
| 109 | if (entry == MOD_RCV) | ||
| 110 | process_rcv(opt); | ||
| 111 | |||
| 112 | return(RMOD_OK); | ||
| 113 | } | ||
| 114 | |||
| 115 | |||
| 116 | /* | ||
| 117 | *********************************************************** | ||
| 118 | * Our OWN/static functions for THIS module * | ||
| 119 | *********************************************************** | ||
| 120 | */ | ||
| 121 | |||
| 122 | /* | ||
| 123 | * initialize all local variables. | ||
| 124 | * We use some 'unused' variables of the masterprogramm | ||
| 125 | */ | ||
| 126 | static void | ||
| 127 | init_vars(struct _opt *opt) | ||
| 128 | { | ||
| 129 | mopt.size = ICMP_ECHO; | ||
| 130 | mopt.size = 56; | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | /* | ||
| 135 | * LOCAL/STATIC function, only available in the module | ||
| 136 | * return 0 on success, != 0 on failure | ||
| 137 | */ | ||
| 138 | static int | ||
| 139 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 140 | { | ||
| 141 | extern char *optarg; | ||
| 142 | /*extern int optind, opterr, optopt;*/ | ||
| 143 | int c; | ||
| 144 | |||
| 145 | while ((c = getopt (argc, argv, "t:s:")) != -1) | ||
| 146 | { | ||
| 147 | switch (c) | ||
| 148 | { | ||
| 149 | case 't': | ||
| 150 | if (strcasecmp (optarg, "echo") == 0) | ||
| 151 | mopt.type = ICMP_ECHO; | ||
| 152 | else if (strcasecmp (optarg, "time") == 0) | ||
| 153 | mopt.type = ICMP_TSTAMP; | ||
| 154 | else | ||
| 155 | return (-1); | ||
| 156 | break; | ||
| 157 | case 's': | ||
| 158 | mopt.size = atoi(optarg); | ||
| 159 | break; | ||
| 160 | case ':': | ||
| 161 | fprintf(stderr, "missing parameter\n"); | ||
| 162 | return(-1); | ||
| 163 | default: | ||
| 164 | return(-1); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | return(0); | ||
| 168 | } | ||
| 169 | |||
| 170 | |||
| 171 | /* | ||
| 172 | * handle incoming icmp ECHO_REPLY packages | ||
| 173 | */ | ||
| 174 | static int | ||
| 175 | process_rcv(struct _opt *opt) | ||
| 176 | { | ||
| 177 | struct icmp *icmp; | ||
| 178 | struct timeval now; | ||
| 179 | double rrt; | ||
| 180 | |||
| 181 | if (ip->ip_p != IPPROTO_ICMP) | ||
| 182 | return(0); | ||
| 183 | |||
| 184 | if (plen < dlt_len + IP_SIZE + ip_options + sizeof(*icmp)) | ||
| 185 | return(0); /* invalid size */ | ||
| 186 | |||
| 187 | icmp = (struct icmp *) (align_buf + IP_SIZE + ip_options); | ||
| 188 | |||
| 189 | // if ((icmp->icmp_type != 0) || (icmp->icmp_code != 0)) | ||
| 190 | // return(0); | ||
| 191 | |||
| 192 | memcpy(&now, pts, sizeof(now)); | ||
| 193 | time_diff((struct timeval *)icmp->icmp_dun.id_data, &now); | ||
| 194 | rrt = now.tv_sec * 1000.0 + now.tv_usec / 1000.0; | ||
| 195 | |||
| 196 | printf("%d bytes from %s: icmp_seq=%u ttl=%d time=%.3f ms\n", | ||
| 197 | (int)(plen - dlt_len - IP_SIZE - ip_options), | ||
| 198 | int_ntoa(ip->ip_src.s_addr), icmp->icmp_hun.ih_idseq.icd_seq, | ||
| 199 | ip->ip_ttl, rrt); | ||
| 200 | |||
| 201 | return(0); | ||
| 202 | |||
| 203 | } | ||
| 204 | |||
| 205 | |||
diff --git a/other/b-scan/tmp/modules/mod_snmp.c b/other/b-scan/tmp/modules/mod_snmp.c new file mode 100644 index 0000000..db56455 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_snmp.c | |||
| @@ -0,0 +1,899 @@ | |||
| 1 | /* | ||
| 2 | * SimpleNetworkManagementProtocol module for bscan. | ||
| 3 | * RFC 1157 | ||
| 4 | * <buggy/lame implementation> | ||
| 5 | * | ||
| 6 | * ###fixme todo: port to sparc | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <bscan/bscan.h> | ||
| 10 | #include <bscan/module.h> | ||
| 11 | #include <bscan/system.h> | ||
| 12 | #include <stdio.h> | ||
| 13 | |||
| 14 | |||
| 15 | #ifndef MOD_NAME | ||
| 16 | #define MOD_NAME "mod_snmp" | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #define SNMP_DFLT_REQOBJ "1.3.6.1.2.1.1" | ||
| 20 | |||
| 21 | #define MAX_VALSTRLEN 512 | ||
| 22 | |||
| 23 | #define MOPT_NOOBJ 0x01 | ||
| 24 | #define MOPT_STRIP 0x02 | ||
| 25 | |||
| 26 | #define SNMP_GET 0xa0 | ||
| 27 | #define SNMP_GET_NEXT 0xa1 | ||
| 28 | #define SNMP_SET 0xa3 | ||
| 29 | #define ASN_SUBCAT 0x30 /* BER encoding, sub-categorie */ | ||
| 30 | |||
| 31 | #ifndef ASN_INTEGER | ||
| 32 | #define ASN_INTEGER ((u_char)0x02) | ||
| 33 | #endif | ||
| 34 | #define ASN_INTEGERSTR "INTEGER" | ||
| 35 | #ifndef ASN_BIT_STR | ||
| 36 | #define ASN_BIT_STR ((u_char)0x03) | ||
| 37 | #endif | ||
| 38 | #define ASN_BIT_STRSTR "BITSTRING" | ||
| 39 | #ifndef ASN_OCTET_STR | ||
| 40 | #define ASN_OCTET_STR ((u_char)0x04) | ||
| 41 | #endif | ||
| 42 | #define ASN_OCTET_STRSTR "STRING" | ||
| 43 | #ifndef ASN_NULL | ||
| 44 | #define ASN_NULL ((u_char)0x05) | ||
| 45 | #endif | ||
| 46 | #define ASN_NULLSTR "NULL" | ||
| 47 | #ifndef ASN_OBJECT_ID | ||
| 48 | #define ASN_OBJECT_ID ((u_char)0x06) | ||
| 49 | #endif | ||
| 50 | #define ASN_OBJECT_IDSTR "OBJ" | ||
| 51 | #ifndef ASN_APPLICATION | ||
| 52 | #define ASN_APPLICATION ((u_char)0x40) | ||
| 53 | #endif | ||
| 54 | #ifndef ASN_LONG_LEN | ||
| 55 | #define ASN_LONG_LEN ((u_char)0x80) | ||
| 56 | #endif | ||
| 57 | #define ASN_APPLICATIONSTR "APPLICATION" | ||
| 58 | #ifndef ASN_IPADDRESS | ||
| 59 | #define ASN_IPADDRESS (ASN_APPLICATION | 0) | ||
| 60 | #endif | ||
| 61 | #define ASN_IPADDRESSSTR "IPADDR" | ||
| 62 | #ifndef ASN_UNSIGNED | ||
| 63 | #define ASN_UNSIGNED (ASN_APPLICATION | 2) | ||
| 64 | #endif | ||
| 65 | #define ASN_UNSIGNEDSTR ASN_INTEGERSTR | ||
| 66 | #ifndef ASN_TIMETICKS | ||
| 67 | #define ASN_TIMETICKS (ASN_APPLICATION | 3) | ||
| 68 | #endif | ||
| 69 | #define ASN_TIMETICKSSTR "TIMETICKS" | ||
| 70 | #ifndef ASN_COUNTER | ||
| 71 | #define ASN_COUNTER (ASN_APPLICATION | 1) | ||
| 72 | #endif | ||
| 73 | #define ASN_COUNTERSTR "COUNTER" | ||
| 74 | |||
| 75 | #define SNMP_ERR_WRONGTYPE (7) | ||
| 76 | #define SNMP_ERR_WRONGLENGTH (8) | ||
| 77 | #define SNMP_ERR_WRONGENCODING (9) | ||
| 78 | #define SNMP_ERR_WRONGVALUE (10) | ||
| 79 | #define SNMP_ERR_NOCREATION (11) | ||
| 80 | #define SNMP_ERR_INCONSISTENTVALUE (12) | ||
| 81 | #define SNMP_ERR_RESOURCEUNAVAILABLE (13) | ||
| 82 | #define SNMP_ERR_COMMITFAILED (14) | ||
| 83 | #define SNMP_ERR_UNDOFAILED (15) | ||
| 84 | #define SNMP_ERR_AUTHORIZATIONERROR (16) | ||
| 85 | #define SNMP_ERR_NOTWRITABLE (17) | ||
| 86 | |||
| 87 | char *snmp_error[] = { | ||
| 88 | "NO ERROR", | ||
| 89 | "TOO BIG", | ||
| 90 | "NO SUCH NAME", | ||
| 91 | "BAD VALUE", | ||
| 92 | "READONLY", | ||
| 93 | "GENERELL ERROR", | ||
| 94 | "NO ACCESS", | ||
| 95 | "WRONG TYPE", | ||
| 96 | "WRONG LENGTH", | ||
| 97 | "WRONG ENCODING", | ||
| 98 | "WRONG VALUE", | ||
| 99 | "NO CREATION", | ||
| 100 | "INCONSISTENT VALUE", | ||
| 101 | "RESOURCE UNAVAILABLE", | ||
| 102 | "COMMIT FAILED", | ||
| 103 | "UNDO FAILED", | ||
| 104 | "AUTORISATION ERROR", | ||
| 105 | "NOT WRITEABLE", | ||
| 106 | "INCONSISTENT NAME" }; | ||
| 107 | |||
| 108 | #define MAX_SNMP_ERR 18 | ||
| 109 | |||
| 110 | |||
| 111 | |||
| 112 | #define ADD_DATA(ptr, in, len, totlen) memcpy(ptr, in, len);\ | ||
| 113 | *totlen = *totlen + len; | ||
| 114 | |||
| 115 | #define min(a,b) ((a)<(b)?(a):(b)) | ||
| 116 | |||
| 117 | |||
| 118 | static int isinit=0; | ||
| 119 | /* | ||
| 120 | * some variables from the binary-process | ||
| 121 | */ | ||
| 122 | extern int dlt_len; | ||
| 123 | extern u_char *align_buf; | ||
| 124 | extern unsigned short ip_options; | ||
| 125 | extern struct ip *ip; | ||
| 126 | extern struct Ether_header *eth; | ||
| 127 | extern u_int plen, pcaplen; | ||
| 128 | extern struct timeval *pts; | ||
| 129 | |||
| 130 | struct _pdu | ||
| 131 | { | ||
| 132 | u_char *varbuf; | ||
| 133 | int varlen; | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct _mopt | ||
| 137 | { | ||
| 138 | char *community; | ||
| 139 | u_char flags; | ||
| 140 | u_char snmptor; /* type of request */ | ||
| 141 | struct _pdu pdu; | ||
| 142 | } static mopt; | ||
| 143 | |||
| 144 | struct _pdunfo | ||
| 145 | { | ||
| 146 | u_char *community; | ||
| 147 | u_char *pdu_type; | ||
| 148 | u_char *error_status; | ||
| 149 | u_char *error_idx; | ||
| 150 | } static pdunfo; | ||
| 151 | |||
| 152 | |||
| 153 | /* | ||
| 154 | * static functions prototypes | ||
| 155 | */ | ||
| 156 | static int mdo_opt(int, char **, struct _opt *); | ||
| 157 | static void init_vars(struct _opt *); | ||
| 158 | static int process_rcv(struct _opt *); | ||
| 159 | static int add_snmp (u_char *, int *); | ||
| 160 | static int add_snmpreq (u_char *, int *, u_char, u_char *, struct _pdu *); | ||
| 161 | static int add_snmp_var(struct _pdu *, u_char *); | ||
| 162 | static int build_snmp_objreq(u_char *, u_char *,u_char *, u_char, u_char *); | ||
| 163 | static int str2asnv(u_char *, u_char, u_char *, u_char *); | ||
| 164 | static int str2objid(u_char *, u_char *, u_char *); | ||
| 165 | |||
| 166 | |||
| 167 | /* | ||
| 168 | * print out usage informations | ||
| 169 | */ | ||
| 170 | void | ||
| 171 | musage() | ||
| 172 | { | ||
| 173 | printf ("\n"MOD_NAME"\n"); | ||
| 174 | printf ("snmp module\n"); | ||
| 175 | printf (" -p <port>, destination port, default 161\n"); | ||
| 176 | printf (" -o <port>, source port, default 53\n"); | ||
| 177 | printf (" -r <request[:type[:value]]>, default '1.3.6.1.2.1.1 (system)'\n"); | ||
| 178 | printf (" -c <community name>, default 'public'\n"); | ||
| 179 | printf (" -g <requesttype>, (get|getnext|set), default 'getnext'\n"); | ||
| 180 | printf (" -s strip unprintable characters from STRING types, and output as text\n"); | ||
| 181 | printf (" -q dont print out OBJ-types\n"); | ||
| 182 | printf ("\n"); | ||
| 183 | printf ("type: i: INTEGER, s: STRING, n: NULLOBJ, o: OBJID\n"); | ||
| 184 | printf (" t: TIMETICKS, a: IPADDRESS, b: BITSTRING, c: COUNTER\n"); | ||
| 185 | printf ("\n"); | ||
| 186 | printf ("you can request multiple objects with one request:\n"); | ||
| 187 | printf ("-g get -r 1.3.6.1.2.1.1.1.0 -r 1.3.6.1.2.1.1.4.0 -r 1.3.6.1.2.1.1.5.0\n"); | ||
| 188 | } | ||
| 189 | |||
| 190 | |||
| 191 | /* | ||
| 192 | * return 0 on success, != 0 on failure | ||
| 193 | */ | ||
| 194 | int | ||
| 195 | init(char **modname, int argc, char *argv[], struct _opt *opt) | ||
| 196 | { | ||
| 197 | #ifdef DEBUG | ||
| 198 | printf("MODULE INIT\n"); | ||
| 199 | #endif | ||
| 200 | if (isinit) | ||
| 201 | return(-1); | ||
| 202 | |||
| 203 | *modname = MOD_NAME; | ||
| 204 | isinit = 1; | ||
| 205 | init_vars(opt); | ||
| 206 | |||
| 207 | if (mdo_opt(argc, argv, opt) != 0) | ||
| 208 | return(-1); | ||
| 209 | |||
| 210 | return(0); | ||
| 211 | } | ||
| 212 | |||
| 213 | /* | ||
| 214 | * fini-routine. called on cleanup | ||
| 215 | */ | ||
| 216 | int | ||
| 217 | fini() | ||
| 218 | { | ||
| 219 | #ifdef DEBUG | ||
| 220 | printf("MODULE FINI\n"); | ||
| 221 | #endif | ||
| 222 | return(0); | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | /* | ||
| 227 | * Module entry point [entry] | ||
| 228 | * RMOD_OK: everything allright. send the packet out [if first] | ||
| 229 | * or do nothing [MOD_RCV]. | ||
| 230 | * RMOD_SKIP: proceed with next IP without sending out the packet. | ||
| 231 | * RMOD_ERROR: failed to create packet. | ||
| 232 | * RMOD_ABRT: critical failure, abort! | ||
| 233 | */ | ||
| 234 | int | ||
| 235 | callmdl(int entry, struct _opt *opt) | ||
| 236 | { | ||
| 237 | #ifdef DEBUG | ||
| 238 | printf("MODULE CALLMDL\n"); | ||
| 239 | #endif | ||
| 240 | if (entry == MOD_FIRSTPKG) | ||
| 241 | { | ||
| 242 | add_snmp(opt->packet+ ETH_SIZE + IP_SIZE + UDP_SIZE, &opt->pkg_len); | ||
| 243 | add_udphdr (opt->packet+ ETH_SIZE+ IP_SIZE, &opt->nt, opt->pkg_len); | ||
| 244 | add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE); | ||
| 245 | opt->pkg_len += UDP_SIZE + IP_SIZE; | ||
| 246 | |||
| 247 | return(RMOD_OK); | ||
| 248 | } | ||
| 249 | |||
| 250 | if (entry == MOD_RCV) | ||
| 251 | process_rcv(opt); | ||
| 252 | |||
| 253 | return(RMOD_OK); | ||
| 254 | } | ||
| 255 | |||
| 256 | |||
| 257 | /* | ||
| 258 | *********************************************************** | ||
| 259 | * Our OWN/static functions for THIS module * | ||
| 260 | *********************************************************** | ||
| 261 | */ | ||
| 262 | |||
| 263 | /* | ||
| 264 | * initialize all local variables. | ||
| 265 | * We use some 'unused' variables of the masterprogramm | ||
| 266 | */ | ||
| 267 | static void | ||
| 268 | init_vars(struct _opt *opt) | ||
| 269 | { | ||
| 270 | opt->nt.sport = htons(32770); | ||
| 271 | opt->nt.dport = htons(161); | ||
| 272 | mopt.flags = 0; | ||
| 273 | mopt.community = "public"; | ||
| 274 | mopt.snmptor = SNMP_GET_NEXT; | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 278 | /* | ||
| 279 | * LOCAL/STATIC function, only available in the module | ||
| 280 | * return 0 on success, != 0 on failure | ||
| 281 | */ | ||
| 282 | static int | ||
| 283 | mdo_opt(int argc, char *argv[], struct _opt *opt) | ||
| 284 | { | ||
| 285 | extern char *optarg; | ||
| 286 | /*extern int optind, opterr, optopt;*/ | ||
| 287 | int c; | ||
| 288 | |||
| 289 | while ((c = getopt (argc, argv, "qsg:c:r:p:o:")) != -1) | ||
| 290 | { | ||
| 291 | switch (c) | ||
| 292 | { | ||
| 293 | case 'q': | ||
| 294 | mopt.flags |= MOPT_NOOBJ; | ||
| 295 | break; | ||
| 296 | case 's': | ||
| 297 | mopt.flags |= MOPT_STRIP; | ||
| 298 | break; | ||
| 299 | case 'p': | ||
| 300 | opt->nt.dport = htons(atoi(optarg)); | ||
| 301 | break; | ||
| 302 | case 'o': | ||
| 303 | opt->nt.sport = htons(atoi(optarg)); | ||
| 304 | break; | ||
| 305 | case 'r': | ||
| 306 | add_snmp_var(&mopt.pdu, optarg); | ||
| 307 | break; | ||
| 308 | case 'c': | ||
| 309 | mopt.community = optarg; | ||
| 310 | break; | ||
| 311 | case 'g': | ||
| 312 | if (strcasecmp (optarg, "get") == 0) | ||
| 313 | mopt.snmptor = SNMP_GET; | ||
| 314 | else if (strcasecmp (optarg, "getnext") == 0) | ||
| 315 | mopt.snmptor = SNMP_GET_NEXT; | ||
| 316 | else if (strcasecmp (optarg, "set") == 0) | ||
| 317 | mopt.snmptor = SNMP_SET; | ||
| 318 | else | ||
| 319 | return (-1); | ||
| 320 | break; | ||
| 321 | case ':': | ||
| 322 | fprintf(stderr, "missing parameter\n"); | ||
| 323 | return(-1); | ||
| 324 | default: | ||
| 325 | return(-1); | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | if (mopt.pdu.varbuf == NULL) | ||
| 330 | add_snmp_var(&mopt.pdu, SNMP_DFLT_REQOBJ); | ||
| 331 | |||
| 332 | return(0); | ||
| 333 | } | ||
| 334 | |||
| 335 | |||
| 336 | static u_char | ||
| 337 | strtoasn_vtype(int src) | ||
| 338 | { | ||
| 339 | |||
| 340 | src = tolower(src); | ||
| 341 | |||
| 342 | switch (src) | ||
| 343 | { | ||
| 344 | case 'i': | ||
| 345 | return(ASN_INTEGER); | ||
| 346 | case 's': | ||
| 347 | return(ASN_OCTET_STR); | ||
| 348 | case 'n': | ||
| 349 | return(ASN_NULL); | ||
| 350 | case 'o': | ||
| 351 | return(ASN_OBJECT_ID); | ||
| 352 | case 't': | ||
| 353 | return(ASN_TIMETICKS); | ||
| 354 | case 'b': | ||
| 355 | return(ASN_BIT_STR); | ||
| 356 | case 'a': | ||
| 357 | return(ASN_IPADDRESS); | ||
| 358 | case 'u': | ||
| 359 | return(ASN_UNSIGNED); | ||
| 360 | case 'c': | ||
| 361 | return(ASN_COUNTER); | ||
| 362 | default: | ||
| 363 | fprintf(stderr, "WARNING: unsupported value-type.\n"); | ||
| 364 | return(src); | ||
| 365 | } | ||
| 366 | |||
| 367 | return(ASN_NULL); | ||
| 368 | } | ||
| 369 | |||
| 370 | /* | ||
| 371 | * add variable to our variable-queue | ||
| 372 | * input: <objid-dodded notation>:<value type>:<value>-format | ||
| 373 | * return 0 on success, !=0 on parse error etc | ||
| 374 | */ | ||
| 375 | static int | ||
| 376 | add_snmp_var(struct _pdu *pdu, u_char *src) | ||
| 377 | { | ||
| 378 | u_char *request; | ||
| 379 | u_char vtype = 5; | ||
| 380 | u_char *value = NULL; | ||
| 381 | u_char *ptr = NULL; | ||
| 382 | u_char reqlen=0; | ||
| 383 | |||
| 384 | if (pdu->varbuf == NULL) | ||
| 385 | { | ||
| 386 | pdu->varbuf = calloc(1, 1024); | ||
| 387 | pdu->varlen = 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | request = src; | ||
| 391 | |||
| 392 | if ( (ptr = strchr(src, ':')) != NULL) | ||
| 393 | *ptr++ = '\0'; | ||
| 394 | |||
| 395 | src = ptr; | ||
| 396 | if (ptr != NULL) | ||
| 397 | { | ||
| 398 | if ( (ptr = strchr(src, ':')) != NULL) | ||
| 399 | { | ||
| 400 | *ptr++ = '\0'; | ||
| 401 | if (strlen(ptr) > 0) | ||
| 402 | value = ptr; | ||
| 403 | } | ||
| 404 | vtype = strtoasn_vtype(*src); | ||
| 405 | } | ||
| 406 | |||
| 407 | if (build_snmp_objreq(pdu->varbuf + pdu->varlen, &reqlen, request, vtype, value) != 0) | ||
| 408 | { | ||
| 409 | fprintf(stderr, "WARNING: error while parsing reqOBJ\n"); | ||
| 410 | return(-1); | ||
| 411 | } | ||
| 412 | |||
| 413 | pdu->varlen += reqlen; | ||
| 414 | |||
| 415 | return(0); | ||
| 416 | } | ||
| 417 | |||
| 418 | /* | ||
| 419 | * convert OBJ-ID and build the snmp-request packet | ||
| 420 | * save the work and reuse [better performance, the snmp | ||
| 421 | * packet is always the same]. | ||
| 422 | * return 0 on success | ||
| 423 | */ | ||
| 424 | static int | ||
| 425 | add_snmp(u_char *ptr, int *lenptr) | ||
| 426 | { | ||
| 427 | static u_char *buf = NULL; | ||
| 428 | static int buflen; | ||
| 429 | |||
| 430 | if (buf != NULL) /* fastmode, use old copy of previous build snmppkg */ | ||
| 431 | { | ||
| 432 | *lenptr = buflen; | ||
| 433 | memcpy(ptr, buf, buflen); | ||
| 434 | return(0); | ||
| 435 | } | ||
| 436 | |||
| 437 | if (buf == NULL) | ||
| 438 | buf = malloc(1024); | ||
| 439 | |||
| 440 | add_snmpreq (ptr, lenptr, mopt.snmptor, mopt.community, &mopt.pdu); | ||
| 441 | |||
| 442 | memcpy(buf, ptr, *lenptr); /* for later reuse */ | ||
| 443 | buflen = *lenptr; | ||
| 444 | |||
| 445 | return(0); | ||
| 446 | } | ||
| 447 | |||
| 448 | /* | ||
| 449 | * convert snmp obj in dotted-notation, 0-terminated string to obj-id in asn.1 | ||
| 450 | */ | ||
| 451 | static int | ||
| 452 | str2objid(u_char *dst, u_char *retlen, u_char *src) | ||
| 453 | { | ||
| 454 | u_char *dotptr; | ||
| 455 | u_char len; | ||
| 456 | |||
| 457 | if (strncmp(src, "1.3.6.1.", 8) != 0) | ||
| 458 | return(-1); /* snmp only , iso.org.dot.internet.* */ | ||
| 459 | |||
| 460 | src += 8; /* we know the first 8 bytes. */ | ||
| 461 | |||
| 462 | memcpy(dst, "\x2b\x06\x01", 3); /* yepp, we know this. "1.3.6.1" */ | ||
| 463 | dst += 3; | ||
| 464 | dotptr = src; | ||
| 465 | len = 3; /* 2b-06-01 */ | ||
| 466 | while ( (dotptr = strchr (src, '.')) != NULL) | ||
| 467 | { | ||
| 468 | *dotptr = '\0'; | ||
| 469 | *dst++ = (u_char)atoi(src); | ||
| 470 | src = ++dotptr; | ||
| 471 | len++; | ||
| 472 | } | ||
| 473 | if (strlen(src) > 0) | ||
| 474 | { | ||
| 475 | *dst++ = (u_char)atoi(src); | ||
| 476 | len++; | ||
| 477 | } | ||
| 478 | |||
| 479 | *retlen = len; | ||
| 480 | return(0); | ||
| 481 | } | ||
| 482 | |||
| 483 | |||
| 484 | /* | ||
| 485 | * convert input to ASN.1 BER encodet <obj-id><value> | ||
| 486 | * dst: guess what. | ||
| 487 | * ptr: snmp obj in dotted-notation (1.3.6.1.2.1.1....), 0-terminated string | ||
| 488 | * tov: type of value, ASN.1 encodet (int, 8octet string, ...) | ||
| 489 | * value: the value (string, 0-terminated) | ||
| 490 | * return: 0 on success | ||
| 491 | */ | ||
| 492 | static int | ||
| 493 | build_snmp_objreq(u_char *dst, u_char *retlen, u_char *src, u_char tov, | ||
| 494 | u_char *value) | ||
| 495 | { | ||
| 496 | u_char *srcw; | ||
| 497 | u_char vlen = 0; | ||
| 498 | u_char *sublen; | ||
| 499 | u_char *subsublen; | ||
| 500 | u_char *subvlen; | ||
| 501 | u_char len; | ||
| 502 | |||
| 503 | srcw = alloca(strlen(src)+1); | ||
| 504 | memcpy(srcw, src, strlen(src)+1); | ||
| 505 | if (strlen(srcw) <= 4) | ||
| 506 | return(-1); | ||
| 507 | |||
| 508 | *dst++ = ASN_SUBCAT; | ||
| 509 | sublen = dst++; /* we set the length later coz we dont know it yet */ | ||
| 510 | |||
| 511 | *dst++ = 0x06; /* OBJ-ID */ | ||
| 512 | subsublen = dst++; /* and this also not */ | ||
| 513 | |||
| 514 | if (str2objid(dst, &len, srcw) != 0) | ||
| 515 | return(-1); | ||
| 516 | |||
| 517 | *subsublen = len; /* length of obj */ | ||
| 518 | dst += len; | ||
| 519 | |||
| 520 | *dst++ = tov; /* type of value */ | ||
| 521 | subvlen = dst++; /* we set this later..we dont know the length yet */ | ||
| 522 | str2asnv(value, tov, dst, &vlen); | ||
| 523 | |||
| 524 | *subvlen = vlen; /* length of value */ | ||
| 525 | |||
| 526 | *sublen = len + vlen + 4; /* length of <obj-id><tov:value> */ | ||
| 527 | |||
| 528 | *retlen = len + vlen + 6; | ||
| 529 | return(0); | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | /* | ||
| 534 | * convert 0-terminated string value to asn encodet value | ||
| 535 | * return 0 on success | ||
| 536 | * on return the length of rvalue < value. | ||
| 537 | * input: value [0 terminated string] | ||
| 538 | * tov [asn]-type of value | ||
| 539 | * output: rvalue [non 0-terminated string with asn-value] | ||
| 540 | * vlen [length of rvalue] | ||
| 541 | * return 0 on success | ||
| 542 | * attention: we use full integers (length=4, not reduced in length | ||
| 543 | * to the minimum size). the snmp-lib reduces the length of an | ||
| 544 | * integer to the minimum size...but this is not a must | ||
| 545 | */ | ||
| 546 | static int | ||
| 547 | str2asnv(u_char *value, u_char tov, u_char *rvalue, u_char *vlen) | ||
| 548 | { | ||
| 549 | unsigned long int ltmp; | ||
| 550 | |||
| 551 | if (rvalue == NULL) | ||
| 552 | return(0); /* yes, NULL is allowed */ | ||
| 553 | if ((rvalue != NULL) && (vlen == NULL)) | ||
| 554 | return(-1); | ||
| 555 | |||
| 556 | switch(tov) | ||
| 557 | { | ||
| 558 | case ASN_INTEGER: | ||
| 559 | ltmp = htonl(strtol(value, NULL, 10)); | ||
| 560 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 561 | *vlen = sizeof(ltmp); | ||
| 562 | break; | ||
| 563 | case ASN_UNSIGNED: | ||
| 564 | case ASN_COUNTER: | ||
| 565 | case ASN_TIMETICKS: | ||
| 566 | ltmp = htonl(strtoul(value, NULL, 10)); | ||
| 567 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 568 | *vlen = (sizeof(ltmp)); | ||
| 569 | break; | ||
| 570 | case ASN_IPADDRESS: | ||
| 571 | ltmp = inet_addr(value); | ||
| 572 | memcpy(rvalue, <mp, sizeof(ltmp)); | ||
| 573 | *vlen = sizeof(ltmp); | ||
| 574 | break; | ||
| 575 | case ASN_OBJECT_ID: | ||
| 576 | str2objid(rvalue, vlen, value); | ||
| 577 | break; | ||
| 578 | case ASN_OCTET_STR: | ||
| 579 | memcpy(rvalue, value, strlen(value)); | ||
| 580 | *vlen = strlen(value); | ||
| 581 | break; | ||
| 582 | case ASN_NULL: | ||
| 583 | *vlen = 0; | ||
| 584 | break; | ||
| 585 | default: | ||
| 586 | *vlen = 0; | ||
| 587 | fprintf(stderr, "WARNING, unsupported value type !\n"); | ||
| 588 | } | ||
| 589 | |||
| 590 | return(0); | ||
| 591 | } | ||
| 592 | |||
| 593 | /* | ||
| 594 | * add snmp request | ||
| 595 | * build the entire SNMP packet [version, community, pdu, id, error, idx, ..] | ||
| 596 | * req: objs + values [BER encodet, already with header and \x30 sub start] | ||
| 597 | * reqlen: len of entire req [objs + values] | ||
| 598 | * tor: type of request [get, getnext, set] | ||
| 599 | */ | ||
| 600 | static int | ||
| 601 | add_snmpreq (u_char *pkt, int *len, u_char tor, u_char *community, struct _pdu *pdu) | ||
| 602 | { | ||
| 603 | int le = 0; | ||
| 604 | |||
| 605 | *(pkt + le++) = ASN_SUBCAT; | ||
| 606 | *(pkt + le++) = (u_char)(pdu->varlen + strlen(community) + 18); | ||
| 607 | ADD_DATA(pkt + le, "\x02\x01\x00\x04" , 4, &le); /* SNMPv1 + STRINGOBJ*/ | ||
| 608 | *(pkt + le++) = (u_char)strlen(community); | ||
| 609 | ADD_DATA(pkt + le, community, strlen(community), &le); | ||
| 610 | *(pkt + le++) = tor; /* PDU GET-NEXTrequest */ | ||
| 611 | /* lenof(<req-id> + <err-state> + <err-idx> + <SUB> <obj+values>) */ | ||
| 612 | *(pkt + le++) = (u_char)(pdu->varlen + 11); | ||
| 613 | /* <req-id> + <err-state> + <err-idx> <SUB-OBJ> */ | ||
| 614 | ADD_DATA(pkt + le, "\x02\x01\x01\x02\x01\00\x02\x01\x00\x30", 10, &le); | ||
| 615 | *(pkt + le++) = (u_char)(pdu->varlen); | ||
| 616 | ADD_DATA(pkt + le, pdu->varbuf, pdu->varlen, &le); | ||
| 617 | |||
| 618 | *len = le; | ||
| 619 | return(0); | ||
| 620 | } | ||
| 621 | |||
| 622 | |||
| 623 | /* | ||
| 624 | * convert asn encoded obj to string | ||
| 625 | * input: string of <type of value><length of value><value> | ||
| 626 | * datalen: max len i'm allowed to read from "ptr --> ..." | ||
| 627 | * return: | ||
| 628 | * prefix is the string representation of the value-type e.g. "OCTET-STRING".. | ||
| 629 | * and '<trunc>' if value got truncated. | ||
| 630 | * is < 64 chars... | ||
| 631 | * val: the value (0-terminated string) | ||
| 632 | * return 0 on success | ||
| 633 | * 1 if truncated (value-length > size of snmp or val to small) | ||
| 634 | * -1 on error | ||
| 635 | */ | ||
| 636 | static int | ||
| 637 | asn2str(u_char *ptr, u_char *prefix, u_char *val, unsigned int datalen) | ||
| 638 | { | ||
| 639 | unsigned long int len, day, hour, min, sec, msec; | ||
| 640 | u_char *ptr2; | ||
| 641 | u_char vlen = *(ptr+1); /* saved value length */ | ||
| 642 | u_char tov = *ptr; | ||
| 643 | unsigned long int ltmp; | ||
| 644 | int i, slen = 0; | ||
| 645 | u_char buf[128]; | ||
| 646 | |||
| 647 | if (vlen > datalen-2) | ||
| 648 | len = datalen-2; | ||
| 649 | else | ||
| 650 | len = vlen; | ||
| 651 | |||
| 652 | *val = '\0'; | ||
| 653 | *prefix = '\0'; | ||
| 654 | |||
| 655 | switch(tov) | ||
| 656 | { | ||
| 657 | case ASN_IPADDRESS: | ||
| 658 | if (len > sizeof(ltmp)) | ||
| 659 | len = sizeof(ltmp); | ||
| 660 | |||
| 661 | ptr2 = (u_char *)<mp; | ||
| 662 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 663 | sprintf(val, "%s", int_ntoa(ltmp)); | ||
| 664 | strcpy(prefix, ASN_IPADDRESSSTR); | ||
| 665 | break; | ||
| 666 | case ASN_NULL: | ||
| 667 | strcpy(prefix, ASN_NULLSTR); | ||
| 668 | break; | ||
| 669 | case ASN_TIMETICKS: | ||
| 670 | if (len > sizeof(ltmp)) | ||
| 671 | len = sizeof(ltmp); | ||
| 672 | |||
| 673 | ltmp = 0; | ||
| 674 | ptr2 = (u_char *)<mp; | ||
| 675 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 676 | ltmp = ntohl(ltmp); | ||
| 677 | day = ltmp / 8640000; | ||
| 678 | hour = (ltmp % 8640000) / 360000; | ||
| 679 | min = (ltmp % 360000) / 6000; | ||
| 680 | sec = (ltmp % 6000) / 100; | ||
| 681 | msec = (ltmp % 100); | ||
| 682 | sprintf(val, "(%lu) %d days, %2.2d:%2.2d:%2.2d.%d", ltmp, | ||
| 683 | (int)day, (int)hour, (int)min, (int)sec, (int)msec); | ||
| 684 | if (tov == ASN_TIMETICKS) | ||
| 685 | strcpy(prefix, ASN_TIMETICKSSTR); | ||
| 686 | break; | ||
| 687 | case ASN_INTEGER: | ||
| 688 | case ASN_UNSIGNED: | ||
| 689 | case ASN_COUNTER: | ||
| 690 | ltmp = 0; | ||
| 691 | if (len > sizeof(ltmp)) | ||
| 692 | len = sizeof(ltmp); | ||
| 693 | |||
| 694 | ptr2 = (u_char *)<mp; | ||
| 695 | memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); | ||
| 696 | |||
| 697 | if (tov == ASN_INTEGER) | ||
| 698 | sprintf(val, "%lu", (unsigned long int)ntohl(ltmp)); | ||
| 699 | else | ||
| 700 | sprintf(val, "%ld", (long int)ntohl(ltmp)); | ||
| 701 | |||
| 702 | if (tov == ASN_INTEGER) | ||
| 703 | strcpy(prefix, ASN_INTEGERSTR); | ||
| 704 | if (tov == ASN_UNSIGNED) | ||
| 705 | strcpy(prefix, ASN_UNSIGNEDSTR); | ||
| 706 | if (tov == ASN_COUNTER) | ||
| 707 | strcpy(prefix, ASN_COUNTERSTR); | ||
| 708 | break; | ||
| 709 | case ASN_OCTET_STR: | ||
| 710 | if (isprintdata(ptr+2, len)) | ||
| 711 | { | ||
| 712 | if (len > MAX_VALSTRLEN-1) | ||
| 713 | len = MAX_VALSTRLEN-1; | ||
| 714 | memcpy(val, ptr+2, len); | ||
| 715 | val[len] = '\0'; | ||
| 716 | } else if ((mopt.flags & MOPT_STRIP) == MOPT_STRIP) { | ||
| 717 | dat2strip(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 718 | } else { | ||
| 719 | dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 720 | } | ||
| 721 | |||
| 722 | strcpy(prefix, ASN_OCTET_STRSTR); | ||
| 723 | break; | ||
| 724 | case ASN_OBJECT_ID: | ||
| 725 | i = 0; | ||
| 726 | slen = 0; | ||
| 727 | while(i < len) | ||
| 728 | { | ||
| 729 | if (*(ptr+2+i) == 0x2b) | ||
| 730 | strcpy(buf, "1.3."); /* substituate shorts */ | ||
| 731 | else | ||
| 732 | snprintf(buf, sizeof(buf), "%d.", *(ptr+2+i)); | ||
| 733 | |||
| 734 | buf[sizeof(buf)-1] = '\0'; | ||
| 735 | slen = strlen(val) + strlen(buf); | ||
| 736 | |||
| 737 | if (slen < MAX_VALSTRLEN -1) | ||
| 738 | strcat(val, buf); | ||
| 739 | else | ||
| 740 | break; | ||
| 741 | |||
| 742 | i++; | ||
| 743 | } | ||
| 744 | val[slen-1] = '\0'; /* remove last '.' */ | ||
| 745 | strcpy(prefix, ASN_OBJECT_IDSTR); | ||
| 746 | break; | ||
| 747 | default: | ||
| 748 | dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); | ||
| 749 | break; | ||
| 750 | } | ||
| 751 | |||
| 752 | if (*prefix == '\0') | ||
| 753 | strcpy(prefix, "UNKNOWN"); | ||
| 754 | |||
| 755 | if (vlen > len) | ||
| 756 | { | ||
| 757 | strcat(prefix, "<trunc>"); | ||
| 758 | return(1); | ||
| 759 | } | ||
| 760 | |||
| 761 | return(0); | ||
| 762 | } | ||
| 763 | |||
| 764 | /* | ||
| 765 | * return TypeOfValue and let next point to the next asn encodet obj | ||
| 766 | * ptr: pointer to asn.1 encodet obj | ||
| 767 | * len: returns the length of the OLD value + suffix [length we skipped] | ||
| 768 | * next: returns a pointer to the next obj. | ||
| 769 | */ | ||
| 770 | static u_char | ||
| 771 | asn_getnext(u_char *ptr, u_char *len, u_char **next) | ||
| 772 | { | ||
| 773 | u_char vlen = *(ptr+1); | ||
| 774 | |||
| 775 | if (*ptr == ASN_SUBCAT) | ||
| 776 | { | ||
| 777 | if (vlen & ASN_LONG_LEN) | ||
| 778 | vlen = vlen & ~ASN_LONG_LEN; | ||
| 779 | else | ||
| 780 | vlen = 0; | ||
| 781 | } | ||
| 782 | |||
| 783 | *next = ptr + vlen + 2; | ||
| 784 | |||
| 785 | *len = vlen + 2; | ||
| 786 | return(**next); | ||
| 787 | } | ||
| 788 | |||
| 789 | #define RETURN_ILLLEN(x,y,r) if (x >= y) return(r); | ||
| 790 | |||
| 791 | /* | ||
| 792 | * handle incoming snmp answers, answer with 'next' if not last record | ||
| 793 | */ | ||
| 794 | static int | ||
| 795 | process_rcv(struct _opt *opt) | ||
| 796 | { | ||
| 797 | struct udphdr *udp; | ||
| 798 | u_char *ptr; | ||
| 799 | int len; | ||
| 800 | int snmplen; | ||
| 801 | uint iphdr_len = 0; | ||
| 802 | u_char objlen; | ||
| 803 | u_char buf[MAX_VALSTRLEN]; | ||
| 804 | u_char prefix[32]; | ||
| 805 | u_char buf2[MAX_VALSTRLEN + 32]; | ||
| 806 | u_char asnprefix[128]; | ||
| 807 | u_char c; | ||
| 808 | |||
| 809 | if (ip->ip_p != IPPROTO_UDP) | ||
| 810 | return(0); | ||
| 811 | |||
| 812 | iphdr_len = IP_SIZE + ip_options; | ||
| 813 | if (plen < dlt_len + iphdr_len + sizeof(*udp)) | ||
| 814 | return(-1); /* invalid size */ | ||
| 815 | |||
| 816 | udp = (struct udphdr *) (align_buf + iphdr_len); | ||
| 817 | ptr = (u_char *) (align_buf + iphdr_len + sizeof(*udp)); | ||
| 818 | snmplen = plen - dlt_len - iphdr_len - sizeof(*udp); | ||
| 819 | len = 0; | ||
| 820 | |||
| 821 | /* | ||
| 822 | * we dont check the value of the ASN_SUBCAT-length coz many buggy | ||
| 823 | * hosts out there return a wrong length [0xff, 0x80, ...] | ||
| 824 | */ | ||
| 825 | |||
| 826 | ptr += 2; len += 3; /* pointing on the 3rd element */ | ||
| 827 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 828 | |||
| 829 | asn_getnext(ptr, &objlen, &ptr); /* skip version, get community */ | ||
| 830 | len += objlen; | ||
| 831 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 832 | pdunfo.community = ptr; | ||
| 833 | |||
| 834 | asn_getnext(ptr, &objlen, &ptr); /* skip community, get pdu */ | ||
| 835 | len += objlen; | ||
| 836 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 837 | pdunfo.pdu_type = ptr; | ||
| 838 | ptr += 2; | ||
| 839 | len += 2; /* skip pdu, get reqid */ | ||
| 840 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 841 | |||
| 842 | asn_getnext(ptr, &objlen, &ptr); /* skip reqid, get errorstatus */ | ||
| 843 | len += objlen; | ||
| 844 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 845 | pdunfo.error_status = ptr; | ||
| 846 | |||
| 847 | asn_getnext(ptr, &objlen, &ptr); /* skip errorstatus, get erroridx */ | ||
| 848 | len += objlen; | ||
| 849 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 850 | pdunfo.error_idx = ptr; | ||
| 851 | |||
| 852 | asn_getnext(ptr, &objlen, &ptr); /* skip erroridx, get */ | ||
| 853 | len += objlen; | ||
| 854 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 855 | |||
| 856 | asn_getnext(ptr, &objlen, &ptr); /* we reached the SUB section */ | ||
| 857 | len += objlen; | ||
| 858 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 859 | |||
| 860 | snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), | ||
| 861 | ntohs(udp->uh_sport)); | ||
| 862 | |||
| 863 | c = *(pdunfo.error_status+2); | ||
| 864 | if (c != 0) | ||
| 865 | { | ||
| 866 | if (c < MAX_SNMP_ERR) | ||
| 867 | { | ||
| 868 | printf("%s%s (%d)\n", prefix, snmp_error[c], | ||
| 869 | *(pdunfo.error_idx+2)); | ||
| 870 | } else { | ||
| 871 | printf("%s UNKNOWN ERROR\n", prefix); | ||
| 872 | } | ||
| 873 | } | ||
| 874 | |||
| 875 | while (1) | ||
| 876 | { | ||
| 877 | asn_getnext(ptr, &objlen, &ptr); | ||
| 878 | if (objlen == 0) | ||
| 879 | return(0); | ||
| 880 | |||
| 881 | len += objlen; | ||
| 882 | RETURN_ILLLEN(len, snmplen, 0); | ||
| 883 | if (*ptr == ASN_SUBCAT) | ||
| 884 | continue; | ||
| 885 | |||
| 886 | if ((mopt.flags & MOPT_NOOBJ) && (*ptr == ASN_OBJECT_ID)) | ||
| 887 | continue; | ||
| 888 | |||
| 889 | asn2str(ptr, asnprefix, buf, snmplen - len + 1); | ||
| 890 | snprintf(buf2, sizeof(buf2)-1, "%s %s", asnprefix, buf); | ||
| 891 | buf2[sizeof(buf2)-1] = '\0'; | ||
| 892 | save_write(stdout, prefix, buf2, strlen(buf2)); | ||
| 893 | } | ||
| 894 | |||
| 895 | return(0); | ||
| 896 | |||
| 897 | } | ||
| 898 | |||
| 899 | |||
diff --git a/other/b-scan/tmp/src/Makefile b/other/b-scan/tmp/src/Makefile new file mode 100644 index 0000000..6deefc4 --- /dev/null +++ b/other/b-scan/tmp/src/Makefile | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | # | ||
| 2 | # Makefile of (m)bscan v0.0, skyper | ||
| 3 | # Massiv Banner Scanner | ||
| 4 | # | ||
| 5 | |||
| 6 | CC=gcc | ||
| 7 | COPT=-Wall -ggdb -I../include -I/usr/include/pcap -static | ||
| 8 | LEX=flex | ||
| 9 | LEXOPT= | ||
| 10 | OBJS=bscan.o arpg.o snarf.o network_raw.o restore.o | ||
| 11 | OBJS2=tty.o system.o signal.o dcd_icmp.o garage.o cf_prse.o module.o | ||
| 12 | SUPOBJ=../support/hpuxdl.o ../support/snprintf.o | ||
| 13 | TARGET=bscan | ||
| 14 | INDENT=indent | ||
| 15 | INDENT_OPT=-bap -nbc -bbo -bl -bli0 -bls -ncdb -nce -cp1 -cs -di2 -ndj -nfc1 -nfca -hnl -i4 -ip5 -lp -psl -nsc -nsob | ||
| 16 | |||
| 17 | # LINUX | ||
| 18 | ####### | ||
| 19 | LOPT=-export-dynamic | ||
| 20 | DEFS=`libnet-config --defines` -DHAVE_DLSYM -D_SVID_SOURCE #-DDEBUG | ||
| 21 | LIBS=-lpcap -ldl -lm `libnet-config --libs` -lpthread | ||
| 22 | |||
| 23 | # SunOS 5.7/5.8 + gcc | ||
| 24 | ##################### | ||
| 25 | #LOPT=-export-dynamic | ||
| 26 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 27 | #LIBS=-lpcap -ldl -lm `libnet-config --libs` -lpthread | ||
| 28 | |||
| 29 | # HP-UX 11.00 | ||
| 30 | ############# | ||
| 31 | #LOPT=-Xlinker -E | ||
| 32 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 33 | #LIBS=-lpcap -ldld -lm `libnet-config --libs` -lpthread | ||
| 34 | |||
| 35 | # HP-UX 10.20 | ||
| 36 | # HP-UX 10.20 is not supported. You need snprintf.c and | ||
| 37 | # some hacks to use IP_HDRINCL and the kernel patches | ||
| 38 | # to access the link_layer interface. | ||
| 39 | ############# | ||
| 40 | #LOPT=-Xlinker -E | ||
| 41 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM -DHP10 #-DDEBUG | ||
| 42 | #LIBS=-lpcap -ldld -lm `libnet-config --libs` -lpthread | ||
| 43 | |||
| 44 | # OpenBSD | ||
| 45 | ######### | ||
| 46 | #LOPT= | ||
| 47 | #DEFS=`libnet-config --defines` -DHAVE_DLSYM #-DDEBUG | ||
| 48 | #LIBS=-lpcap -lm `libnet-config --libs` -lpthread | ||
| 49 | |||
| 50 | all: $(SUPOBJ) $(OBJS2) $(OBJS) | ||
| 51 | $(CC) $(SUPOBJ) $(OBJS) $(OBJS2) $(LOPT) $(LIBS) $(COPT) -o $(TARGET) | ||
| 52 | |||
| 53 | cf_prse.o: | ||
| 54 | $(LEX) $(LEXOPT) -ocf_prse.c cf_prse.l | ||
| 55 | $(CC) $(COPT) -c cf_prse.c | ||
| 56 | |||
| 57 | dcd_icmp.o: dcd_icmp.c | ||
| 58 | $(CC) $(COPT) -c dcd_icmp.c | ||
| 59 | |||
| 60 | garage.o: garage.c | ||
| 61 | $(CC) $(COPT) -c garage.c | ||
| 62 | |||
| 63 | module.o: module.c | ||
| 64 | $(CC) $(COPT) $(DEFS) -c module.c | ||
| 65 | |||
| 66 | system.o: system.c | ||
| 67 | $(CC) $(COPT) -c system.c | ||
| 68 | |||
| 69 | tty.o: tty.c | ||
| 70 | $(CC) $(COPT) -c tty.c | ||
| 71 | |||
| 72 | signal.o: signal.c | ||
| 73 | $(CC) $(COPT) -c signal.c | ||
| 74 | |||
| 75 | ../support/hpuxdl.o: ../support/hpuxdl.c | ||
| 76 | $(MAKE) -C ../support | ||
| 77 | |||
| 78 | ../support/snprintf.o: ../support/snprintf.c | ||
| 79 | $(MAKE) -C ../support | ||
| 80 | |||
| 81 | .c.o: | ||
| 82 | $(CC) $(COPT) $(DEFS) -c $< | ||
| 83 | |||
| 84 | clean: | ||
| 85 | rm -f $(OBJS) $(OBJS2) $(TARGET) cf_prse.c core *~ | ||
| 86 | |||
| 87 | indent: | ||
| 88 | $(INDENT) $(INDENT_OPT) *.c *.h | ||
diff --git a/other/b-scan/tmp/src/arpg.c b/other/b-scan/tmp/src/arpg.c new file mode 100644 index 0000000..0c8a620 --- /dev/null +++ b/other/b-scan/tmp/src/arpg.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * bscan arp routine | ||
| 3 | */ | ||
| 4 | #include <bscan/arpg.h> | ||
| 5 | #include <bscan/snarf.h> | ||
| 6 | #include <libnet.h> | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | void | ||
| 11 | prepare_libnet (struct _libnet *lnet) | ||
| 12 | { | ||
| 13 | |||
| 14 | if (lnet->device == NULL) | ||
| 15 | { | ||
| 16 | struct sockaddr_in sin; | ||
| 17 | if (libnet_select_device (&sin, &lnet->device, lnet->err_buf) == -1) | ||
| 18 | libnet_error (LIBNET_ERR_FATAL, | ||
| 19 | "libnet_select_device failed: %s\n", lnet->err_buf); | ||
| 20 | } | ||
| 21 | |||
| 22 | if ( | ||
| 23 | (lnet->network = | ||
| 24 | libnet_open_link_interface (lnet->device, lnet->err_buf)) == NULL) | ||
| 25 | libnet_error (LIBNET_ERR_FATAL, | ||
| 26 | "libnet_open_link_interface '%s': %s\n", lnet->device, | ||
| 27 | lnet->err_buf); | ||
| 28 | |||
| 29 | |||
| 30 | lnet->packet_size = 60; /* min ethernet frame length -4 CRC */ | ||
| 31 | if (libnet_init_packet (lnet->packet_size, &lnet->packet) == -1) | ||
| 32 | libnet_error (LIBNET_ERR_FATAL, "libnet_init_packet failed\n"); | ||
| 33 | |||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * play arp-god: sends out arp-reply | ||
| 38 | * return: same as libnet_write_link_layer | ||
| 39 | * -1 on failure or bytes written | ||
| 40 | */ | ||
| 41 | int | ||
| 42 | play_arpg (struct _libnet *lnet, u_char spf_sip[4], u_char spf_smac[6], | ||
| 43 | u_char spf_dip[4], u_char spf_dmac[6]) | ||
| 44 | { | ||
| 45 | int c; | ||
| 46 | |||
| 47 | #ifdef DEBUG | ||
| 48 | printf ("sending out arp\n"); | ||
| 49 | #endif | ||
| 50 | libnet_build_ethernet (spf_dmac, | ||
| 51 | spf_smac, ETHERTYPE_ARP, NULL, 0, lnet->packet); | ||
| 52 | |||
| 53 | libnet_build_arp (ARPHRD_ETHER, ETHERTYPE_IP, /* arp for which protocol ? */ | ||
| 54 | 6, /* hardware addr. length */ | ||
| 55 | 4, /* protocol addr. length */ | ||
| 56 | ARPOP_REPLY, spf_smac, spf_sip, spf_dmac, spf_dip, NULL, /* packet payload */ | ||
| 57 | 0, /* length of payload */ | ||
| 58 | lnet->packet + LIBNET_ETH_H); | ||
| 59 | |||
| 60 | c = | ||
| 61 | libnet_write_link_layer (lnet->network, lnet->device, lnet->packet, | ||
| 62 | lnet->packet_size); | ||
| 63 | if (c < lnet->packet_size) | ||
| 64 | { | ||
| 65 | libnet_error (LN_ERR_WARNING, | ||
| 66 | "libnet_write_link_layer only wrote %d bytes\n", c); | ||
| 67 | } | ||
| 68 | #ifdef DEBUG | ||
| 69 | else | ||
| 70 | { | ||
| 71 | printf ("construction and injection completed, wrote all %d bytes\n", | ||
| 72 | c); | ||
| 73 | } | ||
| 74 | #endif | ||
| 75 | |||
| 76 | return (c); | ||
| 77 | } | ||
| 78 | |||
diff --git a/other/b-scan/tmp/src/bscan.c b/other/b-scan/tmp/src/bscan.c new file mode 100644 index 0000000..ed49d1b --- /dev/null +++ b/other/b-scan/tmp/src/bscan.c | |||
| @@ -0,0 +1,851 @@ | |||
| 1 | /* | ||
| 2 | * This is unpublished proprietary source code. | ||
| 3 | * | ||
| 4 | * The contents of these coded instructions, statements and computer | ||
| 5 | * programs may not be disclosed to third parties, copied or duplicated in | ||
| 6 | * any form, in whole or in part, without the prior written permission of | ||
| 7 | * the author. | ||
| 8 | * (that includes you hack.co.za and other lame kid sites who dont | ||
| 9 | * get the point what hacking is about. damn kids.) | ||
| 10 | * | ||
| 11 | * (C) COPYRIGHT by me, 2000 | ||
| 12 | * All Rights Reserved | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <stdlib.h> | ||
| 17 | #include <math.h> | ||
| 18 | #include <bscan/bscan.h> | ||
| 19 | #include <bscan/snarf.h> | ||
| 20 | #include <bscan/tty.h> | ||
| 21 | #include <bscan/system.h> | ||
| 22 | #include <bscan/restore.h> | ||
| 23 | #include <bscan/module.h> | ||
| 24 | #include <bscan/version.h> | ||
| 25 | #include <bscan/cf_prse.h> | ||
| 26 | #include <sys/types.h> | ||
| 27 | #include <signal.h> | ||
| 28 | #include <math.h> | ||
| 29 | #include <libnet.h> | ||
| 30 | |||
| 31 | #ifdef HAVE_DLSYM | ||
| 32 | extern const int modcount; | ||
| 33 | extern const struct _mods mods[MAX_MODULES]; | ||
| 34 | #endif | ||
| 35 | |||
| 36 | unsigned char packet[1024]; | ||
| 37 | struct _opt *opt; | ||
| 38 | |||
| 39 | #define OPTS "XOVhavr:C:L:M:m:l:d:p:i:s:f:o:" | ||
| 40 | |||
| 41 | static unsigned long int gennextip (void); | ||
| 42 | static unsigned long int gennext_spreadip (void); | ||
| 43 | static unsigned long int gennext_random (void); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * make static mac entry in arp-table. | ||
| 47 | * We use system() here [setting mac entry is heavily system dependent] | ||
| 48 | */ | ||
| 49 | int | ||
| 50 | setarp (uint32_t ip, u_char * mac) | ||
| 51 | { | ||
| 52 | char buf[128]; | ||
| 53 | u_char *p = (u_char *) mac; | ||
| 54 | |||
| 55 | snprintf (buf, sizeof (buf) - 1, | ||
| 56 | "arp -s %s %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", int_ntoa (ip), | ||
| 57 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 58 | /* put all your IFL fun in here ! this is the major security hole | ||
| 59 | you were looking for.... */ | ||
| 60 | |||
| 61 | return (system (buf)); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /* | ||
| 66 | * delete the mac entry from the arp-table. | ||
| 67 | * we use system() again | ||
| 68 | */ | ||
| 69 | int | ||
| 70 | unsetarp (uint32_t ip) | ||
| 71 | { | ||
| 72 | char buf[128]; | ||
| 73 | |||
| 74 | snprintf (buf, sizeof (buf) - 1, "arp -d %s", int_ntoa (ip)); | ||
| 75 | /* put all your IFL fun in here ! this is the major security hole | ||
| 76 | you were looking for.... */ | ||
| 77 | |||
| 78 | return (system (buf)); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static void | ||
| 83 | usage (int code, char *fmt, ...) | ||
| 84 | { | ||
| 85 | char buf[1024]; | ||
| 86 | va_list ap; | ||
| 87 | u_char *p = (u_char *) opt->spf_smac; | ||
| 88 | int c; | ||
| 89 | |||
| 90 | printf (VERSION "\n"); | ||
| 91 | printf (" b-scan -s <spoofed source ip> [options] <host/network> ...\n"); | ||
| 92 | printf (" format of <host/network>:\n"); | ||
| 93 | printf (" <host>, 10.23.0.1 or\n"); | ||
| 94 | printf (" <start ip>-<end ip>, 10.23.0.1-10.23.255.254 or\n"); | ||
| 95 | printf (" <start network/mask>, 10.23.0.1/16\n\n"); | ||
| 96 | printf ("Options:\n"); | ||
| 97 | printf (" -r <restore.bscan>\n"); | ||
| 98 | #ifdef HAVE_DLSYM | ||
| 99 | printf (" -L <module.so, shared library file>\n"); | ||
| 100 | #endif | ||
| 101 | printf (" -f <hostlist, one ip/line>\n"); | ||
| 102 | printf (" -s <spoofed ip address on your LOCAL (!) network>\n"); | ||
| 103 | printf (" -m <mac>, make a static arp-entry and spoof from this mac.\n"); | ||
| 104 | printf | ||
| 105 | (" -M <mac>, dont make the static arpentry but spoof from this mac.\n"); | ||
| 106 | printf (" Add the mac to your arp-table manually (arp -s ip mac),\n"); | ||
| 107 | printf (" If no mac is given default mac is used:\n"); | ||
| 108 | printf (" MAC : %x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], | ||
| 109 | p[5]); | ||
| 110 | printf (" -i <ethernet interface>, default eth0\n"); | ||
| 111 | printf | ||
| 112 | (" -X spreadmode [non-sequential, experimental but recommended]\n"); | ||
| 113 | printf (" -O output ip's, dont scan\n"); | ||
| 114 | printf | ||
| 115 | (" -l <pps> limit packets per second, default 1000, 0 = unlimited\n"); | ||
| 116 | printf | ||
| 117 | (" -d <delay> w8 delay seconds for outstanding packets, default 10\n"); | ||
| 118 | printf (" -C <configuration file>\n"); | ||
| 119 | printf (" -v verbose output\n\n"); | ||
| 120 | printf ("Example:\n"); | ||
| 121 | printf ("# bscan -s 10.1.6.6 -i eth2 -L \"modules/mod_banner.so\" -X 2.4.1.0-2.4.9.9\n"); | ||
| 122 | |||
| 123 | #ifdef HAVE_DLSYM | ||
| 124 | for (c = 0; c < modcount; c++) | ||
| 125 | mods[c].musage (); | ||
| 126 | #endif | ||
| 127 | |||
| 128 | if (fmt != NULL) | ||
| 129 | { | ||
| 130 | va_start (ap, fmt); | ||
| 131 | vsnprintf (buf, sizeof (buf) - 1, fmt, ap); | ||
| 132 | va_end (ap); | ||
| 133 | fprintf (stderr, "ERROR: %s\n", buf); | ||
| 134 | } | ||
| 135 | |||
| 136 | exit (code); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * read's next ip from file. | ||
| 141 | * returns ip in NBO | ||
| 142 | * returns -1 (eg. 255.255.255.255) on failure | ||
| 143 | */ | ||
| 144 | unsigned long int | ||
| 145 | readnextip (void) | ||
| 146 | { | ||
| 147 | char buf[64]; | ||
| 148 | |||
| 149 | if (opt->ffd == NULL) | ||
| 150 | { | ||
| 151 | if ((opt->ffd = fopen (opt->hostfile, "r")) == NULL) | ||
| 152 | { | ||
| 153 | perror ("unable to open hostfile"); | ||
| 154 | return (-1); | ||
| 155 | } | ||
| 156 | opt->target = opt->hostfile; | ||
| 157 | } | ||
| 158 | fgets (buf, sizeof (buf), opt->ffd); | ||
| 159 | |||
| 160 | return (inet_addr (buf)); | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * get next ip in NBO from network/mask | ||
| 165 | * [could be random order] | ||
| 166 | * returns -1 [255.255.255.255] if no more ip's | ||
| 167 | * hint: rfc: "the first and last ip in a subnetwork are reserved" | ||
| 168 | */ | ||
| 169 | static unsigned long int | ||
| 170 | gennextip (void) | ||
| 171 | { | ||
| 172 | |||
| 173 | if (opt->ip_pos <= opt->end_ip) | ||
| 174 | return (htonl (opt->ip_pos++)); | ||
| 175 | |||
| 176 | return (-1); | ||
| 177 | |||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 181 | * generate next ip in spread-mode | ||
| 182 | * must: ip.end_ip - ip.start_ip > 2 | ||
| 183 | */ | ||
| 184 | static unsigned long int | ||
| 185 | gennext_spreadip (void) | ||
| 186 | { | ||
| 187 | u_long pos = opt->ip_pos; | ||
| 188 | |||
| 189 | |||
| 190 | if ((opt->ip_offset + 1 >= opt->ip_blklen) && (opt->ip_pos > opt->end_ip)) | ||
| 191 | return (-1); | ||
| 192 | |||
| 193 | if ((opt->ip_pos + opt->ip_blklen > opt->end_ip) | ||
| 194 | && (opt->ip_offset + 1 < opt->ip_blklen)) | ||
| 195 | opt->ip_pos = opt->start_ip + (++opt->ip_offset); | ||
| 196 | else | ||
| 197 | opt->ip_pos += opt->ip_blklen; | ||
| 198 | |||
| 199 | return (htonl (pos)); | ||
| 200 | |||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | static unsigned long int | ||
| 205 | gennext_random (void) | ||
| 206 | { | ||
| 207 | unsigned long int ip; | ||
| 208 | |||
| 209 | if (opt->random_maxcount != 0) { | ||
| 210 | if (--opt->random_maxcount == 0) | ||
| 211 | return (-1); | ||
| 212 | } | ||
| 213 | |||
| 214 | pitch: | ||
| 215 | ip = (random () & 0xffff) << 16; | ||
| 216 | ip |= random () & 0xffff; | ||
| 217 | |||
| 218 | if (((ip & 0xe0000000) >= 0xe0000000) || /* 224.0.0.0/3 */ | ||
| 219 | ((ip & 0xff000000) == 0x7f000000) || /* 127.0.0.0/8 */ | ||
| 220 | ((ip & 0xff000000) == 0x0a000000) || /* 10.0.0.0/8 */ | ||
| 221 | ((ip & 0xffff0000) == 0xc0a80000) || /* 192.168.0.0/16 */ | ||
| 222 | ((ip & 0xffff0000) == 0xac100000) || /* 172.16.0.0/16 */ | ||
| 223 | (ip == 0x00000000)) /* 0.0.0.0/32 */ | ||
| 224 | goto pitch; | ||
| 225 | |||
| 226 | return (htonl (ip)); | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | /* | ||
| 231 | * process all the options and load/init modules | ||
| 232 | */ | ||
| 233 | void | ||
| 234 | do_opt (int argc, char *argv[]) | ||
| 235 | { | ||
| 236 | extern char *optarg; | ||
| 237 | extern int optind; /*, opterr, optopt;*/ | ||
| 238 | unsigned short int sp[ETH_ALEN]; | ||
| 239 | int c; | ||
| 240 | char do_usage = 0; | ||
| 241 | |||
| 242 | |||
| 243 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 244 | { | ||
| 245 | switch (c) | ||
| 246 | { | ||
| 247 | case 'C': /* process conf file */ | ||
| 248 | if (readConfFile (optarg)) | ||
| 249 | { | ||
| 250 | opt->flags |= FileOpt.flags; | ||
| 251 | opt->limit = FileOpt.limit; | ||
| 252 | opt->delay = FileOpt.delay; | ||
| 253 | opt->nt.src = FileOpt.srcAddr; | ||
| 254 | opt->lnet.device = FileOpt.device; | ||
| 255 | for (c = 0; c < 6; c++) | ||
| 256 | opt->spf_smac[c] = FileOpt.mac[c]; | ||
| 257 | } | ||
| 258 | else | ||
| 259 | fprintf (stderr, "%s is not a valid vonfig file\n", optarg); | ||
| 260 | break; | ||
| 261 | case 'L': | ||
| 262 | break; /* process module stuff AFTER main-opts */ | ||
| 263 | case 'h': | ||
| 264 | do_usage = 1; | ||
| 265 | break; | ||
| 266 | case 'r': | ||
| 267 | if (read_restore (optarg) != 0) | ||
| 268 | { | ||
| 269 | fprintf (stderr, "unable to read restore file '%s'\n", | ||
| 270 | optarg); | ||
| 271 | exit (-1); | ||
| 272 | } | ||
| 273 | opt->flags |= OPT_REST; | ||
| 274 | break; | ||
| 275 | case 'l': | ||
| 276 | opt->limit = atoi (optarg); | ||
| 277 | break; | ||
| 278 | case 'v': | ||
| 279 | opt->flags |= OPT_VERB; | ||
| 280 | break; | ||
| 281 | case 'X': | ||
| 282 | opt->flags |= OPT_SPREADSCAN; | ||
| 283 | break; | ||
| 284 | case 'O': | ||
| 285 | opt->flags |= OPT_OUTONLY; /* dont scan, output ip's only */ | ||
| 286 | break; | ||
| 287 | case 'm': | ||
| 288 | opt->flags |= OPT_SETARP; | ||
| 289 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 290 | &sp[3], &sp[4], &sp[5]); | ||
| 291 | for (c = 0; c < 6; c++) | ||
| 292 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 293 | break; | ||
| 294 | case 'M': | ||
| 295 | opt->flags &= ~OPT_SETARP; | ||
| 296 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 297 | &sp[3], &sp[4], &sp[5]); | ||
| 298 | for (c = 0; c < 6; c++) | ||
| 299 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 300 | break; | ||
| 301 | case 'd': | ||
| 302 | opt->delay = atoi (optarg); | ||
| 303 | break; | ||
| 304 | case 'i': | ||
| 305 | opt->lnet.device = optarg; | ||
| 306 | break; | ||
| 307 | case 's': | ||
| 308 | opt->nt.src = inet_addr (optarg); | ||
| 309 | break; | ||
| 310 | case 'f': | ||
| 311 | opt->hostfile = optarg; | ||
| 312 | opt->flags |= OPT_HOSTFILE; | ||
| 313 | break; | ||
| 314 | case 'V': | ||
| 315 | printf (VERSION "\n"); | ||
| 316 | exit (0); | ||
| 317 | case ':': | ||
| 318 | usage (0, "parameter missing", c); | ||
| 319 | break; | ||
| 320 | default: | ||
| 321 | break; | ||
| 322 | usage (0, "unknown option -%c", c); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | /* | ||
| 327 | * init modules AFTER processing main-opts | ||
| 328 | */ | ||
| 329 | #ifdef HAVE_DLSYM | ||
| 330 | optind = 1; | ||
| 331 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 332 | { | ||
| 333 | switch (c) | ||
| 334 | { | ||
| 335 | case 'L': | ||
| 336 | loadinit_mod(optarg); | ||
| 337 | break; | ||
| 338 | } /* eo switch(c) */ | ||
| 339 | } /* eo while */ | ||
| 340 | #endif | ||
| 341 | if (do_usage != 0) | ||
| 342 | usage (0, NULL); | ||
| 343 | |||
| 344 | if ((optind < argc) && (!(opt->flags & OPT_REST))) | ||
| 345 | opt->argvlist = &argv[optind]; | ||
| 346 | if (opt->flags & OPT_OUTONLY) | ||
| 347 | opt->delay = 0; | ||
| 348 | if (opt->nt.src == -1) | ||
| 349 | usage (0, "you must specify a -s source address"); | ||
| 350 | if ((opt->argvlist == NULL) && (opt->hostfile == NULL)) | ||
| 351 | usage (0, "you must specify a -f hostfile or an ip-range"); | ||
| 352 | |||
| 353 | } | ||
| 354 | |||
| 355 | /* | ||
| 356 | * called via SIGCHLD and w8 for the pid [to destroy last kernel structure] | ||
| 357 | * OBSOLETE, ###fixme | ||
| 358 | */ | ||
| 359 | void | ||
| 360 | waitchld (int sig) | ||
| 361 | { | ||
| 362 | int status; | ||
| 363 | wait (&status); /* exit status of the child */ | ||
| 364 | } | ||
| 365 | |||
| 366 | void | ||
| 367 | sig_handle_abort (int sig) | ||
| 368 | { | ||
| 369 | |||
| 370 | if (pthread_self() != opt->bscantid) | ||
| 371 | return; | ||
| 372 | |||
| 373 | fprintf (stderr, "Session aborted ...one more to kill process\n"); | ||
| 374 | signal (sig, die); | ||
| 375 | opt->flags |= OPT_ABRT; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * generic signal driver :> | ||
| 380 | */ | ||
| 381 | void | ||
| 382 | sigdriver (int sig) | ||
| 383 | { | ||
| 384 | |||
| 385 | if (pthread_self() != opt->bscantid) | ||
| 386 | return; | ||
| 387 | |||
| 388 | if (sig == SIGUSR1) | ||
| 389 | print_scanstat (stderr); | ||
| 390 | if ((sig == SIGINT) || (sig == SIGQUIT)) /* ctrl-c */ | ||
| 391 | sig_handle_abort (sig); | ||
| 392 | } | ||
| 393 | |||
| 394 | /* | ||
| 395 | * This function MUST be called on exit (..or use atexit():) | ||
| 396 | * we have threads. Doesnt matter which thread calls this | ||
| 397 | * function...do everything and exit() the process | ||
| 398 | * (kills all threads...not very gentle...but...). | ||
| 399 | */ | ||
| 400 | void | ||
| 401 | die (int sig) | ||
| 402 | { | ||
| 403 | int c = 0; | ||
| 404 | |||
| 405 | print_scanstat (stderr); /* print before cleanup routines...*/ | ||
| 406 | |||
| 407 | if (opt->flags & OPT_ABRT) | ||
| 408 | if (write_restore () != 0) | ||
| 409 | perror ("restorefile failed"); | ||
| 410 | if ((opt->flags & OPT_SETARP) && (unsetarp (opt->nt.src) != 0)) | ||
| 411 | fprintf (stderr, "unable to unset arpentry. do it manually\n"); | ||
| 412 | #ifdef HAVE_DLSYM | ||
| 413 | while (c < modcount) | ||
| 414 | mods[c++].fini (); | ||
| 415 | #endif | ||
| 416 | |||
| 417 | #ifdef DEBUG | ||
| 418 | printf ("calling exit.\n"); | ||
| 419 | #endif | ||
| 420 | |||
| 421 | fflush (stdout); | ||
| 422 | |||
| 423 | exit (0); | ||
| 424 | } | ||
| 425 | |||
| 426 | /* | ||
| 427 | * reset all vars used during the scan (counters, ...) | ||
| 428 | * should be called before the call to make_iprange() | ||
| 429 | * If not...make_iprange thinks we use restore-file | ||
| 430 | */ | ||
| 431 | void | ||
| 432 | reset_vars () | ||
| 433 | { | ||
| 434 | opt->target = NULL; | ||
| 435 | opt->ipscan_count = 0; | ||
| 436 | opt->bsent_count = 0; | ||
| 437 | opt->ip_offset = 0; | ||
| 438 | opt->ip_blklen = 0; | ||
| 439 | opt->ip_pos = 0; | ||
| 440 | opt->start_ip = 0; | ||
| 441 | opt->end_ip = 0; | ||
| 442 | opt->snarf.close_c = 0; | ||
| 443 | opt->snarf.open_c = 0; | ||
| 444 | opt->snarf.refused_c = 0; | ||
| 445 | opt->snarf.icmp_c = 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | void | ||
| 450 | init_vars (char **nullptr) | ||
| 451 | { | ||
| 452 | srandom ((unsigned int) time (NULL)); | ||
| 453 | |||
| 454 | if ((opt = calloc (1, sizeof (*opt))) == NULL) | ||
| 455 | { | ||
| 456 | perror ("calloc"); | ||
| 457 | exit (-1); | ||
| 458 | } | ||
| 459 | memset (opt, 0, sizeof (struct _opt)); | ||
| 460 | |||
| 461 | opt->bscantid = 0; | ||
| 462 | opt->snarftid = 0; | ||
| 463 | opt->packet = packet; | ||
| 464 | opt->pkg_maxlen = sizeof (packet); | ||
| 465 | opt->pkg_len = 0; | ||
| 466 | opt->scan_start.tv_sec = 0; | ||
| 467 | opt->iptotscan_count = 0; | ||
| 468 | opt->scan_start.tv_usec = 0; | ||
| 469 | opt->hostfile = NULL; | ||
| 470 | opt->limit = 1000; | ||
| 471 | opt->flags = OPT_SETARP; | ||
| 472 | opt->ffd = NULL; | ||
| 473 | opt->argvlist = nullptr; | ||
| 474 | opt->lnet.device = NULL; /* done by libnet and libpcap */ | ||
| 475 | memcpy (opt->spf_smac, SPF_SMAC, 6); | ||
| 476 | opt->nt.src = -1; | ||
| 477 | opt->nt.dst = -1; | ||
| 478 | opt->delay = 10; | ||
| 479 | opt->lnet.device = NULL; | ||
| 480 | reset_vars (); | ||
| 481 | |||
| 482 | signal (SIGINT, sigdriver); | ||
| 483 | signal (SIGQUIT, sigdriver); | ||
| 484 | signal (SIGTERM, die); /* also called by client */ | ||
| 485 | signal (SIGCHLD, SIG_IGN); | ||
| 486 | signal (SIGUSR1, sigdriver); | ||
| 487 | } | ||
| 488 | |||
| 489 | void | ||
| 490 | print_opt () | ||
| 491 | { | ||
| 492 | u_char *p = (u_char *) opt->spf_smac; | ||
| 493 | |||
| 494 | fprintf (stderr, "Pid : %d\n", getpid()); | ||
| 495 | fprintf (stderr, "Interface : %s\n", opt->lnet.device); | ||
| 496 | fprintf (stderr, "Source IP : %s\n", int_ntoa (opt->nt.src)); | ||
| 497 | fprintf (stderr, "Source MAC : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
| 498 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 499 | fprintf (stderr, "pps : %u\n", opt->limit); | ||
| 500 | } | ||
| 501 | |||
| 502 | /* | ||
| 503 | * print scanstatistics on filedes | ||
| 504 | */ | ||
| 505 | void | ||
| 506 | print_scanstat (FILE * fd) | ||
| 507 | { | ||
| 508 | char perc = 100; | ||
| 509 | struct timeval tv2; | ||
| 510 | time_t timep; | ||
| 511 | struct tm mytm; | ||
| 512 | |||
| 513 | gettimeofday (&tv2, NULL); | ||
| 514 | time_diff (&opt->scan_start, &tv2); | ||
| 515 | if (tv2.tv_sec == 0) | ||
| 516 | tv2.tv_sec = 1; | ||
| 517 | timep = tv2.tv_sec; | ||
| 518 | gmtime_r (&timep, &mytm); | ||
| 519 | |||
| 520 | if ((opt->end_ip - opt->start_ip) != 0) | ||
| 521 | perc = | ||
| 522 | (((float) | ||
| 523 | opt->ipscan_count / (float) (opt->end_ip - | ||
| 524 | opt->start_ip)) * 100); | ||
| 525 | |||
| 526 | fprintf (fd, | ||
| 527 | "%2.2d:%2.2d:%2.2d:%2.2d %s %3d%% p/s: %6d [o:%lu r:%lu c:%lu i:%lu]\n", | ||
| 528 | mytm.tm_yday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec, | ||
| 529 | opt->target, perc, (int) (opt->iptotscan_count / tv2.tv_sec), | ||
| 530 | opt->snarf.open_c, opt->snarf.refused_c, opt->snarf.close_c, | ||
| 531 | opt->snarf.icmp_c); | ||
| 532 | |||
| 533 | } | ||
| 534 | |||
| 535 | |||
| 536 | /* | ||
| 537 | * calculate beginning and end of ip-range | ||
| 538 | * set start_ip and end_ip and target | ||
| 539 | */ | ||
| 540 | void | ||
| 541 | make_iprange (u_long * network, u_long * netmask, u_long * start_ip, | ||
| 542 | u_long * end_ip, char *str) | ||
| 543 | { | ||
| 544 | char buf[64]; | ||
| 545 | char *ptr; | ||
| 546 | |||
| 547 | opt->target = str; | ||
| 548 | strncpy (buf, str, sizeof (buf)); | ||
| 549 | buf[sizeof (buf) - 1] = '\0'; | ||
| 550 | opt->getnextip = NULL; | ||
| 551 | *start_ip = 0; | ||
| 552 | |||
| 553 | if (strncmp (buf, "random", 6) == 0) { | ||
| 554 | opt->getnextip = (void *) gennext_random; | ||
| 555 | if (strchr (buf, ':') != NULL) { | ||
| 556 | sscanf (strchr (buf, ':') + 1, "%lu", &opt->random_maxcount); | ||
| 557 | } else { | ||
| 558 | opt->random_maxcount = 0; | ||
| 559 | } | ||
| 560 | return; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* a.b.c.d/e */ | ||
| 564 | if (strchr (buf, '/') != NULL) | ||
| 565 | { | ||
| 566 | *netmask = 0xffffffff; /* for the lamers who forget the /<netmask> */ | ||
| 567 | |||
| 568 | if ((ptr = (char *) strrchr (buf, '/')) != NULL) | ||
| 569 | *netmask = 0xffffffff << (32 - atoi (ptr + 1)); | ||
| 570 | |||
| 571 | if ((ptr = (char *) strchr (buf, '/')) != NULL) | ||
| 572 | *ptr = '\0'; | ||
| 573 | |||
| 574 | *network = (ntohl (inet_addr (buf)) & *netmask); | ||
| 575 | *start_ip = (*network & *netmask) + 1; | ||
| 576 | *end_ip = (*network | ~*netmask) - 1; | ||
| 577 | if (*netmask >= 0xfffffffe) | ||
| 578 | (*start_ip)--; | ||
| 579 | if (*netmask == 0xffffffff) | ||
| 580 | (*end_ip)++; | ||
| 581 | } | ||
| 582 | |||
| 583 | /* a.b.c.d - w.x.y.z */ | ||
| 584 | if ((*start_ip == 0) && ((ptr = (char *) strrchr (buf, '-')) != NULL)) | ||
| 585 | { | ||
| 586 | *end_ip = ntohl (inet_addr (ptr + 1)); | ||
| 587 | *ptr = '\0'; | ||
| 588 | *start_ip = ntohl (inet_addr (buf)); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* a.b.c.d */ | ||
| 592 | if (*start_ip == 0) | ||
| 593 | { | ||
| 594 | *end_ip = ntohl (inet_addr (buf)); | ||
| 595 | *start_ip = ntohl (inet_addr (buf)); | ||
| 596 | } | ||
| 597 | |||
| 598 | if (opt->ip_pos == 0) /* if != 0 we use restore-file */ | ||
| 599 | opt->ip_pos = *start_ip; | ||
| 600 | |||
| 601 | /* initialize getnextip-funtion and spread scan variables */ | ||
| 602 | if ((opt->flags & OPT_SPREADSCAN) && (opt->end_ip - opt->start_ip > 2)) | ||
| 603 | { | ||
| 604 | init_spreadscan (opt->end_ip - opt->start_ip); | ||
| 605 | opt->getnextip = (void *) gennext_spreadip; | ||
| 606 | } | ||
| 607 | else | ||
| 608 | { | ||
| 609 | opt->getnextip = (void *) gennextip; | ||
| 610 | } | ||
| 611 | |||
| 612 | } | ||
| 613 | |||
| 614 | /* | ||
| 615 | * initialize offset for spread-scan | ||
| 616 | * call make_iprange before | ||
| 617 | * | ||
| 618 | * most networks are /24. dont let ip_blklen get to big | ||
| 619 | */ | ||
| 620 | void | ||
| 621 | init_spreadscan (u_long diff) | ||
| 622 | { | ||
| 623 | opt->ip_blklen = (u_long) sqrt (diff); | ||
| 624 | |||
| 625 | if (opt->ip_blklen > 100) /* range is 100^2 large */ | ||
| 626 | opt->ip_blklen = 257 + opt->ip_blklen * 0.2; /* use a prime# here */ | ||
| 627 | |||
| 628 | } | ||
| 629 | |||
| 630 | |||
| 631 | /* | ||
| 632 | * output the ip's only. dont scan. | ||
| 633 | */ | ||
| 634 | void | ||
| 635 | do_outonly () | ||
| 636 | { | ||
| 637 | uint32_t ip; | ||
| 638 | |||
| 639 | while ((ip = (*opt->getnextip) ()) != -1) | ||
| 640 | { | ||
| 641 | opt->ipscan_count++; | ||
| 642 | printf ("%s\n", int_ntoa (ip)); | ||
| 643 | } | ||
| 644 | |||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | /* | ||
| 649 | * process a scanrange from argv | ||
| 650 | * Return -1 if abort | ||
| 651 | */ | ||
| 652 | int | ||
| 653 | process_iprange () | ||
| 654 | { | ||
| 655 | int c = 0; | ||
| 656 | int ret; | ||
| 657 | #ifdef HAVE_DLSYM | ||
| 658 | int mc = 0; | ||
| 659 | #endif | ||
| 660 | |||
| 661 | while ((opt->nt.dst = (*opt->getnextip) ()) != -1) | ||
| 662 | { | ||
| 663 | memset (opt->packet, 0, opt->pkg_maxlen); | ||
| 664 | |||
| 665 | opt->pkg_len = 0; | ||
| 666 | |||
| 667 | if (opt->flags & OPT_VERB) | ||
| 668 | fprintf (stderr, "scanning %s:%d\n", | ||
| 669 | int_ntoa (opt->nt.dst), ntohs (opt->nt.dport)); | ||
| 670 | |||
| 671 | #ifdef HAVE_DLSYM | ||
| 672 | for (mc = 0; mc < modcount; mc++) | ||
| 673 | { | ||
| 674 | ret = mods[mc].callmdl (MOD_FIRSTPKG, opt); | ||
| 675 | if (ret == RMOD_SKIP) | ||
| 676 | continue; | ||
| 677 | if (ret == RMOD_ABRT) | ||
| 678 | { | ||
| 679 | fprintf(stderr, "oops: callmdl returned RMOD_ABRT\n"); | ||
| 680 | return(-1); | ||
| 681 | } | ||
| 682 | #endif | ||
| 683 | |||
| 684 | opt->bsent_count += | ||
| 685 | send_ipv4 (opt->sox, opt->packet + ETH_SIZE, opt->pkg_len); | ||
| 686 | opt->iptotscan_count++; | ||
| 687 | opt->ipscan_count++; /* linear ipscan-offset */ | ||
| 688 | |||
| 689 | if (opt->ipscan_count % opt->limit == 0) /* every second */ | ||
| 690 | { | ||
| 691 | if ((c = tty_getchar ()) != -1) | ||
| 692 | print_scanstat (stderr); | ||
| 693 | if (opt->flags & OPT_ABRT) | ||
| 694 | return (-1); /* sig_abort_handler called */ | ||
| 695 | } | ||
| 696 | |||
| 697 | /* do floodprotection */ | ||
| 698 | while (opt->limit > 0) | ||
| 699 | { | ||
| 700 | /* | ||
| 701 | * forgett about the initial value of tv.tv_usec... | ||
| 702 | * This is called 'optimizing algorithms'. The usec does | ||
| 703 | * not count if you scan >>10seconds... | ||
| 704 | */ | ||
| 705 | gettimeofday (&opt->tv2, NULL); | ||
| 706 | opt->sec = (opt->tv2.tv_sec - opt->scan_start.tv_sec) | ||
| 707 | - (opt->scan_start.tv_usec - opt->tv2.tv_usec) / 1000000.0; | ||
| 708 | if ((opt->iptotscan_count / opt->sec) >= opt->limit) | ||
| 709 | usleep (10); /* should give up timeslice */ | ||
| 710 | else | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | #ifdef HAVE_DLSYM | ||
| 714 | } /* modcount-loop */ | ||
| 715 | #endif | ||
| 716 | } | ||
| 717 | return (0); | ||
| 718 | } | ||
| 719 | |||
| 720 | void * | ||
| 721 | p_doit(void *arg) | ||
| 722 | { | ||
| 723 | printf("first thread here\n"); | ||
| 724 | sleep(100); | ||
| 725 | return NULL; | ||
| 726 | } | ||
| 727 | |||
| 728 | |||
| 729 | int | ||
| 730 | main (int argc, char *argv[]) | ||
| 731 | { | ||
| 732 | struct sockaddr_in saddr; | ||
| 733 | struct timeval tv; | ||
| 734 | int size; | ||
| 735 | int pstatus; /* pthread error status */ | ||
| 736 | #ifdef IP_HDRINCL | ||
| 737 | const int on = 1; | ||
| 738 | #endif | ||
| 739 | |||
| 740 | init_vars (&argv[argc]); /* before do_opt */ | ||
| 741 | |||
| 742 | do_opt (argc, argv); | ||
| 743 | tty_init (); | ||
| 744 | |||
| 745 | if (opt->flags & OPT_SETARP) | ||
| 746 | if (setarp (opt->nt.src, opt->spf_smac) != 0) | ||
| 747 | { | ||
| 748 | fprintf (stderr, "unable to set arpentry. do it manually\n"); | ||
| 749 | exit (1); | ||
| 750 | } | ||
| 751 | |||
| 752 | init_network_raw (); | ||
| 753 | prepare_libnet (&opt->lnet); /* used by arpg.c and maybe by bscan.c */ | ||
| 754 | |||
| 755 | memset (&saddr, 0, sizeof (saddr)); | ||
| 756 | |||
| 757 | if ((opt->sox = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) | ||
| 758 | { | ||
| 759 | fprintf (stderr, "error creating socket\n"); | ||
| 760 | exit (1); | ||
| 761 | } | ||
| 762 | #ifdef IP_HDRINCL | ||
| 763 | if (setsockopt (opt->sox, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0) | ||
| 764 | { | ||
| 765 | fprintf (stderr, "error setsockopt\n"); | ||
| 766 | exit (1); | ||
| 767 | } | ||
| 768 | #endif | ||
| 769 | |||
| 770 | size = 160 * 1024; /* OK if setsockopt fails */ | ||
| 771 | setsockopt (opt->sox, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)); | ||
| 772 | |||
| 773 | opt->flags |= OPT_W8SEMA; | ||
| 774 | opt->bscantid = pthread_self(); | ||
| 775 | pstatus = pthread_create(&opt->snarftid, NULL, &do_snarf, opt->lnet.device); | ||
| 776 | if (pstatus != 0) | ||
| 777 | err_abort(pstatus, "pthread_create"); | ||
| 778 | |||
| 779 | while (opt->flags & OPT_W8SEMA) | ||
| 780 | usleep(50); | ||
| 781 | |||
| 782 | print_opt (); | ||
| 783 | |||
| 784 | if (opt->scan_start.tv_sec == 0) | ||
| 785 | gettimeofday (&opt->scan_start, NULL); | ||
| 786 | |||
| 787 | while ((*opt->argvlist != NULL) || (opt->flags & OPT_HOSTFILE)) | ||
| 788 | { | ||
| 789 | if (!(opt->flags & OPT_REST)) | ||
| 790 | reset_vars (); /* reset all counting variables */ | ||
| 791 | |||
| 792 | if (!(opt->flags & OPT_HOSTFILE)) | ||
| 793 | { | ||
| 794 | make_iprange (&opt->network, &opt->netmask, &opt->start_ip, | ||
| 795 | &opt->end_ip, *opt->argvlist++); | ||
| 796 | } | ||
| 797 | else | ||
| 798 | { | ||
| 799 | opt->getnextip = (void *) readnextip; | ||
| 800 | if (opt->flags & OPT_REST) | ||
| 801 | { | ||
| 802 | int c = 0; | ||
| 803 | |||
| 804 | fprintf (stderr, "restore: skipping %lu in '%s'\n", | ||
| 805 | opt->ipscan_count, opt->hostfile); | ||
| 806 | while (c++ < opt->ipscan_count) | ||
| 807 | if ((*opt->getnextip) () == -1) | ||
| 808 | break; | ||
| 809 | } | ||
| 810 | } | ||
| 811 | |||
| 812 | opt->flags &= ~OPT_REST; /* 2nd.. init not by restorefile */ | ||
| 813 | |||
| 814 | if ((opt->getnextip == NULL) || (opt->nt.src == 0) | ||
| 815 | || (opt->nt.src == -1)) | ||
| 816 | usage (0, "no ip/range given or nonparseable range, skip"); | ||
| 817 | if (opt->flags & OPT_OUTONLY) | ||
| 818 | { | ||
| 819 | do_outonly (); | ||
| 820 | continue; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (process_iprange () == -1) | ||
| 824 | { | ||
| 825 | print_scanstat (stderr); | ||
| 826 | break; /* abort scan ! */ | ||
| 827 | } | ||
| 828 | |||
| 829 | if (opt->flags & OPT_HOSTFILE) | ||
| 830 | break; /* process only ONE hostfile */ | ||
| 831 | |||
| 832 | if (*opt->argvlist != NULL) | ||
| 833 | print_scanstat (stderr); | ||
| 834 | } | ||
| 835 | |||
| 836 | gettimeofday (&tv, NULL); | ||
| 837 | time_diff (&opt->scan_start, &tv); | ||
| 838 | opt->sec = tv.tv_sec + tv.tv_usec / 1000000.0; | ||
| 839 | fprintf (stderr, "scanned %lu ip's in %.3f seconds\n", opt->iptotscan_count, | ||
| 840 | opt->sec); | ||
| 841 | if (opt->delay > 0) | ||
| 842 | { | ||
| 843 | fprintf (stderr, "waiting %d sec for outstanding packets...\n", | ||
| 844 | opt->delay); | ||
| 845 | signal (SIGINT, die); /* if waiting exit immediatly on INTR */ | ||
| 846 | sleep (opt->delay); | ||
| 847 | } | ||
| 848 | |||
| 849 | die (0); | ||
| 850 | return (0); | ||
| 851 | } | ||
diff --git a/other/b-scan/tmp/src/cf_prse.l b/other/b-scan/tmp/src/cf_prse.l new file mode 100644 index 0000000..592bf7a --- /dev/null +++ b/other/b-scan/tmp/src/cf_prse.l | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | VOID_LINE "b-scan:" | ||
| 2 | LOCAL_IP "SourceAddress" | ||
| 3 | STATIC_MAC "StaticSpoofedMacAddress" | ||
| 4 | SPOOF_MAC "MacAddress" | ||
| 5 | INTERFACE "Interface" | ||
| 6 | SPREADMODE "SpreadScan" | ||
| 7 | PACKETS_PS "PacketsPerSecond" | ||
| 8 | PATIENCY "MaxWaitDelay" | ||
| 9 | VERBOSE "Verbose" | ||
| 10 | LOAD_MOD "addModule" | ||
| 11 | |||
| 12 | %{ | ||
| 13 | /* | ||
| 14 | * options with a "bool" are allowed to take "yes", "1" and "true" | ||
| 15 | * and the negated counterparts (case insensitive) as argument. | ||
| 16 | * all others take their argument as supplyed on the command line. | ||
| 17 | * | ||
| 18 | * | ||
| 19 | * VOID_LINE lines beginning with this string will be passed directly to stderr | ||
| 20 | * LOCAL_IP -s option | ||
| 21 | * STATIC_MAC -m bool | ||
| 22 | * SPOOF_MAC -M | ||
| 23 | * INTERFACE -i | ||
| 24 | * SPREADMODE -X bool | ||
| 25 | * PACKETS_PS -l | ||
| 26 | * PATIENCY -d | ||
| 27 | * VERBOSE -v bool | ||
| 28 | * MODULE -L | ||
| 29 | */ | ||
| 30 | %} | ||
| 31 | |||
| 32 | |||
| 33 | %{ | ||
| 34 | #include <bscan/cf_prse.h> | ||
| 35 | #include <bscan/module.h> | ||
| 36 | #include <string.h> | ||
| 37 | #include <stdlib.h> | ||
| 38 | #include <sys/socket.h> | ||
| 39 | #include <netinet/in.h> | ||
| 40 | #include <arpa/inet.h> | ||
| 41 | |||
| 42 | |||
| 43 | /* defines from bscan.h. why not include? because it sucks! using libnet-config for pff! */ | ||
| 44 | #define OPT_VERB 0x1 | ||
| 45 | #define OPT_SETARP 0x4 | ||
| 46 | #define OPT_SPREADSCAN 0x8 | ||
| 47 | |||
| 48 | |||
| 49 | char * | ||
| 50 | getArg (char *s) | ||
| 51 | { | ||
| 52 | int x = strlen (s); | ||
| 53 | |||
| 54 | while (s[x] != ' ' && s[x] != '\t') | ||
| 55 | --x; | ||
| 56 | return (s + x + 1); | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | int | ||
| 61 | evaluateBoolArg (char *s) | ||
| 62 | { | ||
| 63 | s = getArg (s); | ||
| 64 | |||
| 65 | if (!strcasecmp (s, "yes") || !strcasecmp (s, "true") || !strcasecmp (s, "1")) | ||
| 66 | return (1); | ||
| 67 | else if (!strcasecmp (s, "no") || !strcasecmp (s, "false") || !strcasecmp (s, "0")) | ||
| 68 | return (0); | ||
| 69 | else | ||
| 70 | return (-1); | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | void | ||
| 75 | set_s_opt (char *s) | ||
| 76 | { | ||
| 77 | s = getArg (s); | ||
| 78 | FileOpt.srcAddr = inet_addr (s); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | void | ||
| 83 | set_m_opt (char *s) | ||
| 84 | { | ||
| 85 | s = getArg (s); | ||
| 86 | if (evaluateBoolArg (s)) | ||
| 87 | FileOpt.flags |= OPT_SETARP; | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 91 | void set_M_opt (char *s) | ||
| 92 | { | ||
| 93 | s = getArg (s); | ||
| 94 | sscanf (s, "%hx:%hx:%hx:%hx:%hx:%hx", &FileOpt.mac[0], &FileOpt.mac[1], | ||
| 95 | &FileOpt.mac[2], &FileOpt.mac[3], &FileOpt.mac[4], &FileOpt.mac[5]); | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | void set_i_opt (char *s) | ||
| 100 | { | ||
| 101 | s = getArg (s); | ||
| 102 | FileOpt.device = (char *) malloc (strlen (s) + 1); | ||
| 103 | memset (FileOpt.device, 0, strlen (s) + 1); | ||
| 104 | memcpy (FileOpt.device, s, strlen (s)); | ||
| 105 | } | ||
| 106 | |||
| 107 | void set_X_opt (char *s) | ||
| 108 | { | ||
| 109 | s = getArg (s); | ||
| 110 | if (evaluateBoolArg (s)) | ||
| 111 | FileOpt.flags |= OPT_SPREADSCAN; | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | void set_l_opt (char *s) | ||
| 116 | { | ||
| 117 | s = getArg (s); | ||
| 118 | FileOpt.limit = atoi (s); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | void set_d_opt (char *s) | ||
| 123 | { | ||
| 124 | s = getArg (s); | ||
| 125 | FileOpt.delay = atoi (s); | ||
| 126 | } | ||
| 127 | |||
| 128 | |||
| 129 | void set_v_opt (char *s) | ||
| 130 | { | ||
| 131 | s = getArg (s); | ||
| 132 | if (evaluateBoolArg (s)) | ||
| 133 | FileOpt.flags |= OPT_VERB; | ||
| 134 | } | ||
| 135 | |||
| 136 | void set_L_opt (char *s) | ||
| 137 | { | ||
| 138 | s = s + strlen ("addModule") + 1; | ||
| 139 | while (*s == ' ' || *s == '\t') | ||
| 140 | s++; | ||
| 141 | loadinit_mod (s); | ||
| 142 | } | ||
| 143 | |||
| 144 | %} | ||
| 145 | %% | ||
| 146 | |||
| 147 | ^{VOID_LINE}[\t !-?a-zA-Z0-9]* fprintf (stderr, "%s\n", yytext); | ||
| 148 | ^{LOCAL_IP}[\t .0-9]* set_s_opt (yytext); | ||
| 149 | ^{STATIC_MAC}[\t a-zA-Z0-9]* set_m_opt (yytext); | ||
| 150 | ^{SPOOF_MAC}[\t :a-fA-F0-9]* set_M_opt (yytext); | ||
| 151 | ^{INTERFACE}[\t a-zA-Z0-9]* set_i_opt (yytext); | ||
| 152 | ^{SPREADMODE}[\t a-zA-Z0-9]* set_X_opt (yytext); | ||
| 153 | ^{PACKETS_PS}[\t a-zA-Z0-9]* set_l_opt (yytext); | ||
| 154 | ^{PATIENCY}[\t a-zA-Z0-9]* set_d_opt (yytext); | ||
| 155 | ^{VERBOSE}[\t a-zA-Z0-9]* set_v_opt (yytext); | ||
| 156 | ^{LOAD_MOD}[\t !-?\-_.:,;a-zA-Z0-9]* set_L_opt (yytext); | ||
| 157 | |||
| 158 | [\n\t a-zA-Z0-9] | ||
| 159 | . | ||
| 160 | |||
| 161 | %% | ||
| 162 | |||
| 163 | int yywrap () { return (1);} | ||
| 164 | |||
| 165 | int | ||
| 166 | readConfFile (char *s) | ||
| 167 | { | ||
| 168 | if ((yyin = fopen (s, "r")) == NULL) | ||
| 169 | return 0; | ||
| 170 | yylex (); | ||
| 171 | return 1; | ||
| 172 | } | ||
diff --git a/other/b-scan/tmp/src/dcd_icmp.c b/other/b-scan/tmp/src/dcd_icmp.c new file mode 100644 index 0000000..c627a56 --- /dev/null +++ b/other/b-scan/tmp/src/dcd_icmp.c | |||
| @@ -0,0 +1,166 @@ | |||
| 1 | /* bscan - icmp decoder | ||
| 2 | * | ||
| 3 | * based on information from | ||
| 4 | * RFC792 - INTERNET CONTROL MESSAGE PROTOCOL | ||
| 5 | * RFC950 - Internet Standard Subnetting Procedure | ||
| 6 | * ??? "ICMP Usage in Scanning" (ICMP_Scanning_v2.5.pdf) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <stdio.h> | ||
| 10 | #include <bscan/dcd_icmp.h> | ||
| 11 | |||
| 12 | static char * icmp_echo_reply[] = { | ||
| 13 | "ICMP ECHOREPLY", | ||
| 14 | NULL | ||
| 15 | }; | ||
| 16 | |||
| 17 | static char * icmp_unreach[] = { | ||
| 18 | "ICMP UNREACH network unreachable", | ||
| 19 | "ICMP UNREACH host unreachable", | ||
| 20 | "ICMP UNREACH protocol unreachable", | ||
| 21 | "ICMP UNREACH port unreachable", | ||
| 22 | "ICMP UNREACH fragmentation needed but don't-fragment bit set", | ||
| 23 | "ICMP UNREACH source route failed", | ||
| 24 | "ICMP UNREACH destination network unknown", | ||
| 25 | "ICMP UNREACH destination host unknown", | ||
| 26 | "ICMP UNREACH source host isolated", | ||
| 27 | "ICMP UNREACH destination network administratively prohibited", | ||
| 28 | "ICMP UNREACH destination host administratively prohibited", | ||
| 29 | "ICMP UNREACH network unreachable for TOS", | ||
| 30 | "ICMP UNREACH host unreachable for TOS", | ||
| 31 | "ICMP UNREACH communication administratively prohibited by filtering", | ||
| 32 | "ICMP UNREACH host precedence violation", | ||
| 33 | "ICMP UNREACH precedence cutoff in effect", | ||
| 34 | NULL | ||
| 35 | }; | ||
| 36 | |||
| 37 | static char * icmp_quench[] = { | ||
| 38 | "ICMP QUENCH", | ||
| 39 | NULL | ||
| 40 | }; | ||
| 41 | |||
| 42 | static char * icmp_redirect[] = { | ||
| 43 | "ICMP REDIRECT Redirect datagrams for the Network", | ||
| 44 | "ICMP REDIRECT Redirect datagrams for the Host", | ||
| 45 | "ICMP REDIRECT Redirect datagrams for the Type of Service and Network", | ||
| 46 | "ICMP REDIRECT Redirect datagrams for the Type of Service and Host", | ||
| 47 | NULL | ||
| 48 | }; | ||
| 49 | |||
| 50 | static char * icmp_alternate[] = { | ||
| 51 | "ICMP ALTERNATEHOSTADDRESS", | ||
| 52 | NULL | ||
| 53 | }; | ||
| 54 | |||
| 55 | static char * icmp_echo[] = { | ||
| 56 | "ICMP ECHO", | ||
| 57 | NULL | ||
| 58 | }; | ||
| 59 | |||
| 60 | static char * icmp_routerad[] = { | ||
| 61 | "ICMP ROUTERADVERTISEMENT", | ||
| 62 | NULL | ||
| 63 | }; | ||
| 64 | |||
| 65 | static char * icmp_routersel[] = { | ||
| 66 | "ICMP ROUTERSELECTION", | ||
| 67 | NULL | ||
| 68 | }; | ||
| 69 | |||
| 70 | static char * icmp_timeexceed[] = { | ||
| 71 | "ICMP TIMEEXCEED time to live exceeded in transit", | ||
| 72 | "ICMP TIMEEXCEED fragment reassembly time exceeded", | ||
| 73 | NULL | ||
| 74 | }; | ||
| 75 | |||
| 76 | static char * icmp_parprob[] = { | ||
| 77 | "ICMP PARAMETER pointer indicates the error", | ||
| 78 | "ICMP PARAMETER missing a required option", | ||
| 79 | "ICMP PARAMETER bad length", | ||
| 80 | NULL | ||
| 81 | }; | ||
| 82 | |||
| 83 | static char * icmp_timestamp[] = { | ||
| 84 | "ICMP TIMESTAMP", | ||
| 85 | NULL | ||
| 86 | }; | ||
| 87 | |||
| 88 | static char * icmp_timestamp_reply[] = { | ||
| 89 | "ICMP TIMESTAMPREPLY", | ||
| 90 | NULL | ||
| 91 | }; | ||
| 92 | |||
| 93 | static char * icmp_information[] = { | ||
| 94 | "ICMP INFORMATION", | ||
| 95 | NULL | ||
| 96 | }; | ||
| 97 | |||
| 98 | static char * icmp_information_reply[] = { | ||
| 99 | "ICMP INFORMATIONREPLY", | ||
| 100 | NULL | ||
| 101 | }; | ||
| 102 | |||
| 103 | static char * icmp_addressmask[] = { | ||
| 104 | "ICMP ADDRESSMASK", | ||
| 105 | NULL | ||
| 106 | }; | ||
| 107 | |||
| 108 | static char * icmp_addressmask_reply[] = { | ||
| 109 | "ICMP ADDRESSMASKREPLY", | ||
| 110 | NULL | ||
| 111 | }; | ||
| 112 | |||
| 113 | static char * icmp_ERR[] = { | ||
| 114 | "ICMP invalid code", | ||
| 115 | NULL | ||
| 116 | }; | ||
| 117 | |||
| 118 | struct icmp_typeelem { | ||
| 119 | int count; | ||
| 120 | char ** tab; | ||
| 121 | }; | ||
| 122 | |||
| 123 | struct icmp_typeelem icmp_tab[] = { | ||
| 124 | { 1, icmp_echo_reply }, /* 0 Echo Reply */ | ||
| 125 | { 0, icmp_ERR }, /* 1 UNUSED */ | ||
| 126 | { 0, icmp_ERR }, /* 2 UNUSED */ | ||
| 127 | { 16, icmp_unreach }, /* 3 Destination Unreachable */ | ||
| 128 | { 1, icmp_quench }, /* 4 Source Quench */ | ||
| 129 | { 4, icmp_redirect }, /* 5 Redirect */ | ||
| 130 | { 1, icmp_alternate }, /* 6 Alternate Host Address */ | ||
| 131 | { 0, icmp_ERR }, /* 7 UNUSED */ | ||
| 132 | { 1, icmp_echo }, /* 8 Echo */ | ||
| 133 | { 1, icmp_routerad }, /* 9 Router Advertisement */ | ||
| 134 | { 1, icmp_routersel }, /* 10 Router Selection */ | ||
| 135 | { 2, icmp_timeexceed }, /* 11 Time Exceeded */ | ||
| 136 | { 3, icmp_parprob }, /* 12 Parameter Problem */ | ||
| 137 | { 1, icmp_timestamp }, /* 13 Timestamp */ | ||
| 138 | { 1, icmp_timestamp_reply }, /* 14 Timestamp Reply */ | ||
| 139 | { 1, icmp_information }, /* 15 Information Request */ | ||
| 140 | { 1, icmp_information_reply }, /* 16 Information Request */ | ||
| 141 | { 1, icmp_addressmask }, /* 17 RFC950: Address Mask Request */ | ||
| 142 | { 1, icmp_addressmask_reply }, /* 18 RFC950: Address Mask Reply */ | ||
| 143 | { 0, NULL }, /* EOList */ | ||
| 144 | }; | ||
| 145 | |||
| 146 | int icmp_type_max = (sizeof (icmp_tab) / sizeof (struct icmp_typeelem)) - 1; | ||
| 147 | |||
| 148 | const char * | ||
| 149 | icmp_str (int type, int code) | ||
| 150 | { | ||
| 151 | struct icmp_typeelem * it; | ||
| 152 | |||
| 153 | if (type < 0 || type >= icmp_type_max) | ||
| 154 | return ("ICMP invalid type"); | ||
| 155 | |||
| 156 | it = &icmp_tab[type]; | ||
| 157 | if (it->count == 0) | ||
| 158 | return (it->tab[0]); | ||
| 159 | |||
| 160 | if (code < 0 || code >= it->count) | ||
| 161 | return ("ICMP invalid code"); | ||
| 162 | |||
| 163 | return (it->tab[code]); | ||
| 164 | } | ||
| 165 | |||
| 166 | |||
diff --git a/other/b-scan/tmp/src/garage.c b/other/b-scan/tmp/src/garage.c new file mode 100644 index 0000000..4beba2d --- /dev/null +++ b/other/b-scan/tmp/src/garage.c | |||
| @@ -0,0 +1,508 @@ | |||
| 1 | /* bscan - garage.c - per IP storage functions | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | * by skyper / teso | ||
| 5 | * | ||
| 6 | * this module implements a per-IP storage method to allow other modules | ||
| 7 | * to store state information about hosts (ie for TCP fingerprinting or | ||
| 8 | * stateful protocols). | ||
| 9 | * | ||
| 10 | * 2000/12/31 version 1.0.1 - scut | ||
| 11 | * - added CIDR helper functions | ||
| 12 | * - added mg_cidr_getmask function to convert CIDR/netmask | ||
| 13 | * notation | ||
| 14 | * - added mg_cidr_maskcount to count max possible hosts in a mask | ||
| 15 | * - added mg_cidr_count function to count hosts in garage that | ||
| 16 | * match a mask | ||
| 17 | * - added ip based counter to the garage structure, this costs | ||
| 18 | * only few cycles when working with elements, but repays for | ||
| 19 | * the mg_count and some of the mg_cidr_* functions | ||
| 20 | * - changed mg_count to take advantage of the garage counter | ||
| 21 | * - added mg_cidr_match function | ||
| 22 | * - workaround for some size-dependant misoptimizations of gcc | ||
| 23 | * | ||
| 24 | * 2000/12/31 version 1.0.0 - scut | ||
| 25 | * - support for storage, retrieval and max-keep counter | ||
| 26 | * with automatic deallocation | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <sys/types.h> | ||
| 30 | #include <stdio.h> | ||
| 31 | #include <stdlib.h> | ||
| 32 | #include <string.h> | ||
| 33 | #include <bscan/garage.h> | ||
| 34 | |||
| 35 | |||
| 36 | /* memory layout: | ||
| 37 | * | ||
| 38 | * each per-ip data is stored in a linked list element. the linked list | ||
| 39 | * can (theoretically) contain up to 2^16 elements, if the entire IP space | ||
| 40 | * is scanned at once. | ||
| 41 | * | ||
| 42 | * up to 2^16 of this linked lists can exist, hence 2^16*2^16 = 2^32 = whole | ||
| 43 | * IPv4 space. to access the correct linked list we calculate a hash value, | ||
| 44 | * to directly read from a one dimensional table of linked list root pointers. | ||
| 45 | * | ||
| 46 | * unsigned long int ip; | ||
| 47 | * | ||
| 48 | * h = ((ip >> 16) + ip) 0xffff) | ||
| 49 | * | ||
| 50 | * the linked list indexed by this two hash values is sorted in ascending | ||
| 51 | * order by the IP as unsigned long int. | ||
| 52 | */ | ||
| 53 | |||
| 54 | #define MG_H(ip) ((((ip) >> 16) + (ip)) & 0xffff) | ||
| 55 | |||
| 56 | |||
| 57 | #ifdef DEBUG | ||
| 58 | unsigned long long int tackall = 0; | ||
| 59 | unsigned long long int tackc = 0; | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #if 0 | ||
| 63 | /* unused code | ||
| 64 | */ | ||
| 65 | static unsigned long int | ||
| 66 | mg_count_slot (ip_list *list); | ||
| 67 | #endif | ||
| 68 | |||
| 69 | |||
| 70 | /* XXX/FIXME/TODO: shouldn't be here | ||
| 71 | */ | ||
| 72 | void * | ||
| 73 | xcalloc (unsigned int factor, unsigned int size) | ||
| 74 | { | ||
| 75 | void * foo = calloc (factor, size); | ||
| 76 | |||
| 77 | if (foo == NULL) { | ||
| 78 | perror ("xcalloc"); | ||
| 79 | |||
| 80 | exit (EXIT_FAILURE); | ||
| 81 | } | ||
| 82 | |||
| 83 | return (foo); | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | /* destroy the ip_list element given in `slot' | ||
| 88 | */ | ||
| 89 | static void | ||
| 90 | mg_destroy_slot (garage_hdlr *g, ip_list *slot, void (* cleaner)(ip_list *)); | ||
| 91 | |||
| 92 | |||
| 93 | garage_hdlr * | ||
| 94 | mg_init (char *name, unsigned long int max_hosts_in_list, | ||
| 95 | void (* cleaner)(ip_list *)) | ||
| 96 | { | ||
| 97 | garage_hdlr * new = xcalloc (1, sizeof (garage_hdlr)); | ||
| 98 | |||
| 99 | new->name = name; | ||
| 100 | new->garage = xcalloc (256 * 256, sizeof (ip_list *)); | ||
| 101 | new->cleaner = cleaner; | ||
| 102 | new->ip_count = 0; | ||
| 103 | |||
| 104 | if (max_hosts_in_list == 0) { | ||
| 105 | new->timeout_tbl = NULL; | ||
| 106 | new->timeout_max = 0; | ||
| 107 | new->timeout_idx = 0; | ||
| 108 | } else { | ||
| 109 | new->timeout_tbl = xcalloc (max_hosts_in_list, | ||
| 110 | sizeof (unsigned long int)); | ||
| 111 | new->timeout_max = max_hosts_in_list; | ||
| 112 | new->timeout_idx = 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | memset (new->garage, '\x00', 256 * 256 * sizeof (ip_list *)); | ||
| 116 | if (new->timeout_tbl != NULL) | ||
| 117 | memset (new->timeout_tbl, '\x00', max_hosts_in_list * | ||
| 118 | sizeof (unsigned long int)); | ||
| 119 | |||
| 120 | return (new); | ||
| 121 | } | ||
| 122 | |||
| 123 | |||
| 124 | void | ||
| 125 | mg_destroy (garage_hdlr *g, int do_handler) | ||
| 126 | { | ||
| 127 | int h; | ||
| 128 | |||
| 129 | |||
| 130 | #ifdef DEBUG | ||
| 131 | printf ("tackcount = %Lu\n", tackc); | ||
| 132 | printf ("tackall = %Lu\n", tackall); | ||
| 133 | printf ("tackmedian = %2.3f\n", (float) ((float) tackall / (float) tackc)); | ||
| 134 | #endif | ||
| 135 | |||
| 136 | for (h = 0 ; h < (256 * 256) ; ++h) { | ||
| 137 | if (g->garage[h] != NULL) { | ||
| 138 | /* the IP list structure for the IP will be free'd | ||
| 139 | * by mg_clean, too, so we don't have to do that | ||
| 140 | * manually | ||
| 141 | */ | ||
| 142 | mg_destroy_slot (g, g->garage[h], (do_handler == 0) ? | ||
| 143 | NULL : g->cleaner); | ||
| 144 | g->garage[h] = NULL; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | free (g->garage); | ||
| 149 | if (g->timeout_tbl == NULL) | ||
| 150 | free (g->timeout_tbl); | ||
| 151 | |||
| 152 | /* g->name is not to be free'd */ | ||
| 153 | |||
| 154 | free (g); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | static void | ||
| 159 | mg_destroy_slot (garage_hdlr *g, ip_list *slot, void (* cleaner)(ip_list *)) | ||
| 160 | { | ||
| 161 | ip_list * next; | ||
| 162 | |||
| 163 | do { | ||
| 164 | next = slot->next; | ||
| 165 | mg_clean (g, slot->ip, cleaner); | ||
| 166 | slot = next; | ||
| 167 | } while (slot != NULL); | ||
| 168 | |||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 172 | |||
| 173 | void | ||
| 174 | mg_write (garage_hdlr *g, unsigned long int ip, void *data, size_t data_len, | ||
| 175 | int data_free) | ||
| 176 | { | ||
| 177 | ip_list * il; | ||
| 178 | ip_elem * new = xcalloc (1, sizeof (ip_elem)); | ||
| 179 | |||
| 180 | |||
| 181 | new->next = NULL; | ||
| 182 | new->data_free = data_free; | ||
| 183 | new->data_len = data_len; | ||
| 184 | new->data = data; | ||
| 185 | |||
| 186 | |||
| 187 | il = g->garage[MG_H (ip)]; | ||
| 188 | if (il == NULL) { | ||
| 189 | il = xcalloc (1, sizeof (ip_list)); | ||
| 190 | il->next = NULL; | ||
| 191 | il->ip = ip; | ||
| 192 | il->data = new; | ||
| 193 | |||
| 194 | g->garage[MG_H (ip)] = il; | ||
| 195 | g->ip_count += 1; | ||
| 196 | } else { | ||
| 197 | ip_list ** cw = &g->garage[MG_H (ip)]; | ||
| 198 | |||
| 199 | while (il != NULL && ip > il->ip) { | ||
| 200 | cw = &il->next; | ||
| 201 | il = il->next; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (il != NULL && ip == il->ip) { | ||
| 205 | new->next = il->data; | ||
| 206 | il->data = new; | ||
| 207 | } else { | ||
| 208 | ip_list * il_tmp = xcalloc (1, sizeof (ip_list)); | ||
| 209 | |||
| 210 | il_tmp->next = il; | ||
| 211 | *cw = il_tmp; | ||
| 212 | il = il_tmp; | ||
| 213 | |||
| 214 | il->ip = ip; | ||
| 215 | il->data = new; | ||
| 216 | |||
| 217 | g->ip_count += 1; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | if (g->timeout_tbl != NULL) { | ||
| 222 | #ifdef DEBUG | ||
| 223 | printf ("tbl = 0x%08lx tbl_idx = %5lu tbl_max = %5lu tbl_count = %8lu\n", | ||
| 224 | (unsigned long int) g->timeout_tbl, | ||
| 225 | (unsigned long int) g->timeout_idx, | ||
| 226 | (unsigned long int) g->timeout_max, | ||
| 227 | (unsigned long int) mg_count (g)); | ||
| 228 | printf ("g->timeout_tbl[g->timeout_idx] = %lu\n", g->timeout_tbl[g->timeout_idx]); | ||
| 229 | printf ("condition = %s\n", (g->timeout_tbl[g->timeout_idx] != 0) ? "true" : "false"); | ||
| 230 | #endif | ||
| 231 | |||
| 232 | if (g->timeout_tbl[g->timeout_idx] != 0) | ||
| 233 | mg_clean (g, g->timeout_tbl[g->timeout_idx], NULL); | ||
| 234 | |||
| 235 | g->timeout_tbl[g->timeout_idx] = il->ip; | ||
| 236 | #ifdef DEBUG | ||
| 237 | printf ("g->timeout_idx = %5ld g->timeout_max = %5ld\n\n", | ||
| 238 | g->timeout_idx, g->timeout_max); | ||
| 239 | #endif | ||
| 240 | g->timeout_idx = (g->timeout_idx + 1) % g->timeout_max; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | |||
| 245 | ip_elem * | ||
| 246 | mg_read (garage_hdlr *g, unsigned long int ip) | ||
| 247 | { | ||
| 248 | #ifdef DEBUG | ||
| 249 | int tackcount = 0; | ||
| 250 | #endif | ||
| 251 | ip_list * il = g->garage[MG_H (ip)]; | ||
| 252 | |||
| 253 | /* no list for this hash value -> no IP stored | ||
| 254 | */ | ||
| 255 | if (il == NULL) | ||
| 256 | return (NULL); | ||
| 257 | |||
| 258 | /* walk the list | ||
| 259 | */ | ||
| 260 | do { | ||
| 261 | if (il->ip == ip) | ||
| 262 | #ifdef DEBUG | ||
| 263 | { | ||
| 264 | printf ("tackcount = %d\n", tackcount); | ||
| 265 | tackall += tackcount; | ||
| 266 | tackc += 1; | ||
| 267 | #endif | ||
| 268 | return (il->data); | ||
| 269 | #ifdef DEBUG | ||
| 270 | } else { | ||
| 271 | tackcount += 1; | ||
| 272 | } | ||
| 273 | #endif | ||
| 274 | |||
| 275 | il = il->next; | ||
| 276 | |||
| 277 | } while (il != NULL && il->ip <= ip); | ||
| 278 | |||
| 279 | return (NULL); | ||
| 280 | } | ||
| 281 | |||
| 282 | |||
| 283 | void | ||
| 284 | mg_clean (garage_hdlr *g, unsigned long int ip, void (* cleaner)(ip_list *)) | ||
| 285 | { | ||
| 286 | ip_elem * iel; | ||
| 287 | ip_elem * iel_tmp; | ||
| 288 | |||
| 289 | ip_list ** cw = &g->garage[MG_H (ip)]; | ||
| 290 | ip_list * il; | ||
| 291 | |||
| 292 | |||
| 293 | il = *cw; | ||
| 294 | |||
| 295 | /* walk the list | ||
| 296 | */ | ||
| 297 | while (il != NULL && il->ip < ip) { | ||
| 298 | cw = &il->next; | ||
| 299 | il = il->next; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (il == NULL || il->ip != ip) | ||
| 303 | return; | ||
| 304 | |||
| 305 | *cw = il->next; | ||
| 306 | |||
| 307 | /* if a cleaner has been given, or there is a default cleaner in the | ||
| 308 | * garage, then run it | ||
| 309 | */ | ||
| 310 | if (cleaner != NULL) { | ||
| 311 | cleaner (il); | ||
| 312 | } else if (g->cleaner != NULL) { | ||
| 313 | g->cleaner (il); | ||
| 314 | } | ||
| 315 | |||
| 316 | iel = il->data; | ||
| 317 | while (iel != NULL) { | ||
| 318 | iel_tmp = iel; | ||
| 319 | if (iel->data_free) | ||
| 320 | free (iel->data); | ||
| 321 | |||
| 322 | iel = iel->next; | ||
| 323 | free (iel_tmp); | ||
| 324 | } | ||
| 325 | |||
| 326 | g->ip_count -= 1; | ||
| 327 | |||
| 328 | free (il); | ||
| 329 | |||
| 330 | return; | ||
| 331 | } | ||
| 332 | |||
| 333 | |||
| 334 | void | ||
| 335 | mg_show (garage_hdlr *g) | ||
| 336 | { | ||
| 337 | int h1, h2; | ||
| 338 | int count; | ||
| 339 | |||
| 340 | char display[] = ".123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
| 341 | |||
| 342 | printf ("=== garage = %s === elements in garage = %lu\n", g->name, mg_count (g)); | ||
| 343 | printf ("0_________0_________0_________0_________0_________0_________0_________\n"); | ||
| 344 | |||
| 345 | for (h1 = 0 ; h1 < 256 ; ++h1) { | ||
| 346 | count = 0; | ||
| 347 | for (h2 = 0 ; h2 < 256 ; ++h2) { | ||
| 348 | if (g->garage[h1 * 256 + h2] != NULL) | ||
| 349 | count += 1; | ||
| 350 | } | ||
| 351 | |||
| 352 | printf ("%c", count >= (sizeof (display) - 1) ? '>' : display[count]); | ||
| 353 | if ((h1 + 1) % 70 == 0) { | ||
| 354 | printf ("\n"); | ||
| 355 | printf ("0_________0_________0_________0_________0_________0_________0_________\n"); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | printf ("\n"); | ||
| 359 | |||
| 360 | } | ||
| 361 | |||
| 362 | |||
| 363 | unsigned long int | ||
| 364 | mg_count (garage_hdlr *g) | ||
| 365 | { | ||
| 366 | return (g->ip_count); | ||
| 367 | } | ||
| 368 | |||
| 369 | |||
| 370 | #if 0 | ||
| 371 | /* unused code | ||
| 372 | */ | ||
| 373 | static unsigned long int | ||
| 374 | mg_count_slot (ip_list *list) | ||
| 375 | { | ||
| 376 | unsigned long int count = 0; | ||
| 377 | |||
| 378 | do { | ||
| 379 | count += 1; | ||
| 380 | list = list->next; | ||
| 381 | } while (list != NULL); | ||
| 382 | |||
| 383 | return (count); | ||
| 384 | } | ||
| 385 | #endif | ||
| 386 | |||
| 387 | |||
| 388 | int | ||
| 389 | mg_ip_isin (garage_hdlr *g, unsigned long int ip) | ||
| 390 | { | ||
| 391 | ip_list * il = g->garage[MG_H (ip)]; | ||
| 392 | |||
| 393 | if (il == NULL) | ||
| 394 | return (0); | ||
| 395 | |||
| 396 | while (il != NULL && ip < il->ip) { | ||
| 397 | il = il->next; | ||
| 398 | } | ||
| 399 | |||
| 400 | if (il != NULL && ip == il->ip) | ||
| 401 | return (1); | ||
| 402 | |||
| 403 | return (0); | ||
| 404 | } | ||
| 405 | |||
| 406 | |||
| 407 | |||
| 408 | /* CIDR routines | ||
| 409 | * | ||
| 410 | * XXX: maybe move some basic CIDR routines to an extra file for maintance | ||
| 411 | * XXX: beta code, please test | ||
| 412 | */ | ||
| 413 | |||
| 414 | unsigned long int | ||
| 415 | mg_cidr_getmask (unsigned long int mask) | ||
| 416 | { | ||
| 417 | /* work around to dumb gcc 'optimizations' (ie compiler bug) | ||
| 418 | */ | ||
| 419 | if (mask == 0) | ||
| 420 | return (0); | ||
| 421 | |||
| 422 | if (mask > 32) { | ||
| 423 | return (mask); | ||
| 424 | } else { | ||
| 425 | unsigned long int nm = 0xffffffff; | ||
| 426 | |||
| 427 | /* clear zero bits | ||
| 428 | */ | ||
| 429 | mask = 32 - mask; | ||
| 430 | nm >>= mask; | ||
| 431 | nm <<= mask; | ||
| 432 | |||
| 433 | return (nm); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | |||
| 438 | unsigned long int | ||
| 439 | mg_cidr_maskcount (unsigned long int mask) | ||
| 440 | { | ||
| 441 | return ((~mg_cidr_getmask (mask)) + 1); | ||
| 442 | } | ||
| 443 | |||
| 444 | |||
| 445 | int | ||
| 446 | mg_cidr_match (unsigned long int ip1, unsigned long int ip2, | ||
| 447 | unsigned long int mask) | ||
| 448 | { | ||
| 449 | mask = mg_cidr_getmask (mask); | ||
| 450 | ip1 &= mask; | ||
| 451 | ip2 &= mask; | ||
| 452 | |||
| 453 | return (ip1 == ip2); | ||
| 454 | } | ||
| 455 | |||
| 456 | |||
| 457 | unsigned long int | ||
| 458 | mg_cidr_count (garage_hdlr *g, unsigned long int ip, unsigned long int mask) | ||
| 459 | { | ||
| 460 | unsigned long int count = 0; | ||
| 461 | unsigned long int ip_start, | ||
| 462 | ip_end; | ||
| 463 | |||
| 464 | |||
| 465 | ip_start = ip & mg_cidr_getmask (mask); | ||
| 466 | ip_end = ip_start + mg_cidr_maskcount (mask); | ||
| 467 | |||
| 468 | /* workaround for /0 cidr mask (if sizeof (unsigned long int) == 4) | ||
| 469 | * it will make ip_end = 0, so we have to catch this case) | ||
| 470 | */ | ||
| 471 | if (ip_end == 0) | ||
| 472 | return (mg_count (g)); | ||
| 473 | |||
| 474 | if ((ip_end - ip_start) >= mg_count (g)) { | ||
| 475 | /* since there are less elements then the ip range contains, | ||
| 476 | * we go for a count-matching-elements-by-scanning-through- | ||
| 477 | * the-entire-array like technique | ||
| 478 | */ | ||
| 479 | unsigned long int h; | ||
| 480 | ip_list * il; | ||
| 481 | |||
| 482 | for (h = 0 ; h < (256 * 256) ; ++h) { | ||
| 483 | if (g->garage[h] != NULL) { | ||
| 484 | il = g->garage[h]; | ||
| 485 | |||
| 486 | do { | ||
| 487 | if (mg_cidr_match (il->ip, ip, mask)) | ||
| 488 | count += 1; | ||
| 489 | |||
| 490 | il = il->next; | ||
| 491 | } while (il != NULL); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | } else { | ||
| 495 | /* there are more elements in the garage then this range | ||
| 496 | * contains, so scam this range only | ||
| 497 | */ | ||
| 498 | do { | ||
| 499 | count += mg_ip_isin (g, ip_start); | ||
| 500 | |||
| 501 | ip_start += 1; | ||
| 502 | } while (ip_start < ip_end); | ||
| 503 | } | ||
| 504 | |||
| 505 | return (count); | ||
| 506 | } | ||
| 507 | |||
| 508 | |||
diff --git a/other/b-scan/tmp/src/module.c b/other/b-scan/tmp/src/module.c new file mode 100644 index 0000000..1748914 --- /dev/null +++ b/other/b-scan/tmp/src/module.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <dlfcn.h> | ||
| 4 | #include <string.h> | ||
| 5 | #include <bscan/module.h> | ||
| 6 | #include <bscan/system.h> | ||
| 7 | |||
| 8 | struct _mods mods[MAX_MODULES]; | ||
| 9 | /* modstructures not initialized */ | ||
| 10 | int modcount = -1; | ||
| 11 | |||
| 12 | /* | ||
| 13 | #ifdef HAVE_DLSYM | ||
| 14 | #define MAKE_DLSYM(x, y) mods[modcount].##x = dlsym(handle, ##y);\ | ||
| 15 | if ((error = dlerror()) != NULL) {\ | ||
| 16 | fprintf(stderr, ##y":%s\n", error); return(1); } | ||
| 17 | #endif | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* I think this is more correct, and also gets rid of some compile warnings. | ||
| 21 | * hope this doesn't break anything. -typo */ | ||
| 22 | #ifdef HAVE_DLSYM | ||
| 23 | #define MAKE_DLSYM(x, y) mods[modcount].x = dlsym(handle, y);\ | ||
| 24 | if ((error = dlerror()) != NULL) {\ | ||
| 25 | fprintf(stderr, y":%s\n", error); return(1); } | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* SunOS 4.1.3 support */ | ||
| 29 | #ifndef RTLD_NOW | ||
| 30 | #define RTLD_NOW 0x00001 | ||
| 31 | #endif | ||
| 32 | /* OpenBSD support */ | ||
| 33 | #ifndef RTLD_GLOBAL | ||
| 34 | #define RTLD_GLOBAL 0x00000 | ||
| 35 | #endif | ||
| 36 | |||
| 37 | /* we really hate theo for this shit of dl* work */ | ||
| 38 | #if defined(__OpenBSD__) | ||
| 39 | # if !(defined(__mips) || defined(__powerpc)) | ||
| 40 | # define DLSYM_AOUT 1 | ||
| 41 | # else | ||
| 42 | # define DLSYM_AOUT 0 | ||
| 43 | # endif | ||
| 44 | #endif | ||
| 45 | #if DLSYM_AOUT == 1 | ||
| 46 | # define DLSYM_UNDERSCORE "_" | ||
| 47 | #else | ||
| 48 | # define DLSYM_UNDERSCORE /**/ | ||
| 49 | #endif | ||
| 50 | |||
| 51 | |||
| 52 | /* | ||
| 53 | * init the module structures. NOT the modules! | ||
| 54 | */ | ||
| 55 | void | ||
| 56 | init_modules () | ||
| 57 | { | ||
| 58 | int c = 0; | ||
| 59 | |||
| 60 | while (c < MAX_MODULES) | ||
| 61 | { | ||
| 62 | mods[c].init = NULL; | ||
| 63 | mods[c].fini = NULL; | ||
| 64 | mods[c].musage = NULL; | ||
| 65 | mods[c].modname = NULL; | ||
| 66 | mods[c].modid = 0; | ||
| 67 | mods[c].modarg = NULL; | ||
| 68 | mods[c++].callmdl = NULL; | ||
| 69 | } | ||
| 70 | modcount = 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | /* | ||
| 75 | * Load a module | ||
| 76 | * Return 0 on success, != 0 on error [no space left, EACCESS, ...] | ||
| 77 | */ | ||
| 78 | int | ||
| 79 | add_module (char *fname, char *modarg) | ||
| 80 | { | ||
| 81 | #ifdef HAVE_DLSYM | ||
| 82 | void *handle; | ||
| 83 | char *error; | ||
| 84 | |||
| 85 | if (modcount == -1) | ||
| 86 | init_modules (); | ||
| 87 | |||
| 88 | if (modcount >= MAX_MODULES) | ||
| 89 | return (2); /* array to small! */ | ||
| 90 | |||
| 91 | handle = dlopen (fname, RTLD_NOW | RTLD_GLOBAL); | ||
| 92 | |||
| 93 | if ((error = dlerror ()) != NULL) | ||
| 94 | { | ||
| 95 | fprintf (stderr, "%s\n", error); | ||
| 96 | return (1); | ||
| 97 | } | ||
| 98 | |||
| 99 | MAKE_DLSYM (init, DLSYM_UNDERSCORE"init"); | ||
| 100 | MAKE_DLSYM (fini, DLSYM_UNDERSCORE"fini"); | ||
| 101 | MAKE_DLSYM (musage, DLSYM_UNDERSCORE"musage"); | ||
| 102 | MAKE_DLSYM (callmdl, DLSYM_UNDERSCORE"callmdl"); | ||
| 103 | |||
| 104 | mods[modcount].modid = modcount; | ||
| 105 | mods[modcount].modarg = modarg; /* not encoded arg */ | ||
| 106 | |||
| 107 | modcount++; | ||
| 108 | |||
| 109 | #endif | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* | ||
| 114 | * split a 'space seperated string' into many arguements | ||
| 115 | * decode esc-sequences | ||
| 116 | */ | ||
| 117 | void | ||
| 118 | split_margs (const char *moptarg, char ***margvp, int *margcp) | ||
| 119 | { | ||
| 120 | char *ptr, *opt; | ||
| 121 | int off; | ||
| 122 | char ch, ch2; | ||
| 123 | |||
| 124 | if (margcp == NULL) | ||
| 125 | return; | ||
| 126 | |||
| 127 | if (margvp == NULL) | ||
| 128 | return; | ||
| 129 | |||
| 130 | if (moptarg == NULL) | ||
| 131 | return; | ||
| 132 | |||
| 133 | moptarg = strdup(moptarg); | ||
| 134 | |||
| 135 | /* | ||
| 136 | * convert " modname -a arg1 -b arg2" to | ||
| 137 | * "modname -a arg1 -b arg2" | ||
| 138 | */ | ||
| 139 | opt = (char *) calloc (1, strlen (moptarg) + 1); | ||
| 140 | off = 0; | ||
| 141 | ch2 = ' '; | ||
| 142 | ptr = (char *) moptarg; | ||
| 143 | while ((ch = *ptr++) != '\0') | ||
| 144 | { | ||
| 145 | if ((ch == ' ') && (ch2 == ' ')) | ||
| 146 | continue; | ||
| 147 | opt[off++] = ch; | ||
| 148 | ch2 = ch; | ||
| 149 | } | ||
| 150 | if (ch2 == ' ') | ||
| 151 | opt[off - 1] = '\0'; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * split argument-string into char *argv[] array | ||
| 155 | */ | ||
| 156 | *margcp = 0; | ||
| 157 | while ((ptr = strchr (opt, ' ')) != NULL) | ||
| 158 | { | ||
| 159 | *ptr++ = '\0'; | ||
| 160 | |||
| 161 | (*margvp) = realloc (*margvp, ((*margcp) + 1) * sizeof (char *)); | ||
| 162 | |||
| 163 | ctoreal(opt, opt); /* decode esc-sequences */ | ||
| 164 | *(*margvp + *margcp) = opt; | ||
| 165 | (*margcp)++; | ||
| 166 | opt = ptr; | ||
| 167 | } | ||
| 168 | (*margvp) = realloc (*margvp, ((*margcp) + 2) * sizeof (char *)); | ||
| 169 | ctoreal(opt, opt); | ||
| 170 | *(*margvp + (*margcp)++) = opt; | ||
| 171 | *(*margvp + (*margcp)) = NULL; /* terminate the array */ | ||
| 172 | |||
| 173 | } | ||
| 174 | |||
| 175 | /* | ||
| 176 | * load and init the module. | ||
| 177 | * this function can exit | ||
| 178 | * return 0 on success | ||
| 179 | */ | ||
| 180 | int | ||
| 181 | loadinit_mod(char *optar) | ||
| 182 | { | ||
| 183 | char **margv = NULL; | ||
| 184 | int margc = 0; | ||
| 185 | extern int optind; | ||
| 186 | extern struct _opt *opt; | ||
| 187 | |||
| 188 | split_margs (optar, &margv, &margc); | ||
| 189 | if (add_module (margv[0], optar) == 0) | ||
| 190 | { | ||
| 191 | int oldoptind = optind; | ||
| 192 | int m = modcount - 1; | ||
| 193 | optind = 1; | ||
| 194 | |||
| 195 | if (mods[m].init ((char **) &mods[m].modname, margc, margv, opt) != 0) | ||
| 196 | { | ||
| 197 | fprintf (stderr, "- [%d]: '%s' init FAILED\n", | ||
| 198 | mods[m].modid, margv[0]); | ||
| 199 | mods[m].musage (); | ||
| 200 | exit (-1); | ||
| 201 | } else | ||
| 202 | fprintf (stderr, "+ [%d]: '%s' initialized\n", | ||
| 203 | mods[m].modid, mods[m].modname); | ||
| 204 | optind = oldoptind; /* restore old optind value */ | ||
| 205 | } else | ||
| 206 | { | ||
| 207 | fprintf (stderr, "+ [-]; '%s' failed\n", optar); | ||
| 208 | exit (-1); | ||
| 209 | } | ||
| 210 | |||
| 211 | return(0); | ||
| 212 | } | ||
| 213 | |||
| 214 | |||
diff --git a/other/b-scan/tmp/src/network_raw.c b/other/b-scan/tmp/src/network_raw.c new file mode 100644 index 0000000..1b87eaa --- /dev/null +++ b/other/b-scan/tmp/src/network_raw.c | |||
| @@ -0,0 +1,497 @@ | |||
| 1 | /* | ||
| 2 | * raw network routines | ||
| 3 | * libnet based (not yet ..but maybe in the future :> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <stdarg.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <sys/types.h> | ||
| 10 | #include <sys/socket.h> | ||
| 11 | #include <sys/wait.h> | ||
| 12 | #ifndef __FAVOR_BSD | ||
| 13 | #define __FAVOR_BSD | ||
| 14 | #endif | ||
| 15 | #ifndef __USE_BSD | ||
| 16 | #define __USE_BSD | ||
| 17 | #endif | ||
| 18 | #ifndef __BSD_SOURCE | ||
| 19 | #define __BSD_SOURCE | ||
| 20 | #endif | ||
| 21 | #include <libnet.h> | ||
| 22 | #include <bscan/network_raw.h> | ||
| 23 | |||
| 24 | static int netraw_lrand = 0; | ||
| 25 | #define LAME_RANDOM (netraw_lrand = (netraw_lrand + (netraw_lrand>>1))) | ||
| 26 | |||
| 27 | /* | ||
| 28 | * init all the network_raw stuff | ||
| 29 | * return 0 on success, -1 on error | ||
| 30 | */ | ||
| 31 | int | ||
| 32 | init_network_raw () | ||
| 33 | { | ||
| 34 | /* seeded by init_vars/bscan.c */ | ||
| 35 | netraw_lrand = 1 + (int) (65335.0 * rand () / (RAND_MAX + 1.0)); | ||
| 36 | return (0); | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | ||
| 40 | * calc. checksum WITH carry flag. | ||
| 41 | * call cksum = CKSUM_CARRY(sum); | ||
| 42 | * we calculate only the initial checksum here. | ||
| 43 | * we can use the result for all further packets | ||
| 44 | */ | ||
| 45 | int | ||
| 46 | in_cksum (unsigned short *addr, int len) | ||
| 47 | { | ||
| 48 | int nleft = len; | ||
| 49 | int sum = 0; | ||
| 50 | u_short *w = addr; | ||
| 51 | u_short answer = 0; | ||
| 52 | |||
| 53 | while (nleft > 1) | ||
| 54 | { | ||
| 55 | sum += *w++; | ||
| 56 | nleft -= 2; | ||
| 57 | } | ||
| 58 | |||
| 59 | if (nleft == 1) /* padding */ | ||
| 60 | { | ||
| 61 | *(u_char *) (&answer) = *(u_char *) w; | ||
| 62 | sum += answer; | ||
| 63 | } | ||
| 64 | |||
| 65 | return (sum); | ||
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | /* | ||
| 70 | * add ICMP_ECHO or ICMP_TSTAMP | ||
| 71 | * len = len of payload | ||
| 72 | * add ICMP-header to pkt | ||
| 73 | */ | ||
| 74 | void | ||
| 75 | add_icmpping (unsigned char *pkt, int len, int which) | ||
| 76 | { | ||
| 77 | struct icmp *icmp = (struct icmp *) pkt; | ||
| 78 | int sum; | ||
| 79 | struct timeval tv; | ||
| 80 | memset (icmp, 0, sizeof (*icmp)); /* sizeof(*icmp) = 28 */ | ||
| 81 | |||
| 82 | if (which == ICMP_ECHO) | ||
| 83 | { | ||
| 84 | icmp->icmp_type = ICMP_ECHO; | ||
| 85 | } | ||
| 86 | else if (which == ICMP_TSTAMP) | ||
| 87 | { | ||
| 88 | if (len < 13) | ||
| 89 | printf ("packet too small for timestamp request, lets blast the packets out anyway\n"); | ||
| 90 | icmp->icmp_type = ICMP_TSTAMP; | ||
| 91 | } | ||
| 92 | else | ||
| 93 | printf ("Your kung-fu is bad!\n"); | ||
| 94 | |||
| 95 | icmp->icmp_hun.ih_idseq.icd_id = LAME_RANDOM; | ||
| 96 | gettimeofday (&tv, NULL); | ||
| 97 | memcpy (icmp->icmp_dun.id_data, &tv, sizeof (tv)); | ||
| 98 | |||
| 99 | sum = in_cksum ((u_short *) icmp, ICMP_SIZE + len); | ||
| 100 | icmp->icmp_cksum = CKSUM_CARRY (sum); | ||
| 101 | } | ||
| 102 | |||
| 103 | |||
| 104 | /* | ||
| 105 | * add udp-header [no checksum] | ||
| 106 | * len = len of payload | ||
| 107 | */ | ||
| 108 | void | ||
| 109 | add_udphdr(unsigned char *pkt, struct net_tuple *nt, int len) | ||
| 110 | { | ||
| 111 | struct udphdr udp; | ||
| 112 | |||
| 113 | memset(&udp, 0, sizeof(udp)); | ||
| 114 | udp.uh_sport = nt->sport; | ||
| 115 | udp.uh_dport = nt->dport; | ||
| 116 | udp.uh_ulen = htons(len + UDP_SIZE); | ||
| 117 | udp.uh_sum = 0; /* no checksum !*/ | ||
| 118 | memcpy(pkt, &udp, sizeof(udp)); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | /* | ||
| 123 | * len = len of payload | ||
| 124 | */ | ||
| 125 | void | ||
| 126 | add_tcphdr (unsigned char *pkt, struct net_tuple *nt, uint8_t flags, int len, | ||
| 127 | tcp_seq * seq, tcp_seq * ack) | ||
| 128 | { | ||
| 129 | struct tcphdr tcp; | ||
| 130 | struct tcphdr *tcpptr; | ||
| 131 | struct _fakehead fakehead; | ||
| 132 | int sum; | ||
| 133 | |||
| 134 | memset (&tcp, 0, sizeof (tcp)); | ||
| 135 | memset (&fakehead, 0, sizeof (fakehead)); | ||
| 136 | tcp.th_dport = nt->dport; | ||
| 137 | tcp.th_sport = nt->sport; | ||
| 138 | fakehead.saddr = nt->src; | ||
| 139 | fakehead.daddr = nt->dst; | ||
| 140 | fakehead.zero = 0; | ||
| 141 | fakehead.protocol = IPPROTO_TCP; | ||
| 142 | fakehead.tot_len = htons (TCP_SIZE + len); | ||
| 143 | sum = in_cksum ((u_short *) & fakehead, sizeof (fakehead)); | ||
| 144 | tcp.th_off = TCP_SIZE >> 2; | ||
| 145 | if (seq != NULL) | ||
| 146 | tcp.th_seq = *seq; | ||
| 147 | else | ||
| 148 | tcp.th_seq = LAME_RANDOM; | ||
| 149 | if (ack != NULL) | ||
| 150 | tcp.th_ack = *ack; | ||
| 151 | tcp.th_flags |= flags; /* ADD the flags */ | ||
| 152 | tcp.th_win = htons (0x3fff); | ||
| 153 | memcpy (pkt, &tcp, sizeof (tcp)); | ||
| 154 | sum += in_cksum ((u_short *) pkt, sizeof (tcp) + len); | ||
| 155 | tcpptr = (struct tcphdr *)pkt; | ||
| 156 | tcpptr->th_sum = CKSUM_CARRY (sum); | ||
| 157 | } | ||
| 158 | |||
| 159 | |||
| 160 | /* | ||
| 161 | * add's ipv4-header of 20 bytes without any options | ||
| 162 | * - IPPROTO_TCP and 40 bytes total length | ||
| 163 | */ | ||
| 164 | void | ||
| 165 | add_iphdr (unsigned char *pkt, uint8_t ip_p, struct net_tuple *nt, int len) | ||
| 166 | { | ||
| 167 | struct ip ip; | ||
| 168 | memset (&ip, 0, IP_SIZE); | ||
| 169 | ip.ip_hl = sizeof (ip) >> 2; | ||
| 170 | ip.ip_v = 4; | ||
| 171 | /*ip->tos = 0; */ | ||
| 172 | ip.ip_len = htons (len + IP_SIZE); /* htons ? */ | ||
| 173 | /*ip->id = 0; done by kernel */ | ||
| 174 | /*ip->frag_off = 0; */ | ||
| 175 | ip.ip_ttl = 0xff; | ||
| 176 | ip.ip_p = ip_p; | ||
| 177 | /*.ip->check = 0; done by kernel */ | ||
| 178 | ip.ip_src.s_addr = nt->src; | ||
| 179 | ip.ip_dst.s_addr = nt->dst; | ||
| 180 | memcpy (pkt, &ip, sizeof (ip)); | ||
| 181 | } | ||
| 182 | |||
| 183 | /* | ||
| 184 | * send out ipv4-packet | ||
| 185 | * with data 'pkt' of length 'len' | ||
| 186 | * returns the number of characters sent, or -1 if an error occured | ||
| 187 | */ | ||
| 188 | int | ||
| 189 | send_ipv4 (int sox, u_char * pkt, size_t len) | ||
| 190 | { | ||
| 191 | struct sockaddr_in to; | ||
| 192 | to.sin_family = AF_INET; | ||
| 193 | memcpy (&to.sin_addr.s_addr, (pkt + 4 * 4), sizeof (u_long)); | ||
| 194 | return (sendto (sox, pkt, len, 0, (struct sockaddr *) &to, sizeof (to))); | ||
| 195 | } | ||
| 196 | |||
| 197 | |||
| 198 | /* | ||
| 199 | * small/lame tcp userland stack | ||
| 200 | * give 'best' tcp-answer to a tcp-packet | ||
| 201 | * return 0 on success | ||
| 202 | * payload + len are optional | ||
| 203 | */ | ||
| 204 | int | ||
| 205 | answer_tcp (int sox, struct ip *ip, struct tcphdr *tcp, uint8_t flags, | ||
| 206 | u_char * payload, uint len) | ||
| 207 | { | ||
| 208 | static u_char *outpkt = NULL; | ||
| 209 | static int msize = 0; | ||
| 210 | struct net_tuple nt; | ||
| 211 | tcp_seq outack; | ||
| 212 | |||
| 213 | if (TCP_SIZE + IP_SIZE + len > msize) | ||
| 214 | { | ||
| 215 | outpkt = realloc (outpkt, TCP_SIZE + IP_SIZE + len); | ||
| 216 | msize = TCP_SIZE + IP_SIZE + len; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (outpkt == NULL) | ||
| 220 | return (-1); | ||
| 221 | if (ip == NULL) | ||
| 222 | return (-1); | ||
| 223 | if (tcp == NULL) | ||
| 224 | return (-1); | ||
| 225 | |||
| 226 | memset (outpkt, 0, TCP_SIZE + IP_SIZE + len); | ||
| 227 | |||
| 228 | nt.sport = tcp->th_dport; | ||
| 229 | nt.dport = tcp->th_sport; | ||
| 230 | nt.src = ip->ip_dst.s_addr; | ||
| 231 | nt.dst = ip->ip_src.s_addr; | ||
| 232 | |||
| 233 | if (payload != NULL) | ||
| 234 | memcpy (outpkt + TCP_SIZE + IP_SIZE, payload, len); | ||
| 235 | |||
| 236 | outack = ntohl (tcp->th_seq) + ntohs (ip->ip_len) - (tcp->th_off << 2) - | ||
| 237 | (ip->ip_hl << 2); | ||
| 238 | if (tcp->th_flags & (TH_SYN | TH_FIN)) | ||
| 239 | outack++; | ||
| 240 | |||
| 241 | outack = htonl (outack); | ||
| 242 | add_tcphdr (outpkt + IP_SIZE, &nt, flags, len, &tcp->th_ack, &outack); | ||
| 243 | |||
| 244 | add_iphdr (outpkt, IPPROTO_TCP, &nt, TCP_SIZE + len); | ||
| 245 | |||
| 246 | send_ipv4 (sox, outpkt, IP_SIZE + TCP_SIZE + len); | ||
| 247 | |||
| 248 | return (0); | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | /* | ||
| 253 | * return 0 if ip-header is valid [length only] | ||
| 254 | * len = length from the begin of the ip-header [20 for normal ip header] | ||
| 255 | */ | ||
| 256 | int | ||
| 257 | vrfy_ip (struct ip *ip, uint32_t len, u_short * ip_options) | ||
| 258 | { | ||
| 259 | u_short _ip_options; | ||
| 260 | |||
| 261 | if (len < sizeof (*ip)) | ||
| 262 | return (-1); | ||
| 263 | |||
| 264 | _ip_options = ip->ip_hl << 2; | ||
| 265 | if (_ip_options > len) | ||
| 266 | return (-1); | ||
| 267 | |||
| 268 | if (_ip_options > 0xefff) | ||
| 269 | return -1; | ||
| 270 | |||
| 271 | if (_ip_options < sizeof (*ip)) | ||
| 272 | _ip_options = 0; | ||
| 273 | else | ||
| 274 | _ip_options -= sizeof (*ip); | ||
| 275 | |||
| 276 | *ip_options = _ip_options; | ||
| 277 | return (0); | ||
| 278 | } | ||
| 279 | |||
| 280 | |||
| 281 | /* | ||
| 282 | * len = len of tcp-header + tcp_options + tcp_data (from wire). | ||
| 283 | * returns 0 if tcp-header is valid [length check only] | ||
| 284 | * returns options | ||
| 285 | * != 0 if something went wrong [header size etc] | ||
| 286 | */ | ||
| 287 | int | ||
| 288 | vrfy_tcp (struct tcphdr *tcp, uint32_t plen, u_short * tcp_options) | ||
| 289 | { | ||
| 290 | u_short _tcp_options; | ||
| 291 | |||
| 292 | if (plen < sizeof (*tcp)) | ||
| 293 | return (-1); | ||
| 294 | |||
| 295 | _tcp_options = tcp->th_off << 2; | ||
| 296 | if (_tcp_options > plen) | ||
| 297 | return (-1); | ||
| 298 | if (_tcp_options > 0xefff) /* this is quite to large for me */ | ||
| 299 | return -1; | ||
| 300 | |||
| 301 | if (_tcp_options <= sizeof (*tcp)) | ||
| 302 | _tcp_options = 0; | ||
| 303 | else | ||
| 304 | _tcp_options -= sizeof (*tcp); | ||
| 305 | |||
| 306 | *tcp_options = _tcp_options; | ||
| 307 | |||
| 308 | return (0); | ||
| 309 | } | ||
| 310 | |||
| 311 | int | ||
| 312 | vrfy_udp (struct udphdr *udp, uint32_t len) | ||
| 313 | { | ||
| 314 | |||
| 315 | if (len < sizeof(*udp)) | ||
| 316 | return (-1); | ||
| 317 | |||
| 318 | return (0); | ||
| 319 | } | ||
| 320 | |||
| 321 | /* | ||
| 322 | * decode NetworkVirtualTerminal Data | ||
| 323 | * data = the raw (nvt)-input | ||
| 324 | * len = length of 'data' | ||
| 325 | * ans = the nvt-answer (IAC don't) | ||
| 326 | * anslen = the calculated anser length | ||
| 327 | * res = the decoded nvt data (login: prompt etc) | ||
| 328 | * reslen = the calculates decoded data length | ||
| 329 | * All parameters must be given (NULL is not allowed) | ||
| 330 | * and initialized | ||
| 331 | * return -1 on failure | ||
| 332 | * return 0 on success | ||
| 333 | * rfc-will: anslen, reslen < len | ||
| 334 | */ | ||
| 335 | #define IACFOUND 0x01 | ||
| 336 | #define DOFOUND 0x02 | ||
| 337 | #define UNKNOWNOPT 0x04 | ||
| 338 | #define SUBNEGO 0x08 | ||
| 339 | #define CRFOUND 0x10 | ||
| 340 | |||
| 341 | #define NVT_SE 0xf0 | ||
| 342 | #define NVT_SB 0xfa | ||
| 343 | #define NVT_WILL 0xfb | ||
| 344 | #define NVT_WONT 0xfc | ||
| 345 | #define NVT_DO 0xfd | ||
| 346 | #define NVT_DONT 0xfe | ||
| 347 | #define IAC 0xff | ||
| 348 | |||
| 349 | int | ||
| 350 | decode_nvt(u_char *data, uint len, u_char *ans, uint *anslen, | ||
| 351 | u_char *res, uint *reslen) | ||
| 352 | { | ||
| 353 | u_char *ptr = data; | ||
| 354 | u_char *ansptr = ans; | ||
| 355 | u_char *resptr = res; | ||
| 356 | u_char flags = 0; | ||
| 357 | int i = 0; | ||
| 358 | u_char c; | ||
| 359 | |||
| 360 | if ( (data == NULL) || (ans == NULL) || (res == NULL)) | ||
| 361 | return(0); | ||
| 362 | |||
| 363 | *anslen = 0; | ||
| 364 | *reslen = 0; | ||
| 365 | |||
| 366 | while (1) | ||
| 367 | { | ||
| 368 | if (i++ >= len) | ||
| 369 | break; | ||
| 370 | c = *ptr++; | ||
| 371 | |||
| 372 | if (flags & UNKNOWNOPT) | ||
| 373 | { | ||
| 374 | flags = 0; | ||
| 375 | continue; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (flags & IACFOUND) | ||
| 379 | { | ||
| 380 | if (c == IAC) /* IAC IAC */ | ||
| 381 | { | ||
| 382 | *resptr++ = IAC; | ||
| 383 | flags = 0; /* reset */ | ||
| 384 | continue; | ||
| 385 | } | ||
| 386 | |||
| 387 | if (flags & SUBNEGO) | ||
| 388 | { | ||
| 389 | if (c == NVT_SE) /* subnegotiation end */ | ||
| 390 | flags = 0; | ||
| 391 | continue; | ||
| 392 | } | ||
| 393 | |||
| 394 | if (flags & DOFOUND) | ||
| 395 | { | ||
| 396 | /* 3com switch test if (c == 0x03) | ||
| 397 | { | ||
| 398 | *ansptr++ = IAC; | ||
| 399 | *ansptr++ = NVT_DO; | ||
| 400 | *ansptr++ = 0x03; | ||
| 401 | *ansptr++ = IAC; | ||
| 402 | *ansptr++ = NVT_WILL; | ||
| 403 | *ansptr++ = 0x18; | ||
| 404 | *ansptr++ = IAC; | ||
| 405 | *ansptr++ = NVT_WILL; | ||
| 406 | *ansptr++ = 0x1f; | ||
| 407 | *ansptr++ = IAC; | ||
| 408 | *ansptr++ = NVT_WILL; | ||
| 409 | *ansptr++ = 0x20; | ||
| 410 | *ansptr++ = IAC; | ||
| 411 | *ansptr++ = NVT_WILL; | ||
| 412 | *ansptr++ = 0x21; | ||
| 413 | *ansptr++ = IAC; | ||
| 414 | *ansptr++ = NVT_WILL; | ||
| 415 | *ansptr++ = 0x22; | ||
| 416 | *ansptr++ = IAC; | ||
| 417 | *ansptr++ = NVT_WILL; | ||
| 418 | *ansptr++ = 0x27; | ||
| 419 | *ansptr++ = IAC; | ||
| 420 | *ansptr++ = NVT_DO; | ||
| 421 | *ansptr++ = 0x05; | ||
| 422 | *ansptr++ = IAC; | ||
| 423 | *ansptr++ = NVT_WILL; | ||
| 424 | *ansptr++ = 0x23; | ||
| 425 | *anslen = *anslen + 24; | ||
| 426 | |||
| 427 | } | ||
| 428 | */ | ||
| 429 | *ansptr++ = IAC; | ||
| 430 | *ansptr++ = NVT_WONT; /* me is dump - im a kid */ | ||
| 431 | *ansptr++ = c; | ||
| 432 | *anslen = *anslen + 3; | ||
| 433 | flags = 0; | ||
| 434 | continue; | ||
| 435 | } | ||
| 436 | |||
| 437 | if (c == NVT_SB) /* subnegotiation */ | ||
| 438 | { | ||
| 439 | flags = SUBNEGO; | ||
| 440 | continue; | ||
| 441 | } | ||
| 442 | |||
| 443 | if (c == NVT_DO) /* DO ... */ | ||
| 444 | { | ||
| 445 | flags |= DOFOUND; | ||
| 446 | continue; | ||
| 447 | } else { | ||
| 448 | flags = ~(IACFOUND | DOFOUND); | ||
| 449 | flags |= UNKNOWNOPT; /* skip next */ | ||
| 450 | continue; | ||
| 451 | } | ||
| 452 | |||
| 453 | } | ||
| 454 | |||
| 455 | if (flags & SUBNEGO) | ||
| 456 | continue; | ||
| 457 | |||
| 458 | if (c == IAC) | ||
| 459 | { | ||
| 460 | flags = IACFOUND; /* just IAC */ | ||
| 461 | continue; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (flags & CRFOUND) | ||
| 465 | { | ||
| 466 | if (c == '\0') | ||
| 467 | { | ||
| 468 | flags &= ~CRFOUND; | ||
| 469 | *res++ = '\r'; | ||
| 470 | *reslen = *reslen + 1; | ||
| 471 | continue; | ||
| 472 | } | ||
| 473 | if (c == '\n') | ||
| 474 | { | ||
| 475 | flags &= ~CRFOUND; | ||
| 476 | *res++ = '\n'; | ||
| 477 | *reslen = *reslen + 1; | ||
| 478 | continue; | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | if (c == '\r') | ||
| 483 | { | ||
| 484 | flags |= CRFOUND; | ||
| 485 | continue; | ||
| 486 | } | ||
| 487 | |||
| 488 | *res++ = c; | ||
| 489 | *reslen = *reslen + 1; | ||
| 490 | |||
| 491 | } | ||
| 492 | |||
| 493 | return(0); | ||
| 494 | } | ||
| 495 | |||
| 496 | |||
| 497 | |||
diff --git a/other/b-scan/tmp/src/restore.c b/other/b-scan/tmp/src/restore.c new file mode 100644 index 0000000..45edbb8 --- /dev/null +++ b/other/b-scan/tmp/src/restore.c | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | /* | ||
| 2 | * bscan, restore.c | ||
| 3 | * this is the buggies part of the entire scanner :> | ||
| 4 | * many buffer overflows in here | ||
| 5 | */ | ||
| 6 | #include <bscan/bscan.h> | ||
| 7 | #include <bscan/system.h> | ||
| 8 | #include <bscan/module.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | |||
| 12 | extern struct _opt *opt; | ||
| 13 | |||
| 14 | #define RESTORE_FILE "restore.bscan" | ||
| 15 | |||
| 16 | #define R_ARGVLIST "argvlist" | ||
| 17 | #define R_MODARG "modarg" | ||
| 18 | #define R_LIMIT "limit" | ||
| 19 | #define R_FLAGS "flags" | ||
| 20 | #define R_DELAY "delay" | ||
| 21 | #define R_PSCANSTAT "pscanstat" | ||
| 22 | #define R_IPSCAN_COUNT "ipscan_count" | ||
| 23 | #define R_IPTOTSCAN_C "iptotscan_count" | ||
| 24 | #define R_BSENT_COUNT "bsent_count" | ||
| 25 | #define R_IP_OFFSET "ip_offset" | ||
| 26 | #define R_IP_BLKLEN "ip_blklen" | ||
| 27 | #define R_IP_POS "ip_pos" | ||
| 28 | #define R_SCAN_TIME "scan_time" | ||
| 29 | #define R_SPF_SIP "spf_sip" | ||
| 30 | #define R_SPF_SMAC "spf_smac" | ||
| 31 | #define R_SNARFICMP_C "snarf.icmp_c" | ||
| 32 | #define R_SNARFCLOSE_C "snarf.close_c" | ||
| 33 | #define R_SNARFOPEN_C "snarf.open_c" | ||
| 34 | #define R_SNARFREFUSED_C "snarf.refused_c" | ||
| 35 | #define R_IDEV "lnet.device" | ||
| 36 | #define R_HOSTFILE "hostfile" | ||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * save everything that is required to restore/restart an inter session | ||
| 41 | */ | ||
| 42 | int | ||
| 43 | write_restore () | ||
| 44 | { | ||
| 45 | u_char *p = (u_char *) opt->spf_smac; | ||
| 46 | FILE *fptr; | ||
| 47 | char **myargv = opt->argvlist; | ||
| 48 | struct timeval tv; | ||
| 49 | #ifdef HAVE_DLSYM | ||
| 50 | int c=0; | ||
| 51 | extern const int modcount; | ||
| 52 | extern const struct _mods mods[MAX_MODULES]; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | if (opt->flags & OPT_VERB) | ||
| 56 | fprintf (stderr, "Writing restore file '%s'\n", RESTORE_FILE); | ||
| 57 | |||
| 58 | if ((fptr = fopen (RESTORE_FILE, "w+")) == NULL) | ||
| 59 | return (-1); | ||
| 60 | |||
| 61 | fprintf (fptr, "# bscan restore file. This is an automatic generated\n"); | ||
| 62 | fprintf (fptr, "# file. Don't edit.\n"); | ||
| 63 | fprintf (fptr, "#\n"); | ||
| 64 | |||
| 65 | fprintf (fptr, R_ARGVLIST ": "); | ||
| 66 | if ((opt->target != NULL) && !(opt->flags & OPT_HOSTFILE)) | ||
| 67 | fprintf (fptr, "\"%s\" ", opt->target); | ||
| 68 | while (*myargv != NULL) | ||
| 69 | fprintf (fptr, "\"%s\" ", *myargv++); | ||
| 70 | fprintf (fptr, "\n"); | ||
| 71 | |||
| 72 | #ifdef HAVE_DLSYM | ||
| 73 | for (c = 0; c < modcount; c++) | ||
| 74 | fprintf(fptr, R_MODARG ": %s\n", mods[c].modarg); | ||
| 75 | #endif | ||
| 76 | |||
| 77 | fprintf (fptr, R_LIMIT ": %u\n", opt->limit); | ||
| 78 | fprintf (fptr, R_DELAY ": %u\n", opt->delay); | ||
| 79 | fprintf (fptr, R_PSCANSTAT ": %u\n", opt->pscanstat); | ||
| 80 | fprintf (fptr, R_IPSCAN_COUNT ": %lu\n", opt->ipscan_count); | ||
| 81 | fprintf (fptr, R_IPTOTSCAN_C ": %lu\n", opt->iptotscan_count); | ||
| 82 | fprintf (fptr, R_BSENT_COUNT ": %lu\n", opt->bsent_count); | ||
| 83 | fprintf (fptr, R_IP_OFFSET ": %lu\n", opt->ip_offset); | ||
| 84 | fprintf (fptr, R_IP_BLKLEN ": %lu\n", opt->ip_blklen); | ||
| 85 | fprintf (fptr, R_IP_POS ": %lu\n", opt->ip_pos); | ||
| 86 | fprintf (fptr, R_FLAGS ": %4.4x\n", opt->flags); | ||
| 87 | memcpy(&tv, &opt->tv2, sizeof(tv)); | ||
| 88 | time_diff (&opt->scan_start, &tv); | ||
| 89 | fprintf (fptr, R_SCAN_TIME ": %ld\n", (long)tv.tv_sec); | ||
| 90 | fprintf (fptr, R_SPF_SIP ": %s\n", int_ntoa (opt->nt.src)); | ||
| 91 | fprintf (fptr, R_SPF_SMAC ": %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
| 92 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 93 | fprintf (fptr, R_SNARFICMP_C ": %lu\n", opt->snarf.icmp_c); | ||
| 94 | fprintf (fptr, R_SNARFCLOSE_C ": %lu\n", opt->snarf.close_c); | ||
| 95 | fprintf (fptr, R_SNARFOPEN_C ": %lu\n", opt->snarf.open_c); | ||
| 96 | fprintf (fptr, R_SNARFREFUSED_C ": %lu\n", opt->snarf.refused_c); | ||
| 97 | if (opt->lnet.device != NULL) | ||
| 98 | fprintf (fptr, R_IDEV ": %s\n", opt->lnet.device); | ||
| 99 | else | ||
| 100 | fprintf (fptr, R_IDEV ": \n"); | ||
| 101 | |||
| 102 | if (opt->hostfile != NULL) | ||
| 103 | fprintf (fptr, R_HOSTFILE ": %s\n", opt->hostfile); | ||
| 104 | else | ||
| 105 | fprintf (fptr, R_HOSTFILE ": \n"); | ||
| 106 | |||
| 107 | fclose (fptr); | ||
| 108 | |||
| 109 | return (0); | ||
| 110 | } | ||
| 111 | |||
| 112 | int | ||
| 113 | restore_processtag (char *tag, char *arg) | ||
| 114 | { | ||
| 115 | char *ptr = arg; | ||
| 116 | int c = 0; | ||
| 117 | |||
| 118 | if ((arg == NULL) || (tag == NULL)) | ||
| 119 | return (-1); | ||
| 120 | |||
| 121 | if (!strcmp (R_ARGVLIST, tag)) | ||
| 122 | if (strlen (arg) > 0) | ||
| 123 | { | ||
| 124 | int toggle = 0; | ||
| 125 | while (*ptr != '\0') | ||
| 126 | if (*ptr++ == '"') | ||
| 127 | c++; | ||
| 128 | ptr = arg; | ||
| 129 | c = c / 2; | ||
| 130 | if (c <= 0) | ||
| 131 | return (-1); /* this should not happen */ | ||
| 132 | if ((opt->argvlist = malloc ((c + 1) * sizeof (char *))) == NULL) | ||
| 133 | return (-1); | ||
| 134 | for (toggle = 0; toggle < c + 1; toggle++) | ||
| 135 | opt->argvlist[toggle] = NULL; | ||
| 136 | |||
| 137 | toggle = 0; | ||
| 138 | ptr = arg; | ||
| 139 | c = 0; | ||
| 140 | while (*ptr != '\0') | ||
| 141 | if (*ptr++ == '"') | ||
| 142 | { | ||
| 143 | *(ptr - 1) = '\0'; | ||
| 144 | if (toggle++ == 1) | ||
| 145 | { | ||
| 146 | toggle = 0; | ||
| 147 | continue; | ||
| 148 | } | ||
| 149 | opt->argvlist[c++] = ptr; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* strings are ready + \0 terminated here */ | ||
| 153 | |||
| 154 | for (toggle = 0; toggle < c; toggle++) | ||
| 155 | opt->argvlist[toggle] = strdup (opt->argvlist[toggle]); | ||
| 156 | |||
| 157 | return (0); | ||
| 158 | } | ||
| 159 | |||
| 160 | if (!strcmp (R_MODARG, tag)) | ||
| 161 | loadinit_mod(arg); | ||
| 162 | |||
| 163 | if (!strcmp (R_DELAY, tag)) | ||
| 164 | opt->delay = atoi (arg); | ||
| 165 | if (!strcmp (R_LIMIT, tag)) | ||
| 166 | opt->limit = atoi (arg); | ||
| 167 | if (!strcmp (R_PSCANSTAT, tag)) | ||
| 168 | opt->pscanstat = atoi (arg); | ||
| 169 | if (!strcmp (R_IPSCAN_COUNT, tag)) | ||
| 170 | opt->ipscan_count = strtoul (arg, NULL, 10); | ||
| 171 | if (!strcmp (R_IPTOTSCAN_C, tag)) | ||
| 172 | opt->iptotscan_count = strtoul (arg, NULL, 10); | ||
| 173 | if (!strcmp (R_BSENT_COUNT, tag)) | ||
| 174 | opt->bsent_count = strtoul (arg, NULL, 10); | ||
| 175 | if (!strcmp (R_IP_OFFSET, tag)) | ||
| 176 | opt->ip_offset = strtoul (arg, NULL, 10); | ||
| 177 | if (!strcmp (R_IP_BLKLEN, tag)) | ||
| 178 | opt->ip_blklen = strtoul (arg, NULL, 10); | ||
| 179 | if (!strcmp (R_IP_POS, tag)) | ||
| 180 | opt->ip_pos = strtoul (arg, NULL, 10); | ||
| 181 | if (!strcmp (R_SCAN_TIME, tag)) | ||
| 182 | { /* doing the date trick ..we had a scannerdowntime.. */ | ||
| 183 | gettimeofday (&opt->scan_start, NULL); | ||
| 184 | opt->scan_start.tv_sec = | ||
| 185 | opt->scan_start.tv_sec - strtoul (arg, NULL, 10); | ||
| 186 | } | ||
| 187 | if (!strcmp (R_SPF_SIP, tag)) | ||
| 188 | opt->nt.src = inet_addr (arg); | ||
| 189 | if (!strcmp (R_SPF_SMAC, tag)) | ||
| 190 | { | ||
| 191 | unsigned short int sp[6]; | ||
| 192 | sscanf (arg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 193 | &sp[3], &sp[4], &sp[5]); | ||
| 194 | for (c = 0; c < 6; c++) | ||
| 195 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 196 | |||
| 197 | } | ||
| 198 | if (!strcmp (R_FLAGS, tag)) | ||
| 199 | { | ||
| 200 | sscanf (arg, "%hx", &opt->flags); | ||
| 201 | opt->flags &= ~OPT_ABRT; | ||
| 202 | opt->flags &= ~OPT_REST; | ||
| 203 | } | ||
| 204 | if (!strcmp (R_SNARFICMP_C, tag)) | ||
| 205 | opt->snarf.icmp_c = strtoul (arg, NULL, 10); | ||
| 206 | if (!strcmp (R_SNARFCLOSE_C, tag)) | ||
| 207 | opt->snarf.close_c = strtoul (arg, NULL, 10); | ||
| 208 | if (!strcmp (R_SNARFOPEN_C, tag)) | ||
| 209 | opt->snarf.open_c = strtoul (arg, NULL, 10); | ||
| 210 | if (!strcmp (R_SNARFREFUSED_C, tag)) | ||
| 211 | opt->snarf.refused_c = strtoul (arg, NULL, 10); | ||
| 212 | if (!strcmp (R_IDEV, tag)) | ||
| 213 | if (strlen (arg) > 0) | ||
| 214 | opt->lnet.device = strdup (arg); | ||
| 215 | if (!strcmp (R_HOSTFILE, tag)) | ||
| 216 | if (strlen (arg) > 0) | ||
| 217 | opt->hostfile = strdup (arg); | ||
| 218 | |||
| 219 | return (0); | ||
| 220 | } | ||
| 221 | |||
| 222 | |||
| 223 | /* | ||
| 224 | * read restore-file | ||
| 225 | * return 0 on success, -1 on failure | ||
| 226 | * sscanf is exploitable. have fun. What kind of stupid admin | ||
| 227 | * who set a +s on this programm. harhar | ||
| 228 | */ | ||
| 229 | int | ||
| 230 | read_restore (char *filename) | ||
| 231 | { | ||
| 232 | FILE *fptr; | ||
| 233 | char buf[1024]; | ||
| 234 | char tag[1024], arg[1024]; | ||
| 235 | |||
| 236 | if (opt->flags & OPT_VERB) | ||
| 237 | fprintf (stderr, "Reading restore file '%s'.\n", filename); | ||
| 238 | |||
| 239 | if ((fptr = fopen (filename, "rb")) == NULL) | ||
| 240 | { | ||
| 241 | printf ("OPEN FAILED\n"); | ||
| 242 | return (-1); | ||
| 243 | } | ||
| 244 | |||
| 245 | while (fgets (buf, sizeof (buf), fptr) != NULL) | ||
| 246 | { | ||
| 247 | if (strchr (buf, '#') != NULL) | ||
| 248 | continue; | ||
| 249 | |||
| 250 | tag[0] = arg[0] = '\0'; | ||
| 251 | sscanf (buf, "%[^: ]%*[: \t]%[^#\n]%*[\n]", tag, arg); | ||
| 252 | |||
| 253 | if (restore_processtag (tag, arg) == -1) | ||
| 254 | { | ||
| 255 | fprintf (stderr, "error while processing restore file with '%s:%s' \n ", tag, arg); | ||
| 256 | exit (-1); | ||
| 257 | } | ||
| 258 | |||
| 259 | } | ||
| 260 | |||
| 261 | fclose (fptr); | ||
| 262 | return (0); | ||
| 263 | } | ||
diff --git a/other/b-scan/tmp/src/signal.c b/other/b-scan/tmp/src/signal.c new file mode 100644 index 0000000..a2af01f --- /dev/null +++ b/other/b-scan/tmp/src/signal.c | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #include <signal.h> | ||
| 2 | #include <bscan/signal.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * add the signals that you want to be set to default-action | ||
| 6 | */ | ||
| 7 | int | ||
| 8 | do_sig_setall (sighandler_t action) | ||
| 9 | { | ||
| 10 | #ifdef SIGHUP | ||
| 11 | signal (SIGHUP, action); | ||
| 12 | #endif | ||
| 13 | #ifdef SIGINT | ||
| 14 | signal (SIGINT, action); | ||
| 15 | #endif | ||
| 16 | #ifdef SIGQUIT | ||
| 17 | signal (SIGQUIT, action); | ||
| 18 | #endif | ||
| 19 | #ifdef SIGABRT | ||
| 20 | signal (SIGABRT, action); | ||
| 21 | #endif | ||
| 22 | #ifdef SIGPIPE | ||
| 23 | signal (SIGPIPE, action); | ||
| 24 | #endif | ||
| 25 | #ifdef SIGALRM | ||
| 26 | signal (SIGALRM, action); | ||
| 27 | #endif | ||
| 28 | #ifdef SIGTERM | ||
| 29 | signal (SIGTERM, action); | ||
| 30 | #endif | ||
| 31 | #ifdef SIGUSR1 | ||
| 32 | signal (SIGUSR1, action); | ||
| 33 | #endif | ||
| 34 | #ifdef SIGUSR1 | ||
| 35 | signal (SIGUSR1, action); | ||
| 36 | #endif | ||
| 37 | #ifdef SIGCHLD | ||
| 38 | signal (SIGCHLD, action); | ||
| 39 | #endif | ||
| 40 | #ifdef SIGCOMT | ||
| 41 | signal (SIGCOMT, action); | ||
| 42 | #endif | ||
| 43 | #ifdef SIGSTOP | ||
| 44 | signal (SIGSTOP, action); | ||
| 45 | #endif | ||
| 46 | #ifdef SIGTSTP | ||
| 47 | signal (SIGTSTP, action); | ||
| 48 | #endif | ||
| 49 | #ifdef SIGTTIM | ||
| 50 | signal (SIGTTIM, action); | ||
| 51 | #endif | ||
| 52 | #ifdef SIGTTOU | ||
| 53 | signal (SIGTTOU, action); | ||
| 54 | #endif | ||
| 55 | |||
| 56 | return (0); | ||
| 57 | } | ||
| 58 | |||
| 59 | /* | ||
| 60 | * sig-ctl function. | ||
| 61 | * atm only SIG_DFL implemented.... | ||
| 62 | */ | ||
| 63 | int | ||
| 64 | sigctl (int flags, sighandler_t action) | ||
| 65 | { | ||
| 66 | int ret = 0; | ||
| 67 | |||
| 68 | if (flags & SIG_SETALL) | ||
| 69 | ret = do_sig_setall (action); | ||
| 70 | |||
| 71 | return (ret); | ||
| 72 | } | ||
diff --git a/other/b-scan/tmp/src/snarf.c b/other/b-scan/tmp/src/snarf.c new file mode 100644 index 0000000..fce8b9e --- /dev/null +++ b/other/b-scan/tmp/src/snarf.c | |||
| @@ -0,0 +1,211 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | |||
| 3 | #include <sys/types.h> | ||
| 4 | #include <sys/socket.h> | ||
| 5 | #ifndef __FAVOR_BSD | ||
| 6 | #define __FAVOR_BSD | ||
| 7 | #endif | ||
| 8 | #ifndef __USE_BSD | ||
| 9 | #define __USE_BSD | ||
| 10 | #endif | ||
| 11 | #ifndef __BSD_SOURCE | ||
| 12 | #define __BSD_SOURCE | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #include <pcap.h> | ||
| 16 | #include <bscan/bscan.h> | ||
| 17 | #include <bscan/snarf.h> | ||
| 18 | #include <bscan/module.h> | ||
| 19 | #include <bscan/signal.h> | ||
| 20 | |||
| 21 | pcap_t *ip_socket; | ||
| 22 | |||
| 23 | /* | ||
| 24 | * some global variables (modules need access etc) | ||
| 25 | */ | ||
| 26 | int dlt_len; | ||
| 27 | u_char *align_buf = NULL; | ||
| 28 | unsigned short ip_options = 0; | ||
| 29 | struct ip *ip; | ||
| 30 | struct Ether_header *eth; | ||
| 31 | u_int pcaplen, plen; | ||
| 32 | struct timeval *pts; | ||
| 33 | |||
| 34 | extern struct _opt *opt; | ||
| 35 | #ifdef HAVE_DLSYM | ||
| 36 | extern const int modcount; | ||
| 37 | extern const struct _mods mods[MAX_MODULES]; | ||
| 38 | #endif | ||
| 39 | |||
| 40 | |||
| 41 | /* | ||
| 42 | * answer on arp-request. | ||
| 43 | */ | ||
| 44 | static void | ||
| 45 | handle_arp (struct pcap_pkthdr *p, struct Ether_header *eth, | ||
| 46 | struct Arphdr *arp) | ||
| 47 | { | ||
| 48 | u_long *ipdummy = (u_long *) arp->ar_tip; | ||
| 49 | |||
| 50 | if (ntohs (arp->ar_op) != ARPOP_REQUEST) | ||
| 51 | return; | ||
| 52 | |||
| 53 | #ifdef DEBUG | ||
| 54 | printf ("ARPG request for %s\n", int_ntoa ((u_long) * ipdummy)); | ||
| 55 | #endif | ||
| 56 | if (*ipdummy == opt->nt.src) | ||
| 57 | play_arpg (&opt->lnet, arp->ar_tip, (u_char *) opt->spf_smac, | ||
| 58 | (u_char *) arp->ar_sip, eth->ether_shost); | ||
| 59 | } | ||
| 60 | |||
| 61 | |||
| 62 | /* | ||
| 63 | * called by libpcap | ||
| 64 | */ | ||
| 65 | static void | ||
| 66 | filter_packet (u_char * u, struct pcap_pkthdr *p, u_char * packet) | ||
| 67 | { | ||
| 68 | int c; | ||
| 69 | static u_char *align_eth = NULL; | ||
| 70 | |||
| 71 | if (p->len < (dlt_len + sizeof (struct Arphdr))) | ||
| 72 | return; | ||
| 73 | if (align_buf == NULL) | ||
| 74 | align_buf = (u_char *) malloc (2048); | ||
| 75 | if (align_eth == NULL) | ||
| 76 | align_eth = (u_char *) malloc (42); | ||
| 77 | |||
| 78 | memcpy ((char *) align_buf, (char *) (packet + dlt_len), p->caplen); | ||
| 79 | memcpy ((char *) align_eth, (char *) packet, 42); | ||
| 80 | eth = (struct Ether_header *) (align_eth); | ||
| 81 | ip = (struct ip *) (align_buf); | ||
| 82 | |||
| 83 | if (ntohs (eth->ether_type) == ETHERTYPE_ARP) | ||
| 84 | { | ||
| 85 | handle_arp (p, eth, (struct Arphdr *) (align_buf)); | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | if (ntohs (eth->ether_type) != ETHERTYPE_IP) | ||
| 91 | return; | ||
| 92 | if (vrfy_ip (ip, p->len - dlt_len, &ip_options) != 0) | ||
| 93 | return; | ||
| 94 | if (ip->ip_dst.s_addr != opt->nt.src) | ||
| 95 | return; | ||
| 96 | if (p->len < (dlt_len + sizeof (*ip) + ip_options)) | ||
| 97 | return; | ||
| 98 | |||
| 99 | /* here only 'my-ip' packets */ | ||
| 100 | |||
| 101 | /* module entry point TWO */ | ||
| 102 | /* packet is verifite, belongs to us + valid size */ | ||
| 103 | /* return of module tell us if we should procced as usual or not */ | ||
| 104 | /* DROP is valid here ! */ | ||
| 105 | |||
| 106 | plen = p->len; | ||
| 107 | pcaplen = p->caplen; | ||
| 108 | pts = &p->ts; | ||
| 109 | |||
| 110 | #ifdef HAVE_DLSYM | ||
| 111 | c = 0; | ||
| 112 | while (c < modcount) | ||
| 113 | mods[c++].callmdl (MOD_RCV, opt); | ||
| 114 | #endif | ||
| 115 | |||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | * init pcap network stuff | ||
| 120 | * only called once on startup. | ||
| 121 | * -1 = error | ||
| 122 | * 0 = success | ||
| 123 | */ | ||
| 124 | int | ||
| 125 | pcap_init_net (char *iface, int promisc, char *filter, int *dltlen) | ||
| 126 | { | ||
| 127 | char errbuf[PCAP_ERRBUF_SIZE]; | ||
| 128 | struct bpf_program prog; | ||
| 129 | bpf_u_int32 network, netmask; | ||
| 130 | |||
| 131 | if (iface == NULL) | ||
| 132 | { | ||
| 133 | iface = pcap_lookupdev (errbuf); | ||
| 134 | if (iface == NULL) | ||
| 135 | { | ||
| 136 | fprintf (stderr, "pcap_lookupdev: %s\n", errbuf); | ||
| 137 | return (-1); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | if (pcap_lookupnet (iface, &network, &netmask, errbuf) < 0) | ||
| 141 | { | ||
| 142 | fprintf (stderr, "pcap_lookupnet: %s\n", errbuf); | ||
| 143 | return (-1); | ||
| 144 | } | ||
| 145 | ip_socket = pcap_open_live (iface, 1024, promisc, 1024, errbuf); | ||
| 146 | if (ip_socket == NULL) | ||
| 147 | { | ||
| 148 | fprintf (stderr, "pcap_open_live: %s\n", errbuf); | ||
| 149 | return (-1); | ||
| 150 | } | ||
| 151 | switch (pcap_datalink (ip_socket)) | ||
| 152 | { | ||
| 153 | case DLT_EN10MB: | ||
| 154 | *dltlen = 14; | ||
| 155 | break; | ||
| 156 | case DLT_SLIP: | ||
| 157 | *dltlen = 16; | ||
| 158 | break; | ||
| 159 | default: | ||
| 160 | *dltlen = 4; | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | if (pcap_compile (ip_socket, &prog, filter, 1, netmask) < 0) | ||
| 164 | { | ||
| 165 | fprintf (stderr, "pcap_compile: %s\n", errbuf); | ||
| 166 | return (-1); | ||
| 167 | } | ||
| 168 | if (pcap_setfilter (ip_socket, &prog) < 0) | ||
| 169 | { | ||
| 170 | fprintf (stderr, "pcap_setfilter: %s\n", errbuf); | ||
| 171 | return (-1); | ||
| 172 | } | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | /* | ||
| 179 | * called by main-thread. | ||
| 180 | * doing all the snarf, arp-reply, tcp-stack stuff from here | ||
| 181 | */ | ||
| 182 | void * | ||
| 183 | do_snarf (void *iface) | ||
| 184 | { | ||
| 185 | /* sigctl (SIG_SETALL, SIG_DFL); | ||
| 186 | signal (SIGINT, SIG_IGN); | ||
| 187 | */ | ||
| 188 | |||
| 189 | pcap_init_net (iface, 1, PCAP_FILTER, &dlt_len); | ||
| 190 | |||
| 191 | /* the parent thread should at least w8 until we are ready to rumble */ | ||
| 192 | opt->flags &= ~OPT_W8SEMA; | ||
| 193 | |||
| 194 | while (1) | ||
| 195 | pcap_loop (ip_socket, -1, (pcap_handler) filter_packet, NULL); | ||
| 196 | |||
| 197 | undo_snarf(); /*### fixme, somewhere else */ | ||
| 198 | |||
| 199 | pthread_exit(NULL); /* no return values needed */ | ||
| 200 | return NULL; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* | ||
| 204 | * close everything that was initialized with do_snarf | ||
| 205 | */ | ||
| 206 | void | ||
| 207 | undo_snarf () | ||
| 208 | { | ||
| 209 | pcap_close (ip_socket); | ||
| 210 | } | ||
| 211 | |||
diff --git a/other/b-scan/tmp/src/system.c b/other/b-scan/tmp/src/system.c new file mode 100644 index 0000000..a3ccc94 --- /dev/null +++ b/other/b-scan/tmp/src/system.c | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <sys/ipc.h> | ||
| 3 | #include <sys/shm.h> | ||
| 4 | #include <sys/mman.h> | ||
| 5 | #include <sys/time.h> | ||
| 6 | #include <stdio.h> | ||
| 7 | #include <unistd.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <ctype.h> | ||
| 11 | #include <fcntl.h> | ||
| 12 | #include <time.h> | ||
| 13 | |||
| 14 | #ifndef SHMMNI | ||
| 15 | #define SHMMNI 100 | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #define MAXSHM 4 /* its bscan. we need <4 shm's */ | ||
| 19 | |||
| 20 | static int shm_id = -1; /* last used id */ | ||
| 21 | static int shm_c = -1; /* shm_alloc counter */ | ||
| 22 | |||
| 23 | static struct _shm | ||
| 24 | { | ||
| 25 | int id; | ||
| 26 | void *ptr; | ||
| 27 | } | ||
| 28 | shm[MAXSHM]; | ||
| 29 | |||
| 30 | |||
| 31 | /* | ||
| 32 | * uhm. hard job for the process coz the process | ||
| 33 | * does not get the shm_id. uhm. i should make a static traking list | ||
| 34 | * of all shared memory segments (addr <-> id mapping maybe ?) | ||
| 35 | * on the other hand...since an attachment count is maintained for | ||
| 36 | * the shared memory segment the segment gets removed when the last | ||
| 37 | * process using the segment terminates or detaches it. | ||
| 38 | * hmm. Seems the following function is completly useless....:> | ||
| 39 | * Hey. why are you reading my comments ? write me: anonymous@segfault.net! | ||
| 40 | */ | ||
| 41 | int | ||
| 42 | shmfree (int shm_id) | ||
| 43 | { | ||
| 44 | if (shm_id < 0) | ||
| 45 | return (-1); | ||
| 46 | return (shmctl (shm_id, IPC_RMID, 0)); | ||
| 47 | } | ||
| 48 | |||
| 49 | /* | ||
| 50 | * kill ALL shm's | ||
| 51 | * uhm. this is brutal. but shm is risky. you can bring | ||
| 52 | * down ANY system if you waste all shm's. Shm's dont get | ||
| 53 | * freed on process-exit !!! syslog will fail, inetd will fail, .. | ||
| 54 | * any program that tries to alloc shared memory...nono good :> | ||
| 55 | * root can use 'ipcrm shm <id>' do free the shm's. | ||
| 56 | * that's why we use this brutal "killall"-method. | ||
| 57 | * something else: killall-method is realy BRUTAL. believe me! | ||
| 58 | * If you have other functions registered on exit (atexit) | ||
| 59 | * and you try to reference to a shm within these function...you are lost | ||
| 60 | * Unexpected things will happen.... | ||
| 61 | */ | ||
| 62 | void | ||
| 63 | shmkillall () | ||
| 64 | { | ||
| 65 | int c; | ||
| 66 | |||
| 67 | for (c = 0; c < shm_c; c++) | ||
| 68 | shmfree (shm[c].id); | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * allocate shared memory (poor but fast IPC) | ||
| 73 | * the value returned is a pointer to the allocated | ||
| 74 | * memory, which is suitably aligned for any kind of | ||
| 75 | * variable, or NULL if the request fails. | ||
| 76 | * | ||
| 77 | * TODO: on SVR4 use open("/dev/zero", O_RDWR); and mmap trick for speedup | ||
| 78 | */ | ||
| 79 | void * | ||
| 80 | shmalloc (int flag, size_t length) | ||
| 81 | { | ||
| 82 | void *shm_addr; | ||
| 83 | int c = 0; | ||
| 84 | |||
| 85 | if (shm_c == -1) /* init all the internal shm stuff */ | ||
| 86 | { | ||
| 87 | atexit (shmkillall); | ||
| 88 | shm_c = 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (shm_c >= MAXSHM) | ||
| 92 | return (NULL); /* no space left in list. no bscan ?? */ | ||
| 93 | |||
| 94 | if (flag == 0) | ||
| 95 | flag = (IPC_CREAT | IPC_EXCL | SHM_R | SHM_W); | ||
| 96 | |||
| 97 | while (c < SHMMNI) /* brute force a NEW shared memory section */ | ||
| 98 | if ((shm_id = shmget (getpid () + c++, length, flag)) != -1) | ||
| 99 | break; | ||
| 100 | else | ||
| 101 | return (NULL); | ||
| 102 | |||
| 103 | if ((shm_addr = shmat (shm_id, NULL, 0)) == NULL) | ||
| 104 | return (NULL); | ||
| 105 | |||
| 106 | shm[shm_c].id = shm_id; | ||
| 107 | shm[shm_c].ptr = shm_addr; | ||
| 108 | shm_c++; /* increase shm-counter */ | ||
| 109 | |||
| 110 | return (shm_addr); | ||
| 111 | } | ||
| 112 | |||
| 113 | #ifdef WITH_NANOSLEEP | ||
| 114 | /* add lib '-lrt' */ | ||
| 115 | /* | ||
| 116 | * nanosec must be in the range 0 to 999 999 999 | ||
| 117 | * ..we dont care about signals here... | ||
| 118 | */ | ||
| 119 | void | ||
| 120 | do_nanosleep (time_t sec, long nsec) | ||
| 121 | { | ||
| 122 | struct timespec mynano; | ||
| 123 | mynano.tv_sec = sec; | ||
| 124 | mynano.tv_nsec = nsec; | ||
| 125 | nanosleep (&mynano, NULL); | ||
| 126 | } | ||
| 127 | #endif | ||
| 128 | |||
| 129 | |||
| 130 | /* | ||
| 131 | * xchange data p1 <-> p2 of length len | ||
| 132 | */ | ||
| 133 | void | ||
| 134 | xchange (void *p1, void *p2, int len) | ||
| 135 | { | ||
| 136 | unsigned char buf[len]; | ||
| 137 | |||
| 138 | memcpy (buf, p1, len); | ||
| 139 | memcpy (p1, p2, len); | ||
| 140 | memcpy (p2, buf, len); | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * calculate time-difference now - in | ||
| 145 | * and return diff in 'now' | ||
| 146 | */ | ||
| 147 | void | ||
| 148 | time_diff (struct timeval *in, struct timeval *now) | ||
| 149 | { | ||
| 150 | if ((now->tv_usec -= in->tv_usec) < 0) | ||
| 151 | { | ||
| 152 | now->tv_sec--; | ||
| 153 | now->tv_usec += 1000000; | ||
| 154 | } | ||
| 155 | now->tv_sec -= in->tv_sec; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* | ||
| 159 | * converts a 'esc-sequenced' string to normal string | ||
| 160 | * return string in dst. | ||
| 161 | * returns 0 on success | ||
| 162 | * todo: \ddd decoding | ||
| 163 | */ | ||
| 164 | int | ||
| 165 | ctoreal(char *src, char *dst) | ||
| 166 | { | ||
| 167 | char c; | ||
| 168 | |||
| 169 | if ((src == NULL) || (dst == NULL)) | ||
| 170 | { | ||
| 171 | dst = NULL; | ||
| 172 | return(0); /* yes, its ok. */ | ||
| 173 | } | ||
| 174 | |||
| 175 | while (*src != '\0') | ||
| 176 | if (*src == '\\') | ||
| 177 | { | ||
| 178 | switch((c = *++src)) | ||
| 179 | { | ||
| 180 | case 'n': | ||
| 181 | *dst++ = '\n'; | ||
| 182 | break; | ||
| 183 | case 'r': | ||
| 184 | *dst++ = '\r'; | ||
| 185 | break; | ||
| 186 | case 't': | ||
| 187 | *dst++ = '\t'; | ||
| 188 | break; | ||
| 189 | case '\\': | ||
| 190 | *dst++ = '\\'; | ||
| 191 | break; | ||
| 192 | case 's': | ||
| 193 | *dst++ = ' '; | ||
| 194 | break; | ||
| 195 | default: | ||
| 196 | *dst++ = c; | ||
| 197 | /* printf("unknown escape sequence 0x%2.2x\n", c);*/ | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | src++; | ||
| 201 | } else | ||
| 202 | { | ||
| 203 | *dst++ = *src++; | ||
| 204 | } | ||
| 205 | *dst = '\0'; | ||
| 206 | return(0); | ||
| 207 | } | ||
| 208 | |||
| 209 | |||
| 210 | /* | ||
| 211 | * parse data, format data and print to fd (only prinatable chars) | ||
| 212 | * supress \r, nonprintable -> '_'; | ||
| 213 | * output line by line [\n] with 'prefix' before each line. | ||
| 214 | * prefix is a 0-terminated string | ||
| 215 | */ | ||
| 216 | void | ||
| 217 | save_write(FILE *fd, char *prefix, unsigned char *data, int data_len) | ||
| 218 | { | ||
| 219 | int c; | ||
| 220 | unsigned char *ptr = data; | ||
| 221 | unsigned char *startptr = data; | ||
| 222 | const char trans[] = | ||
| 223 | "................................ !\"#$%&'()*+,-./0123456789" | ||
| 224 | ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm" | ||
| 225 | "nopqrstuvwxyz{|}~...................................." | ||
| 226 | "....................................................." | ||
| 227 | "........................................"; | ||
| 228 | |||
| 229 | |||
| 230 | if (prefix == NULL) | ||
| 231 | prefix = ""; | ||
| 232 | |||
| 233 | for (c = 0; c < data_len; c++) | ||
| 234 | { | ||
| 235 | if (*data == '\r') /* i dont like these */ | ||
| 236 | { | ||
| 237 | data++; | ||
| 238 | continue; | ||
| 239 | } | ||
| 240 | if (*data == '\n') | ||
| 241 | { | ||
| 242 | *ptr = '\0'; | ||
| 243 | fprintf (fd, "%s%s\n", prefix, startptr); | ||
| 244 | startptr = ++data; | ||
| 245 | ptr = startptr; | ||
| 246 | continue; | ||
| 247 | } | ||
| 248 | |||
| 249 | *ptr++ = trans[*data++]; | ||
| 250 | |||
| 251 | } | ||
| 252 | |||
| 253 | if (ptr != startptr) | ||
| 254 | { | ||
| 255 | *ptr = '\0'; | ||
| 256 | fprintf (fd, "%s%s\n", prefix, startptr); | ||
| 257 | } | ||
| 258 | |||
| 259 | } | ||
| 260 | |||
| 261 | /* | ||
| 262 | * check if data contains any non-printable chars [except \n] | ||
| 263 | * return 0 if yes,,,,1 if not. | ||
| 264 | */ | ||
| 265 | int | ||
| 266 | isprintdata(char *ptr, int len) | ||
| 267 | { | ||
| 268 | char c; | ||
| 269 | |||
| 270 | while(len-- > 0) | ||
| 271 | { | ||
| 272 | c = *ptr++; | ||
| 273 | if (c == '\n') | ||
| 274 | continue; | ||
| 275 | if (!isprint((int)c)) | ||
| 276 | return(0); | ||
| 277 | } | ||
| 278 | |||
| 279 | return(1); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* | ||
| 283 | * convert some data into hex string | ||
| 284 | * We DO 0 terminate the string. | ||
| 285 | * dest = destination | ||
| 286 | * destlen = max. length of dest (size of allocated memory) | ||
| 287 | * data = (non)printable input data | ||
| 288 | * len = input data len | ||
| 289 | * return 0 on success, 1 if data does not fit into dest, -1 on error | ||
| 290 | */ | ||
| 291 | int | ||
| 292 | dat2hexstr(unsigned char *dest, unsigned int destlen, unsigned char *data, | ||
| 293 | unsigned int len) | ||
| 294 | { | ||
| 295 | unsigned int i = 0; | ||
| 296 | unsigned int slen = 0; | ||
| 297 | unsigned char *ptr = dest; | ||
| 298 | unsigned char c; | ||
| 299 | char hex[] = "0123456789ABCDEF"; | ||
| 300 | |||
| 301 | memset(dest, '\0', destlen); | ||
| 302 | |||
| 303 | while (i++ < len) | ||
| 304 | { | ||
| 305 | c = *data++; | ||
| 306 | if (slen + 3 < destlen) | ||
| 307 | { | ||
| 308 | *dest++ = hex[c / 16]; | ||
| 309 | *dest++ = hex[c % 16]; | ||
| 310 | *dest++ = ' '; | ||
| 311 | slen += 3; | ||
| 312 | ptr += 3; | ||
| 313 | } else { | ||
| 314 | return(1); | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | return(0); | ||
| 319 | } | ||
| 320 | |||
| 321 | |||
| 322 | /* dat2strip | ||
| 323 | * | ||
| 324 | * print the data at `data', which is `len' bytes long to the char | ||
| 325 | * array `dest', which is `destlen' characters long. filter out any | ||
| 326 | * non-printables. NUL terminate the dest array in every case. | ||
| 327 | * | ||
| 328 | * return the number of characters written | ||
| 329 | */ | ||
| 330 | |||
| 331 | int | ||
| 332 | dat2strip(unsigned char *dest, unsigned int destlen, unsigned char *data, | ||
| 333 | unsigned int len) | ||
| 334 | { | ||
| 335 | unsigned char *dp; | ||
| 336 | |||
| 337 | for (dp = dest ; dp - dest < destlen && len > 0 ; --len, ++data, ++dp) { | ||
| 338 | if (isprint (*data)) | ||
| 339 | *dp = *data; | ||
| 340 | } | ||
| 341 | |||
| 342 | if (dp - dest < destlen) | ||
| 343 | *dp = '\0'; | ||
| 344 | dest[destlen - 1] = '\0'; | ||
| 345 | |||
| 346 | return (dp - dest); | ||
| 347 | } | ||
| 348 | |||
| 349 | |||
diff --git a/other/b-scan/tmp/src/test_garage.c b/other/b-scan/tmp/src/test_garage.c new file mode 100644 index 0000000..06acf61 --- /dev/null +++ b/other/b-scan/tmp/src/test_garage.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* test_garage.c - test program for the garage module | ||
| 2 | * | ||
| 3 | * by scut / teso | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <time.h> | ||
| 10 | #include <garage.h> | ||
| 11 | |||
| 12 | |||
| 13 | void | ||
| 14 | cleaner_t (ip_list *il); | ||
| 15 | |||
| 16 | int | ||
| 17 | main (int argc, char *argv[]) | ||
| 18 | { | ||
| 19 | int data_len; | ||
| 20 | unsigned char * data; | ||
| 21 | unsigned long int ip, | ||
| 22 | gip = 0; | ||
| 23 | unsigned long int ips; | ||
| 24 | garage_hdlr * hdl; | ||
| 25 | unsigned long int maxkeep; | ||
| 26 | |||
| 27 | printf ("mg_cidr_getmask (20) = 0x%08lx\n", mg_cidr_getmask (20)); | ||
| 28 | printf ("mg_cidr_getmask (0xffffffc0) = 0x%08lx\n", mg_cidr_getmask (0xffffffc0)); | ||
| 29 | |||
| 30 | if (argc < 2 || sscanf (argv[1], "%lu", &ips) != 1) { | ||
| 31 | printf ("usage: %s <number-of-ips> [maxkeep]\n\n", argv[0]); | ||
| 32 | |||
| 33 | exit (EXIT_FAILURE); | ||
| 34 | } | ||
| 35 | if (argc == 3 && sscanf (argv[2], "%lu", &maxkeep) != 1) | ||
| 36 | exit (EXIT_FAILURE); | ||
| 37 | |||
| 38 | srand (time (NULL)); | ||
| 39 | hdl = mg_init ("footest", maxkeep, cleaner_t); | ||
| 40 | |||
| 41 | printf ("mg_cidr_getmask (0) = 0x%08lx\n", mg_cidr_getmask (0)); | ||
| 42 | |||
| 43 | mg_write (hdl, 2048, "foobar", 7, 0); | ||
| 44 | mg_write (hdl, 2050, "foobar", 7, 0); | ||
| 45 | mg_write (hdl, 101911, "foobar", 7, 0); | ||
| 46 | mg_write (hdl, 28914191, "foobar", 7, 0); | ||
| 47 | printf ("mg_cidr_count (hdl, 2048, 32) = %lu\n", mg_cidr_count (hdl, 2048, 32)); | ||
| 48 | printf ("mg_cidr_count (hdl, 2048, 31) = %lu\n", mg_cidr_count (hdl, 2048, 31)); | ||
| 49 | printf ("mg_cidr_count (hdl, 2048, 30) = %lu\n", mg_cidr_count (hdl, 2048, 30)); | ||
| 50 | printf ("mg_cidr_count (hdl, 2048, 13) = %lu\n", mg_cidr_count (hdl, 2048, 13)); | ||
| 51 | printf ("mg_cidr_count (hdl, 2048, 0) = %lu\n", mg_cidr_count (hdl, 2048, 0)); | ||
| 52 | |||
| 53 | |||
| 54 | ip = 123; | ||
| 55 | mg_write (hdl, ip, "foo", 4, 0); | ||
| 56 | mg_read (hdl, ip); | ||
| 57 | mg_clean (hdl, ip, NULL); | ||
| 58 | |||
| 59 | do { | ||
| 60 | ip = rand (); | ||
| 61 | |||
| 62 | data_len = rand () % 64; | ||
| 63 | data_len += 1; /* avoid allocating zero bytes */ | ||
| 64 | data = malloc (data_len); | ||
| 65 | memset (data, '\x73', data_len); | ||
| 66 | data[data_len - 1] = '\0'; | ||
| 67 | |||
| 68 | mg_write (hdl, ip, (void *) data, data_len, 1); | ||
| 69 | if (ips % 137 == 0) | ||
| 70 | gip = ip; | ||
| 71 | |||
| 72 | if (ips % 139 == 0) | ||
| 73 | (void) mg_read (hdl, gip); | ||
| 74 | |||
| 75 | ips -= 1; | ||
| 76 | if (ips % 5000 == 0) | ||
| 77 | mg_show (hdl); | ||
| 78 | |||
| 79 | } while (ips > 0); | ||
| 80 | |||
| 81 | mg_show (hdl); | ||
| 82 | mg_destroy (hdl, 0); | ||
| 83 | |||
| 84 | exit (EXIT_SUCCESS); | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | void | ||
| 89 | cleaner_t (ip_list *il) | ||
| 90 | { | ||
| 91 | if ((rand () % 20000) == 0) | ||
| 92 | printf ("cleaner_t: il = 0x%08lx IP = 0x%08lx\n", | ||
| 93 | (unsigned long int) il, | ||
| 94 | il->ip); | ||
| 95 | |||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
diff --git a/other/b-scan/tmp/src/tty.c b/other/b-scan/tmp/src/tty.c new file mode 100644 index 0000000..5c99b7f --- /dev/null +++ b/other/b-scan/tmp/src/tty.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | /* | ||
| 2 | * most of this stuff is ripped from solar's excelent john-1.6 source | ||
| 3 | */ | ||
| 4 | #include <sys/types.h> | ||
| 5 | #include <sys/stat.h> | ||
| 6 | #include <fcntl.h> | ||
| 7 | |||
| 8 | #include <unistd.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | #include <termios.h> | ||
| 11 | |||
| 12 | static int tty_fd = 0; | ||
| 13 | static int tty_buf = -1; | ||
| 14 | static struct termios saved_ti; | ||
| 15 | |||
| 16 | |||
| 17 | /* | ||
| 18 | * Reads a character, returns -1 if no data available or on error. | ||
| 19 | */ | ||
| 20 | int | ||
| 21 | tty_getchar () | ||
| 22 | { | ||
| 23 | int c; | ||
| 24 | |||
| 25 | /* | ||
| 26 | * process buffer first | ||
| 27 | */ | ||
| 28 | if (tty_buf != -1) | ||
| 29 | { | ||
| 30 | c = tty_buf; | ||
| 31 | tty_buf = -1; | ||
| 32 | return (c); | ||
| 33 | } | ||
| 34 | |||
| 35 | if (tty_fd) | ||
| 36 | { | ||
| 37 | c = 0; | ||
| 38 | if (read (tty_fd, &c, 1) > 0) | ||
| 39 | return c; | ||
| 40 | } | ||
| 41 | |||
| 42 | return (-1); | ||
| 43 | } | ||
| 44 | |||
| 45 | /* | ||
| 46 | * check if someone pressed a key | ||
| 47 | * Actually we do a read on the fd and store the result in a buffer | ||
| 48 | * todo: check with ioctl if data is pending | ||
| 49 | * return 1 is data is pending, 0 if not | ||
| 50 | */ | ||
| 51 | int | ||
| 52 | tty_ischar () | ||
| 53 | { | ||
| 54 | if (tty_buf != -1) | ||
| 55 | return (1); | ||
| 56 | |||
| 57 | if ((tty_buf = tty_getchar ()) != -1) | ||
| 58 | return (1); | ||
| 59 | |||
| 60 | return (0); | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | /* | ||
| 65 | * Restores the terminal parameters and closes the file descriptor. | ||
| 66 | */ | ||
| 67 | void | ||
| 68 | tty_done () | ||
| 69 | { | ||
| 70 | int fd; | ||
| 71 | |||
| 72 | if (!tty_fd) | ||
| 73 | return; | ||
| 74 | |||
| 75 | fd = tty_fd; | ||
| 76 | tty_fd = 0; | ||
| 77 | tcsetattr (fd, TCSANOW, &saved_ti); | ||
| 78 | |||
| 79 | close (fd); | ||
| 80 | } | ||
| 81 | |||
| 82 | |||
| 83 | /* | ||
| 84 | * Initializes the terminal for unbuffered non-blocking input. Also registers | ||
| 85 | * tty_done() via atexit(). | ||
| 86 | */ | ||
| 87 | void | ||
| 88 | tty_init () | ||
| 89 | { | ||
| 90 | int fd; | ||
| 91 | struct termios ti; | ||
| 92 | |||
| 93 | if (tty_fd) | ||
| 94 | return; | ||
| 95 | |||
| 96 | if ((fd = open ("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) | ||
| 97 | return; | ||
| 98 | |||
| 99 | if (tcgetpgrp (fd) != getpid ()) | ||
| 100 | { | ||
| 101 | close (fd); | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | tcgetattr (fd, &ti); | ||
| 106 | saved_ti = ti; | ||
| 107 | ti.c_lflag &= ~(ICANON | ECHO); | ||
| 108 | ti.c_cc[VINTR] = 3; /* CTRL-C is INTR */ | ||
| 109 | ti.c_cc[VMIN] = 1; | ||
| 110 | ti.c_cc[VTIME] = 0; | ||
| 111 | tcsetattr (fd, TCSANOW, &ti); | ||
| 112 | |||
| 113 | tty_fd = fd; | ||
| 114 | |||
| 115 | atexit (tty_done); | ||
| 116 | } | ||
diff --git a/other/b-scan/tmp/support/Makefile b/other/b-scan/tmp/support/Makefile new file mode 100644 index 0000000..4025e1f --- /dev/null +++ b/other/b-scan/tmp/support/Makefile | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | CC=gcc | ||
| 2 | COPT=-Wall -ggdb -I../include | ||
| 3 | DEFS=#-DDEBUG | ||
| 4 | OBJ=hpuxdl.o snprintf.o | ||
| 5 | |||
| 6 | # HPUX 11.00 | ||
| 7 | # DEFS=-DNEED_SNPRINTF -DHAVE_SHL_LOAD #-DDEBUG | ||
| 8 | |||
| 9 | # HPUX 10.20 | ||
| 10 | # DEFS=-DHP10 -DNEED_SNPRINTF -DHAVE_SHL_LOAD #-DDEBUG | ||
| 11 | |||
| 12 | all: $(OBJ) | ||
| 13 | |||
| 14 | .c.o: | ||
| 15 | $(CC) $(COPT) $(DEFS) -c $< | ||
| 16 | |||
| 17 | clean: | ||
| 18 | rm -f $(OBJ) core *~ | ||
| 19 | |||
| 20 | |||
diff --git a/other/b-scan/tmp/support/hpuxdl.c b/other/b-scan/tmp/support/hpuxdl.c new file mode 100644 index 0000000..accaed9 --- /dev/null +++ b/other/b-scan/tmp/support/hpuxdl.c | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | #ifdef HAVE_SHL_LOAD | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <errno.h> | ||
| 5 | #include <dl.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This is a minimal implementation of the ELF dlopen, dlclose, dlsym | ||
| 9 | * and dlerror routines based on HP's shl_load, shl_unload and | ||
| 10 | * shl_findsym. */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Reference Counting. | ||
| 14 | * | ||
| 15 | * Empirically it looks like the HP routines do not maintain a | ||
| 16 | * reference count, so I maintain one here. | ||
| 17 | */ | ||
| 18 | |||
| 19 | typedef struct lib_entry { | ||
| 20 | shl_t handle; | ||
| 21 | int count; | ||
| 22 | struct lib_entry *next; | ||
| 23 | } *LibEntry; | ||
| 24 | |||
| 25 | #define lib_entry_handle(e) ((e)->handle) | ||
| 26 | #define lib_entry_count(e) ((e)->count) | ||
| 27 | #define lib_entry_next(e) ((e)->next) | ||
| 28 | #define set_lib_entry_handle(e,v) ((e)->handle = (v)) | ||
| 29 | #define set_lib_entry_count(e,v) ((e)->count = (v)) | ||
| 30 | #define set_lib_entry_next(e,v) ((e)->next = (v)) | ||
| 31 | #define increment_lib_entry_count(e) ((e)->count++) | ||
| 32 | #define decrement_lib_entry_count(e) ((e)->count--) | ||
| 33 | |||
| 34 | static LibEntry Entries = NULL; | ||
| 35 | |||
| 36 | static LibEntry find_lib_entry(shl_t handle) | ||
| 37 | { | ||
| 38 | LibEntry entry; | ||
| 39 | |||
| 40 | for (entry = Entries; entry != NULL; entry = lib_entry_next(entry)) | ||
| 41 | if (lib_entry_handle(entry) == handle) | ||
| 42 | return entry; | ||
| 43 | return NULL; | ||
| 44 | } | ||
| 45 | |||
| 46 | static LibEntry new_lib_entry(shl_t handle) | ||
| 47 | { | ||
| 48 | LibEntry entry; | ||
| 49 | |||
| 50 | if ((entry = (LibEntry) malloc(sizeof(struct lib_entry))) != NULL) { | ||
| 51 | set_lib_entry_handle(entry, handle); | ||
| 52 | set_lib_entry_count(entry, 1); | ||
| 53 | set_lib_entry_next(entry, Entries); | ||
| 54 | Entries = entry; | ||
| 55 | } | ||
| 56 | return entry; | ||
| 57 | } | ||
| 58 | |||
| 59 | static void free_lib_entry(LibEntry entry) | ||
| 60 | { | ||
| 61 | if (entry == Entries) | ||
| 62 | Entries = lib_entry_next(entry); | ||
| 63 | else { | ||
| 64 | LibEntry last, next; | ||
| 65 | for (last = Entries, next = lib_entry_next(last); | ||
| 66 | next != NULL; | ||
| 67 | last = next, next = lib_entry_next(last)) { | ||
| 68 | if (entry == next) { | ||
| 69 | set_lib_entry_next(last, lib_entry_next(entry)); | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | free(entry); | ||
| 75 | } | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Error Handling. | ||
| 79 | */ | ||
| 80 | |||
| 81 | #define ERRBUFSIZE 1000 | ||
| 82 | |||
| 83 | static char errbuf[ERRBUFSIZE]; | ||
| 84 | static int dlerrno = 0; | ||
| 85 | |||
| 86 | char *dlerror(void) | ||
| 87 | { | ||
| 88 | return dlerrno ? errbuf : NULL; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Opening and Closing Liraries. | ||
| 93 | */ | ||
| 94 | |||
| 95 | void *dlopen(const char *fname, int mode) | ||
| 96 | { | ||
| 97 | shl_t handle; | ||
| 98 | LibEntry entry = NULL; | ||
| 99 | |||
| 100 | dlerrno = 0; | ||
| 101 | if (fname == NULL) | ||
| 102 | handle = PROG_HANDLE; | ||
| 103 | else { | ||
| 104 | handle = shl_load(fname, mode, 0L); | ||
| 105 | if (handle != NULL) { | ||
| 106 | if ((entry = find_lib_entry(handle)) == NULL) { | ||
| 107 | if ((entry = new_lib_entry(handle)) == NULL) { | ||
| 108 | shl_unload(handle); | ||
| 109 | handle = NULL; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | else | ||
| 113 | increment_lib_entry_count(entry); | ||
| 114 | } | ||
| 115 | if (handle == NULL) { | ||
| 116 | char *errstr; | ||
| 117 | dlerrno = errno; | ||
| 118 | errstr = strerror(errno); | ||
| 119 | if (errno == NULL) errstr = "???"; | ||
| 120 | sprintf(errbuf, "can't open %s: %s", fname, errstr); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | #ifdef DEBUG | ||
| 124 | printf("opening library %s, handle = %x, count = %d\n", | ||
| 125 | fname, handle, entry ? lib_entry_count(entry) : -1); | ||
| 126 | if (dlerrno) printf("%s\n", dlerror()); | ||
| 127 | #endif | ||
| 128 | return (void *) handle; | ||
| 129 | } | ||
| 130 | |||
| 131 | int dlclose(void *handle) | ||
| 132 | { | ||
| 133 | LibEntry entry; | ||
| 134 | #ifdef DEBUG | ||
| 135 | entry = find_lib_entry(handle); | ||
| 136 | printf("closing library handle = %x, count = %d\n", | ||
| 137 | handle, entry ? lib_entry_count(entry) : -1); | ||
| 138 | #endif | ||
| 139 | |||
| 140 | dlerrno = 0; | ||
| 141 | if ((shl_t) handle == PROG_HANDLE) | ||
| 142 | return 0; /* ignore attempts to close main program */ | ||
| 143 | else { | ||
| 144 | |||
| 145 | if ((entry = find_lib_entry((shl_t) handle)) != NULL) { | ||
| 146 | decrement_lib_entry_count(entry); | ||
| 147 | if (lib_entry_count(entry) > 0) | ||
| 148 | return 0; | ||
| 149 | else { | ||
| 150 | /* unload once reference count reaches zero */ | ||
| 151 | free_lib_entry(entry); | ||
| 152 | if (shl_unload((shl_t) handle) == 0) | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | } | ||
| 156 | /* if you get to here, an error has occurred */ | ||
| 157 | dlerrno = 1; | ||
| 158 | sprintf(errbuf, "attempt to close library failed"); | ||
| 159 | #ifdef DEBUG | ||
| 160 | printf("%s\n", dlerror()); | ||
| 161 | #endif | ||
| 162 | return -1; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Symbol Lookup. | ||
| 168 | */ | ||
| 169 | |||
| 170 | void *dlsym(void *handle, const char *name) | ||
| 171 | { | ||
| 172 | void *f; | ||
| 173 | shl_t myhandle; | ||
| 174 | |||
| 175 | dlerrno = 0; | ||
| 176 | myhandle = (handle == NULL) ? PROG_HANDLE : (shl_t) handle; | ||
| 177 | |||
| 178 | if (shl_findsym(&myhandle, name, TYPE_PROCEDURE, &f) != 0) { | ||
| 179 | dlerrno = 1; | ||
| 180 | sprintf(errbuf, "symbol %s not found", name); | ||
| 181 | f = NULL; | ||
| 182 | } | ||
| 183 | |||
| 184 | return(f); | ||
| 185 | } | ||
| 186 | |||
| 187 | #endif | ||
diff --git a/other/b-scan/tmp/support/snprintf.c b/other/b-scan/tmp/support/snprintf.c new file mode 100644 index 0000000..f6a7a40 --- /dev/null +++ b/other/b-scan/tmp/support/snprintf.c | |||
| @@ -0,0 +1,331 @@ | |||
| 1 | #ifdef NEED_SNPRINTF | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | #include <string.h> | ||
| 6 | |||
| 7 | #ifndef __P | ||
| 8 | #define __P(p) p | ||
| 9 | #endif | ||
| 10 | |||
| 11 | #include <stdarg.h> | ||
| 12 | #define VA_LOCAL_DECL va_list ap; | ||
| 13 | #define VA_START(f) va_start(ap, f) | ||
| 14 | #define VA_END va_end(ap) | ||
| 15 | |||
| 16 | #ifdef SOLARIS2 | ||
| 17 | #ifdef _FILE_OFFSET_BITS | ||
| 18 | #define SOLARIS26 | ||
| 19 | #endif | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #ifdef SOLARIS26 | ||
| 23 | #define HAS_SNPRINTF | ||
| 24 | #define HAS_VSNPRINTF | ||
| 25 | #endif | ||
| 26 | #ifdef _SCO_DS_ | ||
| 27 | #define HAS_SNPRINTF | ||
| 28 | #endif | ||
| 29 | #ifdef luna2 | ||
| 30 | #define HAS_VSNPRINTF | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /************************************************************** | ||
| 34 | * Original: | ||
| 35 | * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 | ||
| 36 | * A bombproof version of doprnt (dopr) included. | ||
| 37 | * Sigh. This sort of thing is always nasty do deal with. Note that | ||
| 38 | * the version here does not include floating point... | ||
| 39 | * | ||
| 40 | * snprintf() is used instead of sprintf() as it does limit checks | ||
| 41 | * for string length. This covers a nasty loophole. | ||
| 42 | * | ||
| 43 | * The other functions are there to prevent NULL pointers from | ||
| 44 | * causing nast effects. | ||
| 45 | **************************************************************/ | ||
| 46 | |||
| 47 | static void dopr(char *, const char *, va_list); | ||
| 48 | static char *end; | ||
| 49 | |||
| 50 | #ifndef HAS_VSNPRINTF | ||
| 51 | int vsnprintf(char *str, size_t count, const char *fmt, va_list args) | ||
| 52 | { | ||
| 53 | str[0] = 0; | ||
| 54 | end = str + count - 1; | ||
| 55 | dopr(str, fmt, args); | ||
| 56 | if (count > 0) | ||
| 57 | end[0] = 0; | ||
| 58 | return strlen(str); | ||
| 59 | } | ||
| 60 | |||
| 61 | #ifndef HAS_SNPRINTF | ||
| 62 | /* VARARGS3 */ | ||
| 63 | int snprintf(char *str, size_t count, const char *fmt,...) | ||
| 64 | { | ||
| 65 | int len; | ||
| 66 | VA_LOCAL_DECL | ||
| 67 | |||
| 68 | VA_START(fmt); | ||
| 69 | len = vsnprintf(str, count, fmt, ap); | ||
| 70 | VA_END; | ||
| 71 | return len; | ||
| 72 | } | ||
| 73 | #endif | ||
| 74 | |||
| 75 | /* | ||
| 76 | * dopr(): poor man's version of doprintf | ||
| 77 | */ | ||
| 78 | |||
| 79 | static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth)); | ||
| 80 | static void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad)); | ||
| 81 | static void dostr __P((char *, int)); | ||
| 82 | static char *output; | ||
| 83 | static void dopr_outch __P((int c)); | ||
| 84 | |||
| 85 | static void dopr(char *buffer, const char *format, va_list args) | ||
| 86 | { | ||
| 87 | int ch; | ||
| 88 | long value; | ||
| 89 | int longflag = 0; | ||
| 90 | int pointflag = 0; | ||
| 91 | int maxwidth = 0; | ||
| 92 | char *strvalue; | ||
| 93 | int ljust; | ||
| 94 | int len; | ||
| 95 | int zpad; | ||
| 96 | |||
| 97 | output = buffer; | ||
| 98 | while ((ch = *format++)) { | ||
| 99 | switch (ch) { | ||
| 100 | case '%': | ||
| 101 | ljust = len = zpad = maxwidth = 0; | ||
| 102 | longflag = pointflag = 0; | ||
| 103 | nextch: | ||
| 104 | ch = *format++; | ||
| 105 | switch (ch) { | ||
| 106 | case 0: | ||
| 107 | dostr("**end of format**", 0); | ||
| 108 | return; | ||
| 109 | case '-': | ||
| 110 | ljust = 1; | ||
| 111 | goto nextch; | ||
| 112 | case '0': /* set zero padding if len not set */ | ||
| 113 | if (len == 0 && !pointflag) | ||
| 114 | zpad = '0'; | ||
| 115 | case '1': | ||
| 116 | case '2': | ||
| 117 | case '3': | ||
| 118 | case '4': | ||
| 119 | case '5': | ||
| 120 | case '6': | ||
| 121 | case '7': | ||
| 122 | case '8': | ||
| 123 | case '9': | ||
| 124 | if (pointflag) | ||
| 125 | maxwidth = maxwidth * 10 + ch - '0'; | ||
| 126 | else | ||
| 127 | len = len * 10 + ch - '0'; | ||
| 128 | goto nextch; | ||
| 129 | case '*': | ||
| 130 | if (pointflag) | ||
| 131 | maxwidth = va_arg(args, int); | ||
| 132 | else | ||
| 133 | len = va_arg(args, int); | ||
| 134 | goto nextch; | ||
| 135 | case '.': | ||
| 136 | pointflag = 1; | ||
| 137 | goto nextch; | ||
| 138 | case 'l': | ||
| 139 | longflag = 1; | ||
| 140 | goto nextch; | ||
| 141 | case 'u': | ||
| 142 | case 'U': | ||
| 143 | /*fmtnum(value,base,dosign,ljust,len,zpad) */ | ||
| 144 | if (longflag) { | ||
| 145 | value = va_arg(args, long); | ||
| 146 | } | ||
| 147 | else { | ||
| 148 | value = va_arg(args, int); | ||
| 149 | } | ||
| 150 | fmtnum(value, 10, 0, ljust, len, zpad); | ||
| 151 | break; | ||
| 152 | case 'o': | ||
| 153 | case 'O': | ||
| 154 | /*fmtnum(value,base,dosign,ljust,len,zpad) */ | ||
| 155 | if (longflag) { | ||
| 156 | value = va_arg(args, long); | ||
| 157 | } | ||
| 158 | else { | ||
| 159 | value = va_arg(args, int); | ||
| 160 | } | ||
| 161 | fmtnum(value, 8, 0, ljust, len, zpad); | ||
| 162 | break; | ||
| 163 | case 'd': | ||
| 164 | case 'D': | ||
| 165 | if (longflag) { | ||
| 166 | value = va_arg(args, long); | ||
| 167 | } | ||
| 168 | else { | ||
| 169 | value = va_arg(args, int); | ||
| 170 | } | ||
| 171 | fmtnum(value, 10, 1, ljust, len, zpad); | ||
| 172 | break; | ||
| 173 | case 'x': | ||
| 174 | if (longflag) { | ||
| 175 | value = va_arg(args, long); | ||
| 176 | } | ||
| 177 | else { | ||
| 178 | value = va_arg(args, int); | ||
| 179 | } | ||
| 180 | fmtnum(value, 16, 0, ljust, len, zpad); | ||
| 181 | break; | ||
| 182 | case 'X': | ||
| 183 | if (longflag) { | ||
| 184 | value = va_arg(args, long); | ||
| 185 | } | ||
| 186 | else { | ||
| 187 | value = va_arg(args, int); | ||
| 188 | } | ||
| 189 | fmtnum(value, -16, 0, ljust, len, zpad); | ||
| 190 | break; | ||
| 191 | case 's': | ||
| 192 | strvalue = va_arg(args, char *); | ||
| 193 | if (maxwidth > 0 || !pointflag) { | ||
| 194 | if (pointflag && len > maxwidth) | ||
| 195 | len = maxwidth; /* Adjust padding */ | ||
| 196 | fmtstr(strvalue, ljust, len, zpad, maxwidth); | ||
| 197 | } | ||
| 198 | break; | ||
| 199 | case 'c': | ||
| 200 | ch = va_arg(args, int); | ||
| 201 | dopr_outch(ch); | ||
| 202 | break; | ||
| 203 | case '%': | ||
| 204 | dopr_outch(ch); | ||
| 205 | continue; | ||
| 206 | default: | ||
| 207 | dostr("???????", 0); | ||
| 208 | } | ||
| 209 | break; | ||
| 210 | default: | ||
| 211 | dopr_outch(ch); | ||
| 212 | break; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | *output = 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static void fmtstr(char *value, int ljust, int len, int zpad, int maxwidth) | ||
| 219 | { | ||
| 220 | int padlen, strlen; /* amount to pad */ | ||
| 221 | |||
| 222 | if (value == 0) { | ||
| 223 | value = "<NULL>"; | ||
| 224 | } | ||
| 225 | for (strlen = 0; value[strlen]; ++strlen); /* strlen */ | ||
| 226 | if (strlen > maxwidth && maxwidth) | ||
| 227 | strlen = maxwidth; | ||
| 228 | padlen = len - strlen; | ||
| 229 | if (padlen < 0) | ||
| 230 | padlen = 0; | ||
| 231 | if (ljust) | ||
| 232 | padlen = -padlen; | ||
| 233 | while (padlen > 0) { | ||
| 234 | dopr_outch(' '); | ||
| 235 | --padlen; | ||
| 236 | } | ||
| 237 | dostr(value, maxwidth); | ||
| 238 | while (padlen < 0) { | ||
| 239 | dopr_outch(' '); | ||
| 240 | ++padlen; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | static void fmtnum(long value, int base, int dosign, int ljust, int len, int zpad) | ||
| 245 | { | ||
| 246 | int signvalue = 0; | ||
| 247 | unsigned long uvalue; | ||
| 248 | char convert[20]; | ||
| 249 | int place = 0; | ||
| 250 | int padlen = 0; /* amount to pad */ | ||
| 251 | int caps = 0; | ||
| 252 | |||
| 253 | /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", | ||
| 254 | value, base, dosign, ljust, len, zpad )); */ | ||
| 255 | uvalue = value; | ||
| 256 | if (dosign) { | ||
| 257 | if (value < 0) { | ||
| 258 | signvalue = '-'; | ||
| 259 | uvalue = -value; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | if (base < 0) { | ||
| 263 | caps = 1; | ||
| 264 | base = -base; | ||
| 265 | } | ||
| 266 | do { | ||
| 267 | convert[place++] = | ||
| 268 | (caps ? "0123456789ABCDEF" : "0123456789abcdef") | ||
| 269 | [uvalue % (unsigned) base]; | ||
| 270 | uvalue = (uvalue / (unsigned) base); | ||
| 271 | } while (uvalue); | ||
| 272 | convert[place] = 0; | ||
| 273 | padlen = len - place; | ||
| 274 | if (padlen < 0) | ||
| 275 | padlen = 0; | ||
| 276 | if (ljust) | ||
| 277 | padlen = -padlen; | ||
| 278 | /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", | ||
| 279 | convert,place,signvalue,padlen)); */ | ||
| 280 | if (zpad && padlen > 0) { | ||
| 281 | if (signvalue) { | ||
| 282 | dopr_outch(signvalue); | ||
| 283 | --padlen; | ||
| 284 | signvalue = 0; | ||
| 285 | } | ||
| 286 | while (padlen > 0) { | ||
| 287 | dopr_outch(zpad); | ||
| 288 | --padlen; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | while (padlen > 0) { | ||
| 292 | dopr_outch(' '); | ||
| 293 | --padlen; | ||
| 294 | } | ||
| 295 | if (signvalue) | ||
| 296 | dopr_outch(signvalue); | ||
| 297 | while (place > 0) | ||
| 298 | dopr_outch(convert[--place]); | ||
| 299 | while (padlen < 0) { | ||
| 300 | dopr_outch(' '); | ||
| 301 | ++padlen; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | static void dostr(char *str, int cut) | ||
| 306 | { | ||
| 307 | if (cut) { | ||
| 308 | while (*str && cut-- > 0) | ||
| 309 | dopr_outch(*str++); | ||
| 310 | } | ||
| 311 | else { | ||
| 312 | while (*str) | ||
| 313 | dopr_outch(*str++); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | static void dopr_outch(int c) | ||
| 318 | { | ||
| 319 | #if 0 | ||
| 320 | if (iscntrl(c) && c != '\n' && c != '\t') { | ||
| 321 | c = '@' + (c & 0x1F); | ||
| 322 | if (end == 0 || output < end) | ||
| 323 | *output++ = '^'; | ||
| 324 | } | ||
| 325 | #endif | ||
| 326 | if (end == 0 || output < end) | ||
| 327 | *output++ = c; | ||
| 328 | } | ||
| 329 | |||
| 330 | #endif /* HAVE_VSNPRINTF */ | ||
| 331 | #endif /*n NEED_SNPRINTF */ | ||
