| 1 | /* |
| 2 | Copyright (c) 2012, Broadcom Europe Ltd |
| 3 | All rights reserved. |
| 4 | |
| 5 | Redistribution and use in source and binary forms, with or without |
| 6 | modification, are permitted provided that the following conditions are met: |
| 7 | * Redistributions of source code must retain the above copyright |
| 8 | notice, this list of conditions and the following disclaimer. |
| 9 | * Redistributions in binary form must reproduce the above copyright |
| 10 | notice, this list of conditions and the following disclaimer in the |
| 11 | documentation and/or other materials provided with the distribution. |
| 12 | * Neither the name of the copyright holder nor the |
| 13 | names of its contributors may be used to endorse or promote products |
| 14 | derived from this software without specific prior written permission. |
| 15 | |
| 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
| 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | |
| 28 | #include <stdio.h> |
| 29 | #include <stdlib.h> |
| 30 | #include <stdint.h> |
| 31 | |
| 32 | #define PACKET_BUFFER_SIZE 32768 |
| 33 | |
| 34 | enum { |
| 35 | SUCCESS = 0, |
| 36 | SHOWED_USAGE, |
| 37 | FAILED_TO_OPEN_PKTFILE, |
| 38 | FAILED_TO_OPEN_OUTPUT_FILE, |
| 39 | BYTE_ORDER_MARK_MISSING, |
| 40 | INVALID_BYTE_ORDER_MARK, |
| 41 | MEMORY_ALLOCATION_FAILURE, |
| 42 | PACKET_TOO_BIG, |
| 43 | }; |
| 44 | |
| 45 | /** Native byte order word */ |
| 46 | #define NATIVE_BYTE_ORDER 0x50415753U |
| 47 | /** Reverse of native byte order - need to swap bytes around */ |
| 48 | #define SWAP_BYTE_ORDER 0x53574150U |
| 49 | |
| 50 | static unsigned long reverse_byte_order( unsigned long value ) |
| 51 | { |
| 52 | /* Reverse the order of the bytes in the word */ |
| 53 | return ((value << 24) | ((value & 0xFF00) << 8) | ((value >> 8) & 0xFF00) | (value >> 24)); |
| 54 | } |
| 55 | |
| 56 | int main(int argc, char **argv) |
| 57 | { |
| 58 | int status = SUCCESS; |
| 59 | FILE *pktfile = NULL, *output_file = NULL; |
| 60 | uint32_t byte_order, packet_size, packet_read; |
| 61 | char *buffer = NULL; |
| 62 | |
| 63 | if (argc < 2) |
| 64 | { |
| 65 | printf("\ |
| 66 | Usage:\n\ |
| 67 | %s <pkt file> [<output file>]\n\ |
| 68 | <pkt file> is the file to read.\n\ |
| 69 | <output file>, if given, will receive the unpacketized data.\n" , argv[0]); |
| 70 | status = SHOWED_USAGE; |
| 71 | goto end_program; |
| 72 | } |
| 73 | |
| 74 | pktfile = fopen(argv[1], "rb" ); |
| 75 | if (!pktfile) |
| 76 | { |
| 77 | printf("Failed to open pkt file <%s> for reading.\n" , argv[1]); |
| 78 | status = FAILED_TO_OPEN_PKTFILE; |
| 79 | goto end_program; |
| 80 | } |
| 81 | |
| 82 | if (fread(&byte_order, 1, sizeof(byte_order), pktfile) != sizeof(byte_order)) |
| 83 | { |
| 84 | printf("Failed to read byte order header from pkt file.\n" ); |
| 85 | status = BYTE_ORDER_MARK_MISSING; |
| 86 | goto end_program; |
| 87 | } |
| 88 | |
| 89 | if (byte_order != NATIVE_BYTE_ORDER && byte_order != SWAP_BYTE_ORDER) |
| 90 | { |
| 91 | printf("Invalid byte order header: 0x%08x (%u)\n" , byte_order, byte_order); |
| 92 | status = INVALID_BYTE_ORDER_MARK; |
| 93 | goto end_program; |
| 94 | } |
| 95 | |
| 96 | buffer = (char *)malloc(PACKET_BUFFER_SIZE); |
| 97 | if (!buffer) |
| 98 | { |
| 99 | printf("Memory allocation failed\n" ); |
| 100 | status = MEMORY_ALLOCATION_FAILURE; |
| 101 | goto end_program; |
| 102 | } |
| 103 | |
| 104 | if (argc > 2) |
| 105 | { |
| 106 | output_file = fopen(argv[2], "wb" ); |
| 107 | if (!output_file) |
| 108 | { |
| 109 | printf("Failed to open <%s> for output.\n" , argv[2]); |
| 110 | status = FAILED_TO_OPEN_OUTPUT_FILE; |
| 111 | goto end_program; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | while (fread(&packet_size, 1, sizeof(packet_size), pktfile) == sizeof(packet_size)) |
| 116 | { |
| 117 | if (byte_order == SWAP_BYTE_ORDER) |
| 118 | packet_size = reverse_byte_order(packet_size); |
| 119 | |
| 120 | if (packet_size >= PACKET_BUFFER_SIZE) |
| 121 | { |
| 122 | printf("*** Packet size is bigger than buffer (%u > %u)\n" , packet_size, PACKET_BUFFER_SIZE - 1); |
| 123 | status = PACKET_TOO_BIG; |
| 124 | goto end_program; |
| 125 | } |
| 126 | |
| 127 | packet_read = fread(buffer, 1, packet_size, pktfile); |
| 128 | |
| 129 | if (output_file) |
| 130 | { |
| 131 | fwrite(buffer, 1, packet_size, output_file); |
| 132 | } else { |
| 133 | buffer[packet_size] = '\0'; |
| 134 | printf("%s" , buffer); |
| 135 | getchar(); |
| 136 | } |
| 137 | |
| 138 | if (packet_read != packet_size) |
| 139 | printf("*** Invalid packet size (expected %u, got %u)\n" , packet_size, packet_read); |
| 140 | } |
| 141 | |
| 142 | end_program: |
| 143 | if (pktfile) fclose(pktfile); |
| 144 | if (output_file) fclose(output_file); |
| 145 | if (buffer) free(buffer); |
| 146 | return -status; |
| 147 | } |
| 148 | |