wireshark plugin cannot show detail infomation - wireshark-dissector

We develop a software, the protocol use standard pdcp , but add 44 bytes custom datas before standard pdcp protocol.
I write a wireshark plugin to parse packages, ignore head 44 bytes custom data, parse other data use wireshark pdcp dissector. code list below :
static gint ett_dtmpdcp = -1;
static gint hf_sdtprot_pdu_Msg_Content_None
static hf_register_info hf[] = {
{ &hf_sdtprot_pdu_Msg_Content_None,
{ " ", "dtmpdcp.none",
FT_NONE, BASE_NONE,
NULL, 0x0,
NULL, HFILL }
}
};
static gint *ett[] = {
&ett_dtmpdcp
};
int packet_parse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
int item_offset = 44; //ignore head 44 bytes custom data
gint16 pdu_len = tvb_reported_length(tvb);
proto_item * pdcp_item = proto_tree_add_item(tree, proto_dtmpdcp, tvb, 0, -1, ENC_NA);
proto_item_append_text(pdcp_item, ",PDU len : %-05u", pdu_len);
proto_tree * subtree = proto_item_add_subtree(pdcp_item, ett_dtmpdcp);
offset += item_offset;
//use wireshark pdcp dissector,wireshark register pdcp-lte dissector in packet_pdcp_lte.c file
dissector_handle_t handle = find_dissector("pdcp-lte");
if(handle)
{
tvbuff_t* next_tvb = tvb_new_subset(tvb, offset, -1, pdu_len - item_offset);
if(next_tvb)
{
call_dissector(handle, next_tvb, pinfo, subtree);
//tvb_free(next_tvb);
}
}
return 0;
}
const char *c_proto_string = "DTM-PDCP";
static void
dissect_dtmpdcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, c_proto_string);
col_clear(pinfo->cinfo,COL_INFO);
if (tree)
{
gint offset = 0;
do
{
offset = packet_parse(tvb, pinfo, tree, offset);
} while(offset > 0);
}
}
void proto_register_dtmpdcp(void)
{
module_t *sdtpprot_module;
proto_dtmpdcp = proto_register_protocol("PDCP DTM", /* name */
"a-pdcp", /* short name */
"a-pdcp" /* abbrev */
);
proto_register_field_array(proto_dtmpdcp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
sdtpprot_module = prefs_register_protocol(proto_dtmpdcp, NULL);
prefs_register_bool_preference(sdtpprot_module, "desegment",
"Desegment all dtm-pdcp messages spanning multiple TCP segments",
"Whether the dtm-pdcp dissector should desegment all messages spanning multiple TCP segments",
&sdtpprot_desegment);
}
void proto_reg_handoff_dtmpdcp(void)
{
dissector_handle_t dtmpdcp_handle;
int port = 20000;
dtmpdcp_handle = create_dissector_handle(dissect_dtmpdcp, proto_dtmpdcp);
dissector_add_uint("udp.port", port, dtmpdcp_handle);
}
when use this plugin to dissector package, wireshark UI don't show pdcp protocol detail infomation :
PDCP parse
what's wrong with code?
Thanks a lot!

I would start out by removing the if (tree) check in dissect_dtmpdcp(). From README.dissector:
In the interest of speed, if "tree" is NULL, avoid building a
protocol tree and adding stuff to it, or even looking at any packet
data needed only if you're building the protocol tree, if possible.
Note, however, that you must fill in column information, create
conversations, reassemble packets, do calls to "expert" functions,
build any other persistent state needed for dissection, and call
subdissectors regardless of whether "tree" is NULL or not.
This might be inconvenient to do without doing most of the
dissection work; the routines for adding items to the protocol tree
can be passed a null protocol tree pointer, in which case they'll
return a null item pointer, and "proto_item_add_subtree()" returns
a null tree pointer if passed a null item pointer, so, if you're
careful not to dereference any null tree or item pointers, you can
accomplish this by doing all the dissection work. This might not
be as efficient as skipping that work if you're not building a
protocol tree, but if the code would have a lot of tests whether
"tree" is null if you skipped that work, you might still be better
off just doing all that work regardless of whether "tree" is null
or not.
Note also that there is no guarantee, the first time the dissector is
called, whether "tree" will be null or not; your dissector must work
correctly, building or updating whatever state information is
necessary, in either case.
In my experience, adding the check usually does more harm than good.
I'd also suggest that you examine a working Wireshark dissector such as packet-catapult-dct2000.c and modify your dissector accordingly.
For example:
static dissector_handle_t pdcp_lte_handle;
int packet_parse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
...
if (pdcp_lte_handle)
{
tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset);
if (next_tvb)
call_dissector(pdcp_lte_handle, next_tvb, pinfo, subtree);
}
}
void proto_reg_handoff_dtmpdcp(void)
{
...
pdcp_lte_handle = find_dissector("pdcp-lte");
...
}
If this doesn't resolve your problem, you might need to post a sample capture file somewhere (cloudshark, dropbox, etc.) to better be able to assist you.

