Initial Commit
authorSamuel Jero <sj323707@ohio.edu>
Fri, 28 Jun 2013 03:51:03 +0000 (23:51 -0400)
committerSamuel Jero <sj323707@ohio.edu>
Fri, 28 Jun 2013 03:51:03 +0000 (23:51 -0400)
17 files changed:
.cproject [new file with mode: 0644]
.gitignore [new file with mode: 0644]
.project [new file with mode: 0644]
Changelog [new file with mode: 0644]
LICENSE [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
SLL.patch [new file with mode: 0644]
dccp_encap.c [new file with mode: 0644]
encap.c [new file with mode: 0644]
encap.h [new file with mode: 0644]
ltp.c [new file with mode: 0644]
ltp.h [new file with mode: 0644]
ltp2tcp.c [new file with mode: 0644]
ltp2tcp.h [new file with mode: 0644]
sll_encap.c [new file with mode: 0644]
udp_encap.c [new file with mode: 0644]

diff --git a/.cproject b/.cproject
new file mode 100644 (file)
index 0000000..8b7e15f
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1966700308">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1966700308" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="scannerConfiguration">
+                               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+                               <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="makefileGenerator">
+                                               <runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                               <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+                                       <buildOutputProvider>
+                                               <openAction enabled="true" filePath=""/>
+                                               <parser enabled="true"/>
+                                       </buildOutputProvider>
+                                       <scannerInfoProvider id="specsFile">
+                                               <runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+                                               <parser enabled="true"/>
+                                       </scannerInfoProvider>
+                               </profile>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.1966700308" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="cdt.managedbuild.toolchain.gnu.base.1966700308.801907047" name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.1075975217" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.883051863" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder id="cdt.managedbuild.target.gnu.builder.base.969101194" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1531162657" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1223899910" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.2040224232" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.51055088" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.57871697" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.184808408" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="ltp-tcp convert.null.1554396986" name="ltp-tcp convert"/>
+       </storageModule>
+</cproject>
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..a70237a
--- /dev/null
@@ -0,0 +1,2 @@
+*.o
+*~
diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..7e63dec
--- /dev/null
+++ b/.project
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>ltp-tcp convert</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                               <dictionary>
+                                       <key>?name?</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.append_environment</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildArguments</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildCommand</key>
+                                       <value>make</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+                                       <value>clean</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.contents</key>
+                                       <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+                                       <value>false</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.stopOnError</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+                                       <value>true</value>
+                               </dictionary>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+       </natures>
+</projectDescription>
diff --git a/Changelog b/Changelog
new file mode 100644 (file)
index 0000000..a4211e7
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,21 @@
+Version 0.2:
+       2/14/2011
+       New Features:
+       1)Session range option (-s). Allows you to graph only limited range of sessions
+         from a capture.
+       Bug Fixes:
+       1)Prevent Infinite loop by only processing one connection
+
+Version 0.1.1:
+       1/25/2011
+       Bug Fixes:
+       1)Invalid Encapsulation Length computations. A missing ntohs()
+
+Version 0.1:
+       1/23/2011
+       Initial Release
+       Known Issues:
+       1)Only handles one LTP "connection". There isn't a good way to separate
+               different LTP "connections" from new sessions of the same "connection".
+               Use Tcpdump filters to separate connections.
+       2)Uses some special types from Linux (u_char, u_int32_t)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..94a9ed0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  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.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  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.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            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
+state 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) <year>  <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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU 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 Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..60ca81b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,56 @@
+###############################################################################
+#Author: Samuel Jero
+#
+# Date: 12/2010
+#
+# Makefile for program ltptrace
+###############################################################################
+
+CFLAGS= -O2 -Wall -Werror
+
+# for solaris, you probably want:
+#      LDLIBS = -lpcap -lnsl -lsocket
+# for HP, I'm told that you need:
+#      LDLIBS = -lpcap -lstr
+# everybody else (that I know of) just needs:
+#      LDLIBS = -lpcap
+LDLIBS = -lpcap
+
+BINDIR = /usr/local/bin
+MANDIR = /usr/local/man
+
+
+all: ltptrace
+
+ltptrace: main.o ltp.o encap.o udp.o dccp.o sll.o Makefile
+       gcc ${CFLAGS} ${LDLIBS} --std=gnu99 main.o ltp.o encap.o udp.o dccp.o sll.o -oltptrace
+       
+main.o: ltp2tcp.c ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 ltp2tcp.c -omain.o
+
+ltp.o: ltp.c ltp.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 ltp.c -oltp.o
+
+encap.o: encap.c encap.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 encap.c -oencap.o
+       
+udp.o: udp_encap.c encap.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 udp_encap.c -oudp.o
+
+dccp.o: dccp_encap.c encap.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 dccp_encap.c -odccp.o
+
+sll.o: sll_encap.c encap.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 sll_encap.c -osll.o
+
+
+install: ltptrace
+       install -m 755 -o bin -g bin ltptrace ${BINDIR}/ltptrace
+#      install -m 444 -o bin -g bin ltptrace.1 ${MANDIR}/man1/ltptrace.1
+
+uninstall:
+       rm -f ${BINDIR}/ltptrace
+#      rm -f ${MANDIR}/man1/ltptrace.1
+
+clean:
+       rm -f *~ ltptrace core *.o
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..32970da
--- /dev/null
+++ b/README
@@ -0,0 +1,75 @@
+This program is the first step in an LTP connection graphing program. Right now
+it takes an LTP packet capture (LTP in UDP or DCCP in IP in Ethernet) and
+converts it to a TCP packet capture. When this TCP capture is examined using
+Tcptrace (http://www.tcptrace.org), you see a graphical description of the LTP
+connection.
+
+In order to build this program, please simply type make at the commandline. I have not
+included a ./configure script at this time. Contact me, if major problems arise.
+
+Usage is as follows:
+ltptrace -t{encapsulation} ltp_file tcp_file [-d] [-b{block_size}] [-s{start session}-{end session}]
+       -d is debug (repeat for additional verbosity)
+       -t specifies what protocol LTP is encapsulated in.  Right now, only udp and dccp are supported.
+       -b specifies the LTP block size (NOT the bundle size) that is being used over this connection.
+               This information can't be determined from a packet capture, so if not specified
+               it defaults to is 500,000. If you set this value larger than your actual block size, the graph
+               will contain empty spaces between each session, which is handy to separate sessions. However, in that case, tcptrace will report 
+               inaccurate, lost data statistics.
+       -s requests a graph of only the specified range of sessions. Note that the session numbers are just the "session number"
+               from wireshark, not the whole session id.
+
+To generate the graphs run:
+       ltptrace -tudp ltp_file.dmp tcp_file.dmp
+       tcptrace -lGt tcp_file.dmp
+       xplot a2b_tsg.xpl
+
+Plot Interpretation:
+   1. The only Tcptrace graphs that are valid are the Throughput Graph(tput) and Time Sequence Graph (tsg). 
+       The TSG is the main graph you want to look at.
+   2. White segments with arrows at both ends are LTP data segments (for those familiar with tcptrace,
+       these are represented by TCP data carrying packets).
+   3. Purple vertical lines are LTP report segments. The lines show the parts of the session that the receiver
+       is acknowledging (represented by TCP SACKS).
+   4. White crosses are LTP report acknowledgment segments (represented by TCP zero length data segments).
+   5. Retransmitted data is marked in red, just as in TCP.
+   6. LTP cancel and cancel ack segments have a RST_IN or RST_OUT over them (they become TCP Reset packets).
+   7. The green line is the point below which all data has been acknowledged, just as in TCP.
+   8. The yellow line has no meaning for LTP.
+   9. Note that there may be sequence number space between two adjacent sessions. This doesn't necessarily indicate loss.
+       Since the block size is not contained in the packet capture, we have to guess what it should be. If that guess is wrong,
+       there will be additional "space" in each session that isn't filled. Use the -b option to specify the correct block size
+       to eliminate this space.
+  10. A SYN/SYNACK/ACK and FIN/FINACK/ACK are added to the begining and end of the connection. These are purely to make the TCP
+       connections pretty and do not correspond to any packets in the LTP capture.
+
+Statistics:
+Most of the Tcptrace statistics are valid. However, those relating to the receiver's window are meaningless because the window represents nothing in the LTP capture. Unless the block size was specified, the "missed data" statistic is also wrong. The rest of the statistics, including those about the number of packets, number of retransmissions, idle time, and throughput are valid.
+
+
+Limitations:
+       1)Only handles one LTP "connection". There isn't a good way to separate
+               different LTP "connections" from new sessions of the same "connection".
+               Use Tcpdump filters to separate connections. Libpcap filtering could also
+               be added in ltptrace.
+       2)Uses some special types from Linux (u_char, u_int32_t)
+
+
+ltptrace 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 3 of the License, or
+(at your option) any later version.
+
+ltptrace 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 ltptrace.  If not, see <http://www.gnu.org/licenses/>.
+
+Samuel Jero
+Internetworking Research Group
+Ohio University
+sj323707@ohio.edu
+2/23/2011
diff --git a/SLL.patch b/SLL.patch
new file mode 100644 (file)
index 0000000..98b6cd8
--- /dev/null
+++ b/SLL.patch
@@ -0,0 +1,573 @@
+diff -r ab54ffb0cb71 Makefile
+--- a/Makefile Fri Mar 04 11:30:16 2011 -0500
++++ b/Makefile Thu May 19 01:11:51 2011 -0400
+@@ -22,8 +22,8 @@
+ all: ltptrace
+-ltptrace: main.o ltp.o encap.o udp.o dccp.o Makefile
+-      gcc ${CFLAGS} ${LDLIBS} --std=gnu99 main.o ltp.o encap.o udp.o dccp.o -oltptrace
++ltptrace: main.o ltp.o encap.o udp.o dccp.o sll.o Makefile
++      gcc ${CFLAGS} ${LDLIBS} --std=gnu99 main.o ltp.o encap.o udp.o dccp.o sll.o -oltptrace
+       
+ main.o: ltp2tcp.c ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 ltp2tcp.c -omain.o
+@@ -40,6 +40,9 @@
+ dccp.o: dccp_encap.c encap.h ltp2tcp.h
+       gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 dccp_encap.c -odccp.o
++sll.o: sll_encap.c encap.h ltp2tcp.h
++      gcc -c ${CFLAGS} ${LDLIBS} --std=gnu99 sll_encap.c -osll.o
++
+ install: ltptrace
+       install -m 755 -o bin -g bin ltptrace ${BINDIR}/ltptrace
+diff -r ab54ffb0cb71 encap.c
+--- a/encap.c  Fri Mar 04 11:30:16 2011 -0500
++++ b/encap.c  Thu May 19 01:11:51 2011 -0400
+@@ -20,6 +20,10 @@
+               state.en_ops=&dccp_encap;
+               return;
+       }
++      if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
++                      state.en_ops=&sll_encap;
++                      return;
++              }
+       printf("Encapsulation type: %s is not supported\n", string);
+       exit(1);
+ return;
+@@ -245,7 +249,6 @@
+       u_char                          *ptr;
+       struct pcap_pkthdr      nh;
+       u_int32_t                       temp;
+-      struct udp_en_p         *uep;
+       /*Safety Check*/
+       if(eip==NULL){
+@@ -275,7 +278,6 @@
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+-              uep=(struct udp_en_p *) state.en_priv;
+               memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+               /*Adjust IP header*/
+diff -r ab54ffb0cb71 LTP connection visualization/encap.h
+--- a/LTP connection visualization/encap.h     Fri Mar 04 11:30:16 2011 -0500
++++ b/LTP connection visualization/encap.h     Thu May 19 01:11:51 2011 -0400
+@@ -68,6 +68,7 @@
+ /*Encapsulation Operations Structures*/
+ extern struct encap_ops udp_encap;
+ extern struct encap_ops dccp_encap;
++extern struct encap_ops sll_encap;
+ /*Encapsulation Selector*/
+diff -r ab54ffb0cb71 sll_encap.c
+--- /dev/null  Thu Jan 01 00:00:00 1970 +0000
++++ b/sll_encap.c      Thu May 19 01:11:51 2011 -0400
+@@ -0,0 +1,487 @@
++/******************************************************************************
++Author: Samuel Jero
++
++Date: 5/2011
++
++Description:  <SLL, IPv4, UDP> encapsulation functions
++
++******************************************************************************/
++#include "ltp2tcp.h"
++#include <pcap/sll.h>
++#include <netinet/udp.h>
++
++extern int debug;
++
++
++
++/*SLL encapsulation private data structure*/
++struct sll_en_p{
++      int first;
++      struct pcap_pkthdr      header;
++      u_char                          od[sizeof(struct sll_header)+sizeof(struct iphdr)+sizeof(struct udphdr)];
++};
++
++
++/*Fill the encapsulation structure*/
++int fill_sllip4_encap(struct sll_en_p *slip, const u_char* data, int dlen, struct pcap_pkthdr *h){
++      /*safety check*/
++      if(slip==NULL || data==NULL || h==NULL || dlen < sizeof(struct sll_header)+sizeof(struct iphdr)){
++              dbgprintf(1, "Error: SLL, IPv4 Encapsulation method given bad data!\n");
++              return -1;
++      }
++
++      if(slip->first==0){
++              /* First time, allocate memory and copy libpcap header and encap headers
++               * this guarantees the IP "direction" of the encap headers */
++              memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
++              memcpy(slip->od, data,sizeof(struct sll_header)+sizeof(struct iphdr));
++              slip->first=1;
++      }else{
++              /* Just update the libpcap header (and associated timestamp)*/
++              memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
++      }
++      return 0;
++}
++
++/* encapsulation manipulation previous to packet conversion */
++int sll_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
++{
++      struct iphdr                    *iph;
++      struct sll_header               *slh;
++      struct udphdr                   *udph;
++
++      /*Safety checks*/
++      if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
++              dbgprintf(0,"Error: SLL Encapsulation given bad data!\n");
++              exit(1);
++      }
++      if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)
++                      || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
++                      dbgprintf(0, "Error: SLL Encapsulation given packet of wrong size!\n");
++                      return -1;
++      }
++
++      /*initialize encapsulation private data*/
++      if(state.en_priv==NULL){
++              /* First time, allocate memory and copy libpcap header and encap headers
++               * this guarantees the IP "direction" of the encap headers */
++              state.en_priv=malloc(sizeof(struct sll_en_p));
++              if(state.en_priv==NULL){
++                      dbgprintf(0,"Error: Couldn't allocate Memory\n");
++                      exit(1);
++              }
++      }
++      if(fill_sllip4_encap((struct sll_en_p*)state.en_priv, *odata, *olength, h)<0){
++              return -1;
++      }
++
++      /*Copy SLL and IPv4 headers over*/
++      memcpy(*ndata, *odata, sizeof(struct sll_header)+sizeof(struct iphdr));
++      *odata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++      *ndata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++
++      /*Confirm that this is Ethernet and that IPv4 is next*/
++      slh=(struct sll_header*)(*odata -sizeof(struct sll_header)- sizeof(struct iphdr));
++      if(slh->sll_protocol!=htons(ETHERTYPE_IP)){
++              dbgprintf(1, "Note: Packet not SLL or Not IPv4 next\n");
++              return -1;
++      }
++
++      /* Check That this is IPv4 and that UDP is next*/
++      iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
++      if(iph->version!=4){
++              dbgprintf(1, "Note: Packet is not IPv4\n");
++              return -1;
++      }
++      if(iph->protocol!=0x11){
++              dbgprintf(1, "Note: Packet is not UDP\n");
++              return -1;
++      }
++
++      /*set ip to indicate that tcp is next protocol*/
++      iph->protocol=6;
++      iph->check=htonl(0);
++
++      /* Adjust libpcap headers*/
++      h->caplen=sizeof(struct sll_header) +sizeof(struct iphdr);
++      h->len=sizeof(struct sll_header) +sizeof(struct iphdr);
++
++      /*Adjust packet length*/
++      udph=(struct udphdr*)*odata;
++      *olength=ntohs(udph->len);
++
++      /*Adjust New Packet Length*/
++      *nlength-=sizeof(struct sll_header) +sizeof(struct iphdr);
++
++      /*Move Packet Pointer past UDP header*/
++      *odata+=sizeof(struct udphdr);
++return 0;
++}
++
++/* encapsulation manipulation after conversion */
++int sll_encap_post(int tlen, u_char *data)
++{
++      struct iphdr *iph;
++
++      /* Move data pointer to start of IPv4 header*/
++      data+=sizeof(struct sll_header);
++
++      /*Determine if the given length is reasonable*/
++      if((tlen+sizeof(struct iphdr)) > 0xFFFF){
++                      dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
++                      return -1;
++      }
++
++      /*Adjust IPv4 header to account for packet's total length*/
++      iph=(struct iphdr*)data;
++      iph->tot_len=htons(sizeof(struct iphdr)+tlen);
++      return 0;
++}
++
++/* Create a TCP three-way handshake */
++int sll_encap_handshake(struct pcap_pkthdr *h)
++{
++      struct iphdr            *iph;
++      struct tcphdr           *tcph;
++      u_char                          *data;
++      u_char                          *ptr;
++      struct pcap_pkthdr      nh;
++      u_int32_t                       temp;
++      struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
++
++
++      /*Safety Check*/
++      if(h==NULL || state.en_priv==NULL){
++              dbgprintf(1, "Error: SLL, IPv4 Encapsulation handshake method given bad data!\n");
++              return -1;
++      }
++
++      /*create new libpcap header*/
++      memcpy(&nh, h, sizeof(struct pcap_pkthdr));
++
++      /*create buffer for new packet*/
++      ptr=data=malloc(MAX_PACKET);
++      if(data==NULL){
++              dbgprintf(0,"Error: Couldn't allocate Memory\n");
++              exit(1);
++      }
++
++      /* 1)Create Syn Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
++              nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
++
++              /* Copy SLL and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Adjust IP header*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=6;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=0;
++              tcph->syn=1;
++              tcph->rst=0;
++              tcph->ack=0;
++
++              /*Initialize Sequence and Acknowledgment Numbers and Window*/
++              tcph->seq=htonl(state.seq_num++);
++              tcph->ack_seq=htonl(0);
++              tcph->window=htons(WIN_FACTOR);
++
++              /* Add SACK permitted option*/
++              ptr+=sizeof(struct tcphdr);
++              *ptr=4;
++              ptr++;
++              *ptr=2;
++
++              /*Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++
++
++      /* 2)Create Syn,Ack Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
++              nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
++
++              /* Copy SLL and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Adjust IP header, including swapping source and destination*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              temp=iph->saddr;
++              iph->saddr=iph->daddr;
++              iph->daddr=temp;
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=6;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=0;
++              tcph->syn=1;
++              tcph->rst=0;
++              tcph->ack=1;
++
++              /*Initialize Sequence and Acknowledgement Numbers and Window*/
++              tcph->seq=htonl(state.ack_num++);
++              tcph->ack_seq=htonl(state.seq_num);
++              tcph->window=htons(WIN_FACTOR);
++
++              /* Add SACK permitted option*/
++              ptr+=sizeof(struct tcphdr);
++              *ptr=4;
++              ptr++;
++              *ptr=2;
++
++              /*Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++
++      /* 3)Create Ack Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
++
++              /* Copy SLL and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Adjust IP header*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=5;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=0;
++              tcph->syn=0;
++              tcph->rst=0;
++              tcph->ack=1;
++
++              /*Initialize Sequence and Acknowledgement numbers and window*/
++              tcph->seq=htonl(state.seq_num++);
++              tcph->ack_seq=htonl(state.ack_num);
++              tcph->window=htons(WIN_FACTOR);
++
++              /*Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++              return 0;
++}
++
++/* Create a TCP ending handshake */
++int sll_encap_fin()
++{
++      struct iphdr            *iph;
++      struct tcphdr           *tcph;
++      u_char                          *data;
++      u_char                          *ptr;
++      struct pcap_pkthdr      nh;
++      u_int32_t                       temp;
++      struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
++
++      /*Safety Check*/
++      if(slip==NULL){
++              dbgprintf(1,"Error: SLL, IPv4 Encapsulation Finish method given invalid data!\n");
++              return -1;
++      }
++
++      /*copy the libpcap header from private data area*/
++      memcpy(&nh, &slip->header, sizeof(struct pcap_pkthdr));
++
++      /*create buffer for new packet*/
++      ptr=data=malloc(MAX_PACKET);
++      if(data==NULL){
++              dbgprintf(0,"Error: Couldn't allocate Memory\n");
++              exit(1);
++      }
++
++      /* 1)Create Fin Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
++
++              /* Copy Ethernet and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Adjust IP header*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=5;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=1;
++              tcph->syn=0;
++              tcph->rst=0;
++              tcph->ack=1;
++
++              /* Adjust Sequence and Acknowledgment numbers and window*/
++              tcph->seq=htonl(++state.seq_num);
++              tcph->ack_seq=htonl(state.ack_num);
++              tcph->window=htons(WIN_FACTOR);
++
++              /*Update Sequence Number to include the fin packet in the sequence number space*/
++              state.seq_num++;
++
++              /* Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++
++      /* 2)Create Fin,Ack Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.ts.tv_usec+=1000; /*After the previous packet*/
++
++              /* Copy Ethernet and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Update IP header, including swapping source and destination addresses*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              temp=iph->saddr;
++              iph->saddr=iph->daddr;
++              iph->daddr=temp;
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=5;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=1;
++              tcph->syn=0;
++              tcph->rst=0;
++              tcph->ack=1;
++
++              /*Adjust Sequence and Acknowledgment numbers and window*/
++              tcph->seq=htonl(state.ack_num++);
++              tcph->ack_seq=htonl(state.seq_num);
++              tcph->window=htons(WIN_FACTOR);
++
++              /*Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++
++      /* 3)Create Ack Packet*/
++              /*make sure the packet is all zero*/
++              memset(data, 0, MAX_PACKET);
++              ptr=data;
++
++              /*Set the libpcap header*/
++              nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
++              nh.ts.tv_usec+=1000; /*After the previous packet*/
++
++              /* Copy Ethernet and IP headers from private data area*/
++              /* These are headers from the first packet in the capture*/
++              memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
++
++              /*Update IP header*/
++              iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
++              iph->protocol=6;
++              iph->check=htonl(0);
++              iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
++
++              /*Build TCP header*/
++              ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
++              tcph=(struct tcphdr*)ptr;
++              tcph->source=htons(1113);
++              tcph->dest=htons(1113);
++              tcph->doff=5;
++              tcph->check=htonl(0);
++              tcph->urg_ptr=0;
++              tcph->urg=0;
++              tcph->psh=0;
++              tcph->fin=0;
++              tcph->syn=0;
++              tcph->rst=0;
++              tcph->ack=1;
++
++              /*Adjust Sequence and Acknowledgment numbers and window*/
++              tcph->seq=htonl(state.seq_num++);
++              tcph->ack_seq=htonl(state.ack_num);
++              tcph->window=htons(WIN_FACTOR);
++
++              /*Save To Packet Capture*/
++              pcap_dump((u_char*)state.out,&nh, data);
++              return 0;
++}
++
++
++
++
++/* The UDP Encapsulation Structure*/
++struct encap_ops sll_encap = {
++      .pre=sll_encap_pre,
++      .post=sll_encap_post,
++};
+diff -r ab54ffb0cb71 udp_encap.c
+--- a/udp_encap.c      Fri Mar 04 11:30:16 2011 -0500
++++ b/udp_encap.c      Thu May 19 01:11:51 2011 -0400
+@@ -15,13 +15,6 @@
+-/*UDP encapsulation private data structure*/
+-struct udp_en_p{
+-      struct pcap_pkthdr      header;
+-      u_char                          od[sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)];
+-};
+-
+-
+ /* encapsulation manipulation previous to packet conversion */
+ int udp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
diff --git a/dccp_encap.c b/dccp_encap.c
new file mode 100644 (file)
index 0000000..1e0ec9f
--- /dev/null
@@ -0,0 +1,131 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  <ETH, IPv4, DCCP> encapsulation functions
+
+******************************************************************************/
+#include "ltp2tcp.h"
+#include <linux/dccp.h>
+
+
+
+extern int debug;
+
+
+
+/* encapsulation manipulation previous to packet conversion */
+int dccp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
+{
+       struct iphdr                    *iph;
+       struct ether_header             *ethh;
+       struct dccp_hdr                 *dccph;
+
+       /*Safety checks*/
+       if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
+               dbgprintf(0,"Error: DCCP Encapsulation given bad data!\n");
+               exit(1);
+       }
+       if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct dccp_hdr )
+                       || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
+                       dbgprintf(0, "Error: DCCP Encapsulation given packet of wrong size!\n");
+                       return -1;
+       }
+
+       /*Determine what type of DCCP packet this is*/
+       dccph=(struct dccp_hdr*) (*odata + sizeof(struct ether_header)+sizeof(struct iphdr));
+       if(dccph->dccph_type!=DCCP_PKT_DATA && dccph->dccph_type!=DCCP_PKT_DATAACK){
+               /*Packet Contains no data, discard*/
+               dbgprintf(2, "Note: DCCP Encapsulation discarding non-data-carrying packet. Type: %i\n", dccph->dccph_type);
+               return -1;
+       }
+
+       /*We have a data carrying packet, proceed to process*/
+
+
+       /*initialize encapsulation private data*/
+       if(state.en_priv==NULL){
+               /* First time, allocate memory and copy libpcap header and encap headers
+                * this guarantees the IP "direction" of the encap headers */
+               state.en_priv=malloc(sizeof(struct eip4_en_p));
+               if(state.en_priv==NULL){
+                       dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                       exit(1);
+               }
+       }
+       if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
+               return -1;
+       }
+
+       /*Copy Ethernet and IPv4 headers over*/
+       memcpy(*ndata, *odata, sizeof(struct ether_header)+sizeof(struct iphdr));
+       *odata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+       *ndata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+
+       /*Confirm that this is Ethernet and that IPv4 is next*/
+       ethh=(struct ether_header*)(*odata -sizeof(struct ether_header)- sizeof(struct iphdr));
+       if(ethh->ether_type!=htons(ETHERTYPE_IP)){
+               dbgprintf(1, "Note: Packet not Ethernet or Not IPv4 next\n");
+               return -1;
+       }
+
+       /* Check That this is IPv4 and that DCCP is next*/
+       iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
+       if(iph->version!=4){
+               dbgprintf(1, "Note: Packet is not IPv4\n");
+               return -1;
+       }
+       if(iph->protocol!=33){
+               dbgprintf(1, "Note: Packet is not DCCP\n");
+               return -1;
+       }
+
+       /*set IP to indicate that TCP is next protocol*/
+       iph->protocol=6;
+       iph->check=htonl(0);
+
+       /* Adjust libpcap headers*/
+       h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
+       h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
+
+       /*Adjust packet length*/
+       *olength=ntohs(iph->tot_len) - dccph->dccph_doff*4;
+
+       /*Adjust New Packet Length*/
+       *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
+
+       /*Move Packet Pointer past DCCP header*/
+       *odata+=dccph->dccph_doff*4;
+
+       return 0;
+}
+
+/* encapsulation manipulation after conversion */
+int dccp_encap_post(int tlen, u_char *data)
+{
+       return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
+}
+
+/* Create a TCP three-way handshake */
+int dccp_encap_handshake(struct pcap_pkthdr *h)
+{
+       return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
+}
+
+/* Create a TCP ending handshake */
+int dccp_encap_fin()
+{
+       return eip4_fin((struct eip4_en_p*)state.en_priv);
+}
+
+
+
+
+/* The DCCP Encapsulation Structure*/
+struct encap_ops dccp_encap = {
+       .pre=dccp_encap_pre,
+       .post=dccp_encap_post,
+       .handshake=dccp_encap_handshake,
+       .fin=dccp_encap_fin
+};
diff --git a/encap.c b/encap.c
new file mode 100644 (file)
index 0000000..51d2367
--- /dev/null
+++ b/encap.c
@@ -0,0 +1,404 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  Utility Functions for Encapsulation
+
+******************************************************************************/
+#include "ltp2tcp.h"
+
+
+
+/*Encapsulation Selection*/
+void encap_sel(char* string){
+       if(strcmp(string, "udp")==0 || strcmp(string,"UDP")==0){ /*UDP*/
+               state.en_ops=&udp_encap;
+               return;
+       }
+       if(strcmp(string, "dccp")==0 || strcmp(string,"DCCP")==0){ /*DCCP*/
+               state.en_ops=&dccp_encap;
+               return;
+       }
+       if(strcmp(string, "sll")==0 || strcmp(string,"SLL")==0){ /*SLL (Linux Cooked Capture)*/
+                       state.en_ops=&sll_encap;
+                       return;
+               }
+       printf("Encapsulation type: %s is not supported\n", string);
+       exit(1);
+return;
+};
+
+/*Fill the encapsulation structure*/
+int fill_eip4_encap(struct eip4_en_p *eip, const u_char* data, int dlen, struct pcap_pkthdr *h){
+       /*safety check*/
+       if(eip==NULL || data==NULL || h==NULL || dlen < sizeof(struct ether_header)+sizeof(struct iphdr)){
+               dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation method given bad data!\n");
+               return -1;
+       }
+
+       if(eip->first==0){
+               /* First time, allocate memory and copy libpcap header and encap headers
+                * this guarantees the IP "direction" of the encap headers */
+               memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
+               memcpy(eip->od, data,sizeof(struct ether_header)+sizeof(struct iphdr));
+               eip->first=1;
+       }else{
+               /* Just update the libpcap header (and associated timestamp)*/
+               memcpy(&eip->header, h, sizeof(struct pcap_pkthdr));
+       }
+       return 0;
+}
+
+/* encapsulation manipulation after conversion */
+int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data){
+       struct iphdr *iph;
+
+       /* Move data pointer to start of IPv4 header*/
+       data+=sizeof(struct ether_header);
+
+       /*Determine if the given length is reasonable*/
+       if((tlen+sizeof(struct iphdr)) > 0xFFFF){
+                       dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
+                       return -1;
+       }
+
+       /*Adjust IPv4 header to account for packet's total length*/
+       iph=(struct iphdr*)data;
+       iph->tot_len=htons(sizeof(struct iphdr)+tlen);
+       return 0;
+}
+
+/* Create a TCP three-way handshake */
+int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h){
+       struct iphdr            *iph;
+       struct tcphdr           *tcph;
+       u_char                          *data;
+       u_char                          *ptr;
+       struct pcap_pkthdr      nh;
+       u_int32_t                       temp;
+
+       /*Safety Check*/
+       if(h==NULL || state.en_priv==NULL || eip==NULL){
+               dbgprintf(1, "Error: Ethernet, IPv4 Encapsulation handshake method given bad data!\n");
+               return -1;
+       }
+
+       /*create new libpcap header*/
+       memcpy(&nh, h, sizeof(struct pcap_pkthdr));
+
+       /*create buffer for new packet*/
+       ptr=data=malloc(MAX_PACKET);
+       if(data==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+
+       /* 1)Create Syn Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=6;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=1;
+               tcph->rst=0;
+               tcph->ack=0;
+
+               /*Initialize Sequence and Acknowledgment Numbers and Window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(0);
+               tcph->window=htons(WIN_FACTOR);
+
+               /* Add SACK permitted option*/
+               ptr+=sizeof(struct tcphdr);
+               *ptr=4;
+               ptr++;
+               *ptr=2;
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+
+       /* 2)Create Syn,Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header, including swapping source and destination*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               temp=iph->saddr;
+               iph->saddr=iph->daddr;
+               iph->daddr=temp;
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=6;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=1;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Initialize Sequence and Acknowledgement Numbers and Window*/
+               tcph->seq=htonl(state.ack_num++);
+               tcph->ack_seq=htonl(state.seq_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /* Add SACK permitted option*/
+               ptr+=sizeof(struct tcphdr);
+               *ptr=4;
+               ptr++;
+               *ptr=2;
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 3)Create Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(data, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Initialize Sequence and Acknowledgement numbers and window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+       return 0;
+}
+
+/* Create a TCP ending handshake */
+int eip4_fin(struct eip4_en_p *eip){
+       struct iphdr            *iph;
+       struct tcphdr           *tcph;
+       u_char                          *data;
+       u_char                          *ptr;
+       struct pcap_pkthdr      nh;
+       u_int32_t                       temp;
+
+       /*Safety Check*/
+       if(eip==NULL){
+               dbgprintf(1,"Error: Ethernet, IPv4 Encapsulation Finish method given invalid data!\n");
+               return -1;
+       }
+
+       /*copy the libpcap header from private data area*/
+       memcpy(&nh, &eip->header, sizeof(struct pcap_pkthdr));
+
+       /*create buffer for new packet*/
+       ptr=data=malloc(MAX_PACKET);
+       if(data==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+
+       /* 1)Create Fin Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=1;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /* Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(++state.seq_num);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Update Sequence Number to include the fin packet in the sequence number space*/
+               state.seq_num++;
+
+               /* Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 2)Create Fin,Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*After the previous packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Update IP header, including swapping source and destination addresses*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               temp=iph->saddr;
+               iph->saddr=iph->daddr;
+               iph->daddr=temp;
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=1;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(state.ack_num++);
+               tcph->ack_seq=htonl(state.seq_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 3)Create Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct ether_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*After the previous packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, eip->od, sizeof(struct ether_header)+ sizeof(struct iphdr));
+
+               /*Update IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct ether_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+       return 0;
+}
diff --git a/encap.h b/encap.h
new file mode 100644 (file)
index 0000000..5be34df
--- /dev/null
+++ b/encap.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+
+File: encap.h
+
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  Declarations of encapsulation functions for ltp2tcp
+
+******************************************************************************/
+
+#ifndef ENCAP_H_
+#define ENCAP_H_
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+/*
+
+
+*/
+
+/* Encapsulation Operations*/
+struct encap_ops{
+       /* Handle all headers up to LTP:
+        *      h is the libpcap header. It should be returned with the Link+IP length in it.
+        *  odata is the packet being processed starting at the Link header. It should be returned starting at the LTP header.
+        *  ndata is the new packet. It should be returned with a Link+IP header in it.
+        *  olength is the length of the packet being processed. It should be returned as the length of the LTP segment.
+        *  nlength is the remaining length of the new packet. The Link+IP headers should be subtracted from it.
+        *
+        *  Other things to do:
+        *  1)IP must say that TCP is next header
+        *  2)Initialize encapsulation private data as needed (typically store h and Link+IP header for fin() method)
+        */
+       int (*pre)(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength);
+       /*
+        * Do any needed post processing on packet:
+        *  tlen is the length of the TCP segment (data+header)
+        *  data is the new packet starting at the link header
+        *
+        *  Typically update IP length
+        */
+       int (*post)(int tlen, u_char *data);
+       /*
+        * Add a TCP initial Threeway handshake to the connection:
+        *  h is the libpcap header of the current packet.
+        *
+        *  This means create three packets:
+        *      SYN in current Direction (SEQ=0,ACK=0)
+        *      SYN,ACK in opposite Direction (SEQ=0,ACK=1)
+        *      ACK in current Direction (SEQ=1,ACK=1)
+        *
+        *  You typically need Link+IP header from private data
+        *  Output packets to state.out
+        */
+       int (*handshake)(struct pcap_pkthdr *h);
+       /*
+        * Add TCP closing handshake:
+        *      This means create three packets:
+        *              FIN,ACK in current Direction (SEQ=state.seq_num+1, ACK=state.ack_num)
+        *              FIN,ACK in opposite Direction (SEQ=state.ack_num, ACK=state.seq_num+2)
+        *              ACK             in current Direction (SEQ=state.seq_num+2,ACK=state.ack_num+1)
+        *
+        *      You typically need the libpcap header and the Link+IP header from private data
+        *  Output packets to state.out
+        */
+       int (*fin)();
+};
+
+
+/*Encapsulation Operations Structures*/
+extern struct encap_ops udp_encap;
+extern struct encap_ops dccp_encap;
+extern struct encap_ops sll_encap;
+
+
+/*Encapsulation Selector*/
+void encap_sel(char* string);
+
+/*Standard Ethernet, IP encapsulation structures and functions*/
+struct eip4_en_p{
+       struct pcap_pkthdr      header;
+       u_char                          od[sizeof(struct ether_header)+sizeof(struct iphdr)];
+       int                                     first;
+};
+int fill_eip4_encap(struct eip4_en_p *eip, const u_char* data, int dlen, struct pcap_pkthdr *h);
+int eip4_post(struct eip4_en_p *eip, int tlen, u_char* data);
+int eip4_handshake(struct eip4_en_p *eip, struct pcap_pkthdr *h);
+int eip4_fin(struct eip4_en_p *eip);
+
+#endif /* ENCAP_H_ */
diff --git a/ltp.c b/ltp.c
new file mode 100644 (file)
index 0000000..551fb3d
--- /dev/null
+++ b/ltp.c
@@ -0,0 +1,84 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  LTP Header manipulation functions
+
+******************************************************************************/
+#include "ltp.h"
+
+
+/*
+ * SDNV has a zero in high-order bit position of last byte. The high-order
+ * bit of all preceding bytes is set to one. This returns the numeric value
+ * in an integer and sets the value of the second argument to the number of
+ * bytes used to code the SDNV. A -1 is returned if the evaluation fails
+ * (value exceeds maximum for signed integer). 0 is an acceptable value.
+ */
+
+#define SDNV_MASK      0x7f
+
+/*2rd arg is number of bytes in field (returned)*/
+int evaluate_sdnv(const u_char* loc, int *bytecount)
+{
+    int value = 0;
+    u_char curbyte;
+
+    *bytecount = 0;
+
+    /*
+     * Get 1st byte and continue to get them while high-order bit is 1
+     */
+
+    while((curbyte = *(loc++)) & ~SDNV_MASK) {
+       if(*bytecount >= (int) sizeof(int)) {
+           *bytecount = 0;
+           return -1;
+       }
+       value = value << 7;
+       value |= (curbyte & SDNV_MASK);
+       ++*bytecount;
+    }
+
+    /*
+     * Add in the byte whose high-order bit is 0 (last one)
+     */
+
+    value = value << 7;
+    value |= (curbyte & SDNV_MASK);
+    ++*bytecount;
+    return value;
+}
+
+/* Special Function to evaluate 64 bit SDNVs */
+long long evaluate_sdnv_64(const u_char* loc, int *bytecount)
+{
+    long long value = 0;
+    u_char curbyte;
+
+    *bytecount = 0;
+
+    /*
+     * Get 1st byte and continue to get them while high-order bit is 1
+     */
+
+    while((curbyte = *(loc++)) & ~SDNV_MASK) {
+       if(*bytecount >= (int) sizeof(long long)) {
+           *bytecount = 0;
+           return -1;
+       }
+       value = value<< 7;
+       value |= (curbyte & SDNV_MASK);
+       ++*bytecount;
+    }
+
+    /*
+     * Add in the byte whose high-order bit is 0 (last one)
+     */
+
+    value = value << 7;
+    value |= (curbyte & SDNV_MASK);
+    ++*bytecount;
+    return value;
+}
diff --git a/ltp.h b/ltp.h
new file mode 100644 (file)
index 0000000..dec5be9
--- /dev/null
+++ b/ltp.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+
+File: ltp.h
+
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  LTP Header information
+
+******************************************************************************/
+
+#ifndef LTP_H_
+#define LTP_H_
+#include <stdlib.h>
+
+/* structure to hold all the data from an LTP header.
+ *  Note that this isn't the RAW header like in IP,TCP;
+ *  it is a structure to hold all the information. The
+ *  RAW header is mostly SDNV values
+ */
+struct ltp_hdr_d{
+       u_char  vers_ctl;               /* Version and Control Field*/
+       int     sender_id;              /* Session sender id*/
+       int     session_num;    /* session number */
+       u_char  extensions;             /* number of extensions field (split header/trailer)*/
+       int     cls_id;                 /* Data segment Client Service ID */
+       int     offset;                 /* Data segment data offset*/
+       int     length;                 /* Data segment data length*/
+       int     checkpoint;             /* Checkpoint number */
+       int     report;                 /* Report Number */
+       int     ubound;                 /* Report Upper Bound*/
+       int     lbound;                 /* Report Lower Bound*/
+       int     rclaims;                /* Number of Reception Claims for Report */
+       int     reason;                 /* Cancellation Reason code */
+};
+
+/* SDNV manipulation functions*/
+int evaluate_sdnv(const u_char* loc, int *bytecount);
+long long evaluate_sdnv_64(const u_char* loc, int *bytecount);
+
+#endif
diff --git a/ltp2tcp.c b/ltp2tcp.c
new file mode 100644 (file)
index 0000000..59a3f8d
--- /dev/null
+++ b/ltp2tcp.c
@@ -0,0 +1,894 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 01/2011
+
+Description: Program to convert a LTP flow to a TCP flow for LTP analysis via
+               tcptrace.
+
+Notes:
+       1)Only handles one LTP "connection". There isn't a good way to separate
+               different LTP "connections" from new sessions of the same "connection".
+               Use Tcpdump filters to separate connections. Libpcap filtering could also
+               be added in ltp2tcp.
+       2)Uses some special types from Linux (u_char, u_int32_t)
+******************************************************************************/
+#include "ltp2tcp.h"
+
+
+
+int debug=0;
+int MAX_SESSION=500000;
+
+
+
+/* Forward declarations*/
+int init_state();
+int free_state();
+void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
+int convert_packet(struct pcap_pkthdr *h, const u_char *odata, u_char *ndata, int datalength, int newlength);
+int handle_data(const u_char* odata, struct ltp_hdr_d* ltph, struct tcphdr *tcph, int* dlen, int rbuf);
+int handle_report(const u_char* odata, struct ltp_hdr_d* ltph, struct tcphdr *tcph, u_char* tcpopt, int* dlen, int rbuf);
+int claim2sack(const u_char* odata, int ses_id, struct ltp_hdr_d* ltph, struct tcphdr *tcph, u_char* tcpopt, int* dlen, int rbuf);
+int seq_from_session(struct ltp_hdr_d* ltph, struct tcphdr *tcph);
+int ack_from_session(struct ltp_hdr_d* ltph, struct tcphdr *tcph);
+
+
+/*Parse commandline options and open files*/
+int main(int argc, char *argv[])
+{
+       char ebuf[200];
+       char *erbuffer=ebuf;
+       char *lfile=NULL;
+       char *tfile=NULL;
+       char *type=NULL;
+       char *temp;
+       int  tmp;
+
+       /*parse commandline options*/
+       if(argc<4 || argc > 8){
+               printf("Usage: ltp2tcp -t{encapsulation} ltp_file tcp_file [-d] [-b{block_size}]\n");
+               exit(1);
+       }
+
+       /*loop through commandline options*/
+       for(int i=1; i < argc; i++){
+               if(argv[i][0]!='-'){
+                       if(lfile==NULL){ /*assign first non-dash argument to the ltp file*/
+                               lfile=argv[i];
+                       }else{
+                               if(tfile==NULL){
+                                       tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
+                               }else{
+                                       printf("Usage: ltp2tcp -t{encapsulation} ltp_file tcp_file [-d] [-b{block_size}]\n");
+                                       exit(1);
+                               }
+                       }
+               }else{
+                       if(argv[i][1]=='d' && strlen(argv[i])==2){ /*debug option*/
+                               debug++;
+                       }
+                       if(argv[i][1]=='t'){ /*Encapsulation option*/
+                               type=&argv[i][2];
+                       }
+                       if(argv[i][1]=='b'){ /* Block size option*/
+                               tmp=atoi(&argv[i][2]);
+                               if(tmp>0){
+                                       MAX_SESSION=tmp;
+                               }else{
+                                       printf("Usage: ltp2tcp -t{encapsulation} ltp_file tcp_file [-d] [-b{block_size}]\n");
+                                       exit(1);
+                               }
+                       }
+                       if(argv[i][1]=='s'){ /*Session range option*/
+                                       state.ses_min=strtol(&argv[i][2],&temp,10);
+                                       temp++;
+                                       state.ses_max=strtol(temp,NULL,10);
+                       }
+               }
+       }
+       
+       if(lfile==NULL || tfile==NULL || type==NULL){
+               printf("Usage: ltp2tcp -t{encapsulation} ltp_file tcp_file [-d] [-b{block_size}]\n");
+               exit(1);
+       }
+
+       if(state.ses_min<=0 || state.ses_max<=0){
+               state.ses_min=-1;
+               state.ses_max=-1;
+       }
+
+       /*all options validated*/
+
+       if(debug){
+               dbgprintf(1,"Debug On\n");
+               dbgprintf(1,"Input file: %s\n", lfile);
+               dbgprintf(1,"Output file: %s\n", tfile);
+               dbgprintf(1,"Encapsulation: %s\n", type);
+               dbgprintf(1,"Block Size: %i\n", MAX_SESSION);
+               if(state.ses_min>=0){
+                       dbgprintf(1, "Session Range: %i-%i\n", state.ses_min, state.ses_max);
+               }else{
+                       dbgprintf(1, "Session Range: all\n");
+               }
+       }
+
+       /*determine encapsulation type*/
+       encap_sel(type);
+
+       /*attempt to open input file*/
+       state.in=pcap_open_offline(lfile, erbuffer);
+       if(state.in==NULL){
+               printf("Error opening input file\n");
+               exit(1);
+       }
+
+       /*attempt to open output file*/
+       state.out=pcap_dump_open(state.in,tfile);
+       if(state.out==NULL){
+               printf("Error opening output file\n");
+               exit(1);
+       }
+
+       /*setup state*/
+       if(init_state()){
+               exit(1);
+       }
+
+       /*process packets*/
+       u_char *user=(u_char*)state.out;
+       pcap_loop(state.in, -1, handle_packet, user);
+
+       /*add correct TCP termination, if needed*/
+       if(state.en_ops && state.en_ops->fin){
+                       (*state.en_ops->fin)();
+                       free(state.en_priv);
+       }
+       
+       /*close files*/
+       pcap_close(state.in);
+       pcap_dump_close(state.out);
+return 0;
+}
+
+/*initialize the converter state*/
+int init_state()
+{
+       state.seq_num=0;
+       state.ack_num=0;
+       state.win=0;
+       state.started=0;
+       state.seq_ses_id=0;
+       state.ses.size=TBL_SZ;
+       state.ses.max=0;
+       state.en_priv=NULL;
+       state.sender_id=-1;
+       state.ses.table=malloc(TBL_SZ*sizeof(struct tbl));
+       if(state.ses.table==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory!\n");
+               exit(1);
+       }
+return 0;
+}
+
+/*cleanup state*/
+int free_state()
+{
+       struct cl* tmp;
+       struct cl* f;
+
+       /*clean up the session table*/
+       if(state.ses.table){
+
+               /*cleanup the claims in each session*/
+               for(int i=0; i < MAX_SESSION; i ++){
+                       if(state.ses.table[i].a_lst!=NULL){
+                               tmp=state.ses.table[i].a_lst;
+                               while(tmp){
+                                       f=tmp;
+                                       tmp=tmp->next;
+                                       free(f);
+                               }
+                       }
+               }
+
+               free(state.ses.table);
+       }
+       return 0;
+}
+
+/*call back function for pcap_loop--do basic packet handling*/
+void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+       u_char                          *ndata;
+       u_char                          *nptr;
+       const u_char            *optr=bytes;
+       int                             length;
+       int                                     nlength;
+       int                             tlen;
+       struct pcap_pkthdr      nh;
+
+       /*create new libpcap header*/
+       memcpy(&nh, h, sizeof(struct pcap_pkthdr));
+
+       /*create buffer for new packet*/
+       nptr=ndata=malloc(MAX_PACKET);
+       if(ndata==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+
+       /*make sure the packet is all zero*/
+       memset(ndata, 0, MAX_PACKET);
+       length=h->caplen;
+       nlength=MAX_PACKET;
+
+       /*handle encapsulations*/
+       if(state.en_ops && state.en_ops->pre && state.en_ops->post){
+               if((*state.en_ops->pre)(&nh, &optr, &nptr, &length, &nlength)<0){
+                       return;
+               }
+               tlen=convert_packet(&nh, optr, nptr, length, nlength);
+               if(tlen <0){
+                       free(ndata);
+                       return;
+               }
+               if((*state.en_ops->post)(tlen, ndata)<0){
+                       return;
+               }
+       }else{
+               return;
+       }
+
+       /*save packet*/
+       pcap_dump(user,&nh, ndata);
+
+       free(ndata);
+return;
+}
+
+/*do all the ltp to tcp conversions---returns length of TCP segment*/
+int convert_packet(struct pcap_pkthdr *h, const u_char *odata, u_char *ndata, int datalength, int newlength)
+{      
+       u_char*                         ncur=ndata;
+       struct tcphdr           *tcph;
+       u_char*                         tcpopt;
+       u_char                          ctl;
+       struct ltp_hdr_d        ltph;
+       int                             eaten;
+       int                                     tmp;
+       int                                     hext;
+       int                                     dlen=0;
+       int                                     helen;
+
+       /*safety checks*/
+       if(h==NULL || odata==NULL || ndata==NULL|| datalength<1|| newlength < sizeof(struct tcphdr)){
+                       return -1;
+       }
+
+       /*cast TCP header pointers*/
+       tcph=(struct tcphdr*)ncur;
+       tcpopt=ncur+ sizeof(struct tcphdr);
+
+       /*set TCP standard features*/
+       tcph->source=htons(1113);
+       tcph->dest=htons(1113);
+       tcph->doff=5;
+       tcph->check=htonl(0);
+       tcph->urg_ptr=0;
+       tcph->urg=0;
+       tcph->psh=0;
+
+       /*Grab LTP control/version byte*/
+       ltph.vers_ctl=ctl=*odata;
+       odata++;
+       datalength--;
+
+       /* check LTP version*/
+       if((ctl & 0xF0) !=0){
+               dbgprintf(1,"Error: Invalid Packet Version\n");
+               return -1;
+       }
+
+       /* Parse LTP Session ID*/
+       ltph.sender_id=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       datalength-=eaten;
+       if(ltph.sender_id<0 || datalength<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       ltph.session_num=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       datalength-=eaten;
+       if(ltph.session_num<0 || datalength<0){
+                       dbgprintf(1,"Error: Bad SDNV!\n");
+                       return -1;
+       }
+
+       /*Filter sessions*/
+       if(state.ses_min>=0){
+               if((ltph.session_num < state.ses_min)|| (ltph.session_num > state.ses_max)){
+                       dbgprintf(3, "Filtering session: %i\n", ltph.session_num);
+                       return -1;
+               }
+       }
+
+       /*Check LTP Sender*/
+       /* We don't want to be confused if we have multiple LTP connections in this capture*/
+       if(state.sender_id==-1){
+               state.sender_id=ltph.sender_id;
+       }else{
+               if(state.sender_id!=ltph.sender_id){
+                       dbgprintf(1,"Note: Packet from different Sender!!\n");
+                       return -1;
+               }
+       }
+
+       /*Parse and Remove LTP header extensions*/
+       helen=0;
+       ltph.extensions=*odata;
+       odata++;
+       hext=ltph.extensions >> 4;
+       while(hext>0){
+               tmp=evaluate_sdnv(odata+1, &eaten);
+               if(tmp==0 || tmp < eaten || tmp < 0 || datalength < tmp){
+                       dbgprintf(1,"Error: Packet has bad extension length!\n");
+                       return -1;
+               }
+               /* ignore all extensions*/
+               odata+=tmp;
+               helen+=tmp;
+               datalength-=tmp;
+               hext--;
+       }
+
+
+
+       /*make changes by packet type*/
+       if((ctl & 0x0C)==0x0){//RED DATA
+               dbgprintf(2,"Packet Type: RED DATA\n");
+
+               /*Initialize the TCP connection, if this is the start*/
+               if(state.started==0){
+                       state.started=1;
+                       if(state.en_ops && state.en_ops->handshake){
+                               (*state.en_ops->handshake)(h);
+                       }
+               }
+               
+               if(handle_data(odata, &ltph, tcph, &dlen, datalength)<0){
+                       return -1;
+               }
+
+               /*Finalize TCP Header*/
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*check length*/
+               if(newlength < dlen + tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Add data*/
+               memset(ndata + tcph->doff*4, 'A', dlen);
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=tcph->doff*4+dlen;
+               h->caplen+=tcph->doff*4+dlen;
+               return tcph->doff*4+dlen;
+       }
+
+       if((ctl & 0x0C)==0x4){//GREEN DATA
+                       dbgprintf(2,"Packet Type: GREEN DATA\n");
+
+               /*Initialize the TCP connection, if this is the start*/
+               if(state.started==0){
+                       state.started=1;
+                       if(state.en_ops && state.en_ops->handshake){
+                                       (*state.en_ops->handshake)(h);
+                       }
+               }
+
+               if(handle_data(odata, &ltph, tcph, &dlen, datalength)<0){
+                       return -1;
+               }
+
+               /*Finalize TCP Header*/
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*check length*/
+               if(newlength < dlen + tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Add data*/
+               memset(ndata+ tcph->doff*4, 'A', dlen);
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=tcph->doff*4+dlen;
+               h->caplen+=tcph->doff*4+dlen;
+               return tcph->doff*4+dlen;
+       }
+
+       if((ctl & 0x0F)==0x8){//REPORT SEGMENT
+               dbgprintf(2,"Packet Type: REPORT SEGMENT\n");
+
+               /*check length*/
+               if(newlength < 4*8+4+sizeof(struct tcphdr)){
+                       dbgprintf(1, "Error: Indicated Packet Length is may be beyond end of buffer!\n");
+                       return -1;
+               }
+
+               if(handle_report(odata, &ltph, tcph, tcpopt, &dlen, datalength)<0){
+                       return -1;
+               }
+
+               /*Finalize TCP Header*/
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*check length*/
+               if(newlength < tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=tcph->doff*4+dlen;
+               h->caplen+=tcph->doff*4+dlen;
+               return tcph->doff*4+dlen;
+       }
+
+       if((ctl & 0x0F)==0x9){//REPORT ACK
+               dbgprintf(2,"Packet Type: REPORT ACK\n");
+
+               /*Get Seq and Ack Numbers*/
+               if(seq_from_session(&ltph, tcph)<0){
+                       return -1;
+               }
+               tcph->ack_seq=htonl(state.ack_num);
+
+               /*Finalize TCP Header*/
+               tcph->window=htons(WIN_FACTOR);
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*check length*/
+               if(newlength < tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=sizeof(struct tcphdr);
+               h->caplen+=sizeof(struct tcphdr);
+               return sizeof(struct tcphdr);
+       }
+
+       if((ctl & 0x0D)==0xC){ //CANCEL SEGMENT
+               dbgprintf(2,"Packet Type: CANCEL SEGMENT\n");
+
+               /*Get Seq and Ack Numbers*/
+               if((ctl & 0x02)==0x00){
+                       //Sender cancel
+                       if(seq_from_session(&ltph, tcph)<0){
+                               return -1;
+                       }
+                       tcph->ack_seq=htonl(state.ack_num);
+               }else{
+                       //Receiver cancel
+                       if(ack_from_session(&ltph, tcph)<0){
+                               return -1;
+                       }
+                       tcph->seq=htonl(state.ack_num++);
+               }
+
+               /*Finalize TCP Header*/
+               tcph->window=htons(0);
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=1;
+               tcph->ack=0;
+
+               /*check length*/
+               if(newlength < tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=sizeof(struct tcphdr);
+               h->caplen+=sizeof(struct tcphdr);
+               return sizeof(struct tcphdr);
+       }
+
+       if((ctl & 0x0D)==0xD){//CANCEL ACK
+               dbgprintf(2,"Packet Type: CANCEL ACK\n");
+
+               /*Get Seq and Ack Numbers*/
+               if((ctl & 0x02)==0x00){
+                       //Sender ACK
+                       if(seq_from_session(&ltph, tcph)<0){
+                               return -1;
+                       }
+                       tcph->ack_seq=htonl(state.ack_num);
+               }else{
+                       //Receiver ACK
+                       if(ack_from_session(&ltph, tcph)<0){
+                               return -1;
+                       }
+                       tcph->seq=htonl(state.ack_num++);
+               }
+
+               /*Finalize TCP Header*/
+               tcph->window=htons(0);
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=1;
+               tcph->ack=0;
+
+               /*check length*/
+               if(newlength < tcph->doff*4){
+                       dbgprintf(1, "Error: Indicated Packet Length is beyond end of buffer!\n");
+                       return -1;
+               }
+
+               /*Adjust Lengths (packet and TCP segment)*/
+               h->len+=sizeof(struct tcphdr);
+               h->caplen+=sizeof(struct tcphdr);
+               return sizeof(struct tcphdr);
+       }
+
+       /*Anything else is bad!*/
+       dbgprintf(1,"Error: Invalid Packet Type\n");
+return -1;
+}
+
+/* Determine Sequence and Acknowledgment Numbers for Data Segments*/
+int handle_data(const u_char* odata, struct ltp_hdr_d* ltph, struct tcphdr *tcph, int* dlen, int rbuf)
+{
+       int eaten;
+       int i;
+       int found;
+
+       /* Get LTP Client Service ID*/
+       ltph->cls_id=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->cls_id <0 || rbuf <0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get LTP Data Offset*/
+       ltph->offset=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->offset <0 || rbuf <0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get LTP Data Length*/
+       ltph->length=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->length <0 || rbuf <0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+       
+       /* find LTP session */
+       found=0;
+       for(i=0; i < state.ses.size; i++){
+               if(ltph->session_num==state.ses.table[i].num){
+                       found=1;
+                       break;
+               }
+       }
+       
+       /* Not Found, add it*/
+       if(found==0){
+               i=(state.seq_ses_id++)%state.ses.size;
+               state.ses.table[i].num=ltph->session_num;
+               state.ses.table[i].seq_id=state.seq_ses_id;
+               if(state.seq_ses_id==1){
+                       /*First session*/
+                       state.ses.table[i].start=state.seq_num;
+               }else{
+                       state.ses.table[i].start=state.seq_num + MAX_SESSION - state.ses.table[(state.seq_ses_id-2)%state.ses.size].length;
+               }
+       }
+
+       /* Compute TCP Sequence Number */
+       tcph->seq=htonl(state.ses.table[i].start + ltph->offset);
+       if(state.ses.table[i].start + ltph->offset+ltph->length > state.seq_num){
+               state.seq_num=state.ses.table[i].start + ltph->offset + ltph->length;
+       }
+
+       /* Update LTP Session Length*/
+       if(ltph->offset+ltph->length > state.ses.table[i].length){
+               state.ses.table[i].length=ltph->offset+ltph->length;
+       }
+
+       /* Computer TCP Ack Number*/
+       tcph->ack_seq=htonl(state.ack_num);
+
+       /* Get Amount of Data in LTP Segment*/
+       *dlen=ltph->length;
+
+       /* Compute TCP Window*/
+       tcph->window=htons(WIN_FACTOR);
+return 0;
+}
+
+/* Get Sequence and Acknowledgment Number for LTP Reports. Add TCP SACKS*/
+int handle_report(const u_char* odata, struct ltp_hdr_d* ltph, struct tcphdr *tcph, u_char* tcpopt, int* dlen, int rbuf)
+{
+       int eaten;
+       int found;
+       int i;
+       int data_recv;
+
+       /*Set TCP Data Length*/
+       *dlen=0;
+
+       /*Parse LTP header*/
+       /*Get LTP Report ID*/
+       ltph->report=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->report <0 || rbuf<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get LTP Checkpoint ID*/
+       ltph->checkpoint=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->checkpoint <0 || rbuf<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get LTP Report Upper Bound*/
+       ltph->ubound=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->ubound <0 || rbuf<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get LTP Report Lower Bound*/
+       ltph->lbound=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->lbound <0 || rbuf<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /*Get Number of LTP Reception Claims*/
+       ltph->rclaims=evaluate_sdnv(odata, &eaten);
+       odata+=eaten;
+       rbuf-=eaten;
+       if(ltph->rclaims <0 || rbuf<0){
+               dbgprintf(1,"Error: Bad SDNV!\n");
+               return -1;
+       }
+
+       /* find LTP session */
+       found=0;
+       for(i=0; i < state.ses.size; i++){
+               if(ltph->session_num==state.ses.table[i].num){
+                       found=1;
+                       break;
+               }
+       }
+
+       /* LTP session Not Found*/
+       if(found==0){
+               if(debug){
+                       dbgprintf(1,"Error: Session for Report Not Found!\n");
+               }
+               return -1;
+       }
+
+       /* Add TCP SACKS*/
+       data_recv=claim2sack(odata, i, ltph, tcph, tcpopt, dlen, rbuf);
+       if(data_recv<0){
+               return -1;
+       }
+
+       /*Add TCP sequence number*/
+       tcph->seq=htonl(state.ack_num);
+       
+       /* Compute TCP Window*/
+       tcph->window=htons(WIN_FACTOR);
+
+       /* Add TCP Ack Number*/
+       tcph->ack_seq=htonl(state.ses.table[i].start + data_recv+1);
+return 0;
+}
+
+/* Convert LTP Reception Claims into TCP SACKS*/
+int claim2sack(const u_char* odata, int ses_id,struct ltp_hdr_d* ltph, struct tcphdr *tcph, u_char* tcpopt, int* dlen, int rbuf)
+{
+       int             coffset;
+       int             clength;
+       int             eaten;
+       int             max;
+       int                     done;
+       u_char          *olen;
+       u_int32_t*      t_block;
+       struct cl*      tmp=NULL;
+
+       /*Add the Start of the TCP SACK Option*/
+       *tcpopt=5;
+       tcpopt++;
+       olen=tcpopt;
+       tcpopt++;
+       *olen=2;
+       *dlen=0;
+       tcph->doff+=1;
+
+       /* Cast to TCP SACK BLOCK pointer*/
+       t_block=(u_int32_t*)tcpopt;
+       
+       /* Loop over at most 4 Claims*/
+       if(ltph->rclaims>4){
+               max=4;
+       }else{
+               max=ltph->rclaims;
+       }
+
+       for(int i=0; i < max; i++){
+
+               /* Read LTP Claim*/
+               coffset=evaluate_sdnv(odata, &eaten);
+               odata+=eaten;
+               rbuf-=eaten;
+               if(coffset <0 || rbuf<0){
+                       dbgprintf(1,"Error: Bad SDNV!\n");
+                       return -1;
+               }
+               clength=evaluate_sdnv(odata, &eaten);
+               odata+=eaten;
+               rbuf-=eaten;
+               if(clength <0 || rbuf<0){
+                       dbgprintf(1,"Error: Bad SDNV!\n");
+                       return -1;
+               }
+
+               /* Add claim to session info*/
+               if(!state.ses.table[ses_id].a_lst){
+                       state.ses.table[ses_id].a_lst=malloc(sizeof(struct cl));
+                       if(!state.ses.table[ses_id].a_lst){
+                               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                               exit(1);
+                       }
+                       tmp=state.ses.table[ses_id].a_lst;
+               }else{
+                       tmp=state.ses.table[ses_id].a_lst;
+                       while(tmp->next){
+                               tmp=tmp->next;
+                       }
+                       tmp->next=malloc(sizeof(struct cl));
+                       if(!tmp->next){
+                               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                               exit(1);
+                       }
+               }
+               tmp->offset=coffset;
+               tmp->length=clength;
+
+               /*Create TCP SACK*/
+               *t_block=htonl(state.ses.table[ses_id].start+coffset); //Left Side
+               t_block++;
+               *t_block=htonl(state.ses.table[ses_id].start+coffset+clength+1); //Right Side
+               t_block++;
+
+               /*Update TCP header length*/
+               *olen+=8;
+               tcph->doff+=2;
+       }
+
+       /*Calculate Ack number*/
+       done=0;
+       coffset=0;
+       while(!done){
+               tmp=state.ses.table[ses_id].a_lst;
+               done=1;
+               while(tmp){
+                       if((tmp->offset<=coffset) && ((tmp->offset+tmp->length) > coffset)){
+                               coffset=tmp->offset+tmp->length;
+                               done=0;
+                       }
+                       tmp=tmp->next;
+               }
+       }
+       state.ses.table[ses_id].acked=coffset;
+return coffset;
+}
+
+/* Get a TCP seq number from the LTP Session ID for Report ACK and Session Cancellation*/
+int seq_from_session(struct ltp_hdr_d* ltph, struct tcphdr *tcph)
+{
+       int i;
+       int found;
+
+       /*Find LTP session */
+       found=0;
+       for(i=0; i < state.ses.size; i++){
+               if(ltph->session_num==state.ses.table[i].num){
+                       found=1;
+                       break;
+               }
+       }
+
+       /*LTP session Not Found*/
+       if(found==0){
+               dbgprintf(1,"Error: Session for Segment Not Found!\n");
+               return -1;
+       }
+
+       /* Add TCP Sequence Number */
+       tcph->seq=htonl(state.ses.table[i].start + state.ses.table[i].length);
+       /* No length, so don't update state.ses.table[i].length*/
+return 0;
+}
+
+/* Get an TCP Ack number from the LTP session ID for session cancellation*/
+int ack_from_session(struct ltp_hdr_d* ltph, struct tcphdr *tcph)
+{
+
+       int i;
+       int found;
+
+       /* find LTP session */
+       found=0;
+       for(i=0; i < state.ses.size; i++){
+               if(ltph->session_num==state.ses.table[i].num){
+                       found=1;
+                       break;
+               }
+       }
+
+       /* LTP session Not Found*/
+       if(found==0){
+               if(debug){
+                       dbgprintf(1,"Error: Session for Segment Not Found!\n");
+               }
+               return -1;
+       }
+       
+       /* Add TCP Ack Number*/
+       tcph->ack_seq=htonl(state.ses.table[i].start + state.ses.table[i].acked+1);
+return 0;
+}
+
+/*Debug Printf*/
+void dbgprintf(int level, const char *fmt, ...)
+{
+    va_list args;
+    if(debug>=level){
+       va_start(args, fmt);
+       vfprintf(stderr, fmt, args);
+       va_end(args);
+    }
+}
diff --git a/ltp2tcp.h b/ltp2tcp.h
new file mode 100644 (file)
index 0000000..f3d7cb7
--- /dev/null
+++ b/ltp2tcp.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+
+file: ltp2tcp.h
+
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  Header file for LTP 2 TCP Conversion
+
+
+Special Types Used:
+       1)u_char
+       2)u_int32_t
+******************************************************************************/
+#ifndef _LTP2TCP_H_
+#define _LTP2TCP_H_
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#include <pcap.h>
+#include "ltp.h"
+#include "encap.h"
+
+
+
+
+extern int debug;                      /*set to 1 to turn on debugging information, see ltp2tcp.c*/
+extern int MAX_SESSION;                /* max session size, see ltp2tcp.c*/
+
+
+
+
+/*session table*/
+struct session{
+       int             max;            /*max used session*/
+       struct tbl      *table;         /*session table */
+       int             size;           /*session table size */
+};
+
+/*session table structure*/
+struct tbl{
+       int             num;            /*LTP session num */
+       u_int32_t       start;          /*start sequence number*/
+       int                     acked;          /* length of session that has been acked */
+       int                     length;         /* length of session */
+       int                     seq_id;         /*sequential Session id*/
+       struct cl*      a_lst;          /*list of claims*/
+};
+
+/*claim structure*/
+struct cl{
+       struct cl*      next;           /*pointer to next claim*/
+       int             offset;         /*offset for this data piece*/
+       int             length;         /*length of this data peice*/
+};
+
+/*converter state*/
+struct conversion_state{
+       int                             seq_num;        /* Largest TCP sequence Number used*/
+       int                             ack_num;        /* Largest TCP acknowledgment Number used*/
+       int                             win;            /* Largest TCP window used*/
+       int                             started;        /* 1 if we have found any LTP so far, 0 otherwise*/
+       int                                     sender_id;      /* LTP sender ID for this connection*/
+       int                                     seq_ses_id; /* Number of LTP sessions in this connection so far*/
+       struct session          ses;            /* Session Table Structure*/
+       void*                           en_priv;        /* Pointer for Encapsulation data*/
+       struct encap_ops*       en_ops;         /* Pointer to encapsulation operations*/
+       pcap_t*                         in;                     /*libpcap input file discriptor*/
+       pcap_dumper_t*          out;            /*libpcap output file discriptor*/
+       int                                     ses_min;        /*session filtering: low*/
+       int                                     ses_max;        /*session filtering: high*/
+};
+struct conversion_state state;
+
+#define MAX_PACKET     1600            /*Maximum size of TCP packet*/
+#define        WIN_FACTOR      10000           /*Size of TCP window*/
+#define        TBL_SZ          10000           /*Size of Session Table*/
+
+
+
+/*debug printf
+ * Levels:
+ *     0) Always print even if debug isn't specified
+ *  1) Errors and warnings... Don't overload the screen with too much output
+ *  2) Notes and per-packet processing info... as verbose as needed
+ */
+void dbgprintf(int level, const char *fmt, ...);
+
+
+#endif
diff --git a/sll_encap.c b/sll_encap.c
new file mode 100644 (file)
index 0000000..c90d1ed
--- /dev/null
@@ -0,0 +1,489 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 5/2011
+
+Description:  <SLL, IPv4, UDP> encapsulation functions
+
+******************************************************************************/
+#include "ltp2tcp.h"
+#include <pcap/sll.h>
+#include <netinet/udp.h>
+
+extern int debug;
+
+
+
+/*SLL encapsulation private data structure*/
+struct sll_en_p{
+       int first;
+       struct pcap_pkthdr      header;
+       u_char                          od[sizeof(struct sll_header)+sizeof(struct iphdr)+sizeof(struct udphdr)];
+};
+
+
+/*Fill the encapsulation structure*/
+int fill_sllip4_encap(struct sll_en_p *slip, const u_char* data, int dlen, struct pcap_pkthdr *h){
+       /*safety check*/
+       if(slip==NULL || data==NULL || h==NULL || dlen < sizeof(struct sll_header)+sizeof(struct iphdr)){
+               dbgprintf(1, "Error: SLL, IPv4 Encapsulation method given bad data!\n");
+               return -1;
+       }
+
+       if(slip->first==0){
+               /* First time, allocate memory and copy libpcap header and encap headers
+                * this guarantees the IP "direction" of the encap headers */
+               memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
+               memcpy(slip->od, data,sizeof(struct sll_header)+sizeof(struct iphdr));
+               slip->first=1;
+       }else{
+               /* Just update the libpcap header (and associated timestamp)*/
+               memcpy(&slip->header, h, sizeof(struct pcap_pkthdr));
+       }
+       return 0;
+}
+
+/* encapsulation manipulation previous to packet conversion */
+int sll_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
+{
+       struct iphdr                    *iph;
+       struct sll_header               *slh;
+       struct udphdr                   *udph;
+
+       /*Safety checks*/
+       if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
+               dbgprintf(0,"Error: SLL Encapsulation given bad data!\n");
+               exit(1);
+       }
+       if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)
+                       || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
+                       dbgprintf(0, "Error: SLL Encapsulation given packet of wrong size!\n");
+                       return -1;
+       }
+
+       /*initialize encapsulation private data*/
+       if(state.en_priv==NULL){
+               /* First time, allocate memory and copy libpcap header and encap headers
+                * this guarantees the IP "direction" of the encap headers */
+               state.en_priv=malloc(sizeof(struct sll_en_p));
+               if(state.en_priv==NULL){
+                       dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                       exit(1);
+               }
+       }
+       if(fill_sllip4_encap((struct sll_en_p*)state.en_priv, *odata, *olength, h)<0){
+               return -1;
+       }
+
+       /*Copy SLL and IPv4 headers over*/
+       memcpy(*ndata, *odata, sizeof(struct sll_header)+sizeof(struct iphdr));
+       *odata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+       *ndata+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+
+       /*Confirm that this is Ethernet and that IPv4 is next*/
+       slh=(struct sll_header*)(*odata -sizeof(struct sll_header)- sizeof(struct iphdr));
+       if(slh->sll_protocol!=htons(ETHERTYPE_IP)){
+               dbgprintf(1, "Note: Packet not SLL or Not IPv4 next\n");
+               return -1;
+       }
+
+       /* Check That this is IPv4 and that UDP is next*/
+       iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
+       if(iph->version!=4){
+               dbgprintf(1, "Note: Packet is not IPv4\n");
+               return -1;
+       }
+       if(iph->protocol!=0x11){
+               dbgprintf(1, "Note: Packet is not UDP\n");
+               return -1;
+       }
+
+       /*set ip to indicate that tcp is next protocol*/
+       iph->protocol=6;
+       iph->check=htonl(0);
+
+       /* Adjust libpcap headers*/
+       h->caplen=sizeof(struct sll_header) +sizeof(struct iphdr);
+       h->len=sizeof(struct sll_header) +sizeof(struct iphdr);
+
+       /*Adjust packet length*/
+       udph=(struct udphdr*)*odata;
+       *olength=ntohs(udph->len);
+
+       /*Adjust New Packet Length*/
+       *nlength-=sizeof(struct sll_header) +sizeof(struct iphdr);
+
+       /*Move Packet Pointer past UDP header*/
+       *odata+=sizeof(struct udphdr);
+return 0;
+}
+
+/* encapsulation manipulation after conversion */
+int sll_encap_post(int tlen, u_char *data)
+{
+       struct iphdr *iph;
+
+       /* Move data pointer to start of IPv4 header*/
+       data+=sizeof(struct sll_header);
+
+       /*Determine if the given length is reasonable*/
+       if((tlen+sizeof(struct iphdr)) > 0xFFFF){
+                       dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
+                       return -1;
+       }
+
+       /*Adjust IPv4 header to account for packet's total length*/
+       iph=(struct iphdr*)data;
+       iph->tot_len=htons(sizeof(struct iphdr)+tlen);
+       return 0;
+}
+
+/* Create a TCP three-way handshake */
+int sll_encap_handshake(struct pcap_pkthdr *h)
+{
+       struct iphdr            *iph;
+       struct tcphdr           *tcph;
+       u_char                          *data;
+       u_char                          *ptr;
+       struct pcap_pkthdr      nh;
+       u_int32_t                       temp;
+       struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
+
+
+       /*Safety Check*/
+       if(h==NULL || state.en_priv==NULL){
+               dbgprintf(1, "Error: SLL, IPv4 Encapsulation handshake method given bad data!\n");
+               return -1;
+       }
+
+       /*create new libpcap header*/
+       memcpy(&nh, h, sizeof(struct pcap_pkthdr));
+
+       /*create buffer for new packet*/
+       ptr=data=malloc(MAX_PACKET);
+       if(data==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+
+       /* 1)Create Syn Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.ts.tv_usec-=3000; /*Time comes from the first packet received, so make these packets earlier*/
+
+               /* Copy SLL and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=6;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=1;
+               tcph->rst=0;
+               tcph->ack=0;
+
+               /*Initialize Sequence and Acknowledgment Numbers and Window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(0);
+               tcph->window=htons(WIN_FACTOR);
+
+               /* Add SACK permitted option*/
+               ptr+=sizeof(struct tcphdr);
+               *ptr=4;
+               ptr++;
+               *ptr=2;
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+
+       /* 2)Create Syn,Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr)+4;
+               nh.ts.tv_usec+=1000; /*This packet is 1/3rd closer to the first packet then the previous packet created*/
+
+               /* Copy SLL and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header, including swapping source and destination*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               temp=iph->saddr;
+               iph->saddr=iph->daddr;
+               iph->daddr=temp;
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)+4);
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=6;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=1;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Initialize Sequence and Acknowledgement Numbers and Window*/
+               tcph->seq=htonl(state.ack_num++);
+               tcph->ack_seq=htonl(state.seq_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /* Add SACK permitted option*/
+               ptr+=sizeof(struct tcphdr);
+               *ptr=4;
+               ptr++;
+               *ptr=2;
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 3)Create Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*This packet is 2/3rds between SYN and first packet*/
+
+               /* Copy SLL and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(data, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Initialize Sequence and Acknowledgement numbers and window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+               return 0;
+}
+
+/* Create a TCP ending handshake */
+int sll_encap_fin()
+{
+       struct iphdr            *iph;
+       struct tcphdr           *tcph;
+       u_char                          *data;
+       u_char                          *ptr;
+       struct pcap_pkthdr      nh;
+       u_int32_t                       temp;
+       struct sll_en_p         *slip=(struct sll_en_p*)state.en_priv;
+
+       /*Safety Check*/
+       if(slip==NULL){
+               dbgprintf(1,"Error: SLL, IPv4 Encapsulation Finish method given invalid data!\n");
+               return -1;
+       }
+
+       /*copy the libpcap header from private data area*/
+       memcpy(&nh, &slip->header, sizeof(struct pcap_pkthdr));
+
+       /*create buffer for new packet*/
+       ptr=data=malloc(MAX_PACKET);
+       if(data==NULL){
+               dbgprintf(0,"Error: Couldn't allocate Memory\n");
+               exit(1);
+       }
+
+       /* 1)Create Fin Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*Time is from the last packet in the capture; make this packet after that packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Adjust IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=1;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /* Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(++state.seq_num);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Update Sequence Number to include the fin packet in the sequence number space*/
+               state.seq_num++;
+
+               /* Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 2)Create Fin,Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*After the previous packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Update IP header, including swapping source and destination addresses*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               temp=iph->saddr;
+               iph->saddr=iph->daddr;
+               iph->daddr=temp;
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct sll_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=1;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(state.ack_num++);
+               tcph->ack_seq=htonl(state.seq_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+
+       /* 3)Create Ack Packet*/
+               /*make sure the packet is all zero*/
+               memset(data, 0, MAX_PACKET);
+               ptr=data;
+
+               /*Set the libpcap header*/
+               nh.caplen=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.len=sizeof(struct sll_header) +sizeof(struct iphdr)+sizeof(struct tcphdr);
+               nh.ts.tv_usec+=1000; /*After the previous packet*/
+
+               /* Copy Ethernet and IP headers from private data area*/
+               /* These are headers from the first packet in the capture*/
+               memcpy(ptr, slip->od, sizeof(struct sll_header)+ sizeof(struct iphdr));
+
+               /*Update IP header*/
+               iph= (struct iphdr *) (ptr + sizeof(struct sll_header));
+               iph->protocol=6;
+               iph->check=htonl(0);
+               iph->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
+
+               /*Build TCP header*/
+               ptr+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+               tcph=(struct tcphdr*)ptr;
+               tcph->source=htons(1113);
+               tcph->dest=htons(1113);
+               tcph->doff=5;
+               tcph->check=htonl(0);
+               tcph->urg_ptr=0;
+               tcph->urg=0;
+               tcph->psh=0;
+               tcph->fin=0;
+               tcph->syn=0;
+               tcph->rst=0;
+               tcph->ack=1;
+
+               /*Adjust Sequence and Acknowledgment numbers and window*/
+               tcph->seq=htonl(state.seq_num++);
+               tcph->ack_seq=htonl(state.ack_num);
+               tcph->window=htons(WIN_FACTOR);
+
+               /*Save To Packet Capture*/
+               pcap_dump((u_char*)state.out,&nh, data);
+               return 0;
+}
+
+
+
+
+/* The UDP Encapsulation Structure*/
+struct encap_ops sll_encap = {
+       .pre=sll_encap_pre,
+       .post=sll_encap_post,
+       .handshake=sll_encap_handshake,
+       .fin=sll_encap_fin,
+};
diff --git a/udp_encap.c b/udp_encap.c
new file mode 100644 (file)
index 0000000..b14ede8
--- /dev/null
@@ -0,0 +1,121 @@
+/******************************************************************************
+Author: Samuel Jero
+
+Date: 12/2010
+
+Description:  <ETH, IPv4, UDP> encapsulation functions
+
+******************************************************************************/
+#include "ltp2tcp.h"
+#include <netinet/udp.h>
+
+
+
+extern int debug;
+
+
+
+
+/* encapsulation manipulation previous to packet conversion */
+int udp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
+{
+       struct iphdr                    *iph;
+       struct ether_header             *ethh;
+       struct udphdr                   *udph;
+
+       /*Safety checks*/
+       if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
+               dbgprintf(0,"Error: UDP Encapsulation given bad data!\n");
+               exit(1);
+       }
+       if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)
+                       || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
+                       dbgprintf(0, "Error: UDP Encapsulation given packet of wrong size!\n");
+                       return -1;
+       }
+
+       /*initialize encapsulation private data*/
+       if(state.en_priv==NULL){
+               /* First time, allocate memory and copy libpcap header and encap headers
+                * this guarantees the IP "direction" of the encap headers */
+               state.en_priv=malloc(sizeof(struct eip4_en_p));
+               if(state.en_priv==NULL){
+                       dbgprintf(0,"Error: Couldn't allocate Memory\n");
+                       exit(1);
+               }
+       }
+       if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
+               return -1;
+       }
+
+       /*Copy Ethernet and IPv4 headers over*/
+       memcpy(*ndata, *odata, sizeof(struct ether_header)+sizeof(struct iphdr));
+       *odata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+       *ndata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
+
+       /*Confirm that this is Ethernet and that IPv4 is next*/
+       ethh=(struct ether_header*)(*odata -sizeof(struct ether_header)- sizeof(struct iphdr));
+       if(ethh->ether_type!=htons(ETHERTYPE_IP)){
+               dbgprintf(1, "Note: Packet not Ethernet or Not IPv4 next\n");
+               return -1;
+       }
+
+       /* Check That this is IPv4 and that UDP is next*/
+       iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
+       if(iph->version!=4){
+               dbgprintf(1, "Note: Packet is not IPv4\n");
+               return -1;
+       }
+       if(iph->protocol!=0x11){
+               dbgprintf(1, "Note: Packet is not UDP\n");
+               return -1;
+       }
+
+       /*set ip to indicate that tcp is next protocol*/
+       iph->protocol=6;
+       iph->check=htonl(0);
+
+       /* Adjust libpcap headers*/
+       h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
+       h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
+
+       /*Adjust packet length*/
+       udph=(struct udphdr*)*odata;
+       *olength=ntohs(udph->len);
+
+       /*Adjust New Packet Length*/
+       *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
+
+       /*Move Packet Pointer past UDP header*/
+       *odata+=sizeof(struct udphdr);
+return 0;
+}
+
+/* encapsulation manipulation after conversion */
+int udp_encap_post(int tlen, u_char *data)
+{
+       return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
+}
+
+/* Create a TCP three-way handshake */
+int udp_encap_handshake(struct pcap_pkthdr *h)
+{
+       return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
+}
+
+/* Create a TCP ending handshake */
+int udp_encap_fin()
+{
+       return eip4_fin((struct eip4_en_p*)state.en_priv);
+}
+
+
+
+
+/* The UDP Encapsulation Structure*/
+struct encap_ops udp_encap = {
+       .pre=udp_encap_pre,
+       .post=udp_encap_post,
+       .handshake=udp_encap_handshake,
+       .fin=udp_encap_fin
+};