mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Added 2nd implementation of serval packet decoder for aiding debugging
of packet formation and decoding. Fixed time calculation bug (duplicate time functions based off different epochs). Various debugging fiddles and tweaks.
This commit is contained in:
parent
23ee957169
commit
9156a68c7f
6
mphlr.h
6
mphlr.h
@ -874,7 +874,9 @@ int rhizome_server_poll();
|
||||
#include "nacl.h"
|
||||
|
||||
|
||||
#define DEBUG_OVERLAYINTERFACES 4
|
||||
#define DEBUG_OVERLAYINTERFACES 2
|
||||
#define DEBUG_PACKETXFER 1
|
||||
#define DEBUG_VERBOSE 2
|
||||
#define DEBUG_VERBOSE 4
|
||||
#define DEBUG_VERBOSE_IO 8
|
||||
|
||||
int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int plen);
|
||||
|
@ -155,7 +155,6 @@ int overlayServerMode()
|
||||
}
|
||||
/* Check if we need to trigger any ticks on any interfaces */
|
||||
overlay_check_ticks();
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -294,6 +293,7 @@ int overlay_frame_process(int interface,overlay_frame *f)
|
||||
overlay_route_saw_selfannounce(interface,f,now);
|
||||
break;
|
||||
case OF_TYPE_SELFANNOUNCE_ACK:
|
||||
fprintf(stderr,"!!! selfannounce_ack\n");
|
||||
overlay_route_saw_selfannounce_ack(interface,f,now);
|
||||
break;
|
||||
case OF_TYPE_NODEANNOUNCE:
|
||||
|
@ -277,44 +277,60 @@ int overlay_rx_messages()
|
||||
|
||||
/* Grab packets from interfaces in round-robin fashion until all have been grabbed,
|
||||
or until we have spent too long (maybe 10ms?) */
|
||||
int now = overlay_gettime_ms();
|
||||
while(count>0)
|
||||
for(i=0;i<overlay_interface_count;i++)
|
||||
{
|
||||
struct sockaddr src_addr;
|
||||
unsigned int addrlen=sizeof(src_addr);
|
||||
unsigned char transaction_id[8];
|
||||
|
||||
overlay_last_interface_number=i;
|
||||
|
||||
if (overlay_interfaces[i].fileP) {
|
||||
/* Read from dummy interface file */
|
||||
long long length=lseek(overlay_interfaces[i].fd,0,SEEK_END);
|
||||
lseek(overlay_interfaces[i].fd,overlay_interfaces[i].offset,SEEK_SET);
|
||||
if (debug&DEBUG_OVERLAYINTERFACES) fprintf(stderr,"Reading from interface #%d log at offset %d, end of file at %lld.\n",i,
|
||||
overlay_interfaces[i].offset,length);
|
||||
if (read(overlay_interfaces[i].fd,&packet[0],2048)==2048)
|
||||
{
|
||||
overlay_interfaces[i].offset+=2048;
|
||||
plen=2048-128;
|
||||
bzero(&transaction_id[0],8);
|
||||
bzero(&src_addr,sizeof(src_addr));
|
||||
if ((packet[0]==0x01)&&!(packet[1]|packet[2]|packet[3])) {
|
||||
{ if (packetOk(i,&packet[128],plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed or unsupported packet from dummy interface (packetOK() failed)"); } }
|
||||
else WHY("Invalid packet version in dummy interface");
|
||||
{
|
||||
for(i=0;i<overlay_interface_count;i++)
|
||||
{
|
||||
struct sockaddr src_addr;
|
||||
unsigned int addrlen=sizeof(src_addr);
|
||||
unsigned char transaction_id[8];
|
||||
|
||||
overlay_last_interface_number=i;
|
||||
|
||||
if (overlay_interfaces[i].fileP) {
|
||||
/* Read from dummy interface file */
|
||||
long long length=lseek(overlay_interfaces[i].fd,0,SEEK_END);
|
||||
if (overlay_interfaces[i].offset<length)
|
||||
{
|
||||
lseek(overlay_interfaces[i].fd,overlay_interfaces[i].offset,SEEK_SET);
|
||||
if (debug&DEBUG_OVERLAYINTERFACES)
|
||||
fprintf(stderr,"Reading from interface #%d log at offset %d, end of file at %lld.\n",i,
|
||||
overlay_interfaces[i].offset,length);
|
||||
if (read(overlay_interfaces[i].fd,&packet[0],2048)==2048)
|
||||
{
|
||||
overlay_interfaces[i].offset+=2048;
|
||||
plen=2048-128;
|
||||
plen=packet[110]+(packet[111]<<8);
|
||||
if (plen>(2048-128)) plen=-1;
|
||||
if (debug) serval_packetvisualise(stderr,
|
||||
"Read from dummy interface",
|
||||
&packet[128],plen);
|
||||
bzero(&transaction_id[0],8);
|
||||
bzero(&src_addr,sizeof(src_addr));
|
||||
if ((plen>=0)&&(packet[0]==0x01)&&!(packet[1]|packet[2]|packet[3])) {
|
||||
{ if (packetOk(i,&packet[128],plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed or unsupported packet from dummy interface (packetOK() failed)"); } }
|
||||
else WHY("Invalid packet version in dummy interface");
|
||||
}
|
||||
else { c[i]=0; count--; }
|
||||
}
|
||||
} else {
|
||||
/* Read from UDP socket */
|
||||
plen=recvfrom(overlay_interfaces[i].fd,packet,sizeof(packet),MSG_DONTWAIT,
|
||||
&src_addr,&addrlen);
|
||||
if (plen<0) { c[i]=0; count--; } else {
|
||||
/* We have a frame from this interface */
|
||||
if (debug) serval_packetvisualise(stderr,"Read from real interface",
|
||||
packet,plen);
|
||||
if (debug&DEBUG_OVERLAYINTERFACES)fprintf(stderr,"Received %d bytes on interface #%d\n",plen,i);
|
||||
|
||||
if (packetOk(i,packet,plen,NULL,&src_addr,addrlen,1)) WHY("Malformed packet");
|
||||
}
|
||||
else { c[i]=0; count--; }
|
||||
} else {
|
||||
/* Read from UDP socket */
|
||||
plen=recvfrom(overlay_interfaces[i].fd,packet,sizeof(packet),MSG_DONTWAIT,
|
||||
&src_addr,&addrlen);
|
||||
if (plen<0) { c[i]=0; count--; } else {
|
||||
/* We have a frame from this interface */
|
||||
if (debug&DEBUG_OVERLAYINTERFACES)fprintf(stderr,"Received %d bytes on interface #%d\n",plen,i);
|
||||
|
||||
if (packetOk(i,packet,plen,NULL,&src_addr,addrlen,1)) WHY("Malformed packet");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Don't sit here forever, or else we will never send any packets */
|
||||
if (overlay_gettime_ms()>(now+10)) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -373,13 +389,18 @@ int overlay_broadcast_ensemble(int interface_number,
|
||||
/* bytes 94-97 = TX frequency in Hz, uncorrected for doppler (which must be done at the receiving end to take into account
|
||||
relative motion) */
|
||||
/* bytes 98-109 = coding method (use for doppler response etc) null terminated string */
|
||||
/* bytes 110-127 reserved for future use */
|
||||
/* bytes 110-111 = length of packet body in bytes */
|
||||
/* bytes 112-127 reserved for future use */
|
||||
|
||||
if (len>2048-128) {
|
||||
WHY("Truncating long packet to fit within 1920 byte limit for dummy interface");
|
||||
len=2048-128;
|
||||
}
|
||||
|
||||
/* Record length of packet */
|
||||
buf[110]=len&0xff;
|
||||
buf[111]=(len>>8)&0xff;
|
||||
|
||||
bzero(&buf[128+len],2048-(128+len));
|
||||
bcopy(bytes,&buf[128],len);
|
||||
if (write(overlay_interfaces[interface_number].fd,buf,2048)!=2048)
|
||||
@ -649,19 +670,6 @@ int overlay_tick_interface(int i, long long now)
|
||||
|
||||
}
|
||||
|
||||
long long overlay_time_in_ms()
|
||||
{
|
||||
long long now;
|
||||
struct timeval nowtv;
|
||||
if (gettimeofday(&nowtv,NULL))
|
||||
return WHY("gettimeofday() failed");
|
||||
|
||||
/* Get current time in milliseconds */
|
||||
now=nowtv.tv_sec*1000LL;
|
||||
now=now+nowtv.tv_usec/1000;
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
|
||||
int overlay_check_ticks()
|
||||
@ -672,7 +680,7 @@ int overlay_check_ticks()
|
||||
/* Check for changes to interfaces */
|
||||
overlay_interface_discover();
|
||||
|
||||
long long now=overlay_time_in_ms();
|
||||
long long now=overlay_gettime_ms();
|
||||
|
||||
/* Now check if the next tick time for the interfaces is no later than that time.
|
||||
If so, trigger a tick on the interface. */
|
||||
|
@ -208,6 +208,7 @@ int overlay_frame_resolve_addresses(int interface,overlay_frame *f)
|
||||
|
||||
int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
{
|
||||
|
||||
/* Pull the first record from the HLR database and turn it into a
|
||||
self-announcment. These are shorter than regular Subscriber Observation
|
||||
Notices (SON) because they are just single-hop announcments of presence.
|
||||
@ -291,7 +292,8 @@ int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
if (ob_append_int(b,overlay_sequence_number))
|
||||
return WHY("ob_append_int() could not add high sequence number to self-announcement");
|
||||
overlay_interfaces[interface].last_tick_ms=overlay_sequence_number;
|
||||
|
||||
fprintf(stderr,"last tick seq# = %lld\n",overlay_interfaces[interface].last_tick_ms);
|
||||
|
||||
/* A byte that indicates which interface we are sending over */
|
||||
if (ob_append_byte(b,interface))
|
||||
return WHY("ob_append_int() could not add interface number to self-announcement");
|
||||
|
@ -80,6 +80,7 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
if (p->nexthop_address_status!=OA_RESOLVED) {
|
||||
if (overlay_get_nexthop((unsigned char *)p->destination,p->nexthop,&nexthoplen,&p->nexthop_interface)) fail++;
|
||||
else p->nexthop_address_status=OA_RESOLVED;
|
||||
fprintf(stderr,"!!! Resolved nexthop\n");
|
||||
}
|
||||
|
||||
if (p->source[0]<0x10) {
|
||||
@ -183,7 +184,7 @@ int overlay_payload_enqueue(int q,overlay_frame *p)
|
||||
if (l) l->next=p;
|
||||
p->prev=l;
|
||||
p->next=NULL;
|
||||
p->enqueued_at=overlay_time_in_ms();
|
||||
p->enqueued_at=overlay_gettime_ms();
|
||||
|
||||
overlay_tx[q].last=p;
|
||||
if (!overlay_tx[q].first) overlay_tx[q].first=p;
|
||||
|
@ -475,6 +475,12 @@ int overlay_route_ack_selfannounce(overlay_frame *f,overlay_neighbour *n)
|
||||
OVERLAY_MESH_MANAGEMENT messages.
|
||||
|
||||
Also, we should check for older such frames on the queue and drop them.
|
||||
|
||||
There is one caveat to the above: until the first selfannounce gets returned,
|
||||
we don't have an open route. Thus we need to just make sure that the ack
|
||||
goes out broadcast if we don't know about a return path. Once the return path
|
||||
starts getting built, it should be fine.
|
||||
|
||||
*/
|
||||
|
||||
/* XXX Allocate overlay_frame structure and populate it */
|
||||
@ -486,17 +492,35 @@ int overlay_route_ack_selfannounce(overlay_frame *f,overlay_neighbour *n)
|
||||
out->modifiers=0;
|
||||
out->ttl=6; /* maximum time to live for an ack taking an indirect route back
|
||||
to the originator. If it were 1, then we would not be able to
|
||||
handle mono-directional links (which WiFi is notorious for). */
|
||||
handle mono-directional links (which WiFi is notorious for).
|
||||
XXX 6 is quite an arbitrary selection however. */
|
||||
|
||||
/* Set destination of ack to source of observed frame */
|
||||
if (overlay_frame_set_neighbour_as_destination(out,n)) {
|
||||
op_free(out);
|
||||
return WHY("overlay_frame_set_neighbour_as_source() failed");
|
||||
}
|
||||
|
||||
|
||||
/* set source to ourselves */
|
||||
overlay_frame_set_me_as_source(out);
|
||||
/* (next-hop will get set at TX time, so no need to set it here) */
|
||||
/* Next-hop will get set at TX time, so no need to set it here.
|
||||
However, if there is no known next-hop for this node (because the return path
|
||||
has not yet begun to be built), then we need to set the nexthop to broadcast. */
|
||||
out->nexthop_address_status=OA_UNINITIALISED;
|
||||
{ unsigned char nexthop[SID_SIZE]; int nexthoplen,interface;
|
||||
if (overlay_get_nexthop(out->destination,nexthop,&nexthoplen,&interface))
|
||||
{
|
||||
/* No path, so set nexthop to be broadcast, but don't broadcast it too far. */
|
||||
int i;
|
||||
for(i=0;i<SID_SIZE;i++) out->nexthop[i]=0xff;
|
||||
out->nexthop_address_status=OA_RESOLVED;
|
||||
out->ttl=2;
|
||||
WHY("Broadcasting ack to selfannounce");
|
||||
}
|
||||
else
|
||||
WHY("singlecasting ack to selfannounce via known route");
|
||||
}
|
||||
|
||||
/* Set the time in the ack. Use the last sequence number we have seen
|
||||
from this neighbour, as that may be helpful information for that neighbour
|
||||
@ -700,6 +724,7 @@ int overlay_route_saw_selfannounce(int interface,overlay_frame *f,long long now)
|
||||
s2=ntohl(*((int*)&f->payload->bytes[4]));
|
||||
sender_interface=f->payload->bytes[8];
|
||||
fprintf(stderr,"Received self-announcement for sequence range [%08x,%08x] from interface %d\n",s1,s2,sender_interface);
|
||||
dump("Payload",&f->payload->bytes[0],f->payload->length);
|
||||
|
||||
overlay_route_i_can_hear(f->source,sender_interface,s1,s2,interface,now);
|
||||
|
||||
|
@ -369,7 +369,7 @@ int rhizome_bundle_import(char *bundle,char *groups[], int ttl,
|
||||
rhizome_manifest_set(m,"filehash",hexhash);
|
||||
if (rhizome_manifest_get(m,"version",NULL)!=0)
|
||||
/* Version not set, so set one */
|
||||
rhizome_manifest_set_ll(m,"version",overlay_time_in_ms());
|
||||
rhizome_manifest_set_ll(m,"version",overlay_gettime_ms());
|
||||
rhizome_manifest_set_ll(m,"first_byte",0);
|
||||
rhizome_manifest_set_ll(m,"last_byte",rhizome_file_size(filename));
|
||||
}
|
||||
@ -853,7 +853,7 @@ int rhizome_store_bundle(rhizome_manifest *m,char *associated_filename)
|
||||
WHY("*** Writing into manifests table");
|
||||
snprintf(sqlcmd,1024,
|
||||
"INSERT INTO MANIFESTS(id,manifest,version,inserttime,bar) VALUES('%s',?,%lld,%lld,?);",
|
||||
manifestid,m->version,overlay_time_in_ms());
|
||||
manifestid,m->version,overlay_gettime_ms());
|
||||
|
||||
if (m->haveSecret) {
|
||||
if (rhizome_store_keypair_bytes(m->cryptoSignPublic,m->cryptoSignSecret))
|
||||
@ -1218,7 +1218,7 @@ int rhizome_manifest_finalise(rhizome_manifest *m,int signP)
|
||||
if (rhizome_manifest_get(m,"version",NULL))
|
||||
{
|
||||
/* No version set */
|
||||
m->version = overlay_time_in_ms();
|
||||
m->version = overlay_gettime_ms();
|
||||
rhizome_manifest_set_ll(m,"version",m->version);
|
||||
}
|
||||
else
|
||||
|
374
serval_packetvisualise.c
Normal file
374
serval_packetvisualise.c
Normal file
@ -0,0 +1,374 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_SPACES 120
|
||||
char *spaces=" "" "" "" "
|
||||
" "" "" "" "
|
||||
" "" "" "" ";
|
||||
char *indent(int n)
|
||||
{
|
||||
return &spaces[MAX_SPACES-n];
|
||||
}
|
||||
|
||||
int senderSet=0;
|
||||
unsigned char senderAddress[32];
|
||||
|
||||
int serval_packetvisualise_renderaddress(FILE *f,unsigned char *packet,int *ofs,int senderP)
|
||||
{
|
||||
switch(packet[*ofs]) {
|
||||
case 0x00: /* ourself */
|
||||
if (senderSet) {
|
||||
int i;
|
||||
for(i=0;i<senderSet;i++) fprintf(f,"%02X",senderAddress[i]);
|
||||
if (senderSet<32) fprintf(f,"*");
|
||||
fprintf(f," <same as sender's address>");
|
||||
} else {
|
||||
fprintf(f," <WARNING: self-reference to sender's address>");
|
||||
}
|
||||
(*ofs)++;
|
||||
break;
|
||||
case 0x01: /* by index */
|
||||
fprintf(f,"<address associated with index #%02x by sender>",
|
||||
packet[(*ofs)+1]);
|
||||
(*ofs)+=2;
|
||||
break;
|
||||
case 0x03: /* previously used address */
|
||||
fprintf(f,"<same as previous address>");
|
||||
(*ofs)++;
|
||||
break;
|
||||
case 0x09: /* prefix 3 bytes and assign index */
|
||||
case 0x05: /* prefix 3 bytes */
|
||||
{ int skip=0;
|
||||
if (packet[*ofs]&8) skip=1;
|
||||
(*ofs)++;
|
||||
fprintf(f,"%02X%02X%02X* <24 bit prefix",
|
||||
packet[(*ofs)],packet[(*ofs)+1],packet[(*ofs)+2]);
|
||||
if (senderP) bcopy(&packet[*ofs],senderAddress,3); senderSet=3;
|
||||
if (skip) fprintf(f," assigned index 0x%02x",packet[(*ofs)+3]);
|
||||
fprintf(f,">");
|
||||
(*ofs)+=3+skip;
|
||||
}
|
||||
break;
|
||||
case 0x0a: /* prefix 7 bytes and assign index */
|
||||
case 0x06: /* prefix 7 bytes */
|
||||
{ int skip=0;
|
||||
if (packet[*ofs]&8) skip=1;
|
||||
(*ofs)++;
|
||||
fprintf(f,"%02X%02X%02X%02X%02X%02X%02X* <56 bit prefix",
|
||||
packet[(*ofs)],packet[(*ofs)+1],packet[(*ofs)+2],packet[(*ofs)+3],
|
||||
packet[(*ofs)+4],packet[(*ofs)+5],packet[(*ofs)+6]);
|
||||
if (senderP) bcopy(&packet[*ofs],senderAddress,7); senderSet=7;
|
||||
if (skip) fprintf(f," assigned index 0x%02x",packet[(*ofs)+7]);
|
||||
fprintf(f,">");
|
||||
(*ofs)+=7+skip;
|
||||
}
|
||||
break;
|
||||
case 0x07: /* prefix 11 bytes */
|
||||
(*ofs)++;
|
||||
fprintf(f,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X* <88 bit prefix>",
|
||||
packet[(*ofs)],packet[(*ofs)+1],packet[(*ofs)+2],packet[(*ofs)+3],
|
||||
packet[(*ofs)+4],packet[(*ofs)+5],packet[(*ofs)+6],packet[(*ofs)+7],
|
||||
packet[(*ofs)+8],packet[(*ofs)+9],packet[(*ofs)+10]);
|
||||
if (senderP) bcopy(&packet[*ofs],senderAddress,11); senderSet=11;
|
||||
(*ofs)+=11;
|
||||
break;
|
||||
case 0x0f: /* broadcast */
|
||||
fprintf(f,"<broadcast>"); (*ofs)++; break;
|
||||
case 0x0b: /* prefix 11 bytes and assign index */
|
||||
case 0x0d: /* prefix 11 bytes and assign 2-byte index */
|
||||
|
||||
case 0x02: /* reserved */
|
||||
case 0x04: /* reserved */
|
||||
case 0x0c: /* reserved */
|
||||
fprintf(f,"<illegal address token 0x%02x>",packet[(*ofs)]);
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
case 0x0e: /* full address and assign 2-byte index */
|
||||
case 0x08: /* full address and assign index */
|
||||
{
|
||||
int skip=0;
|
||||
if (packet[*ofs]==0x08) { (*ofs)++; skip=1; }
|
||||
else if (packet[*ofs]==0x0e) { (*ofs)++; skip=2; }
|
||||
/* naturally presented 32 byte address */
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<32;i++) fprintf(f,"%02x",packet[(*ofs)+i]);
|
||||
if (senderP) bcopy(&packet[*ofs],senderAddress,32); senderSet=32;
|
||||
}
|
||||
if (skip) {
|
||||
fprintf(f," <literal 256 bit address, assigned index 0x");
|
||||
int i;
|
||||
for(i=0;i<skip;i++) fprintf(stderr,"%02x",packet[(*ofs)+skip]);
|
||||
fprintf(f,">");
|
||||
} else
|
||||
fprintf(f," <literal 256 bit address>");
|
||||
(*ofs)+=32+skip;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int isOverlayPacket(FILE *f,unsigned char *packet,int *ofs,int len)
|
||||
{
|
||||
if (packet[(*ofs)]!=0x4f) return 0;
|
||||
if (packet[(*ofs)+1]!=0x10) return 0;
|
||||
|
||||
int version = (packet[(*ofs)+2]<<8)+packet[(*ofs)+3];
|
||||
|
||||
fprintf(f,"%sServal Overlay Mesh Packet version %d (0x%04x)\n",
|
||||
indent(4),version,version);
|
||||
if (version>0x001) {
|
||||
fprintf(f,"%s WARNING: Packet version is newer than I know about.\n",indent(4));
|
||||
}
|
||||
(*ofs)+=4;
|
||||
|
||||
senderSet=0;
|
||||
while((*ofs)<len)
|
||||
{
|
||||
int dumpRaw=0;
|
||||
int next_frame_ofs=-1;
|
||||
int frame_ofs=*ofs;
|
||||
int frame_flags=0;
|
||||
int frame_type=packet[(*ofs)++];
|
||||
if ((frame_type&0xf0)==0xe0) {
|
||||
frame_type=frame_type<<8;
|
||||
frame_type|=packet[(*ofs)++];
|
||||
frame_type&=0xfff;
|
||||
} else if ((frame_type&0xf0)==0xf0) {
|
||||
frame_type=frame_type<<16;
|
||||
frame_type|=packet[(*ofs)++]<<8;
|
||||
frame_type|=packet[(*ofs)++];
|
||||
frame_type&=0xfffff;
|
||||
}
|
||||
|
||||
frame_flags=frame_type&0xf;
|
||||
frame_type&=0xfffffff0;
|
||||
|
||||
int ttl=packet[(*ofs)++];
|
||||
|
||||
int rfs=packet[*ofs];
|
||||
switch(rfs) {
|
||||
case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe:
|
||||
rfs=250+256*(rfs-0xfa)+packet[++(*ofs)];
|
||||
break;
|
||||
case 0xff: rfs=(packet[(*ofs)+1]<<8)+packet[(*ofs)+2]; (*ofs)+=2;
|
||||
default: /* Length is natural value of field, so nothing to do */
|
||||
break;
|
||||
}
|
||||
(*ofs)++;
|
||||
|
||||
fprintf(f,"%sOverlay Frame at offset 0x%x\n%stype identifier = 0x%x, modifier bits = 0x%x.\n",
|
||||
indent(6),frame_ofs,indent(8),frame_type,frame_flags);
|
||||
fprintf(f,"%sTime-to-live = %d (0x%02x)\n%sframe payload bytes = %d (0x%x).\n",
|
||||
indent(8),ttl,ttl,indent(8),rfs,rfs);
|
||||
|
||||
/* Assuming that there is no compression or crypto, we just use the plain body
|
||||
of the frame. */
|
||||
unsigned char *frame=&packet[*ofs];
|
||||
int frame_len=rfs;
|
||||
|
||||
next_frame_ofs=(*ofs)+rfs;
|
||||
|
||||
int cantDecodeFrame=0;
|
||||
int cantDecodeRecipient=0;
|
||||
fprintf(f,"%sframe is ",indent(8));
|
||||
switch(frame_flags&0x3) {
|
||||
case 0: fprintf(f,"not compressed"); break;
|
||||
case 1: fprintf(f,"gzip-compressed"); break;
|
||||
case 2: fprintf(f,"bzip2-compressed"); break;
|
||||
case 3: fprintf(f,"marked as compressed using illegal code 0x3");
|
||||
cantDecodeFrame=1;
|
||||
break;
|
||||
}
|
||||
fprintf(f,"\n%sframe is ",indent(8));
|
||||
switch(frame_flags&0xc) {
|
||||
case 0: fprintf(f,"not encrypted"); break;
|
||||
case 4: fprintf(f,"encrypted using recipients public key");
|
||||
cantDecodeFrame=1; break;
|
||||
case 8: fprintf(f,"encrypted using recipients public key, signed using senders private key");
|
||||
cantDecodeFrame=1; break;
|
||||
case 0xc: fprintf(f,"encrypted using recipients public key, signed using senders private key, and addresses are also encrypted");
|
||||
cantDecodeFrame=1; cantDecodeRecipient=1; break;
|
||||
}
|
||||
fprintf(f,"\n");
|
||||
|
||||
if (!cantDecodeRecipient) {
|
||||
/* Show next-hop, sender and destination addresses */
|
||||
fprintf(f,"%sFrame next-hop address: ",indent(8));
|
||||
if (serval_packetvisualise_renderaddress(f,packet,ofs,0))
|
||||
{ fprintf(f,"\n%sERROR: Cannot decode remainder of frame\n",indent(8));
|
||||
dumpRaw=1;
|
||||
goto nextframe;
|
||||
}
|
||||
fprintf(f,"\n%sFrame destination address: ",indent(8));
|
||||
if (serval_packetvisualise_renderaddress(f,packet,ofs,0))
|
||||
{ fprintf(f,"\n%sERROR: Cannot decode remainder of frame\n",indent(8));
|
||||
dumpRaw=1;
|
||||
goto nextframe;
|
||||
}
|
||||
fprintf(f,"\n%sFrame source address: ",indent(8));
|
||||
if (serval_packetvisualise_renderaddress(f,packet,ofs,1))
|
||||
{ fprintf(f,"\n%sERROR: Cannot decode remainder of frame\n",indent(8));
|
||||
dumpRaw=1;
|
||||
goto nextframe;
|
||||
}
|
||||
fprintf(f,"\n");
|
||||
fprintf(f,"%sFrame payload begins at offset 0x%x\n",indent(8),*ofs);
|
||||
frame=&packet[*ofs];
|
||||
frame_len=next_frame_ofs-(*ofs);
|
||||
frame_ofs=0;
|
||||
} else {
|
||||
fprintf(f,"%sWARNING: Cannot decode frame addresses due to encryption.\n",
|
||||
indent(8));
|
||||
}
|
||||
|
||||
if (cantDecodeFrame) {
|
||||
fprintf(f,"%sWARNING: Cannot decode compressed and/or encrypted frame.\n",indent(8));
|
||||
int i,j;
|
||||
for(i=0;i<frame_len;i+=16)
|
||||
{
|
||||
fprintf(f,"%s%04x :",indent(10),i);
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f," %02x",frame[i+j]);
|
||||
for(;j<16;j++) fprintf(f," ");
|
||||
fprintf(f," ");
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f,"%c",frame[i+j]>=' '
|
||||
&&frame[i+j]<0x7c?frame[i+j]:'.');
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Decrypt and/or decompress frame */
|
||||
|
||||
switch(frame_type) {
|
||||
case 0x10: /* self-announce */
|
||||
{
|
||||
unsigned long long time;
|
||||
int i;
|
||||
fprintf(f,"%sSelf-announcement\n",indent(8));
|
||||
time=0; for(i=0;i<4;i++) time=(time<<8)|frame[frame_ofs++];
|
||||
fprintf(f,"%sStart time: %10lldms (0x%08llx)\n",indent(10),time,time);
|
||||
time=0; for(i=0;i<4;i++) time=(time<<8)|frame[frame_ofs++];
|
||||
fprintf(f,"%sEnd time: %10lldms (0x%08llx)\n",indent(10),time,time);
|
||||
fprintf(f,"%sSender's Interface number: %d\n",indent(10),frame[frame_ofs++]);
|
||||
}
|
||||
break;
|
||||
case 0x20: /* self-announce ack */
|
||||
{
|
||||
unsigned long long time;
|
||||
int i;
|
||||
fprintf(f,"%sACK of self-announce\n",indent(8));
|
||||
time=0; for(i=0;i<4;i++) time=(time<<8)|frame[frame_ofs++];
|
||||
fprintf(f,"%sObservation time : %10lldsecs (0x%08llx)\n",indent(10),time,time);
|
||||
while(frame_ofs<frame_len) {
|
||||
int iface=frame[frame_ofs++];
|
||||
int score=frame[frame_ofs++];
|
||||
fprintf(f,"%sinterface #%d reachability score: %d (0x%02x)\n",
|
||||
indent(12),iface,score,score);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x30: /* MDP frame */
|
||||
case 0x40: /* voice frame */
|
||||
case 0x50: /* rhizome advertisement */
|
||||
case 0x60: /* please explain (request for expansion of an abbreviated address) */
|
||||
case 0x70: /* node announce */
|
||||
default:
|
||||
/* Reserved values */
|
||||
fprintf(f,"%sWARNING: Packet contains reserved/unknown frame type 0x%02x\n",
|
||||
indent(8),frame_type);
|
||||
int i,j;
|
||||
for(i=0;i<frame_len;i+=16)
|
||||
{
|
||||
fprintf(f,"%sframe+%04x :",indent(10),i);
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f," %02x",frame[i+j]);
|
||||
for(;j<16;j++) fprintf(f," ");
|
||||
fprintf(f," ");
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f,"%c",frame[i+j]>=' '
|
||||
&&frame[i+j]<0x7c?frame[i+j]:'.');
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextframe:
|
||||
if (next_frame_ofs<0) {
|
||||
fprintf(f,"%sERROR: Cannot continue decoding payload due to previous error(s)\n",indent(6));
|
||||
return 1;
|
||||
}
|
||||
if (dumpRaw) {
|
||||
int i,j;
|
||||
for(i=0;i<next_frame_ofs;i+=16)
|
||||
if (i+15>=(*ofs))
|
||||
{
|
||||
fprintf(f,"%s%04x :",indent(10),i);
|
||||
for(j=0;j<16&&(i+j)<next_frame_ofs;j++) if ((i+j)<(*ofs)) fprintf(f," "); else fprintf(f," %02x",packet[i+j]);
|
||||
for(;j<16;j++) fprintf(f," ");
|
||||
fprintf(f," ");
|
||||
for(j=0;j<16&&(i+j)<next_frame_ofs;j++) if ((i+j)<(*ofs)) fprintf(f," "); else fprintf(f,"%c",packet[i+j]>=' '
|
||||
&&packet[i+j]<0x7c?packet[i+j]:'.');
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
}
|
||||
(*ofs)=next_frame_ofs;
|
||||
continue;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int isDNAPacket(FILE *f,unsigned char *packet,int *ofs,int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int len)
|
||||
{
|
||||
if (message) fprintf(f,"%s:\n",message);
|
||||
|
||||
int i,j;
|
||||
fprintf(f," Packet body of %d (0x%x) bytes:\n",len,len);
|
||||
for(i=0;i<len;i+=16)
|
||||
{
|
||||
fprintf(f," %04x :",i);
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f," %02x",packet[i+j]);
|
||||
for(;j<16;j++) fprintf(f," ");
|
||||
fprintf(f," ");
|
||||
for(j=0;j<16&&(i+j)<len;j++) fprintf(f,"%c",packet[i+j]>=' '
|
||||
&&packet[i+j]<0x7c?packet[i+j]:'.');
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
|
||||
int ofs=0;
|
||||
fprintf(f," Packet Structure:\n");
|
||||
|
||||
if (isOverlayPacket(f,packet,&ofs,len))
|
||||
{ }
|
||||
else if (isDNAPacket(f,packet,&ofs,len))
|
||||
{ }
|
||||
else {
|
||||
/* Unknown packet type. */
|
||||
}
|
||||
|
||||
if (ofs<len) {
|
||||
fprintf(stderr," WARNING: The last %d (0x%x) bytes of the packet were not parsed.\n",len-ofs,len-ofs);
|
||||
for(i=0;i<len;i+=16)
|
||||
if (i+15>=ofs)
|
||||
{
|
||||
fprintf(f," %04x :",i);
|
||||
for(j=0;j<16&&(i+j)<len;j++) if ((i+j)<ofs) fprintf(f," "); else fprintf(f," %02x",packet[i+j]);
|
||||
for(;j<16;j++) fprintf(f," ");
|
||||
fprintf(f," ");
|
||||
for(j=0;j<16&&(i+j)<len;j++) if ((i+j)<ofs) fprintf(f," "); else fprintf(f,"%c",packet[i+j]>=' '
|
||||
&&packet[i+j]<0x7c?packet[i+j]:'.');
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user