/[dynamips]/upstream/dynamips-0.2.7-RC2/cisco_eeprom.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC2/cisco_eeprom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 16457 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2006 Christophe Fillot. All rights reserved.
4 *
5 * Cisco EEPROM manipulation functions.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <sys/socket.h>
14
15 #include "utils.h"
16 #include "cisco_eeprom.h"
17
18 /* ====================================================================== */
19 /* NM-1E: 1 Ethernet Port Network Module EEPROM */
20 /* ====================================================================== */
21 static m_uint16_t eeprom_nm_1e_data[] = {
22 0x0143, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
23 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
24 };
25
26 /* ====================================================================== */
27 /* NM-4E: 4 Ethernet Port Network Module EEPROM */
28 /* ====================================================================== */
29 static m_uint16_t eeprom_nm_4e_data[] = {
30 0x0142, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
31 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
32 };
33
34 /* ====================================================================== */
35 /* NM-1FE-TX: 1 FastEthernet Port Network Module EEPROM */
36 /* ====================================================================== */
37 static m_uint16_t eeprom_nm_1fe_tx_data[] = {
38 0x0144, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
39 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
40 };
41
42 /* ====================================================================== */
43 /* NM-16ESW: 16 FastEthernet Port Switch Network Module EEPROM */
44 /* ====================================================================== */
45 static m_uint16_t eeprom_nm_16esw_data[] = {
46 0x04FF, 0x4002, 0xA941, 0x0100, 0xC046, 0x0320, 0x003B, 0x3401,
47 0x4245, 0x3080, 0x0000, 0x0000, 0x0203, 0xC18B, 0x3030, 0x3030,
48 0x3030, 0x3030, 0x3030, 0x3003, 0x0081, 0x0000, 0x0000, 0x0400,
49 0xCF06, 0x0013, 0x1A1D, 0x0BD1, 0x4300, 0x11FF, 0xFFFF, 0xFFFF,
50 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
51 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
52 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
53 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
54 };
55
56 /* ====================================================================== */
57 /* NM-4T: 4 Serial Network Module EEPROM */
58 /* ====================================================================== */
59 static m_uint16_t eeprom_nm_4t_data[] = {
60 0x0154, 0x0101, 0x009D, 0x2D64, 0x5009, 0x0A02, 0x0000, 0x0000,
61 0x5800, 0x0000, 0x9811, 0x0300, 0x0005, 0xFFFF, 0xFFFF, 0xFFFF,
62 };
63
64 /* ====================================================================== */
65 /* NM-2E2W: 2 Ethernet ports with 2 WIC slots Module EEPROM */
66 /* ====================================================================== */
67 static m_uint16_t eeprom_nm_2e2w_data[] = {
68 0x011E, 0x0102, 0x009A, 0xEBB1, 0x5004, 0x9305, 0x0000, 0x0000,
69 0x5000, 0x0000, 0x9808, 0x1217, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
70 };
71
72 /* ====================================================================== */
73 /* NM-2W: 2 WIC slots Module EEPROM */
74 /* ====================================================================== */
75 static m_uint16_t eeprom_nm_2w_data[] = {
76 0x04FF, 0x4000, 0xD641, 0x0100, 0xC046, 0x0320, 0x0012, 0xBF01,
77 0x4247, 0x3080, 0x0000, 0x0000, 0x0205, 0xC18B, 0x4A41, 0x4430,
78 0x3730, 0x3330, 0x375A, 0x3203, 0x0081, 0x0000, 0x0000, 0x0400,
79 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
80 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
81 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
82 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
83 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
84 };
85
86 /* ====================================================================== */
87 /* NM-1A-OC3MM: 1 ATM OC3 port Module EEPROM */
88 /* ====================================================================== */
89 static m_uint16_t eeprom_nm_1a_oc3mm_data[] = {
90 0x019A, 0x0100, 0x015B, 0x41D9, 0x500E, 0x7402, 0x0000, 0x0000,
91 0x7800, 0x0000, 0x0011, 0x2117, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
92 };
93
94 /* ====================================================================== */
95 /* NM EEPROMs */
96 /* ====================================================================== */
97
98 static const struct cisco_eeprom eeprom_nm_array[] = {
99 { "NM-1E", eeprom_nm_1e_data, sizeof(eeprom_nm_1e_data)/2 },
100 { "NM-4E", eeprom_nm_4e_data, sizeof(eeprom_nm_4e_data)/2 },
101 { "NM-1FE-TX", eeprom_nm_1fe_tx_data, sizeof(eeprom_nm_1fe_tx_data)/2 },
102 { "NM-16ESW", eeprom_nm_16esw_data, sizeof(eeprom_nm_16esw_data)/2 },
103 { "NM-4T", eeprom_nm_4t_data, sizeof(eeprom_nm_4t_data)/2 },
104 { "NM-2E2W", eeprom_nm_2e2w_data, sizeof(eeprom_nm_2e2w_data)/2 },
105 { "NM-2W", eeprom_nm_2w_data, sizeof(eeprom_nm_2w_data)/2 },
106 { "NM-1A-OC3MM", eeprom_nm_1a_oc3mm_data,
107 sizeof(eeprom_nm_1a_oc3mm_data)/2 },
108 { NULL, NULL, 0 },
109 };
110
111 /* Find a NM EEPROM */
112 const struct cisco_eeprom *cisco_eeprom_find_nm(char *name)
113 {
114 return(cisco_eeprom_find(eeprom_nm_array,name));
115 }
116
117 /* ====================================================================== */
118 /* PA-FE-TX: 1 FastEthernet Port Adapter EEPROM */
119 /* ====================================================================== */
120 static m_uint16_t eeprom_pa_fe_tx_data[] = {
121 0x0111, 0x0102, 0xffff, 0xffff, 0x4906, 0x9804, 0x0000, 0x0000,
122 0x6000, 0x0000, 0x9812, 0x1700, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
123 };
124
125 /* ====================================================================== */
126 /* PA-2FE-TX: 2 FastEthernet Port Adapter EEPROM */
127 /* ====================================================================== */
128 static m_uint16_t eeprom_pa_2fe_tx_data[] = {
129 0x04FF, 0x4002, 0x2441, 0x0100, 0xC18B, 0x5858, 0x5830, 0x3030,
130 0x3030, 0x3030, 0x3082, 0x4915, 0x2C04, 0x4241, 0x3003, 0x0081,
131 0x0000, 0x0000, 0x0400, 0x8000, 0x0000, 0x00CB, 0x9450, 0x412D,
132 0x3246, 0x452D, 0x4658, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
133 0x20C0, 0x4603, 0x2000, 0x20A0, 0x04FF, 0xFFFF, 0xFFFF, 0xFFFF,
134 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
135 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
136 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
137 };
138
139 /* ====================================================================== */
140 /* PA-GE: 1 GigabitEthernet Port Adapter EEPROM */
141 /* ====================================================================== */
142 static m_uint16_t eeprom_pa_ge_data[] = {
143 0x0198, 0x0100, 0x0000, 0x0000, 0x000C, 0x4803, 0x0000, 0x0000,
144 0x5000, 0x0000, 0x9906, 0x0300, 0x0001, 0xFFFF, 0xFFFF, 0xFFFF,
145 };
146
147 /* ====================================================================== */
148 /* PA-4E: 4 Ethernet Port Adapter EEPROM */
149 /* ====================================================================== */
150 static m_uint16_t eeprom_pa_4e_data[] = {
151 0x0102, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
152 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
153 };
154
155 /* ====================================================================== */
156 /* PA-8E: 8 Ethernet Port Adapter EEPROM */
157 /* ====================================================================== */
158 static m_uint16_t eeprom_pa_8e_data[] = {
159 0x0101, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
160 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
161 };
162
163 /* ====================================================================== */
164 /* PA-4T+: 4 Serial Port Adapter EEPROM */
165 /* ====================================================================== */
166 static m_uint16_t eeprom_pa_4t_data[] = {
167 0x010C, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
168 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
169 };
170
171 /* ====================================================================== */
172 /* PA-8T: 8 Serial Port Adapter EEPROM */
173 /* ====================================================================== */
174 static m_uint16_t eeprom_pa_8t_data[] = {
175 0x010E, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
176 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
177 };
178
179 /* ====================================================================== */
180 /* PA-A1: 1 ATM Port Adapter EEPROM */
181 /* ====================================================================== */
182 static m_uint16_t eeprom_pa_a1_data[] = {
183 0x0117, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
184 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
185 };
186
187 /* ====================================================================== */
188 /* PA-POS-OC3: 1 POS Port Adapter EEPROM */
189 /* ====================================================================== */
190 static m_uint16_t eeprom_pa_pos_oc3_data[] = {
191 0x0196, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
192 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
193 };
194
195 /* ====================================================================== */
196 /* PA-4B: 4 BRI Port Adapter EEPROM */
197 /* ====================================================================== */
198 static m_uint16_t eeprom_pa_4b_data[] = {
199 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
200 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
201 };
202
203 /* ====================================================================== */
204 /* PA-MC-8TE1 */
205 /* ====================================================================== */
206 static m_uint16_t eeprom_pa_mc8te1_data[] = {
207 0x04FF, 0x4003, 0x4E41, 0x0200, 0xC18B, 0x4A41, 0x4530, 0x3834,
208 0x3159, 0x3251, 0x3082, 0x491D, 0x7D02, 0x4241, 0x3003, 0x0081,
209 0x0000, 0x0000, 0x0400, 0x8000, 0x0127, 0x9BCB, 0x9450, 0x412D,
210 0x4D43, 0x2D38, 0x5445, 0x312B, 0x2020, 0x2020, 0x2020, 0x2020,
211 0x20C0, 0x4603, 0x2000, 0x4BBB, 0x02FF, 0xFFFF, 0xFFFF, 0xFFFF,
212 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
213 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
214 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
215 };
216
217 /* ====================================================================== */
218 /* PA EEPROMs */
219 /* ====================================================================== */
220
221 static const struct cisco_eeprom eeprom_pa_array[] = {
222 { "PA-FE-TX", eeprom_pa_fe_tx_data, sizeof(eeprom_pa_fe_tx_data)/2 },
223 { "PA-2FE-TX", eeprom_pa_2fe_tx_data, sizeof(eeprom_pa_2fe_tx_data)/2 },
224 { "PA-GE", eeprom_pa_ge_data, sizeof(eeprom_pa_ge_data)/2 },
225 { "PA-4E", eeprom_pa_4e_data, sizeof(eeprom_pa_4e_data)/2 },
226 { "PA-8E", eeprom_pa_8e_data, sizeof(eeprom_pa_8e_data)/2 },
227 { "PA-4T+", eeprom_pa_4t_data, sizeof(eeprom_pa_4t_data)/2 },
228 { "PA-8T", eeprom_pa_8t_data, sizeof(eeprom_pa_8t_data)/2 },
229 { "PA-A1", eeprom_pa_a1_data, sizeof(eeprom_pa_a1_data)/2 },
230 { "PA-POS-OC3", eeprom_pa_pos_oc3_data, sizeof(eeprom_pa_pos_oc3_data)/2 },
231 { "PA-4B", eeprom_pa_4b_data, sizeof(eeprom_pa_4b_data)/2 },
232 { "PA-MC-8TE1", eeprom_pa_mc8te1_data, sizeof(eeprom_pa_mc8te1_data)/2 },
233 { NULL, NULL, 0 },
234 };
235
236 /* Find a PA EEPROM */
237 const struct cisco_eeprom *cisco_eeprom_find_pa(char *name)
238 {
239 return(cisco_eeprom_find(eeprom_pa_array,name));
240 }
241
242 /* ====================================================================== */
243 /* Utility functions */
244 /* ====================================================================== */
245
246 /* Find an EEPROM in the specified EEPROM array */
247 const struct cisco_eeprom *
248 cisco_eeprom_find(const struct cisco_eeprom *eeproms,char *name)
249 {
250 int i;
251
252 for(i=0;eeproms[i].name;i++)
253 if (!strcmp(eeproms[i].name,name))
254 return(&eeproms[i]);
255
256 return NULL;
257 }
258
259 /* Copy an EEPROM */
260 int cisco_eeprom_copy(struct cisco_eeprom *dst,const struct cisco_eeprom *src)
261 {
262 m_uint16_t *data;
263
264 if (!src || !src)
265 return(-1);
266
267 cisco_eeprom_free(dst);
268
269 if (!(data = malloc(src->len << 1)))
270 return(-1);
271
272 memcpy(data,src->data,src->len << 1);
273 dst->name = src->name;
274 dst->data = data;
275 dst->len = src->len;
276 return(0);
277 }
278
279 /* Free resources used by an EEPROM */
280 void cisco_eeprom_free(struct cisco_eeprom *eeprom)
281 {
282 if (eeprom && eeprom->data) {
283 free(eeprom->data);
284 eeprom->data = NULL;
285 eeprom->len = 0;
286 }
287 }
288
289 /* Return TRUE if the specified EEPROM contains usable data */
290 int cisco_eeprom_valid(struct cisco_eeprom *eeprom)
291 {
292 return((eeprom && eeprom->data) ? TRUE : FALSE);
293 }
294
295 /* Get a byte from an EEPROM */
296 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
297 size_t offset,m_uint8_t *val)
298 {
299 m_uint16_t tmp;
300
301 if (offset >= (eeprom->len << 1))
302 return(-1);
303
304 tmp = eeprom->data[offset >> 1];
305
306 if (!(offset & 1))
307 tmp >>= 8;
308
309 *val = tmp & 0xFF;
310 return(0);
311 }
312
313 /* Set a byte to an EEPROM */
314 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
315 size_t offset,m_uint8_t val)
316 {
317 m_uint16_t tmp;
318
319 if (offset >= (eeprom->len << 1))
320 return(-1);
321
322 tmp = eeprom->data[offset >> 1];
323
324 if (offset & 1)
325 tmp = (tmp & 0xFF00) | val;
326 else
327 tmp = (tmp & 0x00FF) | (val << 8);
328
329 eeprom->data[offset >> 1] = tmp;
330 return(0);
331 }
332
333 /* Get an EEPROM region */
334 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
335 m_uint8_t *data,size_t data_len)
336 {
337 size_t i;
338
339 for(i=0;i<data_len;i++) {
340 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
341 return(-1);
342 }
343
344 return(0);
345 }
346
347 /* Set an EEPROM region */
348 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
349 m_uint8_t *data,size_t data_len)
350 {
351 size_t i;
352
353 for(i=0;i<data_len;i++) {
354 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
355 return(-1);
356 }
357
358 return(0);
359 }
360
361 /* Get a field of a Cisco EEPROM v4 */
362 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
363 m_uint8_t *len,size_t *offset)
364 {
365 m_uint8_t tmp;
366
367 /* Read field type */
368 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
369 return(-1);
370
371 /* No more field */
372 if (*type == 0xFF)
373 return(0);
374
375 /* Get field length */
376 tmp = (*type >> 6) & 0x03;
377
378 if (tmp == 0x03) {
379 /* Variable len */
380 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
381 return(-1);
382
383 *len = tmp & 0x0F;
384 } else {
385 /* Fixed len */
386 *len = 1 << tmp;
387 }
388
389 return(1);
390 }
391
392 /* Dump a Cisco EEPROM with format version 4 */
393 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
394 {
395 m_uint8_t type,len,tmp;
396 size_t i,offset=2;
397
398 printf("Dumping EEPROM contents:\n");
399
400 do {
401 /* Read field */
402 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
403 break;
404
405 printf(" Field 0x%2.2x: ",type);
406
407 for(i=0;i<len;i++) {
408 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
409 break;
410
411 printf("%2.2x ",tmp);
412 }
413
414 printf("\n");
415
416 offset += len;
417 }while(offset < (eeprom->len << 1));
418 }
419
420 /* Returns the offset of the specified field */
421 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
422 m_uint8_t field_type,
423 size_t *field_offset)
424 {
425 m_uint8_t type,len;
426 size_t offset=2;
427
428 do {
429 /* Read field */
430 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
431 break;
432
433 if (type == field_type) {
434 *field_offset = offset;
435 return(0);
436 }
437
438 offset += len;
439 }while(offset < (eeprom->len << 1));
440
441 return(-1);
442 }

  ViewVC Help
Powered by ViewVC 1.1.26