~ubuntu-branches/ubuntu/lucid/efibootmgr/lucid

« back to all changes in this revision

Viewing changes to src/lib/unparse_path.c

  • Committer: Bazaar Package Importer
  • Author(s): Bdale Garbee
  • Date: 2002-03-30 13:53:32 UTC
  • Revision ID: james.westby@ubuntu.com-20020330135332-3l2qicrkpm8v4ex4
Tags: upstream-0.3.4
ImportĀ upstreamĀ versionĀ 0.3.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  unparse_path.[ch]
 
3
 
 
4
  Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
 
5
 
 
6
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdint.h>
 
23
#include <stdint.h>
 
24
#include <sys/stat.h>
 
25
#include <fcntl.h>
 
26
#include <string.h>
 
27
#include <netinet/in.h>
 
28
 
 
29
#include "efi.h"
 
30
#include "unparse_path.h"
 
31
#include "efichar.h"
 
32
 
 
33
 
 
34
 
 
35
 
 
36
void
 
37
dump_raw_data(void *data, uint64_t length)
 
38
{
 
39
        char buffer1[80], buffer2[80], *b1, *b2, c;
 
40
        unsigned char *p = data;
 
41
        unsigned long column=0;
 
42
        uint64_t length_printed = 0;
 
43
        const char maxcolumn = 16;
 
44
        while (length_printed < length) {
 
45
                b1 = buffer1;
 
46
                b2 = buffer2;
 
47
                for (column = 0;
 
48
                     column < maxcolumn && length_printed < length; 
 
49
                     column ++) {
 
50
                        b1 += sprintf(b1, "%02x ",(unsigned int) *p);
 
51
                        if (*p < 32 || *p > 126) c = '.';
 
52
                        else c = *p;
 
53
                        b2 += sprintf(b2, "%c", c);
 
54
                        p++;
 
55
                        length_printed++;
 
56
                }
 
57
                /* pad out the line */
 
58
                for (; column < maxcolumn; column++)
 
59
                {
 
60
                        b1 += sprintf(b1, "   ");
 
61
                        b2 += sprintf(b2, " ");
 
62
                }
 
63
 
 
64
                printf("%s\t%s\n", buffer1, buffer2);
 
65
        }
 
66
}
 
67
 
 
68
 
 
69
 
 
70
unsigned long
 
71
unparse_raw(char *buffer, uint8_t *p, uint64_t length)
 
72
{
 
73
        uint64_t i; unsigned char c;
 
74
        char *q = buffer;
 
75
        for (i=0; i<length; i++) {
 
76
                c = p[i];
 
77
                //if (c < 32 || c > 127) c = '.';
 
78
                q += sprintf(q, "%02x", c);
 
79
        }
 
80
        return q - buffer;
 
81
}
 
82
 
 
83
unsigned long
 
84
unparse_raw_text(char *buffer, uint8_t *p, uint64_t length)
 
85
{
 
86
        uint64_t i; unsigned char c;
 
87
        char *q = buffer;
 
88
        for (i=0; i<length; i++) {
 
89
                c = p[i];
 
90
                if (c < 32 || c > 127) c = '.';
 
91
                q += sprintf(q, "%c", c);
 
92
        }
 
93
        return q - buffer;
 
94
}
 
95
 
 
96
static int
 
97
unparse_ipv4_port(char *buffer, uint32_t ipaddr, uint16_t port)
 
98
{
 
99
        unsigned char *ip;
 
100
//      ipaddr = nltoh(ipaddr);
 
101
//      port = nstoh(port);
 
102
        ip = (unsigned char *)&ipaddr;
 
103
        return sprintf(buffer, "%hhu.%hhu.%hhu.%hhu:%hu",
 
104
                       ip[0], ip[1], ip[2], ip[3], 
 
105
                       port);
 
106
}
 
107
 
 
108
 
 
109
static int
 
110
unparse_acpi_path(char *buffer, EFI_DEVICE_PATH *path)
 
111
{
 
112
        ACPI_DEVICE_PATH *acpi = (ACPI_DEVICE_PATH *)path;
 
113
 
 
114
        switch (path->subtype) {
 
115
        case 1:
 
116
                return sprintf(buffer, "ACPI(%x,%x)", acpi->_HID, acpi->_UID);
 
117
                break;
 
118
        default:
 
119
                return unparse_raw(buffer, (uint8_t *)path, path->length);
 
120
                break;
 
121
        }
 
122
        return 0;
 
123
}
 
