/* 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. */ #include #include #include #include #include #include #include "xprintf.h" #define MAX_SPACES 120 const char *spaces=" "" "" "" " " "" "" "" " " "" "" "" "; const char *indent(int n) { return &spaces[MAX_SPACES-n]; } int senderSet=0; unsigned char senderAddress[32]; static void _dump(XPRINTF xpf, const unsigned char *data, size_t len, size_t ofs, const char *prefix); #ifdef STANDALONE 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"); return 0; case 0xFE: xprintf(xpf,""); return 0; case 0xFD: xprintf(xpf,""); return 0; case 0xFC: xprintf(xpf,""); return 0; default: if (len>32){ xprintf(xpf,"",len); return -1; } int i; for (i=0;i 1) return 0; xprintf(xpf,"%sPacket version %d (0x%02x)\n", indent(4),version,version); unsigned int encapsulation = packet[(*ofs)++]; xprintf(xpf,"%sEncapsulation (0x%02x);", indent(4),encapsulation); switch (encapsulation){ case 1: xprintf(xpf, " OVERLAY\n"); break; case 2: xprintf(xpf, " SINGLE\n"); break; default: xprintf(xpf, " UNKNOWN\n"); // TODO dump remainder? return -1; } xprintf(xpf, "%sSender; ", indent(4)); int ret=serval_packetvisualise_renderaddress(xpf,packet,ofs,0); xprintf(xpf, "\n"); if (ret) return ret; unsigned int packet_flags = packet[(*ofs)++]; xprintf(xpf, "%sFlags (0x%02x);", indent(4), packet_flags); if (packet_flags & 1) xprintf(xpf, " UNICAST"); if (packet_flags & 2) xprintf(xpf, " HAS_INTERFACE"); if (packet_flags & 4) xprintf(xpf, " HAS_SEQUENCE"); xprintf(xpf, "\n"); if (packet_flags & 2) xprintf(xpf, "%sSender Interface; 0x%02x\n", indent(4), packet[(*ofs)++]); if (packet_flags & 4) xprintf(xpf, "%sSequence; 0x%02x\n", indent(4), packet[(*ofs)++]); while((*ofs)> 5) & 3); } int o_type=0; if (payload_flags & 128){ o_type = packet[(*ofs)++]; xprintf(xpf, "%sOverlay Type (0x%02x); %s\n", indent(6), o_type, overlay_type(o_type)); } if (version >=1){ xprintf(xpf, "%sMDP Sequence; 0x%02x\n", indent(6), packet[(*ofs)++]); } int payload_len = 0; if (encapsulation==1){ payload_len=packet[(*ofs)++]<<8; payload_len|=packet[(*ofs)++]; xprintf(xpf, "%sPayload length; 0x%04x\n", indent(6), payload_len); if (payload_len > len - *ofs) return -1; }else{ payload_len = len - *ofs; } const unsigned char *payload_start = &packet[*ofs]; (*ofs)+=payload_len; if (payload_flags & 16){ xprintf(xpf, "%sPayload unreadable due to encryption\n", indent(8)); continue; } if (payload_flags & 32){ payload_len -= 64; } if (!(payload_flags & 128)){ size_t payload_offset=0; uint32_t dest_port_raw = get_packed_uint32(payload_start, &payload_offset); int same = dest_port_raw&1; uint32_t dest_port = dest_port_raw >> 1; xprintf(xpf, "%sDestination Port (0x%04x); %d %s\n", indent(8), dest_port_raw, dest_port, port_name(dest_port)); if (same){ xprintf(xpf, "%sSource Port; SAME\n", indent(8)); }else{ uint32_t src_port = get_packed_uint32(payload_start, &payload_offset); xprintf(xpf, "%sSource Port; %d %s\n", indent(8), src_port, port_name(src_port)); } payload_start += payload_offset; payload_len -= payload_offset; } xprintf(xpf, "%sPayload body;\n", indent(8)); _dump(xpf, payload_start, payload_len, 0, indent(10)); if (payload_flags & 32){ xprintf(xpf, "%sSignature;\n", indent(8)); _dump(xpf, payload_start+payload_len, 64, 0, indent(10)); } } return 1; } int serval_packetvisualise_xpf(XPRINTF xpf, const char *message, const unsigned char *packet, size_t len) { if (message) xprintf(xpf, "%s: ",message); xprintf(xpf,"Packet body of %d (0x%x) bytes:\n",(int)len,(int)len); _dump(xpf, packet, len, 0, " "); size_t ofs=0; xprintf(xpf," Packet Structure:\n"); if (isOverlayPacket(xpf,packet,&ofs,len)) { } if (ofs= ofs && i + j < len) xprintf(xpf," %02x", data[i+j]); else xprintf(xpf, " "); xprintf(xpf, " "); for (j = 0; j < 16 && i + j < len; ++j) xputc(i + j < ofs ? ' ' : data[i+j] >= ' ' && data[i+j] < 0x7c ? data[i+j] : '.', xpf); xputc('\n', xpf); } } int serval_packetvisualise(const char *message, const unsigned char *packet, size_t len) { return serval_packetvisualise_xpf(XPRINTF_STDIO(stdout),message, packet, len); }