OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #include <stdlib.h> |
2 | #include <sys/types.h> |
||
3 | #include <stdio.h> |
||
4 | #include <inttypes.h> |
||
5 | #include <string.h> |
||
6 | #include <getopt.h> |
||
7 | #include <unistd.h> |
||
8 | #include <sys/time.h> |
||
9 | #include <sys/stat.h> |
||
10 | #include "bcmalgo.h" |
||
11 | |||
12 | |||
13 | #define UTIL_VERSION "0.1" |
||
14 | #define ENDIAN_REVERSE_NEEDED |
||
15 | |||
16 | uint32_t reverse_endian32 ( uint32_t data ) |
||
17 | { |
||
18 | #ifdef ENDIAN_REVERSE_NEEDED |
||
19 | return 0 | ( data & 0x000000ff ) << 24 |
||
20 | | ( data & 0x0000ff00 ) << 8 |
||
21 | | ( data & 0x00ff0000 ) >> 8 |
||
22 | | ( data & 0xff000000 ) >> 24; |
||
23 | #else |
||
24 | return data; |
||
25 | #endif |
||
26 | } |
||
27 | |||
28 | uint16_t reverse_endian16 ( uint16_t data ) |
||
29 | { |
||
30 | #ifdef ENDIAN_REVERSE_NEEDED |
||
31 | return 0 | ( data & 0x00ff ) << 8 |
||
32 | | ( data & 0xff00 ) >> 8; |
||
33 | #else |
||
34 | return data; |
||
35 | #endif |
||
36 | } |
||
37 | |||
38 | |||
39 | |||
40 | uint32_t get_buffer_crc ( char* filebuffer,size_t size ) |
||
41 | { |
||
42 | |||
43 | long crc=0xffffffffL; |
||
44 | long crcxor = 0xffffffffL; |
||
45 | long num4 = 0xffffffffL; |
||
46 | long num5 = size; |
||
47 | long num6 = 0x4c11db7L; |
||
48 | long num7 = 0x80000000L; |
||
49 | int i; |
||
50 | long j; |
||
51 | for ( i = 0; i < ( num5 ); i++ ) |
||
52 | { |
||
53 | long num2 = filebuffer[i]; |
||
54 | for ( j = 0x80L; j != 0L; j = j >> 1 ) |
||
55 | { |
||
56 | long num3 = crc & num7; |
||
57 | crc = crc << 1; |
||
58 | if ( ( num2 & j ) != 0L ) |
||
59 | { |
||
60 | num3 ^= num7; |
||
61 | } |
||
62 | if ( num3 != 0L ) |
||
63 | { |
||
64 | crc ^= num6; |
||
65 | } |
||
66 | } |
||
67 | } |
||
68 | crc ^= crcxor; |
||
69 | crc &= num4; |
||
70 | |||
71 | uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 ); |
||
72 | uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 ); |
||
73 | uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 ); |
||
74 | uint8_t b4 = ( uint8_t ) ( crc & 0xffL ); |
||
75 | int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 ); |
||
76 | return reverse_endian32 ( crc_result ); |
||
77 | } |
||
78 | |||
79 | //Thnx to Vector for the algo. |
||
80 | uint32_t get_file_crc ( char* filename ) |
||
81 | { |
||
82 | struct stat buf; |
||
83 | stat ( filename,&buf ); |
||
84 | char* filebuffer = malloc ( buf.st_size+10 ); |
||
85 | FILE* fd = fopen ( filename,"r" ); |
||
86 | fread ( filebuffer, 1, buf.st_size,fd ); |
||
87 | fclose ( fd ); |
||
88 | uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size ); |
||
89 | free ( filebuffer ); |
||
90 | return crc; |
||
91 | } |
||
92 | |||
93 | |||
94 | |||
95 | uint16_t get_hcs ( ldr_header_t* hd ) |
||
96 | { |
||
97 | uint8_t* head = ( uint8_t* ) hd; |
||
98 | uint8_t hcs_minor; |
||
99 | uint8_t hcs_major; |
||
100 | uint16_t n = 0xffff; |
||
101 | uint16_t m = 0; |
||
102 | int state = 0; |
||
103 | int i,j; |
||
104 | for ( i = 0; i < 0x54; i++ ) |
||
105 | { |
||
106 | uint16_t m = head[i]; |
||
107 | m = m << 8; |
||
108 | for ( j = 0; j < 8; j++ ) |
||
109 | { |
||
110 | if ( ( ( n ^ m ) & 0x8000 ) == 0 ) |
||
111 | { |
||
112 | state = 0; |
||
113 | } |
||
114 | else |
||
115 | { |
||
116 | state = 1; |
||
117 | } |
||
118 | n = n << 1; |
||
119 | if ( state ) |
||
120 | { |
||
121 | n ^= 0x1021; |
||
122 | } |
||
123 | m = m << 1; |
||
124 | } |
||
125 | n &= 0xffff; |
||
126 | } |
||
127 | n ^= 0xffff; |
||
128 | hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 ); |
||
129 | hcs_minor = ( uint8_t ) ( n & 0xff ); |
||
130 | uint16_t hcs = hcs_major <<8 | hcs_minor; |
||
131 | return hcs; |
||
132 | } |
||
133 | |||
134 | ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ) |
||
135 | { |
||
136 | ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) ); |
||
137 | hd->magic=reverse_endian16 ( magic ); |
||
138 | hd->control=0; //FixMe: Make use of it once compression is around |
||
139 | hd->rev_min = reverse_endian16 ( rev_min ); |
||
140 | hd->rev_maj = reverse_endian16 ( rev_maj ); |
||
141 | hd->build_date = reverse_endian32 ( build_date ); |
||
142 | hd->filelen = reverse_endian32 ( filelen ); |
||
143 | hd->ldaddress = reverse_endian32 ( ldaddress ); |
||
144 | printf ( "Creating header for %s...\n", filename ); |
||
145 | if ( strlen ( filename ) >63 ) |
||
146 | { |
||
147 | printf ( "[!] Filename too long - stripping it to 63 bytes.\n" ); |
||
148 | strncpy ( ( char* ) &hd->filename, filename, 63 ); |
||
149 | hd->filename[63]=0x00; |
||
150 | } |
||
151 | else |
||
152 | { |
||
153 | strcpy ( ( char* ) &hd->filename, filename ); |
||
154 | } |
||
155 | hd->crc=reverse_endian32 ( crc_data ); |
||
156 | hd->hcs = reverse_endian16 ( get_hcs ( hd ) ); |
||
157 | return hd; |
||
158 | } |
||
159 | |||
160 | static char control_unc[] = "Uncompressed"; |
||
161 | static char control_lz[] = "LZRW1/KH"; |
||
162 | static char control_mlzo[] = "mini-LZO"; |
||
163 | static char control_nrv[] = "NRV2D99 [Bootloader?]"; |
||
164 | static char control_nstdlzma[] = "(non-standard) LZMA"; |
||
165 | static char control_unk[] = "Unknown"; |
||
166 | char* get_control_info ( uint16_t control ) |
||
167 | { |
||
168 | control = reverse_endian16 ( control ); |
||
169 | switch ( control ) |
||
170 | { |
||
171 | case 0: |
||
172 | return control_unc; |
||
173 | break; |
||
174 | case 1: |
||
175 | return control_lz; |
||
176 | break; |
||
177 | case 2: |
||
178 | return control_mlzo; |
||
179 | break; |
||
180 | case 3: |
||
181 | return control_unc; |
||
182 | break; |
||
183 | case 4: |
||
184 | return control_nrv; |
||
185 | break; |
||
186 | case 5: |
||
187 | return control_nstdlzma; |
||
188 | break; |
||
189 | case 6: |
||
190 | return control_unc; |
||
191 | break; |
||
192 | case 7: |
||
193 | return control_unc; |
||
194 | break; |
||
195 | default: |
||
196 | return control_unk; |
||
197 | break; |
||
198 | } |
||
199 | |||
200 | } |
||
201 | |||
202 | int dump_header ( ldr_header_t* hd ) |
||
203 | { |
||
204 | printf ( "=== Header Information ===\n" ); |
||
205 | printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) ); |
||
206 | printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) ); |
||
207 | printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) ); |
||
208 | printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) ); |
||
209 | printf ( "File name :\t%s\n", ( char* ) &hd->filename ); |
||
210 | printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) ); |
||
211 | printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe: |
||
212 | printf ( "HCS:\t\t0x%04X ",reverse_endian16 ( hd->hcs ) ); |
||
213 | uint16_t hcs = get_hcs ( hd ); |
||
214 | int ret=0; |
||
215 | if ( hcs ==reverse_endian16 ( hd->hcs ) ) |
||
216 | { |
||
217 | printf ( "(OK!)\n" ); |
||
218 | } |
||
219 | else |
||
220 | { |
||
221 | printf ( "(ERROR! expected 0x%04X)\n",hcs ); |
||
222 | ret=1; |
||
223 | } |
||
224 | //printf("HCS:\t0x%02X",reverse_endian32(hd->hcs)); |
||
225 | printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe: |
||
226 | printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what |
||
227 | printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) ); |
||
228 | printf ( "=== Binary Header Dump===\n" ); |
||
229 | int i,j; |
||
230 | uint8_t* head = ( uint8_t* ) hd; |
||
231 | for ( i=0;i<=sizeof ( ldr_header_t );i++ ) |
||
232 | { |
||
233 | if ( i % 8==0 ) |
||
234 | printf ( "\n" ); |
||
235 | printf ( "0x%02x ",head[i] ); |
||
236 | } |
||
237 | printf ( "\n\n== End Of Header dump ==\n" ); |
||
238 | return ret; |
||
239 | } |
||
240 | |||
241 | |||
242 | void print_copyright() |
||
243 | { |
||
244 | printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" ); |
||
245 | printf ( "Copyright (C) 2009 Andrew 'Necromant' Andrianov\n" |
||
246 | "This is free software, and you are welcome to redistribute it\n" |
||
247 | "under certain conditions. See COPYING for details\n" ); |
||
248 | } |