124
 
 
125
static int
 
126
unparse_vendor_path(char *buffer, VENDOR_DEVICE_PATH *path)
 
127
{
 
128
        char text_guid[40], *p = buffer, *q = (uint8_t *)path + 20;
 
129
        efi_guid_unparse(&path->vendor_guid, text_guid);
 
130
        p += sprintf(p, "Vendor(%s,", text_guid);
 
131
        p += unparse_raw(p, q, path->length - 20);
 
132
        p += sprintf(p, ")");
 
133
        return p - buffer;
 
134
}
 
135
 
 
136
static int
 
137
unparse_hardware_path(char *buffer, EFI_DEVICE_PATH *path)
 
138
{
 
139
        PCI_DEVICE_PATH *pci = (PCI_DEVICE_PATH *)path;
 
140
        PCCARD_DEVICE_PATH *pccard = (PCCARD_DEVICE_PATH *)path;
 
141
        MEMORY_MAPPED_DEVICE_PATH *mm = (MEMORY_MAPPED_DEVICE_PATH *)path;
 
142
        CONTROLLER_DEVICE_PATH *ctlr = (CONTROLLER_DEVICE_PATH *)path;
 
143
 
 
144
        switch (path->subtype) {
 
145
        case 1:
 
146
                return sprintf(buffer, "PCI(%x,%x)",
 
147
                               pci->function, pci->device);
 
148
                break;
 
149
        case 2:
 
150
                return sprintf(buffer, "PCCARD(%x)", pccard->socket);
 
151
                break;
 
152
        case 3:
 
153
                return sprintf(buffer, "MM(%x,%llx,%llx)",
 
154
                               mm->memory_type,
 
155
                               mm->start, mm->end);
 
156
                break;
 
157
        case 4:
 
158
                return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
 
159
                break;
 
160
 
 
161
        case 5:
 
162
                return sprintf(buffer, "Controller(%x)", ctlr->controller);
 
163
                break;
 
164
 
 
165
        default:
 
166
                return unparse_raw(buffer, (uint8_t *)path, path->length);
 
167
        }
 
168
        return 0;
 
169
}
 
170
 
 
171
 
 
172
static int
 
173
unparse_messaging_path(char *buffer, EFI_DEVICE_PATH *path)
 
174
{
 
175
        ATAPI_DEVICE_PATH *atapi = (ATAPI_DEVICE_PATH *)path;
 
176
        SCSI_DEVICE_PATH *scsi = (SCSI_DEVICE_PATH *)path;
 
177
        FIBRE_CHANNEL_DEVICE_PATH *fc = (FIBRE_CHANNEL_DEVICE_PATH *)path;
 
178
        I1394_DEVICE_PATH *i1394 = (I1394_DEVICE_PATH *)path;
 
179
        USB_DEVICE_PATH *usb = (USB_DEVICE_PATH *)path;
 
180
        MAC_ADDR_DEVICE_PATH *mac = (MAC_ADDR_DEVICE_PATH *)path;
 
181
        USB_CLASS_DEVICE_PATH *usbclass = (USB_CLASS_DEVICE_PATH *)path;
 
182
        I2O_DEVICE_PATH *i2o = (I2O_DEVICE_PATH *)path; 
 
183
        IPv4_DEVICE_PATH *ipv4 = (IPv4_DEVICE_PATH *)path;
 
184
        IPv6_DEVICE_PATH *ipv6 = (IPv6_DEVICE_PATH *)path;
 
185
        char *p = buffer;
 
186
 
 
187
        switch (path->subtype) {
 
188
        case 1:
 
189
                return sprintf(buffer, "ATAPI(%x,%x,%x)",
 
190
                               atapi->primary_secondary,
 
191
                               atapi->slave_master, atapi->lun);
 
192
                break;
 
193
        case 2:
 
194
                return sprintf(buffer, "SCSI(%x,%x)", scsi->id, scsi->lun);
 
195
                break;
 
196
 
 
197
        case 3:
 
198
                return sprintf(buffer, "FC(%llx,%llx)", fc->wwn, fc->lun);
 
199
                break;
 
200
        case 4:
 
201
                return sprintf(buffer, "1394(%llx)", i1394->guid);
 
202
                break;
 
203
        case 5:
 
204
                return sprintf(buffer, "USB(%x,%x)", usb->port, usb->endpoint);
 
205
                break;
 
206
        case 6:
 
207
                return sprintf(buffer, "I2O(%x)", i2o->tid);
 
208
                break;
 
209
        case 11:
 
210
                p += sprintf(p, "MAC(");
 
211
                p += unparse_raw(p, mac->macaddr, 6);
 
212
                p += sprintf(p, ",%hhx)", mac->iftype);
 
213
                return (int) (p - buffer);
 
214
                break;
 
215
        case 12:
 
216
                p += sprintf(p, "IPv4(");
 
217
                p += unparse_ipv4_port(p, ipv4->local_ip, ipv4->local_port);
 
218
                p += sprintf(p, "<->");
 
219
                p += unparse_ipv4_port(p, ipv4->remote_ip, ipv4->remote_port);
 
220
                p += sprintf(p, ",%hx, %hhx", ipv4->protocol, ipv4->static_addr);
 
221
                return (int) (p - buffer);
 
222
                break;
 
223
 
 
224
        case 15:
 
225
                return sprintf(buffer, "USBClass(%hx,%hx,%hhx,%hhx,%hhx)",
 
226
                               usbclass->vendor, usbclass->product,
 
227
                               usbclass->class, usbclass->subclass,
 
228
                               usbclass->protocol);
 
229
                break;
 
230
        default:
 
231
                return unparse_raw(buffer, (uint8_t *)path, path->length);
 
232
                break;
 
233
        }
 
234
        return 0;
 
235
}
 