Related

Blue screen when rewriting packets at DATAGRAM_DATA layer in WFP

I've been trying to modify outgoing DNS packets via the DATAGRAM_DATA layer in WFP, however i get blue screen errors when rewriting the destination ip in the outgoing packet. What am i doing wrong?
I admit i found the parameters for FwpsInjectTransportSendAsync a bit confusing, and was unsure exactly what to put in for the sendParams arg - though i think what i have looks right.
RtlIpv4StringToAddressExW(
L"1.1.1.1", // hard-coding the new (rewritten) dns server for now
FALSE,
&sin4.sin_addr,
&sin4.sin_port);
RtlIpv4StringToAddressExW(
L"8.8.8.8", // hard-coding the original dns server for now
FALSE,
&origSin4.sin_addr,
&origSin4.sin_port);
if ((Direction == FWP_DIRECTION_OUTBOUND) && (PacketInjectionState == FWPS_PACKET_NOT_INJECTED) && (RemotePort == 53) && (RemoteAddress == origSin4.sin_addr.S_un.S_addr))
{
UINT32 IpHeaderSize = inMetaValues->ipHeaderSize;
UINT32 TransportHeaderSize = inMetaValues->transportHeaderSize;
UINT64 endpointHandle = inMetaValues->transportEndpointHandle;
PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)layerData);
NdisRetreatNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, 0, NULL);
PNET_BUFFER_LIST NetBufferList = NULL;
NTSTATUS Status = FwpsAllocateCloneNetBufferList(layerData, NULL, NULL, 0, &NetBufferList);
if (!NT_SUCCESS(Status))
{
return;
}
NdisAdvanceNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, FALSE, NULL);
if (!NetBufferList)
{
return;
}
NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
PIPV4_HEADER IpHeader = NdisGetDataBuffer(NetBuffer, sizeof(IPV4_HEADER), NULL, 1, 0);
// Rewriting the dest ip
IpHeader->DestinationAddress = sin4.sin_addr.S_un.S_addr;
// Updating the IP checksum
UpdateIpv4HeaderChecksum(IpHeader, sizeof(IPV4_HEADER));
// not 100% sure the sendParams argument is setup correctly, the docs are slightly unclear
FWPS_TRANSPORT_SEND_PARAMS sendParams = {
.remoteAddress = (UCHAR*)IpHeader->DestinationAddress,
.remoteScopeId = inMetaValues->remoteScopeId,
.controlData = inMetaValues->controlData,
.controlDataLength = inMetaValues->controlDataLength,
.headerIncludeHeader = inMetaValues->headerIncludeHeader,
.headerIncludeHeaderLength = inMetaValues->headerIncludeHeaderLength
};
Status = FwpsInjectTransportSendAsync(g_InjectionHandle, NULL, endpointHandle, 0, &sendParams, AF_INET, inMetaValues->compartmentId, NetBufferList, DriverDatagramDataInjectComplete, NULL);
if (!NT_SUCCESS(Status))
{
FwpsFreeCloneNetBufferList(NetBufferList, 0);
}
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
}
Two things stand out to me, both in the sendParams.
First, remoteAddress is incorrect. It needs to a pointer to the address, so it should be (UCHAR*)&IpHeader->DestinationAddress.
Second, FwpsInjectTransportSendAsync() is asynchronous so any parameters you pass to it need to stay valid until it completes which may be after your calling function returns. Typically you allocate some context structure that contains sendParams and deep copies of relevant members (remoteAddress and controlData). You pass this as the context to the completion routine where you free it.

Crashes after parsing the equation

