2012-08-01 08:24:02 +00:00
/*
Serval Mesh
Copyright ( C ) 2010 - 2012 Paul Gardner - Stephen
Copyright ( C ) 2010 - 2012 Serval Project Pty Limited
Copyright ( C ) 2012 Serval Project Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
2012-08-03 03:43:47 +00:00
# include <stdarg.h>
2012-01-10 03:35:26 +00:00
# include <stdlib.h>
# include <string.h>
2012-08-03 07:14:05 +00:00
# include "xprintf.h"
2012-01-10 03:35:26 +00:00
# define MAX_SPACES 120
2012-08-03 03:43:47 +00:00
const char * spaces = " " " " " " " "
2012-01-10 03:35:26 +00:00
" " " " " " " "
" " " " " " " " ;
2012-08-03 03:43:47 +00:00
const char * indent ( int n )
2012-01-10 03:35:26 +00:00
{
return & spaces [ MAX_SPACES - n ] ;
}
int senderSet = 0 ;
unsigned char senderAddress [ 32 ] ;
2012-08-03 07:14:05 +00:00
static void _dump ( XPRINTF xpf , const unsigned char * data , size_t len , size_t ofs , const char * fmt , . . . ) ;
2012-01-10 03:35:26 +00:00
2012-07-16 06:58:07 +00:00
# ifdef STANDALONE
2012-08-03 07:14:05 +00:00
2012-07-16 06:58:07 +00:00
int main ( int argc , char * * argv )
{
int i , n ;
int len ;
unsigned char buff [ 8192 ] ;
for ( n = 0 ; n < 1024 ; n + + )
{
int i ;
len = random ( ) % 8192 ;
for ( i = 0 ; i < len ; i + + ) buff [ i ] = random ( ) & 0xff ;
2012-08-03 07:14:05 +00:00
serval_packetvisualise ( XPRINTF_STDIO ( stdout ) , " Fuzz Test " , buff , len ) ;
2012-07-16 06:58:07 +00:00
}
return 0 ;
}
# endif
2012-08-03 07:14:05 +00:00
int serval_packetvisualise_renderaddress ( XPRINTF xpf , const unsigned char * packet , size_t * ofs , int senderP )
2012-01-10 03:35:26 +00:00
{
2012-01-10 06:51:26 +00:00
2012-01-10 03:35:26 +00:00
switch ( packet [ * ofs ] ) {
case 0x00 : /* ourself */
if ( senderSet ) {
int i ;
2012-08-03 07:14:05 +00:00
for ( i = 0 ; i < senderSet ; i + + ) xprintf ( xpf , " %02X " , senderAddress [ i ] ) ;
if ( senderSet < 32 ) xprintf ( xpf , " * " ) ;
xprintf ( xpf , " <same as sender's address> " ) ;
2012-01-10 03:35:26 +00:00
} else {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <WARNING: self-reference to sender's address> " ) ;
2012-01-10 03:35:26 +00:00
}
( * ofs ) + + ;
break ;
case 0x01 : /* by index */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <address associated with index #%02x by sender> " ,
2012-01-10 03:35:26 +00:00
packet [ ( * ofs ) + 1 ] ) ;
( * ofs ) + = 2 ;
break ;
case 0x03 : /* previously used address */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <same as previous address> " ) ;
2012-01-10 03:35:26 +00:00
( * 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 ) + + ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %02X%02X%02X* <24 bit prefix " ,
2012-01-10 03:35:26 +00:00
packet [ ( * ofs ) ] , packet [ ( * ofs ) + 1 ] , packet [ ( * ofs ) + 2 ] ) ;
if ( senderP ) bcopy ( & packet [ * ofs ] , senderAddress , 3 ) ; senderSet = 3 ;
2012-08-03 07:14:05 +00:00
if ( skip ) xprintf ( xpf , " assigned index 0x%02x " , packet [ ( * ofs ) + 3 ] ) ;
xprintf ( xpf , " > " ) ;
2012-01-10 03:35:26 +00:00
( * 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 ) + + ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %02X%02X%02X%02X%02X%02X%02X* <56 bit prefix " ,
2012-01-10 03:35:26 +00:00
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 ;
2012-08-03 07:14:05 +00:00
if ( skip ) xprintf ( xpf , " assigned index 0x%02x " , packet [ ( * ofs ) + 7 ] ) ;
xprintf ( xpf , " > " ) ;
2012-01-10 03:35:26 +00:00
( * ofs ) + = 7 + skip ;
}
break ;
case 0x07 : /* prefix 11 bytes */
( * ofs ) + + ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X* <88 bit prefix> " ,
2012-01-10 03:35:26 +00:00
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 */
2012-01-10 11:26:07 +00:00
{
int i ;
( * ofs ) + + ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <broadcast BPI= " ) ;
for ( i = 0 ; i < 8 ; i + + ) xprintf ( xpf , " %02X " , packet [ ( * ofs ) + i ] ) ;
2012-01-10 11:26:07 +00:00
( * ofs ) + = 8 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " > " ) ; break ;
2012-01-10 11:26:07 +00:00
}
2012-01-10 03:35:26 +00:00
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 */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <illegal address token 0x%02x> " , packet [ ( * ofs ) ] ) ;
2012-01-10 03:35:26 +00:00
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 ;
2012-08-03 07:14:05 +00:00
for ( i = 0 ; i < 32 ; i + + ) xprintf ( xpf , " %02x " , packet [ ( * ofs ) + i ] ) ;
2012-01-10 03:35:26 +00:00
if ( senderP ) bcopy ( & packet [ * ofs ] , senderAddress , 32 ) ; senderSet = 32 ;
}
if ( skip ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <literal 256 bit address, assigned index 0x " ) ;
2012-01-10 03:35:26 +00:00
int i ;
2012-08-03 07:14:05 +00:00
for ( i = 0 ; i < skip ; i + + ) xprintf ( xpf , " %02x " , packet [ ( * ofs ) + skip ] ) ;
xprintf ( xpf , " > " ) ;
2012-01-10 03:35:26 +00:00
} else
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " <literal 256 bit address> " ) ;
2012-01-10 03:35:26 +00:00
( * ofs ) + = 32 + skip ;
}
}
return 0 ;
}
2012-08-03 07:14:05 +00:00
int isOverlayPacket ( XPRINTF xpf , const unsigned char * packet , size_t * ofs , size_t len )
2012-01-10 03:35:26 +00:00
{
if ( packet [ ( * ofs ) ] ! = 0x4f ) return 0 ;
if ( packet [ ( * ofs ) + 1 ] ! = 0x10 ) return 0 ;
int version = ( packet [ ( * ofs ) + 2 ] < < 8 ) + packet [ ( * ofs ) + 3 ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sServal Overlay Mesh Packet version %d (0x%04x) \n " ,
2012-01-10 03:35:26 +00:00
indent ( 4 ) , version , version ) ;
if ( version > 0x001 ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %s WARNING: Packet version is newer than I know about. \n " , indent ( 4 ) ) ;
2012-01-10 03:35:26 +00:00
}
( * 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 ) + + ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sOverlay Frame at offset 0x%x \n %stype identifier = 0x%x, modifier bits = 0x%x. \n " ,
2012-01-10 03:35:26 +00:00
indent ( 6 ) , frame_ofs , indent ( 8 ) , frame_type , frame_flags ) ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sTime-to-live = %d (0x%02x) \n %sframe payload bytes = %d (0x%x). \n " ,
2012-01-10 03:35:26 +00:00
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 . */
2012-08-01 08:24:02 +00:00
const unsigned char * frame = & packet [ * ofs ] ;
2012-01-10 03:35:26 +00:00
int frame_len = rfs ;
next_frame_ofs = ( * ofs ) + rfs ;
int cantDecodeFrame = 0 ;
int cantDecodeRecipient = 0 ;
2012-04-14 15:39:25 +00:00
int showSignature = 0 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sframe is " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
switch ( frame_flags & 0x3 ) {
2012-08-03 07:14:05 +00:00
case 0 : xprintf ( xpf , " not compressed " ) ; break ;
case 1 : xprintf ( xpf , " gzip-compressed " ) ; break ;
case 2 : xprintf ( xpf , " bzip2-compressed " ) ; break ;
case 3 : xprintf ( xpf , " marked as compressed using illegal code 0x3 " ) ;
2012-01-10 03:35:26 +00:00
cantDecodeFrame = 1 ;
break ;
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n %sframe is " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
switch ( frame_flags & 0xc ) {
2012-08-03 07:14:05 +00:00
case 0 : xprintf ( xpf , " not encrypted " ) ; break ;
case 4 : xprintf ( xpf , " encrypted using recipients public key (SID) " ) ;
2012-01-10 03:35:26 +00:00
cantDecodeFrame = 1 ; break ;
2012-08-03 07:14:05 +00:00
case 8 : xprintf ( xpf , " signed using senders public signing key (SAS) " ) ;
2012-04-14 15:39:25 +00:00
/* This doesn't stop us displaying the frame, as the body is still en claire.
It does mean that we should present the signature block , and not
show the signature as part of the packet body . */
cantDecodeFrame = 0 ;
showSignature = 1 ;
break ;
2012-08-03 07:14:05 +00:00
case 0xc : xprintf ( xpf , " authcrypted (encrypted and authenticated) using CryptoBox (SID) " ) ;
2012-01-10 03:35:26 +00:00
cantDecodeFrame = 1 ; break ;
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n " ) ;
2012-01-10 03:35:26 +00:00
if ( ! cantDecodeRecipient ) {
/* Show next-hop, sender and destination addresses */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sFrame next-hop address: " , indent ( 8 ) ) ;
if ( serval_packetvisualise_renderaddress ( xpf , packet , ofs , 0 ) )
{ xprintf ( xpf , " \n %sERROR: Cannot decode remainder of frame \n " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
dumpRaw = 1 ;
goto nextframe ;
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n %sFrame destination address: " , indent ( 8 ) ) ;
if ( serval_packetvisualise_renderaddress ( xpf , packet , ofs , 0 ) )
{ xprintf ( xpf , " \n %sERROR: Cannot decode remainder of frame \n " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
dumpRaw = 1 ;
goto nextframe ;
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n %sFrame source address: " , indent ( 8 ) ) ;
if ( serval_packetvisualise_renderaddress ( xpf , packet , ofs , 1 ) )
{ xprintf ( xpf , " \n %sERROR: Cannot decode remainder of frame \n " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
dumpRaw = 1 ;
goto nextframe ;
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n " ) ;
xprintf ( xpf , " %sFrame payload begins at offset 0x%x \n " , indent ( 8 ) , * ofs ) ;
2012-01-10 03:35:26 +00:00
frame = & packet [ * ofs ] ;
frame_len = next_frame_ofs - ( * ofs ) ;
2012-04-14 15:39:25 +00:00
if ( showSignature ) frame_len - = 64 ;
2012-01-10 03:35:26 +00:00
frame_ofs = 0 ;
} else {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sWARNING: Cannot decode frame addresses due to encryption. \n " ,
2012-01-10 03:35:26 +00:00
indent ( 8 ) ) ;
}
if ( cantDecodeFrame ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sWARNING: Cannot decode compressed and/or encrypted frame. \n " , indent ( 8 ) ) ;
_dump ( xpf , frame , frame_len , 0 , " %s " , indent ( 10 ) ) ;
2012-01-10 03:35:26 +00:00
}
else {
/* Decrypt and/or decompress frame */
switch ( frame_type ) {
case 0x10 : /* self-announce */
{
unsigned long long time ;
int i ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sSelf-announcement \n " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
time = 0 ; for ( i = 0 ; i < 4 ; i + + ) time = ( time < < 8 ) | frame [ frame_ofs + + ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sStart time: %10lldms (0x%08llx) \n " , indent ( 10 ) , time , time ) ;
2012-01-10 03:35:26 +00:00
time = 0 ; for ( i = 0 ; i < 4 ; i + + ) time = ( time < < 8 ) | frame [ frame_ofs + + ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sEnd time: %10lldms (0x%08llx) \n " , indent ( 10 ) , time , time ) ;
xprintf ( xpf , " %sSender's Interface number: %d \n " , indent ( 10 ) , frame [ frame_ofs + + ] ) ;
2012-01-10 03:35:26 +00:00
}
break ;
case 0x20 : /* self-announce ack */
{
unsigned long long time ;
int i ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sACK of self-announce \n " , indent ( 8 ) ) ;
2012-01-10 03:35:26 +00:00
time = 0 ; for ( i = 0 ; i < 4 ; i + + ) time = ( time < < 8 ) | frame [ frame_ofs + + ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sStart time: %10lldms (0x%08llx) \n " , indent ( 10 ) , time , time ) ;
2012-04-29 02:26:47 +00:00
time = 0 ; for ( i = 0 ; i < 4 ; i + + ) time = ( time < < 8 ) | frame [ frame_ofs + + ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sEnd time: %10lldms (0x%08llx) \n " , indent ( 10 ) , time , time ) ;
2012-04-14 00:20:10 +00:00
int iface = frame [ frame_ofs + + ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sSender Interface : %d \n " , indent ( 10 ) , iface ) ;
2012-01-10 03:35:26 +00:00
}
break ;
2012-01-10 04:27:32 +00:00
case 0x50 : /* rhizome advertisement */
{
2012-01-11 03:57:40 +00:00
int i , j , k ;
int rhizome_ad_frame_type = frame [ 0 ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sRhizome bundle advertisement frame, version %d \n " , indent ( 8 ) , rhizome_ad_frame_type ) ;
2012-07-02 06:37:35 +00:00
unsigned short int http_port = 0 ;
2012-01-11 03:57:40 +00:00
i = 1 ;
2012-06-25 08:33:00 +00:00
switch ( rhizome_ad_frame_type ) {
2012-07-02 06:37:35 +00:00
case 3 :
case 4 :
2012-06-25 08:33:00 +00:00
http_port = ( frame [ i ] < < 8 ) + frame [ i + 1 ] ;
i + = 2 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sHTTP port = %d \n " , indent ( 8 ) , http_port ) ;
2012-07-02 06:37:35 +00:00
break ;
}
switch ( rhizome_ad_frame_type ) {
case 2 :
case 4 :
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sBundle BAR(s) (i=%d, frame_len=%d): \n " , indent ( 8 ) , i , frame_len ) ;
2012-07-02 06:37:35 +00:00
break ;
2012-06-25 08:33:00 +00:00
case 1 :
2012-07-02 06:37:35 +00:00
case 3 :
2012-06-25 08:33:00 +00:00
/* Frame contains whole manifest(s) */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sBundle Manifest(s) (i=%d, frame_len=%d): \n " , indent ( 8 ) , i , frame_len ) ;
2012-06-25 08:33:00 +00:00
while ( i < frame_len ) {
2012-01-11 03:57:40 +00:00
/* Check for end of manifests */
2012-07-02 06:37:35 +00:00
if ( frame [ i ] = = 0xff ) { i + = 1 ; break ; }
/* Check remaining bytes */
int manifest_len = ( frame [ i ] < < 8 ) + frame [ i + 1 ] ;
i + = 2 ;
if ( i > frame_len ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sERROR: Unexpected end of Frame -- skipping rest of frame. \n " , indent ( 10 ) ) ;
2012-07-02 06:37:35 +00:00
break ;
}
2012-02-15 13:08:23 +00:00
if ( manifest_len > ( frame_len - i ) ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sERROR: Manifest extends for 0x%x bytes, but frame contains only 0x%x more bytes -- skipping rest of frame. \n " , indent ( 10 ) , manifest_len , frame_len - i ) ;
_dump ( xpf , frame , frame_len , 0 , " %s " , indent ( 12 ) ) ;
2012-02-15 13:08:23 +00:00
i = frame_len ;
break ;
}
2012-01-11 03:57:40 +00:00
/* find manifest self-signature block */
for ( j = 0 ; j < manifest_len ; j + + ) if ( frame [ i + j ] = = 0 ) { j + + ; break ; }
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %smanifest id @0x%x-0x%x/0x%x (len=0x%x) (from first signature block) = " ,
2012-02-15 13:08:23 +00:00
indent ( 10 ) , i , i + manifest_len - 1 , frame_len , manifest_len ) ;
2012-08-03 07:14:05 +00:00
for ( k = 0 ; k < 32 ; k + + ) xprintf ( xpf , " %02X " , frame [ i + j + k + 1 + 64 ] ) ;
xprintf ( xpf , " \n " ) ;
2012-01-11 03:57:40 +00:00
/* Print manifest text body */
int column = 0 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sManifest variables: \n " , indent ( 12 ) ) ;
2012-01-11 03:57:40 +00:00
for ( k = 0 ; k < ( j - 1 ) ; k + + ) {
2012-08-03 07:14:05 +00:00
if ( ! column ) { xprintf ( xpf , " %s " , indent ( 14 ) ) ; column = 14 ; }
2012-01-11 03:57:40 +00:00
switch ( frame [ i + k ] ) {
case ' \r ' : /* ignore CR */
case ' \n ' : /* LF */
column = 0 ;
/* fall through */
default :
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %c " , frame [ i + k ] ) ;
2012-01-11 03:57:40 +00:00
}
}
/* Print manifest signature blocks */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sManifest signature blocks \n " , indent ( 12 ) ) ;
2012-01-11 03:57:40 +00:00
for ( ; j < manifest_len ; )
{
int sigLen = frame [ i + j ] ;
switch ( sigLen ) {
case 0x61 : /* cryptosign signature */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sNaCl CryptoSign Generated Signature \n " , indent ( 14 ) ) ;
xprintf ( xpf , " %sPublic key of signatory = " , indent ( 16 ) ) ;
for ( k = 0 ; k < 32 ; k + + ) xprintf ( xpf , " %02X " , frame [ i + j + 1 + 64 + k ] ) ;
xprintf ( xpf , " \n " ) ;
xprintf ( xpf , " %sSignature data: " , indent ( 16 ) ) ;
2012-01-11 03:57:40 +00:00
for ( k = 0 ; k < 64 ; k + + )
{
2012-08-03 07:14:05 +00:00
if ( ! ( k & 0xf ) ) xprintf ( xpf , " \n %s " , indent ( 18 - 1 ) ) ;
xprintf ( xpf , " %02X " , frame [ i + j + 1 + k ] ) ;
2012-01-11 03:57:40 +00:00
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n " ) ;
2012-01-11 03:57:40 +00:00
break ;
case 0 :
sigLen = 1 ;
default :
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sUnknown Signature Type 0x%02x \n " , indent ( 14 ) , frame [ i + j ] ) ;
xprintf ( xpf , " %sSignature data: " , indent ( 16 ) ) ;
2012-01-11 03:57:40 +00:00
for ( k = 0 ; k < ( sigLen - 1 ) ; k + + )
{
2012-08-03 07:14:05 +00:00
if ( ! ( k & 0xf ) ) xprintf ( xpf , " \n %s " , indent ( 18 - 1 ) ) ;
xprintf ( xpf , " %02X " , frame [ i + j + 1 + k ] ) ;
2012-01-11 03:57:40 +00:00
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " \n " ) ;
2012-01-11 03:57:40 +00:00
break ;
}
j + = sigLen ;
}
i + = manifest_len ;
}
2012-06-25 08:33:00 +00:00
break ;
default :
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sWARNING: Version is newer than I understand. \n " , indent ( 10 ) ) ;
2012-06-25 08:33:00 +00:00
break ;
2012-01-11 03:57:40 +00:00
}
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sBundle Advertisement Records (BARs): \n " , indent ( 8 ) ) ;
2012-01-11 03:57:40 +00:00
for ( ; i < ( frame_len - 31 ) ; i + = 32 ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %smanifest id = %02X%02X%02X%02X%02X%02X%02X%02X* \n " ,
2012-01-10 04:27:32 +00:00
indent ( 10 ) , frame [ i ] , frame [ i + 1 ] , frame [ i + 2 ] , frame [ i + 3 ] ,
frame [ i + 4 ] , frame [ i + 5 ] , frame [ i + 6 ] , frame [ i + 7 ] ) ;
unsigned long long manifest_version = 0 ;
for ( j = 0 ; j < 7 ; j + + ) manifest_version = ( manifest_version < < 8 ) | frame [ i + 8 + j ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %smanifest revision = %lld (0x%llx) \n " ,
2012-01-10 04:27:32 +00:00
indent ( 12 ) , manifest_version , manifest_version ) ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %smanifest TTL = %d (0x%x) \n " ,
2012-01-10 04:27:32 +00:00
indent ( 12 ) , frame [ i + 16 ] , frame [ i + 16 ] ) ;
unsigned long long file_size = 0 ;
for ( j = 0 ; j < 6 ; j + + ) file_size = ( file_size < < 8 ) + frame [ i + 18 + j ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sassociated file size = %lld (0x%llx) bytes \n " ,
2012-01-10 04:27:32 +00:00
indent ( 12 ) , file_size , file_size ) ;
double lat0 = ( ( frame [ i + 24 ] < < 8 ) + frame [ i + 25 ] ) * 180 / 65535 - 90 ;
double long0 = ( ( frame [ i + 26 ] < < 8 ) + frame [ i + 27 ] ) * 360 / 65535 - 180 ;
double lat1 = ( ( frame [ i + 28 ] < < 8 ) + frame [ i + 29 ] ) * 180 / 65535 - 90 ;
double long1 = ( ( frame [ i + 30 ] < < 8 ) + frame [ i + 31 ] ) * 360 / 65535 - 180 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sgeographic extent of relevance (lat,long) = (%.f,%.f) - (%.f,%.f) \n " ,
2012-01-10 04:27:32 +00:00
indent ( 12 ) , lat0 , long0 , lat1 , long1 ) ;
}
}
2012-04-13 17:48:44 +00:00
break ;
case 0x70 : /* node announce */
{
int i ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sNode reachability announcment(s): \n " , indent ( 8 ) ) ;
2012-04-13 17:48:44 +00:00
for ( i = 0 ; i < frame_len ; i + = 8 )
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %s %02X%02X%02X%02X%02X%02X* best link score = %d, via %d gateways \n " ,
2012-04-13 17:48:44 +00:00
indent ( 10 ) ,
frame [ i + 0 ] , frame [ i + 1 ] , frame [ i + 2 ] , frame [ i + 3 ] ,
frame [ i + 4 ] , frame [ i + 5 ] ,
frame [ i + 6 ] , frame [ i + 7 ] ) ;
}
2012-01-10 04:27:32 +00:00
break ;
2012-01-10 03:35:26 +00:00
case 0x30 : /* MDP frame */
2012-04-13 19:27:37 +00:00
{
int version = ( frame [ 0 ] < < 8 ) | ( frame [ 1 ] ) ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sMDP frame (version=0x%04x): \n " , indent ( 8 ) , version ) ;
2012-04-13 23:49:11 +00:00
int src_port = ( frame [ 2 ] < < 24 ) | ( frame [ 3 ] < < 16 ) | ( frame [ 4 ] < < 8 ) | frame [ 5 ] ;
int dst_port = ( frame [ 6 ] < < 24 ) | ( frame [ 7 ] < < 16 ) | ( frame [ 8 ] < < 8 ) | frame [ 9 ] ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %s source port =%-6d (0x%08x) \n " ,
2012-04-13 19:27:37 +00:00
indent ( 10 ) , src_port , src_port ) ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %s destination port =%-6d (0x%08x) \n " ,
2012-04-13 19:27:37 +00:00
indent ( 10 ) , dst_port , dst_port ) ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sMDP Payload: \n " , indent ( 10 ) ) ;
_dump ( xpf , frame + 10 , frame_len - 10 , 0 , " %sframe+ " , indent ( 12 ) ) ;
2012-04-13 19:27:37 +00:00
}
break ;
2012-01-10 03:35:26 +00:00
case 0x40 : /* voice frame */
case 0x60 : /* please explain (request for expansion of an abbreviated address) */
default :
2012-01-10 04:27:32 +00:00
{
/* Reserved values */
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sWARNING: Packet contains reserved/unknown frame type 0x%02x \n " , indent ( 8 ) , frame_type ) ;
_dump ( xpf , frame , frame_len , 0 , " %sframe+ " , indent ( 10 ) ) ;
2012-01-10 04:27:32 +00:00
}
2012-01-10 03:35:26 +00:00
break ;
}
2012-04-14 15:39:25 +00:00
if ( showSignature ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sWARNING: Signature is for display purposes, and has not been verified \n " , indent ( 8 ) ) ;
xprintf ( xpf , " %sFrame signature block (SAS signed): \n " , indent ( 8 ) ) ;
_dump ( xpf , frame + frame_len , len < 64 ? len : 64 , 0 , " %s " , indent ( 10 ) ) ;
2012-04-14 15:39:25 +00:00
}
2012-01-10 03:35:26 +00:00
}
nextframe :
if ( next_frame_ofs < 0 ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %sERROR: Cannot continue decoding payload due to previous error(s) \n " , indent ( 6 ) ) ;
2012-01-10 03:35:26 +00:00
return 1 ;
}
2012-08-03 03:43:47 +00:00
if ( dumpRaw )
2012-08-03 07:14:05 +00:00
_dump ( xpf , packet , next_frame_ofs , * ofs , " %s " , indent ( 10 ) ) ;
2012-01-10 03:35:26 +00:00
( * ofs ) = next_frame_ofs ;
continue ;
}
return 1 ;
}
2012-08-03 07:14:05 +00:00
int isDNAPacket ( XPRINTF xpf , const unsigned char * packet , size_t * ofs , size_t len )
2012-01-10 03:35:26 +00:00
{
return 0 ;
}
2012-08-03 07:14:05 +00:00
int serval_packetvisualise ( XPRINTF xpf , const char * message , const unsigned char * packet , size_t len )
2012-01-10 03:35:26 +00:00
{
2012-08-03 03:43:47 +00:00
if ( message )
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %s: " , message ) ;
xprintf ( xpf , " Packet body of %d (0x%x) bytes: \n " , len , len ) ;
_dump ( xpf , packet , len , 0 , " " ) ;
2012-08-01 08:24:02 +00:00
size_t ofs = 0 ;
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " Packet Structure: \n " ) ;
if ( isOverlayPacket ( xpf , packet , & ofs , len ) )
2012-08-01 08:24:02 +00:00
;
2012-08-03 07:14:05 +00:00
else if ( isDNAPacket ( xpf , packet , & ofs , len ) )
2012-08-01 08:24:02 +00:00
;
2012-01-10 03:35:26 +00:00
else {
/* Unknown packet type. */
}
if ( ofs < len ) {
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " WARNING: The last %d (0x%x) bytes of the packet were not parsed. \n " , len - ofs , len - ofs ) ;
_dump ( xpf , packet , len , ofs , " " ) ;
2012-01-10 03:35:26 +00:00
}
return 0 ;
}
2012-08-03 03:43:47 +00:00
2012-08-03 07:14:05 +00:00
static void _dump ( XPRINTF xpf , const unsigned char * data , size_t len , size_t ofs , const char * fmt , . . . )
2012-08-03 03:43:47 +00:00
{
va_list ap ;
va_start ( ap , fmt ) ;
int i , j ;
for ( i = ( ofs / 16 ) * 16 ; i < len ; i + = 16 ) {
2012-08-03 07:14:05 +00:00
vxprintf ( xpf , fmt , ap ) ;
xprintf ( xpf , " %04x: " , i ) ;
2012-08-03 03:43:47 +00:00
for ( j = 0 ; j < 16 ; + + j )
if ( i + j > = ofs & & i + j < len )
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " %02x " , data [ i + j ] ) ;
2012-08-03 03:43:47 +00:00
else
2012-08-03 07:14:05 +00:00
xprintf ( xpf , " " ) ;
xprintf ( xpf , " " ) ;
2012-08-03 03:43:47 +00:00
for ( j = 0 ; j < 16 & & i + j < len ; + + j )
2012-08-03 07:14:05 +00:00
xputc ( i + j < ofs ? ' ' : data [ i + j ] > = ' ' & & data [ i + j ] < 0x7c ? data [ i + j ] : ' . ' , xpf ) ;
xputc ( ' \n ' , xpf ) ;
2012-08-03 03:43:47 +00:00
}
va_end ( ap ) ;
}