Moved Decoder app to Programs

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1960 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2008-07-22 23:03:55 +00:00
parent 660db80eb5
commit ef71c02528
4 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
<?xml version="1.0"?>
<project
name="libsecondlife"
default="build">
<!-- global framework settings -->
<property
name="target.framework"
value="${framework::get-target-framework()}" />
<property
name="assembly.dir"
value="${framework::get-assembly-directory(target.framework)}" />
<!-- global project settings -->
<xmlpeek
file="../../libsecondlife.build"
xpath="/project/property[@name = 'project.version']/@value"
property="project.version" />
<property
name="build.number"
value="${math::abs(math::floor(timespan::get-total-days(datetime::now()
- datetime::parse('01/01/2002'))))}" />
<property
name="assembly"
value="Decoder"/>
<property
name="bin_dir"
value="../../bin" />
<!-- default configuration -->
<property
name="project.config"
value="debug" /> <!-- debug|release -->
<!-- named configurations -->
<target
name="init"
description="Initializes build properties">
<call target="${project.config}" />
</target>
<target
name="debug"
description="configures a debug build">
<property
name="build.debug"
value="true" />
<property
name="package.name"
value="${project::get-name()}-${project.version}-${project.config}" />
<property
name="assembly.configuration"
value="${framework::get-target-framework()}.${platform::get-name()} [${project.config}]" />
</target>
<target
name="release"
description="configures a release build">
<property
name="project.config"
value="release" />
<property
name="build.debug"
value="false" />
<property
name="package.name"
value="${project::get-name()}-${project.version}" />
<property
name="assembly.configuration"
value="${framework::get-target-framework()}.${platform::get-name()}" />
</target>
<!-- build tasks -->
<target
name="build"
depends="init"
description="Builds the binaries for the current configuration">
<echo message="Build Directory is ${bin_dir}/" />
<mkdir
dir="${bin_dir}"
failonerror="false" />
<csc
target="exe"
debug="${build.debug}"
output="${bin_dir}/${assembly}.exe">
<sources failonempty="true">
<include name="*.cs" />
</sources>
<references basedir="${bin_dir}/">
<include name="libsecondlife.dll"/>
</references>
</csc>
</target>
<target
name="clean"
depends="init"
description="Deletes the current configuration">
<delete failonerror="false">
<fileset basedir="${bin_dir}/">
<include name="${assembly}.exe" />
<include name="${assembly}.pdb" />
<include name="**/${assembly}.*.resources" />
</fileset>
</delete>
</target>
<target
name="*"
description="Handles unknown targets">
<echo message="skip" />
</target>
</project>

248
Programs/Decoder/Decoder.cs Normal file
View File

