/[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 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (12 years, 2 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/cisco_eeprom.c
File MIME type: text/plain
File size: 14876 byte(s)
dynamips-0.2.7-RC1

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 const 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 const 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 const 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 EEPROMs */
66 /* ====================================================================== */
67
68 static const struct cisco_eeprom eeprom_nm_array[] = {
69 { "NM-1E", (m_uint16_t *)eeprom_nm_1e_data, sizeof(eeprom_nm_1e_data)/2 },
70 { "NM-4E", (m_uint16_t *)eeprom_nm_4e_data, sizeof(eeprom_nm_4e_data)/2 },
71 { "NM-1FE-TX", (m_uint16_t *)eeprom_nm_1fe_tx_data,
72 sizeof(eeprom_nm_1fe_tx_data)/2 },
73 { "NM-16ESW", (m_uint16_t *)eeprom_nm_16esw_data,
74 sizeof(eeprom_nm_16esw_data)/2 },
75 { "NM-4T", eeprom_nm_4t_data, sizeof(eeprom_nm_4t_data)/2 },
76 { NULL, NULL, 0 },
77 };
78
79 /* Find a NM EEPROM */
80 const struct cisco_eeprom *cisco_eeprom_find_nm(char *name)
81 {
82 return(cisco_eeprom_find(eeprom_nm_array,name));
83 }
84
85 /* ====================================================================== */
86 /* PA-FE-TX: 1 FastEthernet Port Adapter EEPROM */
87 /* ====================================================================== */
88 static const m_uint16_t eeprom_pa_fe_tx_data[] = {
89 0x0111, 0x0102, 0xffff, 0xffff, 0x4906, 0x9804, 0x0000, 0x0000,
90 0x6000, 0x0000, 0x9812, 0x1700, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
91 };
92
93 /* ====================================================================== */
94 /* PA-2FE-TX: 2 FastEthernet Port Adapter EEPROM */
95 /* ====================================================================== */
96 static const m_uint16_t eeprom_pa_2fe_tx_data[] = {
97 0x04FF, 0x4002, 0x2441, 0x0100, 0xC18B, 0x5858, 0x5830, 0x3030,
98 0x3030, 0x3030, 0x3082, 0x4915, 0x2C04, 0x4241, 0x3003, 0x0081,
99 0x0000, 0x0000, 0x0400, 0x8000, 0x0000, 0x00CB, 0x9450, 0x412D,
100 0x3246, 0x452D, 0x4658, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
101 0x20C0, 0x4603, 0x2000, 0x20A0, 0x04FF, 0xFFFF, 0xFFFF, 0xFFFF,
102 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
103 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
104 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
105 };
106
107 /* ====================================================================== */
108 /* PA-GE: 1 GigabitEthernet Port Adapter EEPROM */
109 /* ====================================================================== */
110 static const m_uint16_t eeprom_pa_ge_data[] = {
111 0x0198, 0x0100, 0x0000, 0x0000, 0x000C, 0x4803, 0x0000, 0x0000,
112 0x5000, 0x0000, 0x9906, 0x0300, 0x0001, 0xFFFF, 0xFFFF, 0xFFFF,
113 };
114
115 /* ====================================================================== */
116 /* PA-4E: 4 Ethernet Port Adapter EEPROM */
117 /* ====================================================================== */
118 static const m_uint16_t eeprom_pa_4e_data[] = {
119 0x0102, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
120 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
121 };
122
123 /* ====================================================================== */
124 /* PA-8E: 8 Ethernet Port Adapter EEPROM */
125 /* ====================================================================== */
126 static const m_uint16_t eeprom_pa_8e_data[] = {
127 0x0101, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
128 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
129 };
130
131 /* ====================================================================== */
132 /* PA-4T+: 4 Serial Port Adapter EEPROM */
133 /* ====================================================================== */
134 static m_uint16_t eeprom_pa_4t_data[] = {
135 0x010C, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
136 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
137 };
138
139 /* ====================================================================== */
140 /* PA-8T: 8 Serial Port Adapter EEPROM */
141 /* ====================================================================== */
142 static m_uint16_t eeprom_pa_8t_data[] = {
143 0x010E, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
144 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
145 };
146
147 /* ====================================================================== */
148 /* PA-A1: 1 ATM Port Adapter EEPROM */
149 /* ====================================================================== */
150 static const m_uint16_t eeprom_pa_a1_data[] = {
151 0x0117, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
152 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
153 };
154
155 /* ====================================================================== */
156 /* PA-POS-OC3: 1 POS Port Adapter EEPROM */
157 /* ====================================================================== */
158 static const m_uint16_t eeprom_pa_pos_oc3_data[] = {
159 0x0196, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
160 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
161 };
162
163 /* ====================================================================== */
164 /* PA-4B: 4 BRI Port Adapter EEPROM */
165 /* ====================================================================== */
166 static const m_uint16_t eeprom_pa_4b_data[] = {
167 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
168 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
169 };
170
171 /* ====================================================================== */
172 /* PA-MC-8TE1 */
173 /* ====================================================================== */
174 static const m_uint16_t eeprom_pa_mc8te1_data[] = {
175 0x04FF, 0x4003, 0x4E41, 0x0200, 0xC18B, 0x4A41, 0x4530, 0x3834,
176 0x3159, 0x3251, 0x3082, 0x491D, 0x7D02, 0x4241, 0x3003, 0x0081,
177 0x0000, 0x0000, 0x0400, 0x8000, 0x0127, 0x9BCB, 0x9450, 0x412D,
178 0x4D43, 0x2D38, 0x5445, 0x312B, 0x2020, 0x2020, 0x2020, 0x2020,
179 0x20C0, 0x4603, 0x2000, 0x4BBB, 0x02FF, 0xFFFF, 0xFFFF, 0xFFFF,
180 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
181 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
182 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
183 };
184
185 /* ====================================================================== */
186 /* PA EEPROMs */
187 /* ====================================================================== */
188
189 static const struct cisco_eeprom eeprom_pa_array[] = {
190 { "PA-FE-TX", (m_uint16_t *)eeprom_pa_fe_tx_data,
191 sizeof(eeprom_pa_fe_tx_data)/2 },
192 { "PA-2FE-TX", (m_uint16_t *)eeprom_pa_2fe_tx_data,
193 sizeof(eeprom_pa_2fe_tx_data)/2 },
194 { "PA-GE", (m_uint16_t *)eeprom_pa_ge_data, sizeof(eeprom_pa_ge_data)/2 },
195 { "PA-4E", (m_uint16_t *)eeprom_pa_4e_data, sizeof(eeprom_pa_4e_data)/2 },
196 { "PA-8E", (m_uint16_t *)eeprom_pa_8e_data, sizeof(eeprom_pa_8e_data)/2 },
197 { "PA-4T+", eeprom_pa_4t_data, sizeof(eeprom_pa_4t_data)/2 },
198 { "PA-8T", eeprom_pa_8t_data, sizeof(eeprom_pa_8t_data)/2 },
199 { "PA-A1", (m_uint16_t *)eeprom_pa_a1_data, sizeof(eeprom_pa_a1_data)/2 },
200 { "PA-POS-OC3", (m_uint16_t *)eeprom_pa_pos_oc3_data,
201 sizeof(eeprom_pa_pos_oc3_data)/2 },
202 { "PA-4B", (m_uint16_t *)eeprom_pa_4b_data, sizeof(eeprom_pa_4b_data)/2 },
203 { "PA-MC-8TE1", (m_uint16_t *)eeprom_pa_mc8te1_data,
204 sizeof(eeprom_pa_mc8te1_data)/2 },
205 { NULL, NULL, 0 },
206 };
207
208 /* Find a PA EEPROM */
209 const struct cisco_eeprom *cisco_eeprom_find_pa(char *name)
210 {
211 return(cisco_eeprom_find(eeprom_pa_array,name));
212 }
213
214 /* ====================================================================== */
215 /* Utility functions */
216 /* ====================================================================== */
217
218 /* Find an EEPROM in the specified EEPROM array */
219 const struct cisco_eeprom *
220 cisco_eeprom_find(const struct cisco_eeprom *eeproms,char *name)
221 {
222 int i;
223
224 for(i=0;eeproms[i].name;i++)
225 if (!strcmp(eeproms[i].name,name))
226 return(&eeproms[i]);
227
228 return NULL;
229 }
230
231 /* Copy an EEPROM */
232 int cisco_eeprom_copy(struct cisco_eeprom *dst,const struct cisco_eeprom *src)
233 {
234 m_uint16_t *data;
235
236 if (!src || !src)
237 return(-1);
238
239 cisco_eeprom_free(dst);
240
241 if (!(data = malloc(src->len << 1)))
242 return(-1);
243
244 memcpy(data,src->data,src->len << 1);
245 dst->name = src->name;
246 dst->data = data;
247 dst->len = src->len;
248 return(0);
249 }
250
251 /* Free resources used by an EEPROM */
252 void cisco_eeprom_free(struct cisco_eeprom *eeprom)
253 {
254 if (eeprom && eeprom->data) {
255 free(eeprom->data);
256 eeprom->data = NULL;
257 eeprom->len = 0;
258 }
259 }
260
261 /* Return TRUE if the specified EEPROM contains usable data */
262 int cisco_eeprom_valid(struct cisco_eeprom *eeprom)
263 {
264 return((eeprom && eeprom->data) ? TRUE : FALSE);
265 }
266
267 /* Get a byte from an EEPROM */
268 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
269 size_t offset,m_uint8_t *val)
270 {
271 m_uint16_t tmp;
272
273 if (offset >= (eeprom->len << 1))
274 return(-1);
275
276 tmp = eeprom->data[offset >> 1];
277
278 if (!(offset & 1))
279 tmp >>= 8;
280
281 *val = tmp & 0xFF;
282 return(0);
283 }
284
285 /* Set a byte to an EEPROM */
286 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
287 size_t offset,m_uint8_t val)
288 {
289 m_uint16_t tmp;
290
291 if (offset >= (eeprom->len << 1))
292 return(-1);
293
294 tmp = eeprom->data[offset >> 1];
295
296 if (offset & 1)
297 tmp = (tmp & 0xFF00) | val;
298 else
299 tmp = (tmp & 0x00FF) | (val << 8);
300
301 eeprom->data[offset >> 1] = tmp;
302 return(0);
303 }
304
305 /* Get an EEPROM region */
306 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
307 m_uint8_t *data,size_t data_len)
308 {
309 size_t i;
310
311 for(i=0;i<data_len;i++) {
312 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
313 return(-1);
314 }
315
316 return(0);
317 }
318
319 /* Set an EEPROM region */
320 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
321 m_uint8_t *data,size_t data_len)
322 {
323 size_t i;
324
325 for(i=0;i<data_len;i++) {
326 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
327 return(-1);
328 }
329
330 return(0);
331 }
332
333 /* Get a field of a Cisco EEPROM v4 */
334 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
335 m_uint8_t *len,size_t *offset)
336 {
337 m_uint8_t tmp;
338
339 /* Read field type */
340 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
341 return(-1);
342
343 /* No more field */
344 if (*type == 0xFF)
345 return(0);
346
347 /* Get field length */
348 tmp = (*type >> 6) & 0x03;
349
350 if (tmp == 0x03) {
351 /* Variable len */
352 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
353 return(-1);
354
355 *len = tmp & 0x0F;
356 } else {
357 /* Fixed len */
358 *len = 1 << tmp;
359 }
360
361 return(1);
362 }
363
364 /* Dump a Cisco EEPROM with format version 4 */
365 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
366 {
367 m_uint8_t type,len,tmp;
368 size_t i,offset=2;
369
370 printf("Dumping EEPROM contents:\n");
371
372 do {
373 /* Read field */
374 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
375 break;
376
377 printf(" Field 0x%2.2x: ",type);
378
379 for(i=0;i<len;i++) {
380 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
381 break;
382
383 printf("%2.2x ",tmp);
384 }
385
386 printf("\n");
387
388 offset += len;
389 }while(offset < (eeprom->len << 1));
390 }
391
392 /* Returns the offset of the specified field */
393 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
394 m_uint8_t field_type,
395 size_t *field_offset)
396 {
397 m_uint8_t type,len;
398 size_t offset=2;
399
400 do {
401 /* Read field */
402 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
403 break;
404
405 if (type == field_type) {
406 *field_offset = offset;
407 return(0);
408 }
409
410 offset += len;
411 }while(offset < (eeprom->len << 1));
412
413 return(-1);
414 }

  ViewVC Help
Powered by ViewVC 1.1.26