1 |
/* |
2 |
* Cisco C7200 Simulation Platform. |
3 |
* Copyright (c) 2005,2006 Christophe Fillot. All rights reserved. |
4 |
* |
5 |
* Extract IOS configuration from a NVRAM file (standalone tool) |
6 |
*/ |
7 |
|
8 |
#include <stdio.h> |
9 |
#include <stdlib.h> |
10 |
#include <string.h> |
11 |
#include <time.h> |
12 |
#include <errno.h> |
13 |
|
14 |
#include "mips64.h" |
15 |
#include "dynamips.h" |
16 |
#include "memory.h" |
17 |
#include "device.h" |
18 |
#include "dev_c7200.h" |
19 |
#include "dev_c3600.h" |
20 |
|
21 |
#define PLATFORM_C7200 0x37323030 |
22 |
#define PLATFORM_C3600 0x33363030 |
23 |
|
24 |
/* Export configuration from 7200 NVRAM */ |
25 |
int dev_nvram_7200_export_config(FILE *nvram_fd,FILE *cfg_fd) |
26 |
{ |
27 |
m_uint32_t tag,start,end,len,clen,nvlen; |
28 |
char buffer[512]; |
29 |
int res = -1; |
30 |
|
31 |
fseek(nvram_fd,C7200_NVRAM_ROM_RES_SIZE+6,SEEK_SET); |
32 |
fread(&tag,sizeof(tag),1,nvram_fd); |
33 |
if (ntohl(tag) != 0xF0A5ABCD) { |
34 |
fprintf(stderr,"NVRAM: Unable to find IOS tag (tag=0x%8.8x)!\n", |
35 |
ntohl(tag)); |
36 |
goto done; |
37 |
} |
38 |
|
39 |
fseek(nvram_fd,0x06,SEEK_CUR); |
40 |
fread(&start,sizeof(start),1,nvram_fd); |
41 |
fread(&end,sizeof(end),1,nvram_fd); |
42 |
fread(&nvlen,sizeof(nvlen),1,nvram_fd); |
43 |
start = htonl(start) + 1; |
44 |
end = htonl(end); |
45 |
nvlen = htonl(nvlen); |
46 |
|
47 |
if ((start <= C7200_NVRAM_ADDR) || (end <= C7200_NVRAM_ADDR) || |
48 |
(end <= start)) |
49 |
{ |
50 |
fprintf(stderr,"NVRAM: invalid configuration markers " |
51 |
"(start=0x%x,end=0x%x).\n",start,end); |
52 |
goto done; |
53 |
} |
54 |
|
55 |
clen = len = end - start; |
56 |
if ((clen + 1) != nvlen) { |
57 |
fprintf(stderr,"NVRAM: invalid configuration size (0x%x)\n",nvlen); |
58 |
goto done; |
59 |
} |
60 |
|
61 |
start -= C7200_NVRAM_ADDR; |
62 |
fseek(nvram_fd,start,SEEK_SET); |
63 |
|
64 |
while(len > 0) { |
65 |
if (len > sizeof(buffer)) |
66 |
clen = sizeof(buffer); |
67 |
else |
68 |
clen = len; |
69 |
|
70 |
fread(buffer,clen,1,nvram_fd); |
71 |
fwrite(buffer,clen,1,cfg_fd); |
72 |
len -= clen; |
73 |
} |
74 |
|
75 |
res = 0; |
76 |
done: |
77 |
return res; |
78 |
} |
79 |
|
80 |
/* Export configuration from 3600 NVRAM */ |
81 |
int dev_nvram_3600_export_config(FILE *nvram_fd,FILE *cfg_fd) |
82 |
{ |
83 |
m_uint32_t tag,start,end,len,clen,nvlen; |
84 |
char buffer[512]; |
85 |
int res = -1; |
86 |
|
87 |
fseek(nvram_fd,C3600_NVRAM_ROM_RES_SIZE+6,SEEK_SET); |
88 |
fread(&tag,sizeof(tag),1,nvram_fd); |
89 |
if (ntohl(tag) != 0xF0A5ABCD) { |
90 |
fprintf(stderr,"NVRAM: Unable to find IOS tag (tag=0x%8.8x)!\n", |
91 |
ntohl(tag)); |
92 |
goto done; |
93 |
} |
94 |
|
95 |
fseek(nvram_fd,0x06,SEEK_CUR); |
96 |
fread(&start,sizeof(start),1,nvram_fd); |
97 |
fread(&end,sizeof(end),1,nvram_fd); |
98 |
fread(&nvlen,sizeof(nvlen),1,nvram_fd); |
99 |
start = htonl(start) + 1 + C3600_NVRAM_ADDR + C3600_NVRAM_ROM_RES_SIZE + 8; |
100 |
end = htonl(end) + C3600_NVRAM_ADDR + C3600_NVRAM_ROM_RES_SIZE + 8; |
101 |
nvlen = htonl(nvlen); |
102 |
|
103 |
if ((start <= C3600_NVRAM_ADDR) || (end <= C3600_NVRAM_ADDR) || |
104 |
(end <= start)) |
105 |
{ |
106 |
fprintf(stderr,"NVRAM: invalid configuration markers " |
107 |
"(start=0x%x,end=0x%x).\n",start,end); |
108 |
goto done; |
109 |
} |
110 |
|
111 |
clen = len = end - start; |
112 |
if ((clen + 1) != nvlen) { |
113 |
fprintf(stderr,"NVRAM: invalid configuration size (0x%x)\n",nvlen); |
114 |
goto done; |
115 |
} |
116 |
|
117 |
start -= C3600_NVRAM_ADDR; |
118 |
fseek(nvram_fd,start,SEEK_SET); |
119 |
|
120 |
while(len > 0) { |
121 |
if (len > sizeof(buffer)) |
122 |
clen = sizeof(buffer); |
123 |
else |
124 |
clen = len; |
125 |
|
126 |
fread(buffer,clen,1,nvram_fd); |
127 |
fwrite(buffer,clen,1,cfg_fd); |
128 |
len -= clen; |
129 |
} |
130 |
|
131 |
res = 0; |
132 |
done: |
133 |
return res; |
134 |
} |
135 |
|
136 |
/* Export configuration from NVRAM */ |
137 |
int dev_nvram_export_config(char *nvram_filename,char *cfg_filename) |
138 |
{ |
139 |
m_uint32_t platform; |
140 |
FILE *nvram_fd,*cfg_fd; |
141 |
char platform_string[5]; |
142 |
int res = -1; |
143 |
|
144 |
if (!(nvram_fd = fopen(nvram_filename,"r"))) { |
145 |
fprintf(stderr,"Unable to open NVRAM file '%s'!\n",nvram_filename); |
146 |
return(-1); |
147 |
} |
148 |
|
149 |
if (!(cfg_fd = fopen(cfg_filename,"w"))) { |
150 |
fprintf(stderr,"Unable to create config file '%s'!\n",cfg_filename); |
151 |
return(-1); |
152 |
} |
153 |
|
154 |
fseek(nvram_fd,0x200,SEEK_SET); |
155 |
fread(&platform,sizeof(platform),1,nvram_fd); |
156 |
|
157 |
switch(ntohl(platform)) { |
158 |
case PLATFORM_C7200: |
159 |
res = dev_nvram_7200_export_config(nvram_fd,cfg_fd); |
160 |
break; |
161 |
case PLATFORM_C3600: |
162 |
res = dev_nvram_3600_export_config(nvram_fd,cfg_fd); |
163 |
break; |
164 |
default: |
165 |
memcpy(platform_string,&platform,4); |
166 |
platform_string[4] = '\0'; |
167 |
fprintf(stderr,"NVRAM: unknown platform %s (platform=0x%x)!\n", |
168 |
platform_string,ntohl(platform)); |
169 |
} |
170 |
|
171 |
fclose(nvram_fd); |
172 |
fclose(cfg_fd); |
173 |
return(res); |
174 |
} |
175 |
|
176 |
int main(int argc,char *argv[]) |
177 |
{ |
178 |
printf("Cisco 7200/3600 NVRAM configuration export.\n"); |
179 |
printf("Copyright (c) 2006 Christophe Fillot.\n\n"); |
180 |
|
181 |
if (argc != 3) { |
182 |
fprintf(stderr,"Usage: %s nvram_file config_file\n",argv[0]); |
183 |
exit(EXIT_FAILURE); |
184 |
} |
185 |
|
186 |
if (!dev_nvram_export_config(argv[1],argv[2])) |
187 |
printf("Configuration written to %s\n",argv[2]); |
188 |
|
189 |
return(0); |
190 |
} |