236
 
 
237
static int
 
238
unparse_media_hard_drive_path(char *buffer, EFI_DEVICE_PATH *path)
 
239
{
 
240
        HARDDRIVE_DEVICE_PATH *hd = (HARDDRIVE_DEVICE_PATH *)path;
 
241
        char text_uuid[40], *sig=text_uuid;
 
242
        
 
243
        switch (hd->signature_type) {
 
244
        case 0x00:
 
245
                sprintf(sig, "None");
 
246
                break;
 
247
        case 0x01:
 
248
                sprintf(sig, "%08x", *(uint32_t *)hd->signature);
 
249
                break;
 
250
        case 0x02: /* GPT */
 
251
                efi_guid_unparse((efi_guid_t *)hd->signature, sig);
 
252
                break;
 
253
        default:
 
254
                break;
 
255
        }
 
256
 
 
257
        return sprintf(buffer, "HD(%x,%llx,%llx,%s)",
 
258
                       hd->part_num, hd->start, hd->size, sig);
 
259
}
 
260
 
 
261
 
 
262
 
 
263
static int
 
264
unparse_media_path(char *buffer, EFI_DEVICE_PATH *path)
 
265
{
 
266
 
 
267
        CDROM_DEVICE_PATH *cdrom = (CDROM_DEVICE_PATH *)path;
 
268
        MEDIA_PROTOCOL_DEVICE_PATH *media = (MEDIA_PROTOCOL_DEVICE_PATH *)path;
 
269
        FILE_PATH_DEVICE_PATH *file = (FILE_PATH_DEVICE_PATH *)path;
 
270
        char text_guid[40], *p = buffer;
 
271
        char file_name[80];
 
272
        memset(file_name, 0, sizeof(file_name));
 
273
 
 
274
        switch (path->subtype) {
 
275
        case 1:
 
276
                return unparse_media_hard_drive_path(buffer, path);
 
277
                break;
 
278
        case 2:
 
279
                return sprintf(buffer, "CD-ROM(%x,%llx,%llx)",
 
280
                               cdrom->boot_entry, cdrom->start, cdrom->size);
 
281
                break;
 
282
        case 3:
 
283
                return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
 
284
                break;
 
285
        case 4:
 
286
                efichar_to_char(file_name, file->path_name, 80);
 
287
                return sprintf(p, "File(%s)", file_name);
 
288
                break;
 
289
        case 5:
 
290
                efi_guid_unparse(&media->guid, text_guid);
 
291
                return sprintf(buffer, "Media(%s)", text_guid);
 
292
                break;
 
293
        default:
 
294
                break;
 
295
        }
 
296
        return 0;
 
297
}
 