The application want to parse a string equation to mathematics and return the data to user. for this purpose the library is used is exprtk
for easy analysis I have shared minimum working code
minimum working code
when application parses the string to code back to back [multithreaded but locked]
void reset()
{
// Why? because msvc doesn't support swap properly.
//stack_ = std::stack<std::pair<char,std::size_t> >();
/**
it was crashing on destructor on ~deque()
stating memory reallocation
so I change it to pop so for now this has been resolved
*/
while(stack_.size()) stack_.pop();
state_ = true;
error_token_.clear();
}
now the code always crashes on
static inline void destroy(control_block*& cntrl_blck)
{
if (cntrl_blck)
{
/**now crashes on this condition check*/
if ( (0 != cntrl_blck->ref_count) && (0 == --cntrl_blck->ref_count) )
{
delete cntrl_blck;
}
cntrl_blck = 0;
}
}
UPDATE
pastebin code updated new code with main has been added with main and minimum working code.
all the shared_ptr has been removed. now they are normal objects.
as for exprtk reset function has been changed to original one
void reset()
{
// Why? because msvc doesn't support swap properly.
stack_ = std::stack<std::pair<char,std::size_t> >();
state_ = true;
error_token_.clear();
}
and backtrace of gdb has been added backtrace

RX - how to use it in a performant way?