@@ -0,0 +1,248 @@
/*
* Decoder.cs: decodes pasted packet dumps
* See the README for usage instructions.
*
* Copyright (c) 2006 Austin Jennings
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Neither the name of the openmetaverse.org nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using OpenMetaverse;
using OpenMetaverse.Packets;
class Decoder {
private static int BUFSIZE = 8096;
private static GridClient client = new GridClient();
private static string grep = null;
private static byte[] data = new byte[BUFSIZE];
private static byte[] temp = new byte[BUFSIZE];
private static bool boring;
private static string endpoints;
private static int pos;
private static Mode mode = Mode.Generic;
private static Regex regex = RegexForMode(mode);
private enum Mode
{Generic
,TCPDump
};
private static Regex RegexForMode(Mode mode) {
switch (mode) {
case Mode.Generic:
return new Regex(@"(?:\s|PD:|^)(?:([0-9a-fA-F][0-9a-fA-F]){1,2}(?:\s|$))+");
case Mode.TCPDump:
return new Regex(@"^\t0x....: (?:([0-9a-f][0-9a-f]){1,2}(?: |$))+");
default:
throw new Exception("RegexForMode broken");
}
}
private static Regex _modeRegex_TCPDump = new Regex(@"^\d\d:\d\d:\d\d\.\d+ IP \S+ > \S+: ");
private static void SetMode(string line) {
if (_modeRegex_TCPDump.Match(line).Success)
regex = RegexForMode(mode = Mode.TCPDump);
}
public static void Main(string[] args) {
if (args.Length > 0) {
// FIXME
Console.WriteLine("sorry, filtering is currently broken :(");
return;
// grep = String.Join(" ", args);
}
for (Reset();;) {
string line = Console.ReadLine();
if (line == null) {
if (pos != 0)
Done();
return;
}
if (mode == Mode.Generic)
SetMode(line);
Match m = regex.Match(line);
if (m.Success) {
if (pos == 0 && m.Groups[1].Captures.Count < 4) {
boring = true;
continue;
}
while (pos + m.Groups[1].Captures.Count >= BUFSIZE) {
byte[] newData = new byte[data.Length + BUFSIZE];
Array.Copy(data, 0, newData, 0, pos);
data = newData;
}
foreach (Capture capture in m.Groups[1].Captures)
data[pos++] = Byte.Parse(capture.ToString(), NumberStyles.AllowHexSpecifier);
} else {
if (pos != 0)
Done();
Prepare(line);
}
}
}
private static void Reset() {
byte[] clear = {0,0,0,0,0,0,0,0};
Array.Copy(clear, 0, data, 0, 8);
boring = false;
endpoints = "";
pos = 0;
}
private static Regex _prepareRegex_TCPDump_0 = new Regex(@"^\d\d:\d\d:\d\d\.\d+ (.+)");
private static Regex _prepareRegex_TCPDump_1 = new Regex(@"^IP (\S+ > \S+): UDP, ");
private static Regex _prepareRegex_TCPDump_2 = new Regex(@"\.lindenlab\.com\.\d+");
private static void Prepare(string line) {
Match m;
if (mode == Mode.TCPDump && (m = _prepareRegex_TCPDump_0.Match(line)).Success)
// packet header
if ((m = _prepareRegex_TCPDump_1.Match(m.Groups[1].Captures[0].ToString())).Success)
// UDP header
if (_prepareRegex_TCPDump_2.Match(m.Groups[1].Captures[0].ToString()).Success)
// SL header
endpoints = m.Groups[1].Captures[0].ToString();
else
boring = true;
else
boring = true;
}
private static void Done()
{
byte[] zeroBuffer = new byte[4096];
if (!boring) try {
byte[] buf;
if ((data[0] & 0xF0) == 0x40) {
// strip IP and UDP headers
int headerlen = (data[0] & 0x0F) * 4 + 8;
if ((data[6] & 0x1F) != 0x00 || data[7] != 0x00) {
// nonzero fragment offset; we already told them we're truncating the packet
Reset();
return;
}
if ((data[6] & 0x02) != 0x00) {
Console.WriteLine("*** truncating fragmented packet ***");
}
if (data.Length - headerlen > temp.Length)
temp = new byte[data.Length];
Array.Copy(data, headerlen, temp, 0, pos -= headerlen);
if ((temp[0] & Helpers.MSG_ZEROCODED) != 0) {
pos = Helpers.ZeroDecode(temp, pos, data);
buf = data;
} else
buf = temp;
} else
if ((data[0] & Helpers.MSG_ZEROCODED) != 0) {
pos = Helpers.ZeroDecode(data, pos, temp);
buf = temp;
} else
buf = data;
Packet packet = Packet.BuildPacket(buf, ref pos, zeroBuffer);
if (grep != null) {
bool match = false;
//FIXME: This needs to be updated for the new API
//foreach (Block block in packet.Blocks())
//{
// foreach (Field field in block.Fields)
// {
// string value;
// if (field.Layout.Type == FieldType.Variable)
// value = DataConvert.toChoppedString(field.Data);
// else
// value = field.Data.ToString();
// if (Regex.Match(packet.Layout.Name + "." + block.Layout.Name + "." + field.Layout.Name + " = " + value, grep, RegexOptions.IgnoreCase).Success)
// {
// match = true;
// break;
// }
// // try matching variable fields in 0x notation
// if (field.Layout.Type == FieldType.Variable)
// {
// StringWriter sw = new StringWriter();
// sw.Write("0x");
// foreach (byte b in (byte[])field.Data)
// sw.Write("{0:x2}", b);
// if (Regex.Match(packet.Layout.Name + "." + block.Layout.Name + "." + field.Layout.Name + " = " + sw, grep, RegexOptions.IgnoreCase).Success)
// {
// match = true;
// break;
// }
// }
// }
//}
if (!match) {
Reset();
return;
}
}
Console.WriteLine("{0,5} {1} {2}"
,packet.Header.Sequence
,InterpretOptions(packet.Header)
,endpoints
);
Console.WriteLine(packet);
} catch (Exception e) {
Console.WriteLine(e.Message);
}
Reset();
}
private static string InterpretOptions(Header header) {
return "["
+ (header.AppendedAcks ? "Ack" : " ")
+ " "
+ (header.Resent ? "Res" : " ")
+ " "
+ (header.Reliable ? "Rel" : " ")
+ " "
+ (header.Zerocoded ? "Zer" : " ")
+ "]"
;
}
}

View File

@@ -0,0 +1,67 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7AE16AC1-E64C-4FDC-9B85-4BB6145D511C}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Decoder</RootNamespace>
<AssemblyName>Decoder</AssemblyName>
<StartupObject>Decoder</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
<OutputPath>bin\Release-docs\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
<Name>OpenMetaverse</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Decoder.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

60
Programs/Decoder/README Normal file
View File

@@ -0,0 +1,60 @@
Decoder is a tool that decodes packet dumps according to the Second
Life network protocol. Decoder tries to be semi-intelligent about
finding packet data in its input, and for example supports parsing
Second Life's console output or acting as a filter for tcpdump.
BUILDING
========
To build Decoder, you must check out the entire libsecondlife trunk
with subversion:
svn co svn://svn.gna.org/svn/libsecondlife/trunk libsecondlife
The libsecondlife-cs project must be built first; see
libsecondlife-cs/README for instructions. Building SLProxy should be
straightforward with Microsoft Visual Studio. If you're using Mono,
you can build the solution with the included build script:
perl build
The SLProxy library and its example applications will be built in
bin/Debug. In order to run the example applications, you must first
add the libsecondlife-cs build directory to your MONO_PATH environment
variable. For example, if your libsecondlife-cs directory is
~/libsecondlife/libsecondlife-cs and your shell is bash, you can type:
export MONO_PATH=$MONO_PATH:~/libsecondlife/libsecondlife-cs/bin/Debug/
USAGE
=====
You can use Decoder by either copying and pasting packet dumps
directly, or piping it a logfile, as below:
Decoder.exe < some.log
Decoder will attempt to automatically extract the packet data from the
rest of the input. If you paste the packet dump directly rather than
piping in a logfile, you may have to press enter a couple times to
indicate that the packet dump is complete.
You can filter packets by providing a regular expression as a
command-line argument. In this case, at least one field in the form
"PacketName.BlockName.FieldName = FieldValue" must match (case
insensitive) for the packet to be displayed. In the case of
variable-length fields, the FieldValue will be rendered as a
hexadecimal numeral preceeded by 0x, and if that doesn't match,
as a UTF-8 string if possible.
USAGE WITH TCPDUMP
==================
Decoder has enhanced support for tcpdump output. Traffic not related
to SL will be filtered, and the endpoints for each packet will be
displayed. To generate output suitable for Decoder, you must run
tcpdump with the options `-x -s0'. For example:
$ sudo tcpdump -x -s0 | mono Decoder.exe > ~/sldump
See the manpage for tcpdump(1) for more information.