298
 
 
299
static int
 
300
unparse_bios_path(char *buffer, EFI_DEVICE_PATH *path)
 
301
{
 
302
        BIOS_BOOT_SPEC_DEVICE_PATH *bios = (BIOS_BOOT_SPEC_DEVICE_PATH *)path;
 
303
        char *p = buffer, *q = (uint8_t *)path + 8;
 
304
        p += sprintf(p, "BIOS(%x,%x,",
 
305
                     bios->device_type, bios->status_flag);
 
306
        p += unparse_raw(p, q, path->length - 8);
 
307
        p += sprintf(p, ")");
 
308
        return p - buffer;
 
309
}
 
310
 
 
311
 
 
312
uint64_t
 
313
unparse_path(char *buffer, EFI_DEVICE_PATH *path, uint16_t pathsize)
 
314
{
 
315
        uint16_t parsed_length = 0;
 
316
        char *p = buffer;
 
317
        int exit_now = 0;
 
318
 
 
319
        while (parsed_length < pathsize && !exit_now) {
 
320
                switch (path->type) {
 
321
                case 0x01:
 
322
                        p += unparse_hardware_path(p, path);
 
323
                        break;
 
324
                case 0x02:
 
325
                        p += unparse_acpi_path(p, path);
 
326
                        break;
 
327
                case 0x03:
 
328
                        p += unparse_messaging_path(p, path);
 
329
                        break;
 
330
                case 0x04:
 
331
                        p += unparse_media_path(p, path);
 
332
                        break;
 
333
                case 0x05:
 
334
                        p += unparse_bios_path(p, path);
 
335
                        break;
 
336
                case 0x7F:
 
337
                        exit_now = 1;
 
338
                        break;
 
339
                case 0xFF:
 
340
                        exit_now = 1;
 
341
                        break;
 
342
                default:
 
343
                        printf("\nwierd path");
 
344
                        dump_raw_data(path, 4);
 
345
                        break;
 
346
                }
 
347
//              p += sprintf(p, "\\");
 
348
                parsed_length += path->length;
 
349
                path = (EFI_DEVICE_PATH *) ((uint8_t *)path + path->length);
 
350
        }
 
351
 
 
352
        return p - buffer;
 
353
}
 
354
 
 
355
 
 
356
#if 0
 
357
static void
 
358
unparse_var(efi_variable_t *var)
 
359
{
 
360
        char buffer[1024];
 
361
        memset(buffer, 0, sizeof(buffer));
 
362
 
 
363
        unparse_path(buffer, (EFI_DEVICE_PATH *)var->Data, var->DataSize);
 
364
        printf("%s\n", buffer);
 
365
}
 
366
 
 
367
static int
 
368
compare_hardware_path_pci(EFI_DEVICE_PATH *path,
 
369
                          int device, int func)
 
370
{
 
371
        uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
 
372
        uint8_t path_device, path_func;
 
373
 
 
374
        switch (path->subtype) {
 
375
        case 1:
 
376
                /* PCI */
 
377
                path_func   = *(uint8_t *)p;
 
378
                path_device = *(uint8_t *)(p+1);
 
379
                
 
380
                return !(path_func == func && path_device == device);
 
381
                
 
382
                break;
 
383
        default:
 
384
                break;
 
385
        }
 
386
        return 1;
 
387
}
 
388
 
 
389
static int
 
390
compare_hardware_path_scsi(EFI_DEVICE_PATH *path, int id, int lun)
 
391
{
 
392
        uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
 
393
        uint16_t path_id, path_lun;
 
394
 
 
395
        switch (path->subtype) {
 
396
        case 2:
 
397
                /* SCSI */
 
398
                path_id   = *(uint16_t *)p;
 
399
                path_lun = *(uint16_t *)(p+2);
 
400
                
 
401
                return !(path_id == id && path_lun == lun);
 
402
                break;
 
403
        default:
 
404
                break;
 
405
        }
 
406
        return 1;
 
407
}
 
408
 
 
409
static int
 
410
compare_hardware_path_acpi(EFI_DEVICE_PATH *path, int bus)
 
