Wireshark-dev: [Wireshark-dev] question regarding my wireshark dissector code.
From: Brian Oleksa <oleksab@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 02 Jul 2009 14:49:04 -0400
@WiresharkersI have created this helen dissector. It has been running great ever since then.
I have some NON-helen packets that I want to dissect. Instead of writing another dissector, I added it to the packet-helen.c code.
As you can see at the top of this file I call a new procedure called: void proto_reg_handoff_netalive(void) Which works great and reads in the port # from the file correctly.I even get into the void dissect_netalive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) procedure with no problems:
But I am not dissecting anything. The only thing that I get in the wireshark GUI is the word "NETALIVE".
Why I am not seeing the dissection tree under the NETALIVE protocol....??Basically.......all I did was I mirrored the helen protocol....it compiles fine but I do not see my packets being dissected.
Any thoughts or suggestions...? The latest code is attached. Thank you very much for your help. It is greatly appreciated. Brian
/* packet-helen.c
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <glib.h>
#include <epan/packet.h>
#include <time.h>
#include <string.h>
#define PROTO_TAG_HELEN "HELEN"
#define PROTO_TAG_NETALIVE "NETALIVE"
/* Wireshark ID of the HELEN protocol */
static int proto_helen = -1;
static int proto_netalive = -1;
/* These are the handles of our subdissectors */
static dissector_handle_t data_handle = NULL;
static dissector_handle_t netalivedata_handle = NULL;
static dissector_handle_t helen_handle;
static dissector_handle_t netalive_handle;
void dissect_helen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
void dissect_netalive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
//You now put your ports in the ports file
//this port can be changed to whatever port SA is running on.
//static int global_helen_port = 7636;
static const value_string packettypenames[] = {
{ 0, "TEXT"
},
{ 1, "SOMETHING_ELSE"
},
{ 0, NULL
}
};
// Declarations:
int numBytesInMode(int numBits);
int numBytesInBitmask(int numBits);
/* The following hf_* variables are used to hold the Wireshark IDs of
* our header fields; they are filled out when we call
* proto_register_field_array() in proto_register_helen()
*/
/** Kts attempt at defining the protocol */
static gint hf_helen = -1;
//static gint hf_helen_header = -1;
static gint hf_helen_length = -1;
static gint hf_helen_type = -1;
static gint hf_helen_text = -1;
static gint hf_netalive = -1;
//static gint hf_helen_header = -1;
static gint hf_netalive_length = -1;
static gint hf_netalive_type = -1;
static gint hf_netalive_text = -1;
static gint hf_helen_magic = -1;
static gint hf_helen_checksum = -1;
static gint hf_helen_txTime = -1;
/* These are the ids of the subtrees that we may be creating */
static gint ett_helen = -1;
static gint ett_helen_header = -1;
static gint ett_helen_length = -1;
static gint ett_helen_type = -1;
static gint ett_helen_text = -1;
static gint ett_netalive = -1;
static gint ett_netalive_header = -1;
static gint ett_netalive_length = -1;
static gint ett_netalive_type = -1;
static gint ett_netalive_text = -1;
void proto_reg_handoff_helen(void) {
static gboolean initialized = FALSE;
int portnumber;
FILE *fp;
#if defined(_WIN32)
fp = fopen("ports.txt", "r");
#else
fp = fopen("ports", "r");
#endif
if (fp == NULL) {
printf("Can't open the ports file! \n");
printf("Make sure the file exists where the wireshark executable lives at \n");
exit(1);
}
while (fscanf(fp, "%d\n", &portnumber) != EOF) {
printf("Port number = %d\n", portnumber);
if (!initialized) {
data_handle = find_dissector("data");
helen_handle = create_dissector_handle(dissect_helen, proto_helen);
//This is to be used for hard coded ports (see static variable above)
//dissector_add("udp.port", global_helen_port, helen_handle);
//This line read the port number from the file.
dissector_add("udp.port", portnumber, helen_handle);
}
}
fclose(fp);
}
void proto_reg_handoff_netalive(void) {
static gboolean isinitialized = FALSE;
static gboolean isnetalivefilehere = TRUE;
int netaliveportnumber;
FILE *fpnetalive;
#if defined(_WIN32)
fpnetalive = fopen("netaliveport.txt", "r");
#else
fpnetalive = fopen("netaliveport", "r");
#endif
if (fpnetalive == NULL) {
printf("Can't open the netalive ports file! \n");
printf("Make sure the file exists where the wireshark executable lives at \n");
isnetalivefilehere = FALSE;
//exit(1);
}
//if netalive ports file is there....then go into this loop.
//if it is not there then just continue on.
if(isnetalivefilehere)
{
while (fscanf(fpnetalive, "%d\n", &netaliveportnumber) != EOF) {
printf("Net Alive Port number = %d\n", netaliveportnumber);
if (!isinitialized) {
netalivedata_handle = find_dissector("data");
netalive_handle = create_dissector_handle(dissect_netalive, proto_netalive);
printf("I am here 1\n");
//This line read the port number from the file.
dissector_add("udp.port", netaliveportnumber, netalive_handle);
}
}
}
fclose(fpnetalive);
}
void proto_register_helen(void) {
/* A header field is something you can search/filter on.
*
* This creates a structure to register our fields. It consists of an
* array of hf_register_info structures, each of which are of the format
* {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
*/
static hf_register_info hf[] = {
{ &hf_helen,
{ "Data", "helen.data", FT_NONE, BASE_NONE, NULL, 0x0,
"HELEN PDU", HFILL
}
},
{ &hf_helen_magic,
{ "Magic Number", "helen.header", FT_BYTES, BASE_HEX, NULL, 0x0,
"HELEN Header", HFILL
}
},
{ &hf_helen_checksum,
{ "Checksum", "helen.header", FT_UINT64, BASE_DEC, NULL, 0x0,
"HELEN Header", HFILL
}
},
{ &hf_helen_txTime,
{ "System Tx Time", "helen.header", FT_UINT64, BASE_DEC, NULL, 0x0,
"HELEN Header", HFILL
}
},
{ &hf_helen_length,
{ "Package Length2", "helen.len", FT_UINT32, BASE_DEC, NULL, 0x0,
"Package Length3", HFILL
}
},
{ &hf_helen_type,
{ "Type", "helen.type", FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0,
"Package Type", HFILL
}
},
{ &hf_helen_text,
{ "Text", "helen.text", FT_STRING, BASE_NONE, NULL, 0x0,
"Text", HFILL
}
}
};
static gint * ett[] = {
&ett_helen,
&ett_helen_header,
&ett_helen_length,
&ett_helen_type,
&ett_helen_text,
};
proto_helen = proto_register_protocol("HELEN", "HELEN", "helen");
proto_register_field_array(proto_helen, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("helen", dissect_helen, proto_helen);
}
void proto_register_netalive(void) {
/* A header field is something you can search/filter on.
*
* This creates a structure to register our fields. It consists of an
* array of hf_register_info structures, each of which are of the format
* {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
*/
static hf_register_info hf[] = {
{ &hf_netalive,
{ "Data", "netalive.data", FT_NONE, BASE_NONE, NULL, 0x0,
"NETALIVE PDU", HFILL
}
},
{ &hf_netalive_length,
{ "Package Length2", "netalive.len", FT_UINT32, BASE_DEC, NULL, 0x0,
"Package Length3", HFILL
}
},
{ &hf_netalive_type,
{ "Type", "helen.type", FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0,
"Package Type", HFILL
}
},
{ &hf_netalive_text,
{ "Text", "netalive.text", FT_STRING, BASE_NONE, NULL, 0x0,
"Text", HFILL
}
}
};
static gint * ett[] = {
&ett_netalive,
&ett_netalive_header,
&ett_netalive_length,
&ett_netalive_type,
&ett_netalive_text,
};
proto_netalive = proto_register_protocol("NETALIVE", "NETALIVE", "netalive");
proto_register_field_array(proto_netalive, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("netalive", dissect_netalive, proto_netalive);
}
static const value_string helen_vals[] = {
{1, "GPS"},
{2, "Flow"},
{3, "Host"},
{1000, "Minotaur SA Extension"},
{1002, "Minotaur SA Status Extension"},
{1003, "Minotaur SA Redline Aspect Extension"},
{1013, "Leger Extension"},
{1024, "Alares Data Extension"},
{1025, "Alares Control Extension"}
};
guint16 swap16(guint16 in) {
guint8 high = (in >> 8) & 0xff;
guint8 low = in & 0xff;
guint16 newVal = (low << 8) | high;
return newVal;
}
guint32 swap32(guint32 in) {
guint8 b1 = (in >> 24) & 0xff;
guint8 b2 = (in >> 16) & 0xff;
guint8 b3 = (in >> 8) & 0xff;
guint8 b4 = in & 0xff;
guint32 newVal = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
return newVal;
}
//time converter method here
//int txTime()
//{
// time_t now;
// struct tm *ts;
// char buf[80];
// now = time(NULL);
// ts = localtime(&now);
// return strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
//return value;
//}
void dissect_netalive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
proto_item *netalive_item = NULL;
proto_item *netalive_sub_item = NULL;
proto_tree *netalive_tree = NULL;
proto_tree *netalive_header_tree = NULL;
guint16 type = 0;
printf("I am here 2\n");
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_NETALIVE);
/* Clear out stuff in the info column */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
}
// This is not a good way of dissecting packets. The tvb length should
// be sanity checked so we aren't going past the actual size of the buffer.
type = tvb_get_guint8(tvb, 4); // Get the type byte
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Info Type:[%s]",
pinfo->srcport, pinfo->destport,
val_to_str(type, packettypenames, "Unknown Type:0x%02x"));
}
printf("I am here 3\n");
if (tree) { /* we are being asked for details */
guint32 offset = 0;
netalive_item = proto_tree_add_item(tree, proto_netalive, tvb, 0, -1, FALSE);
netalive_tree = proto_item_add_subtree(netalive_item, ett_netalive);
netalive_header_tree = proto_item_add_subtree(netalive_item, ett_netalive);
netalive_header_tree = proto_item_add_subtree(netalive_sub_item, ett_netalive);
{
guint8 * ptr = (guint8*) tvb->real_data;
guint8 * packet_header = ptr;
proto_tree *netalive_sub_tree = NULL;
int swap = 1;
guint8 designator;
guint8 version;
guint8 updaterate;
guint8 nodeId;
char buf[100];
//glong timestamp;
gfloat longitude;
gfloat latitude;
gfloat altitude;
guint8 altitudetype;
guint8 radiostatus;
guint8 networksize;
guint16 inbound;
guint16 outbound;
int numOneBitsInMask;
char * statusStr = "";
char * tempStr = "";
int codeOffset;
ptr = packet_header;
offset = (ptr - tvb->real_data);
codeOffset = offset;
//guint16 bead;
//char * packet_name = "";
// Hardcoding to ALWAYS SWAP as we don't know how to detect when to swap!
//int i;
printf("I am here 4\n");
//for (;;) {
//if (1==1) {
printf("I am here 5\n");
// if (swap) {
// code = swap16(code);
// }
//
// ptr += 1;
// offset += 1;
// numBytes = *((guint16*) ptr);
// if (swap) {
// numBytes = swap16(numBytes);
// }
//NetAlive
//NetAlive designator
designator = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"Net Alive Designator : %d", designator);
offset += 1;
//NetAlive version
version = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"Net Alive version : %d", version);
offset += 1;
//NetAlive update rate
updaterate = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"Net Alive update rate : %d", updaterate);
offset += 1;
//Source node ID
nodeId = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"Source Node ID : %d", nodeId);
offset += 1;
//Time Stamp....
//this is just getting system time....and not the time off the radio.
//However...the radios time should be the same at the system time
//time_t now;
//struct tm *ts;
//char buf[80];
// now = time(NULL);
ptr += 8;
// ts = localtime(&now);
// strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
// proto_tree_add_uint_format(netalive_sub_tree, hf_helen_length, tvb, offset, 8, 0,
// "%s", buf);
offset += 8;
//GPS Latitude
latitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
latitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
"Latitude: %f", latitude);
offset += 4;
//GPS Longitude
longitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
longitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
"Longitude: %f", longitude);
offset += 4;
//GPS Altitude:
altitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
altitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 4, 0,
"Altitude: %f", altitude);
offset += 4;
//GPS Altitude type
altitudetype = * ((guint8*) ptr);
if ( (altitudetype & 1) == 0) {
statusStr = "Sea Level in ";
} else {
statusStr = "High above ellipsoid (HAE) in ";
}
if ( (altitudetype & 2) == 0) {
tempStr = "meters";
} else {
tempStr = "feet";
}
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"%s%s", statusStr, tempStr);
ptr += 1;
offset += 1;
//Radio status and alerts
radiostatus = * ((guint8*) ptr);
buf[0] = (char)0;
if ((radiostatus & 1) == 1) {
strcat(buf,"BIT Fail,");
} else if ((radiostatus & 2) == 1) {
strcat(buf,"No GPS,");
} else if ((radiostatus & 4) == 1) {
strcat(buf,"Login Alert,");
}
// We could rip out the ending comma (if it exists!) by trying the following:
{
char* p2; // Put this at the top!
if (strlen(buf) > 0) {
p2 = buf + strlen(buf) - 1;
*p2 = (char)0;
}
}
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"%s", buf);
ptr += 1;
offset += 1;
//Network size
networksize = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 1, 0,
"Network size : %d", networksize);
offset += 1;
//SPARE....so I am skipping this slot.
ptr += 1;
offset += 1;
//Inbound throughput
inbound = * ((guint16*) ptr);
if (swap) {
inbound = swap16(inbound);
}
ptr += 2;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 2, 0,
"Inbound throughput : %d", inbound);
offset += 2;
//Outbound throughput
outbound = * ((guint16*) ptr);
if (swap) {
outbound = swap16(outbound);
}
ptr += 2;
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, 2, 0,
"Outbound throughput : %d", outbound);
offset += 2;
//Waveform Bitmask
numOneBitsInMask = 0;
{
int i;
char buf2[10];
int numBytes = numBytesInBitmask(networksize);
buf[0] = (char)0;
for (i = 0; i < numBytes; i++) {
guint8 val = *((guint8*)ptr);
if (val & 1) numOneBitsInMask++;
if (val & 2) numOneBitsInMask++;
if (val & 4) numOneBitsInMask++;
if (val & 8) numOneBitsInMask++;
if (val & 16) numOneBitsInMask++;
if (val & 32) numOneBitsInMask++;
if (val & 64) numOneBitsInMask++;
if (val & 128) numOneBitsInMask++;
sprintf(buf2,"%x",val);
strcat(buf,buf2);
ptr++;
}
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, numBytes, 0,
"Waveform Bitmask : %s", buf);
offset += numBytes;
}
//Waveform Mode
{
int i;
char buf2[10];
int numBytes = numBytesInMode(numOneBitsInMask);
buf[0] = (char)0;
for (i = 0; i < numBytes; i++) {
guint8 val = *((guint8*)ptr);
// This would be nice:
// 17: BPSK 4
sprintf(buf2,"%x",val);
strcat(buf,buf2);
ptr++;
}
proto_tree_add_uint_format(netalive_sub_tree, hf_netalive_length, tvb, offset, numBytes, 0,
"Waveform Mode : %s", buf);
offset += numBytes;
printf("I am here... 6\n");
}
//}
}
}
}
int numBytesInBitmask(int numBits){
int q = numBits / 8;
int extraBits = numBits % 8;
//printf("I am here... 7\n");
if (extraBits > 0) {
q++;
}
return q;
}
int numBytesInMode(int numBits){
int q = numBits / 2;
int extraBits = numBits % 2;
if (extraBits > 0) {
q++;
}
return q;
}
void dissect_helen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
proto_item *helen_item = NULL;
proto_item *helen_sub_item = NULL;
proto_tree *helen_tree = NULL;
proto_tree *helen_header_tree = NULL;
guint16 type = 0;
printf("Inside dissect_helen 1\n");
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_HELEN);
/* Clear out stuff in the info column */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
}
// This is not a good way of dissecting packets. The tvb length should
// be sanity checked so we aren't going past the actual size of the buffer.
type = tvb_get_guint8(tvb, 4); // Get the type byte
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Info Type:[%s]",
pinfo->srcport, pinfo->destport,
val_to_str(type, packettypenames, "Unknown Type:0x%02x"));
}
if (tree) { /* we are being asked for details */
guint32 offset = 0;
printf("Inside dissect_helen 2\n");
helen_item = proto_tree_add_item(tree, proto_helen, tvb, 0, -1, FALSE);
helen_tree = proto_item_add_subtree(helen_item, ett_helen);
helen_header_tree = proto_item_add_subtree(helen_item, ett_helen);
//helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_header, tvb, offset, -1, FALSE);
helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_magic, tvb, 0, 2, FALSE);
helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_checksum, tvb, 2, 8, FALSE);
//helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_txTime, tvb, 10, 8, FALSE);
//need to format the time..!!
helen_sub_item = proto_tree_add_item(helen_tree, hf_helen_txTime, tvb, 10, 8, FALSE);
helen_header_tree = proto_item_add_subtree(helen_sub_item, ett_helen);
{
guint8 * ptr = (guint8*) tvb->real_data;
guint8 * packet_header = ptr;
guint16 bead;
char buf[100];
char * packet_name = "";
proto_tree *helen_sub_tree = NULL;
int swap = 0;
bead = *((guint16*) packet_header);
if (bead != 0xBEAD) {
swap = 1;
}
offset += 18;
ptr += 18; /* Skip the header.*/
packet_header = ptr;
printf("Inside dissect_helen 3\n");
for (;;) {
guint16 code = *((guint16*) packet_header);
guint16 numBytes = 0;
int unknownPacket = 0;
int codeOffset;
ptr = packet_header;
// Must re-set the offset because of Flow control messages that specify only 12 bytes, but actually contain 16:
offset = (ptr - tvb->real_data);
codeOffset = offset;
printf("Inside dissect_helen 4\n");
if (swap) {
code = swap16(code);
}
ptr += 2;
offset += 2;
numBytes = *((guint16*) ptr);
if (swap) {
numBytes = swap16(numBytes);
}
ptr += 2;
offset += 2;
switch (code) {
case 0: packet_name = "End of Packet";
break;
case 1: packet_name = "GPS Extension";
break;
case 2: packet_name = "Flow Extension";
break;
case 3: packet_name = "Host Extension";
break;
case 1000: packet_name = "Minotaur SA";
break;
case 1002: packet_name = "Minotaur SA Status Ext";
break;
case 1003: packet_name = "Minotaur SA Redline Aspect Ext";
break;
case 1013: packet_name = "Leger Ext";
break;
case 1024: packet_name = "Alares Data Ext";
break;
case 1025: packet_name = "Alares Control Ext";
break;
default: packet_name = "Unknown code";
unknownPacket = 1;
break;
}
//strcpy(buf, "Packet Code ");
strcpy(buf, " ");
strcat(buf, packet_name);
if (unknownPacket) {
sprintf(buf, "Unknown packet: %d", code);
}
helen_item = proto_tree_add_text(tree, tvb, codeOffset, 2, "%s", buf);
helen_sub_tree = proto_item_add_subtree(helen_item, ett_helen);
if (code == 0) {
break;
}
// GPS:
if (code == 1) {
guint8 fieldsAvail;
fieldsAvail = *((guint8*) ptr);
ptr += 1;
offset += 1;
//printf("%s \n", "This is the GPS Extension");
// Status:
if ((fieldsAvail & 1) != 0) {
guint8 status;
char * statusStr = "";
status = *((guint8*) ptr);
if (status == 0) {
statusStr = "Good";
} else if (status == 1) {
statusStr = "No Fix";
} else if (status == 2) {
statusStr = "Bad GPS Read";
}
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"%s", statusStr);
ptr += 1;
offset += 1;
}
// Time: ...This is the first attempt at time
//if ( (fieldsAvail & 2) != 0) {
//guint32 halfTime1, halfTime2;
//halfTime1 = *((guint32*)ptr);
//ptr += 4;
//halfTime2 = *((guint32*)ptr);
//ptr += 4;
//scanf("%X",halfTime1);
//printf("%f",halfTime1);
//proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
// "Time: %X %X", halfTime1, halfTime2);
//offset += 8;
//}
// Time:
//this is just getting system time....and not the time of the GPS.
//However...the GPS time should be the same at the system time
if ((fieldsAvail & 2) != 0) {
time_t now;
struct tm *ts;
char buf[80];
now = time(NULL);
ptr += 8;
ts = localtime(&now);
strftime(buf, sizeof (buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"%s", buf);
offset += 8;
}
// Longitude:
if ((fieldsAvail & 4) != 0) {
gfloat longitude;
longitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
longitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Longitude: %f", longitude);
offset += 4;
}
// Latitude:
if ((fieldsAvail & 8) != 0) {
gfloat latitude;
latitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
latitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Latitude: %f", latitude);
offset += 4;
}
// Altitude:
if ((fieldsAvail & 16) != 0) {
gfloat altitude;
altitude = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
altitude = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Altitude: %f", altitude);
offset += 4;
}
// Bearing:
if ((fieldsAvail & 32) != 0) {
gfloat bearing;
bearing = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
bearing = *((gfloat*) & temp);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Bearing: %f", bearing);
offset += 4;
}
// Speed:
if ((fieldsAvail & 64) != 0) {
gfloat speed;
speed = *((gfloat*) ptr);
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
speed = *((gfloat*) & temp);
}
ptr += 4;
//If speed is NOT available or less than or equal to zero...then do not display it.
if (speed != 0.0) {
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Speed: %f", speed);
}
offset += 4;
}
// Number of Satellites:
if ((fieldsAvail & 128) != 0) {
guint8 nos;
nos = *((guint8*) ptr);
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"Number of Satellites: %d", nos);
ptr += 1;
offset += 1;
}
}
// FLOW:
if (code == 2) {
char flowname[9];
guint32 seq;
guint32 src;
//printf("This is the Flow Extension\n");
strncpy(flowname, ptr, 8);
flowname[8] = '\0';
ptr += 8;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"Flowname: %s", flowname);
offset += 8;
// Sequence number:
seq = *((guint32*) ptr);
if (swap) {
seq = swap32(seq);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Sequence #: %d", seq);
offset += 4;
// need to verify if this works (test with leger)
if (numBytes == 16) {
// Source:
src = *((guint32*) ptr);
if (swap) {
src = swap32(src);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Source : %d", src);
offset += 4;
}
}
// HOST:
if (code == 3) {
guint8 size;
//printf("%s \n", "This is the Host Extension");
// Size:
size = *((guint8*) ptr);
ptr += 1;
offset += 1;
if (size == 4) {
guint32 addr;
addr = *((guint32*) ptr);
if (swap) {
addr = swap32(addr);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Address: %d.%d.%d.%d", addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
offset += 4;
}
//I was board so I added the IPv6 address translation here in this else statement....However..I cannot test it..but it should work.
else {
guint32 addr1, addr2, addr3, addr4;
addr1 = *((guint32*) ptr);
ptr += 4;
addr2 = *((guint32*) ptr);
ptr += 4;
addr3 = *((guint32*) ptr);
ptr += 4;
addr4 = *((guint32*) ptr);
ptr += 4;
if (swap) {
addr1 = swap32(addr1);
addr2 = swap32(addr2);
addr3 = swap32(addr3);
addr4 = swap32(addr4);
}
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 16, 0,
"Address: %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d",
addr1 >> 24, (addr1 >> 16) & 0xff, (addr1 >> 8) & 0xff, addr1 & 0xff,
addr2 >> 24, (addr2 >> 16) & 0xff, (addr2 >> 8) & 0xff, addr2 & 0xff,
addr3 >> 24, (addr3 >> 16) & 0xff, (addr3 >> 8) & 0xff, addr3 & 0xff,
addr4 >> 24, (addr4 >> 16) & 0xff, (addr4 >> 8) & 0xff, addr4 & 0xff
);
offset += 16;
}
}
//Minotaur SA Ext:
if (code == 1000) {
guint32 id;
//printf("%s \n", "This is the Minotaur SA Ext");
id = *((guint32*) ptr);
if (swap) {
id = swap32(id);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Harmonice ID #: %d", id);
offset += 4;
}
//Minotaur SA Status Ext:
if (code == 1002) {
guint32 stuff;
//printf("%s \n", "This is the Minotaur SA Status Ext");
stuff = *((guint32*) ptr);
//if (swap){
// id = swap32(id);
//}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, numBytes, 0,
"Minotaur Status Ext:");
offset += numBytes;
}
//Minotaur SA Redline Aspect Ext:
//Need more info.. Need size and data types
if (code == 1003) {
guint32 stuff;
//printf("%s \n", "This is the Minotaur SA Redline Aspect Ext");
stuff = *((guint32*) ptr);
//if (swap){
// id = swap32(id);
//}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Minotaur SA Redline Aspect:");
offset += 4;
}
//Leger Ext:
//Need more info.. Need size and data types
if (code == 1013) {
guint32 stuff;
printf("%s \n", "This is the Leger Ext");
stuff = *((guint32*) ptr);
//if (swap){
// id = swap32(id);
//}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Leger Ext:");
offset += 4;
}
//Alares Data Ext:
if (code == 1024) {
glong key;
guint32 id;
guint32 messageId;
guint32 totalBlks;
guint32 blockId;
glong theTime;
guint8 repairStatus;
char * repairStatusStr = "";
//time_t rightnow;
//struct tme *tss;
//char buff[80];
//rightnow = time(NULL);
//tss = localtime(&rightnow);
//printf("%s \n", "This is the Alares Data Ext");
//Alares Session Key
if (swap) {
// 64-bit swap, done as 2 32-bit swaps in the
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
*((guint32*) ptr) = temp;
temp = *((guint32*) (ptr + 4));
temp = swap32(temp);
*((guint32*) ptr + 4) = temp;
}
key = *((glong*) ptr);
ptr += 8;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"Alares Session Key: %ld", key);
offset += 8;
//ID for Source
id = *((guint32*) ptr);
if (swap) {
id = swap32(id);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"ID for source #: %d", id);
offset += 4;
//Message ID
messageId = *((guint32*) ptr);
if (swap) {
messageId = swap32(messageId);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Message ID: %d", messageId);
offset += 4;
//Total Blocks
totalBlks = *((guint32*) ptr);
if (swap) {
totalBlks = swap32(totalBlks);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Total Blocks: %d", totalBlks);
offset += 4;
//Tx Time
if (swap) {
// 64-bit swap, done as 2 32-bit swaps in the
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
*((guint32*) ptr) = temp;
temp = *((guint32*) (ptr + 4));
temp = swap32(temp);
*((guint32*) ptr + 4) = temp;
}
theTime = *((glong*) ptr);
ptr += 8;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"Tx Time: %ld", theTime);
offset += 8;
//Block ID
blockId = *((guint32*) ptr);
if (swap) {
blockId = swap32(blockId);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Block ID #: %d", blockId);
offset += 4;
//Is Repair
repairStatus = *((guint8*) ptr);
if (repairStatus == 0) {
repairStatusStr = "Not Repair";
} else if (repairStatus == 1) {
repairStatusStr = "Repair";
}
ptr += 1;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"%s", repairStatusStr);
offset += 1;
}
//Need sizes for each variable
//Chat
if (code == 2014)
{
//guint16 id;
//char * user;
//glong txtime;
//glong rxtime;
//guint16 messageid;
//glong session;
}
//Wave Relay
if (code == 2013) {
guint8 status;
guint32 mac;
guint8 numofrec;
//guint32 nodeinfo;
guint32 macaddr;
guint32 snr;
char * statusStr = "";
int i;
//printf("%s \n", "This is the Wave Relay Ext");
//status
status = * ((guint8*) ptr);
if (status == 0) {
statusStr = "Good";
} else if (status == 1) {
statusStr = "Stale / Not Read";
}
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"%s", statusStr);
ptr += 1;
offset += 1;
//MAC
mac = * ((guint32*) (ptr - 1));
mac >>= 8;
ptr += 3;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 3, 0,
"MAC : %d", mac);
offset += 3;
//Number of records
numofrec = * ((guint8*) ptr);
ptr += 1;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"Number of Records : %d", numofrec);
offset += 1;
//OLSR Node Information
for (i = 0; i < numofrec; i++) {
//MAC address
macaddr = * ((guint32*) ptr);
macaddr = macaddr & 0xffffff;
ptr += 3;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 3, 0,
"MAC Address: %d", macaddr);
offset += 3;
//SNR
snr = * ((guint32*) ptr);
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"SNR : %d", snr);
offset += 4;
}
}
//Alares Control Ext:
if (code == 1025) {
glong key;
guint32 id;
//guint32 healFac;
gdouble healFac;
guint8 noem;
guint8 noe;
guint32 src;
guint32 message;
guint32 start;
guint32 end;
int index1, index2;
//printf("%s \n", "This is the Alares Control Ext");
//Alares Session Key
if (swap) {
// 64-bit swap, done as 2 32-bit swaps in the
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
*((guint32*) ptr) = temp;
temp = *((guint32*) (ptr + 4));
temp = swap32(temp);
*((guint32*) ptr + 4) = temp;
}
key = *((glong*) ptr);
ptr += 8;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"Alares Session Key: %ld", key);
offset += 8;
//Unique ID for Source
id = *((guint32*) ptr);
if (swap) {
id = swap32(id);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Unique ID for source: %d", id);
offset += 4;
//Healing Factor
if (swap) {
guint32 temp = *((guint32*) ptr);
temp = swap32(temp);
*((guint32*) ptr) = temp;
temp = *((guint32*) (ptr + 4));
temp = swap32(temp);
*((guint32*) ptr + 4) = temp;
}
healFac = *((gdouble*) ptr);
ptr += 8;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 8, 0,
"Healing Factor: %e", healFac);
offset += 8;
//Number of Erasures in Message
noem = *((guint8*) ptr);
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"Number of Erasures in Message: %d", noem);
ptr += 1;
offset += 1;
for (index1 = 0; index1 < noem; index1++) {
//Missing Data
//Source
src = *((guint32*) ptr);
if (swap) {
src = swap32(src);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Source of Missing Data: %d", src);
offset += 4;
//Message
//guint32 stuff;
message = *((guint32*) ptr);
printf("%s \n", "This is the Missing Data Message");
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, numBytes, 0,
"Missing Data Message:");
offset += numBytes;
//message = *((guint32*) ptr);
//if (swap) {
// message = swap32(message);
//}
//ptr += 4;
//proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
// "Missing Data Message: %d", message);
//offset += 4;
//offset += numBytes;
//Number of Erasures
noe = *((guint8*) ptr);
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 1, 0,
"Number of Erasures: %d", noe);
ptr += 1;
offset += 1;
for (index2 = 0; index2 < noe; index2++) {
//Erasures
//Starting Block
start = *((guint32*) ptr);
if (swap) {
start = swap32(start);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Starting Block: %d", start);
offset += 4;
//Ending Block
end = *((guint32*) ptr);
if (swap) {
end = swap32(end);
}
ptr += 4;
proto_tree_add_uint_format(helen_sub_tree, hf_helen_length, tvb, offset, 4, 0,
"Ending Block: %d", end);
offset += 4;
} // end of for j
} /* end of for i */
}
packet_header += numBytes + 4;
}
}
offset += 4;
offset += 1;
}
}
- Follow-Ups:
- Re: [Wireshark-dev] question regarding my wireshark dissector code.
- From: Townsend, Matthew
- Re: [Wireshark-dev] question regarding my wireshark dissector code.
- From: wsgd
- Re: [Wireshark-dev] question regarding my wireshark dissector code.
- Prev by Date: Re: [Wireshark-dev] WireShark on MAC OS X Leopard 10.5.7
- Next by Date: [Wireshark-dev] buildbot failure in Wireshark (development) on Windows-XP-Win64
- Previous by thread: Re: [Wireshark-dev] VB: [Wireshark-commits] rev 28920: /trunk/ /trunk/gtk/: hostlist_table.c /trunk/: Makefile.am Makefile.common Makefile.nmake config.h.win32 configure.in mkstemp.c mkstemp.h tempfile.c tempfile.h
- Next by thread: Re: [Wireshark-dev] question regarding my wireshark dissector code.
- Index(es):