I am trying to understand how to structure my program to use RX in a performant matter.My app has a vector of objects in the 3D world. each object occupied a box, and have a 'hit' stream, which represent a mouse hover over it. I thought of two options of how to structure:
Option 1
struct object_t
{
string name_;
box bounding_box_;
observable<bool> hit_;
};
struct scene_t
{
scene_t(observable<point> mouse) : hit_(hit(mouse))
{
add({"background", {/* ... */}, {}};
}
object_t& add(object_t o)
{
int object_index = objects_.size();
o.hit_ = hit_
.map([=](int index){ return index == object_index; })
.distinct_until_changed();
objects_.push_back(o);
return objects_.back();
}
//! given a stream of mouse points,
//! calculate on which object index(in objects_) the mouse is hover over.
//! 0 if its over the background.
observable<int> hit(observable<point> mouse);
using objects_t = std::vector<object_t>;
objects_t objects_;
observable<int> hit_
};
Option 2
struct object_t
{
string name_;
box bounding_box_;
void signal_hit(boot is_hit) { hit_.get_observer().on_next(is_hit); }
observable<bool> hit() const { return hit_.get_observable(); }
private:
subject<bool> hit_;
};
struct scene_t
{
scene_t(observable<point> mouse) : hit_(hit(mouse))
{
add({"background", {/* ... */}, {}};
hit_
.start_with(0)
.buffer(2, 1) // take two hits together, the current and the previos
.subscribe([this](std::vector<int> indices) {
objects_[indices[1]].signal_hit(false); // we leave this one
objects_[indices[0]].signal_hit(true); // and entering this one
});
}
object_t& add(object_t o)
{
objects_.push_back(o);
return objects_.back();
}
//! ... as above
};
Now the question is how to chain the result of the hit function to the object_t::hit stream. I see two ways:
Option 1, is fully functional, but very poorly performing, since for every mouse point, all objects stream will need to calculate their value.
Option 2. is not fully functional, as I use subject to push the values to the right stream, in an imperative way. but is very performant as only the right (two) object(s) hit stream get to fire.
Note:
The implementation is in rxcpp, but its general to any language we have RX in it, or general FRP paradigm, this is why I tagged rxjs\rx.net\frp etc.
thanks in advance :-)
If there is one source observable and N subscribers then there will have to be at least N computations every time the source emits. There is no way around that which I can think of.

Developing iTunes like application in c#

I need to develop an application in c# that could automatically detect an iPhone when it is connected to the system and read a particular file for the iPhone file system. I basically want this file to be downloaded automatically from device to the PC. I used USBpcap tool that suggests that iTunes connects to phone using some XML format. Any help or insight greatly appreciated. Is there any documentation of Third party APIs that can get me started? There are some applications that can replicate iTunes functionality e.g Copytrans
Is there any protocol or APIs provided by Apple?
I have been digging the internet and found this link Layered communication for iPhone.
Also I am using the LibUsbDotNet libraries for communicating to the usb device(Example). Can any one suggest which EndPoints should be used.
It seems to me that I have to implement usbmuxd in windows application. It is a multilayer protocol. There must be some libraries that implement usbmuxd(I dont think I have to implement the protocol all by my self)
I dont have much idea about iTunes communication as well as USB communication. I am adding as much information as I can(of course with the things I come up with in my R&D). Any help is highly appreciated.
public static DateTime LastDataEventDate = DateTime.Now;
public static UsbDevice MyUsbDevice;
#region SET YOUR USB Vendor and Product ID!
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1452, 4768);
#endregion
private void LibUSB()
{
ErrorCode ec = ErrorCode.None;
try
{
// Find and open the usb device.
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
// If the device is open and ready
if (MyUsbDevice == null)
throw new Exception("Device Not Found.");
// If this is a "whole" usb device (libusb-win32, linux libusb)
// it will have an IUsbDevice interface. If not (WinUSB) the
// variable will be null indicating this is an interface of a
// device.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
// open read endpoint 1.
UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep03);
// open write endpoint 1.
UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep02);
int bytesWritten;
ec = writer.Write(usbmux_header.GetBytes(), 2000, out bytesWritten);
if (ec != ErrorCode.None)
throw new Exception(UsbDevice.LastErrorString);
byte[] readBuffer = new byte[1024];
while (ec == ErrorCode.None)
{
int bytesRead;
// If the device hasn't sent data in the last 100 milliseconds,
// a timeout error (ec = IoTimedOut) will occur.
ec = reader.Read(readBuffer, 10000, out bytesRead);
if (ec == ErrorCode.Win32Error)
throw new Exception("port not open");
if (bytesRead == 0)
throw new Exception("No more bytes!");
// Write that output to the console.
Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
}
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
}
finally
{
if (MyUsbDevice != null)
{
if (MyUsbDevice.IsOpen)
{
// If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
// it exposes an IUsbDevice interface. If not (WinUSB) the
// 'wholeUsbDevice' variable will be null indicating this is
// an interface of a device; it does not require or support
// configuration and interface selection.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Release interface #0.
wholeUsbDevice.ReleaseInterface(0);
}
MyUsbDevice.Close();
}
MyUsbDevice = null;
// Free usb resources
UsbDevice.Exit();
}
}
}
class usbmux_header
{
public static UInt32 length = 10; // length of message, including header
public static UInt32 reserved = 0; // always zero
public static UInt32 type = 3; // message type
public static UInt32 tag = 2; // responses to this query will echo back this tag
public static byte[] GetBytes()
{
byte[] lgth = BitConverter.GetBytes(length);
byte[] res = BitConverter.GetBytes(reserved);
byte[] tpe = BitConverter.GetBytes(type);
byte[] tg = BitConverter.GetBytes(tag);
byte[] retArray = new byte[16];
lgth.CopyTo(retArray, 0);
res.CopyTo(retArray, 4);
tpe.CopyTo(retArray, 8);
tg.CopyTo(retArray, 12);
return retArray;
}
};
I have been trying to send hello packet bytes to iPhone but I am not able to read any response from phone.
To play with ipod you can use SharePodLib
As I understand it, only one client can use the USB connection to iOS at one time. On both macOS and Windows, that one client is usbmux. That library multiplexes TCP connections with higher-level clients, including iTunes, Photos, and (on macOS) the open-source peertalk library.
So on Windows, you wouldn't want to implement your own usbmux, but rather a client that sits on top of that, analogous to peertalk. I haven't seen anything open-source that does this, but a number of developers have accomplished it with their own proprietary software.
If anybody else has pointers about using usbmux on Windows, I'd love to hear about it.
—Dave
You can use imobiledevice-net. It provides a C# API to connect to iOS devices using your PC.
For example, to list all iOS devices connected to your PC, you would run something like this:
ReadOnlyCollection<string> udids;
int count = 0;
var idevice = LibiMobileDevice.Instance.iDevice;
var lockdown = LibiMobileDevice.Instance.Lockdown;
var ret = idevice.idevice_get_device_list(out udids, ref count);
if (ret == iDeviceError.NoDevice)
{
// Not actually an error in our case
return;
}
ret.ThrowOnError();
// Get the device name
foreach (var udid in udids)
{
iDeviceHandle deviceHandle;
idevice.idevice_new(out deviceHandle, udid).ThrowOnError();
LockdownClientHandle lockdownHandle;
lockdown.lockdownd_client_new_with_handshake(deviceHandle, out lockdownHandle, "Quamotion").ThrowOnError();
string deviceName;
lockdown.lockdownd_get_device_name(lockdownHandle, out deviceName).ThrowOnError();
deviceHandle.Dispose();
lockdownHandle.Dispose();
}