411
{
 
412
        uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
 
413
        uint32_t _HID, _UID;
 
414
 
 
415
        switch (path->subtype) {
 
416
        case 1:
 
417
                /* ACPI */
 
418
                _HID = *(uint32_t *)p;
 
419
                _UID = *(uint32_t *)(p+4);
 
420
                
 
421
                /* FIXME: Need to convert _HID and _UID to bus number */
 
422
 
 
423
                return 0;
 
424
                break;
 
425
        default:
 
426
                break;
 
427
        }
 
428
        return 1;
 
429
}
 
430
 
 
431
static int
 
432
compare_media_path_harddrive(EFI_DEVICE_PATH *path, uint32_t num,
 
433
                             uint64_t start, uint64_t size)
 
434
{
 
435
        HARDDRIVE_DEVICE_PATH *p = (HARDDRIVE_DEVICE_PATH *)path;
 
436
        
 
437
 
 
438
        switch (path->subtype) {
 
439
        case 1:
 
440
                /* Hard Drive */
 
441
                return !(p->part_num == num
 
442
                         && p->start == start
 
443
                         && p->size == size);
 
444
                break;
 
445
        default:
 
446
                break;
 
447
        }
 
448
        return 1;
 
449
}
 
450
 
 
451
 
 
452
 
 
453
int
 
454
compare_pci_scsi_disk_blk(efi_variable_t *var,
 
455
                          int bus, int device, int func,
 
456
                          int host, int channel, int id, int lun,
 
457
                          uint64_t start, uint64_t size)
 
458
{
 
459
 
 
460
        EFI_DEVICE_PATH *path = (EFI_DEVICE_PATH *) var->Data;
 
461
        uint64_t parsed_length = 0;
 
462
        int exit_now = 0;
 
463
        int rc = 0;
 
464
 
 
465
        while (parsed_length < var->DataSize && !exit_now && !rc) {
 
466
                switch (path->type) {
 
467
                case 0x01:
 
468
                        /* Hardware (PCI) */
 
469
                        rc = compare_hardware_path_pci(path, device, func);
 
470
                        break;
 
471
                case 0x02:
 
472
                        /* ACPI */
 
473
                        rc = compare_hardware_path_acpi(path, bus);
 
474
                        break;
 
475
                case 0x03:
 
476
                        /* Messaging (SCSI) */
 
477
                        rc = compare_messaging_path_scsi(path, id, lun);
 
478
                        break;
 
479
                case 0x04:
 
480
                        /* Media (Hard Drive) */
 
481
                        rc = compare_media_path_harddrive(path, 0,
 
482
                                                          start, size);
 
483
                        break;
 
484
                case 0x7F:
 
485
                case 0xFF:
 
486
                        exit_now = 1;
 
487
                        break;
 
488
                case 0x05: /* BIOS */
 
489
                default:
 
490
                        break;
 
491
                }
 
492
                parsed_length += path->length;
 
493
                path = var->Data + parsed_length;
 
494
        }
 
495
        return rc;
 
496
}
 
497
 
 
498
#endif  
 
499
 
 
500
 
 
501
 
 
502
 
 
503
 
 
504
 
 
505
 
 
506
 
 
507
 
 
508
 
 
509
 
 
510
 
 
511
#ifdef UNPARSE_PATH
 
512
static void
 
513
usage(void)
 
514
{
 
515
        printf("Usage: dumppath filename\n");
 
516
        printf("\t where filename is a blkXXXX EFI variable from /proc/efi/vars\n");
 
517
}
 
518
 
 
519
int
 
520
main(int argc, char **argv)
 
521
{
 
522
        int fd = 0;
 
523
        ssize_t size;
 
524
        efi_variable_t var;
 
525
 
 
526
        if (argc == 1) {
 
527
                usage();
 
528
                exit(-1);
 
529
        }
 
530
 
 
531
        
 
532
        fd = open(argv[1], O_RDONLY);
 
533
        if (fd == -1) {
 
534
                perror("Failed to open file.");
 
535
                exit(-1);
 
536
        }
 
537
        size = read(fd, &var, sizeof(var));
 
538
        if (size == -1 || size < sizeof(var)) {
 
539
                perror("Failed to read file.");
 
540
                close(fd);
 
541
                exit(-1);
 
542
        }
 
543
        unparse_var(&var);
 
544
        
 
545
                
 
546
        return 0;
 
547
}
 
548
#endif