NPAPI plugin develop on mac10.8

I have some problems,i use xcode write a npapi plugin on mac10.8,I want to draw a picture on the plugin but when i get the pNPWindow->window pointer through NPP_SetWindow(NPP instance, NPWindow* pNPWindow); I find that nNPWindow->window is NULL ,i spend must to find the problem,but i can not,somebody can help me。 sorry,my english so poor。
code is like that,
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
{
if(instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
CPlugin *plugin = new CPlugin(instance);
if(plugin == NULL)
return NPERR_OUT_OF_MEMORY_ERROR;
instance->pdata = (void *)plugin;
NPBool supportsCG = false;
NPError err;
err = browser->getvalue(instance, NPNVsupportsCoreGraphicsBool,&supportsCG);
if (err == NPERR_NO_ERROR && supportsCG)
browser->setvalue(instance,NPPVpluginDrawingModel,(void*)NPDrawingModelCoreGraphics);
return NPERR_NO_ERROR;
}
NPError NPP_SetWindow(NPP instance, NPWindow* pNPWindow)
{
if(instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if(pNPWindow == NULL)
return NPERR_GENERIC_ERROR;
if(pNPWindow->window)
writelog("window != NULL");
if(pNPWindow->window == NULL) //this is he problem pNPWindow->window always NULL
writelog("window == NULL");
return NPERR_NO_ERROR;
}
Anything you're going to use on Mac 10.8 won't support the carbon event model, so window will always be NULL. Assuming that you're trying to use the CoreGraphics drawing model you will get the CGContextRef when the event is fired to draw.
See https://wiki.mozilla.org/NPAPI:CocoaEventModel for more information on the Cocoa event model. The other option you have is the CoreAnimation model (with the InvalidatingCoreAnimation model on firefox and chrome)
You might want to take a look at FireBreath, which works on 10.8 and abstracts all of the complication of this stuff for you.
NPP_SetWindow (NPP npp, NPWindow* pNPWindow)
For many, this will be where the real fun starts — this function is called to tell the plugin which window they are in. From the Gecko SDK (npapi.h):
typedef struct _NPWindow
{
void* window; /* Platform specific window handle */
/* OS/2: x - Position of bottom left corner */
/* OS/2: y - relative to visible netscape window */
int32 x; /* Position of top left corner relative */
int32 y; /* to a netscape page. */
uint32 width; /* Maximum window size */
uint32 height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
void * ws_info; /* Platform-dependent additonal data, linux specific */
NPWindowType type; /* Is this a window or a drawable? */
} NPWindow;
A pointer to this structure is passed in with each call. On windows, the “void* window” will dereference to an HWND. On other platforms, it will likewise be dereferenced as an appropriate type.
Notice that again NPP npp is the first parameter. This will be the case on all NPP functions except NPP_New, where the mimetype is also passed in. Since we created a PluginInstance object and assigned it to npp->pdata in NPP_New, we need to create a small stub function to forward our NPP_New to a method on that object, like so:
// Called by browser whenever the window is changed, including to set up or destroy
NPErrorNPP_SetWindow (NPP npp, NPWindow* pNPWindow)
{
if (npp == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
else if (npp->pdata == NULL)
return NPERR_GENERIC_ERROR;
PluginInstance *inst = (PluginInstance *)npp->pdata;
return inst->NpapiSetWindow(pNPWindow);
}
On windows, when SetWindow is called we need to save the HWND and subclass the window so that we can get our own window event proc.
NPError PluginInstance::NpapiSetWindow (NPWindow* pNPWindow)
{
NPError rv = NPERR_NO_ERROR;
if(pNPWindow == NULL)
return NPERR_GENERIC_ERROR;
// window just created; in initWindow, set initialized to true
if(!this->initialized) {
if(!this->initWindow(pNPWindow)) {
return NPERR_MODULE_LOAD_FAILED_ERROR;
}
}
// Window was already created; just pass on the updates
this->updateWindow(pNPWindow);
return rv;
}
With these functions, we get notified in one function when the window is first set, and another is called each time an update is made.

Resources