static ssize_t unparse_bios_path(char *buffer, size_t buffer_size, EFI_DEVICE_PATH *path) { BIOS_BOOT_SPEC_DEVICE_PATH *bios = (BIOS_BOOT_SPEC_DEVICE_PATH *)path; char *p = buffer; unsigned char *q = (uint8_t *)path + 8; char a[16], b[16]; size_t needed; off_t buf_offset = 0; needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "BIOS(%x,%x,", get(a, bios->device_type), get(b, bios->status_flag)); if (needed < 0) return -1; buf_offset += needed; needed = unparse_raw(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, q, path->length - 8); if (needed < 0) return -1; buf_offset += needed; needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ")"); if (needed < 0) return -1; buf_offset += needed; return buf_offset; }
static int unparse_hardware_path(char *buffer, EFI_DEVICE_PATH *path) { PCI_DEVICE_PATH *pci = (PCI_DEVICE_PATH *)path; PCCARD_DEVICE_PATH *pccard = (PCCARD_DEVICE_PATH *)path; MEMORY_MAPPED_DEVICE_PATH *mm = (MEMORY_MAPPED_DEVICE_PATH *)path; CONTROLLER_DEVICE_PATH *ctlr = (CONTROLLER_DEVICE_PATH *)path; char a[16], b[16], c[16]; switch (path->subtype) { case 1: return sprintf(buffer, "PCI(%x,%x)", get(a, pci->device), get(b, pci->function)); break; case 2: return sprintf(buffer, "PCCARD(%x)", get(a, pccard->socket)); break; case 3: return sprintf(buffer, "MM(%x,%" PRIx64 ",%" PRIx64 ")", get(a, mm->memory_type), get(b, mm->start), get(c, mm->end)); break; case 4: return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path); break; case 5: return sprintf(buffer, "Controller(%x)", get(a, ctlr->controller)); break; default: return unparse_raw(buffer, (uint8_t *)path, path->length); } return 0; }
static int unparse_vendor_path(char *buffer, VENDOR_DEVICE_PATH *path) { char text_guid[40], *p = buffer; unsigned char *q = (uint8_t *)path + 20; efi_guid_unparse(&path->vendor_guid, text_guid); p += sprintf(p, "Vendor(%s,", text_guid); p += unparse_raw(p, q, path->length - 20); p += sprintf(p, ")"); return p - buffer; }
static int unparse_bios_path(char *buffer, EFI_DEVICE_PATH *path) { BIOS_BOOT_SPEC_DEVICE_PATH *bios = (BIOS_BOOT_SPEC_DEVICE_PATH *)path; char *p = buffer; unsigned char *q = (uint8_t *)path + 8; char a[16], b[16]; p += sprintf(p, "BIOS(%x,%x,", get(a, bios->device_type), get(b, bios->status_flag)); p += unparse_raw(p, q, path->length - 8); p += sprintf(p, ")"); return p - buffer; }
static int unparse_acpi_path(char *buffer, EFI_DEVICE_PATH *path) { ACPI_DEVICE_PATH *acpi = (ACPI_DEVICE_PATH *)path; char a[16], b[16]; switch (path->subtype) { case 1: return sprintf(buffer, "ACPI(%x,%x)", get(a, acpi->_HID), get(b, acpi->_UID)); break; default: return unparse_raw(buffer, (uint8_t *)path, path->length); break; } return 0; }
static ssize_t unparse_vendor_path(char *buffer, size_t buffer_size, char *prefix, VENDOR_DEVICE_PATH *path) { char *text_guid; unsigned char *q = (uint8_t *)path + 20; int rc; size_t needed; off_t buf_offset = 0; rc = efi_guid_to_str(&path->vendor_guid, &text_guid); if (rc < 0) return -1; needed = snprintf(buffer, buffer_size, "%s(%s,", prefix ? prefix : "Vendor", text_guid); free(text_guid); if (needed < 0) return -1; buf_offset += needed; needed = unparse_raw(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, q, path->length - 20); if (needed < 0) return -1; buf_offset += needed; needed = snprintf(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ")"); if (needed < 0) return -1; buf_offset += needed; return buf_offset; }
static int unparse_messaging_path(char *buffer, EFI_DEVICE_PATH *path) { ATAPI_DEVICE_PATH *atapi = (ATAPI_DEVICE_PATH *)path; SCSI_DEVICE_PATH *scsi = (SCSI_DEVICE_PATH *)path; FIBRE_CHANNEL_DEVICE_PATH *fc = (FIBRE_CHANNEL_DEVICE_PATH *)path; I1394_DEVICE_PATH *i1394 = (I1394_DEVICE_PATH *)path; USB_DEVICE_PATH *usb = (USB_DEVICE_PATH *)path; MAC_ADDR_DEVICE_PATH *mac = (MAC_ADDR_DEVICE_PATH *)path; USB_CLASS_DEVICE_PATH *usbclass = (USB_CLASS_DEVICE_PATH *)path; I2O_DEVICE_PATH *i2o = (I2O_DEVICE_PATH *)path; IPv4_DEVICE_PATH *ipv4 = (IPv4_DEVICE_PATH *)path; /* IPv6_DEVICE_PATH *ipv6 = (IPv6_DEVICE_PATH *)path; */ char *p = buffer; char a[16], b[16], c[16], d[16], e[16]; switch (path->subtype) { case 1: return sprintf(buffer, "ATAPI(%x,%x,%x)", get(a, atapi->primary_secondary), get(b, atapi->slave_master), get(c, atapi->lun)); break; case 2: return sprintf(buffer, "SCSI(%x,%x)", get(a, scsi->id), get(b, scsi->lun)); break; case 3: return sprintf(buffer, "FC(%" PRIx64 ",%" PRIx64 ")", get(a, fc->wwn), get(b, fc->lun)); break; case 4: return sprintf(buffer, "1394(%" PRIx64 ")", get(a, i1394->guid)); break; case 5: return sprintf(buffer, "USB(%x,%x)", get(a, usb->port), get(b, usb->endpoint)); break; case 6: return sprintf(buffer, "I2O(%x)", get(a, i2o->tid)); break; case 11: p += sprintf(p, "MAC("); p += unparse_raw(p, mac->macaddr, 6); p += sprintf(p, ",%hhx)", get(a, mac->iftype)); return (int) (p - buffer); break; case 12: p += sprintf(p, "IPv4("); p += unparse_ipv4_port(p, ipv4->local_ip, ipv4->local_port); p += sprintf(p, "<->"); p += unparse_ipv4_port(p, ipv4->remote_ip, ipv4->remote_port); p += sprintf(p, ",%hx, %hhx", get(a, ipv4->protocol), get(b, ipv4->static_addr)); return (int) (p - buffer); break; case 15: return sprintf(buffer, "USBClass(%hx,%hx,%hhx,%hhx,%hhx)", get(a, usbclass->vendor), get(b, usbclass->product), get(c, usbclass->class), get(d, usbclass->subclass), get(e, usbclass->protocol)); break; default: return unparse_raw(buffer, (uint8_t *)path, path->length); break; } return 0; }
ssize_t unparse_path(char *buffer, size_t buffer_size, EFI_DEVICE_PATH *path, uint16_t pathsize) { uint16_t parsed_length = 0; char *p = buffer; size_t needed; off_t buf_offset = 0; int exit_now = 0; while (parsed_length < pathsize && !exit_now) { switch (path->type) { case 0x01: needed = unparse_hardware_path(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, path); if (needed < 0) return -1; buf_offset += needed; break; case 0x02: needed = unparse_acpi_path(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, path); if (needed < 0) return -1; buf_offset += needed; break; case 0x03: needed = unparse_messaging_path(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, path); if (needed < 0) return -1; buf_offset += needed; break; case 0x04: needed = unparse_media_path(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, path); if (needed < 0) return -1; buf_offset += needed; break; case 0x05: needed = unparse_bios_path(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, path); if (needed < 0) return -1; buf_offset += needed; break; case 0x7F: exit_now = 1; break; case 0xFF: exit_now = 1; break; default: needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "Unknown(%d,%d,", path->type, path->subtype); if (needed < 0) return -1; buf_offset += needed; if (path->length + sizeof (END_DEVICE_PATH) > (uint64_t)(pathsize - parsed_length)){ needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "invalid size)"); if (needed < 0) return -1; buf_offset += needed; exit_now = 1; } else { needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "%d,", path->length); if (needed < 0) return -1; buf_offset += needed; needed = unparse_raw(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, (uint8_t *)path + offsetof(EFI_DEVICE_PATH, data), path->length); if (needed < 0) return -1; buf_offset += needed; needed = snprintf(p + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ")"); if (needed < 0) return -1; buf_offset += needed; } break; } // p += sprintf(p, "\\"); parsed_length += path->length; path = (EFI_DEVICE_PATH *) ((uint8_t *)path + path->length); } return buf_offset; }
static ssize_t unparse_messaging_path(char *buffer, size_t buffer_size, EFI_DEVICE_PATH *path) { ATAPI_DEVICE_PATH *atapi = (ATAPI_DEVICE_PATH *)path; SATA_DEVICE_PATH *sata = (SATA_DEVICE_PATH *)path; SCSI_DEVICE_PATH *scsi = (SCSI_DEVICE_PATH *)path; FIBRE_CHANNEL_DEVICE_PATH *fc = (FIBRE_CHANNEL_DEVICE_PATH *)path; I1394_DEVICE_PATH *i1394 = (I1394_DEVICE_PATH *)path; USB_DEVICE_PATH *usb = (USB_DEVICE_PATH *)path; MAC_ADDR_DEVICE_PATH *mac = (MAC_ADDR_DEVICE_PATH *)path; USB_CLASS_DEVICE_PATH *usbclass = (USB_CLASS_DEVICE_PATH *)path; I2O_DEVICE_PATH *i2o = (I2O_DEVICE_PATH *)path; IPv4_DEVICE_PATH *ipv4 = (IPv4_DEVICE_PATH *)path; /* IPv6_DEVICE_PATH *ipv6 = (IPv6_DEVICE_PATH *)path; */ NVME_DEVICE_PATH *nvme = (NVME_DEVICE_PATH *)path; char a[16], b[16], c[16], d[16], e[16]; size_t needed; off_t buf_offset = 0; switch (path->subtype) { case 1: return snprintf(buffer, buffer_size, "ATAPI(%x,%x,%x)", get(a, atapi->primary_secondary), get(b, atapi->slave_master), get(c, atapi->lun)); case 2: return snprintf(buffer, buffer_size, "SCSI(%x,%x)", get(a, scsi->id), get(b, scsi->lun)); case 3: return snprintf(buffer, buffer_size, "FC(%" PRIx64 ",%" PRIx64 ")", get(a, fc->wwn), get(b, fc->lun)); case 4: return snprintf(buffer, buffer_size, "1394(%" PRIx64 ")", get(a, i1394->guid)); case 5: return snprintf(buffer, buffer_size, "USB(%x,%x)", get(a, usb->port), get(b, usb->endpoint)); case 6: return snprintf(buffer, buffer_size, "I2O(%x)", get(a, i2o->tid)); case 10: return unparse_vendor_path(buffer, buffer_size, "VenMsg", (VENDOR_DEVICE_PATH *)path); case 11: needed = snprintf(buffer, buffer_size, "MAC("); if (needed < 0) return needed; buf_offset += needed; needed = snprintf(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "MAC("); if (needed < 0) return needed; buf_offset += needed; needed = unparse_raw(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, mac->macaddr, 6); if (needed < 0) return needed; buf_offset += needed; needed = snprintf(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ",%hhx)", get(a, mac->iftype)); if (needed < 0) return needed; buf_offset += needed; return buf_offset; case 12: needed = snprintf(buffer, buf_offset, "IPv4("); if (needed < 0) return -1; buf_offset += needed; needed = unparse_ipv4_port(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ipv4->local_ip, ipv4->local_port); if (needed < 0) return -1; buf_offset += needed; needed = snprintf(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, "<->"); if (needed < 0) return -1; buf_offset += needed; needed = unparse_ipv4_port(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ipv4->remote_ip, ipv4->remote_port); if (needed < 0) return -1; buf_offset += needed; needed = snprintf(buffer + buf_offset, buffer_size == 0 ? 0 : buffer_size - buf_offset, ",%hx, %hhx", get(a, ipv4->protocol), get(b, ipv4->static_addr)); if (needed < 0) return -1; buf_offset += needed; return buf_offset; case 15: return snprintf(buffer, buffer_size, "USBClass(%hx,%hx,%hhx,%hhx,%hhx)", get(a, usbclass->vendor), get(b, usbclass->product), get(c, usbclass->class), get(d, usbclass->subclass), get(e, usbclass->protocol)); case 18: return snprintf(buffer, buffer_size, "SATA(%hx,%hx,%hx)", get(a, sata->port), get(b, sata->port_multiplier), get(c, sata->lun)); case 23: return snprintf(buffer, buffer_size, "NVME(%x,%lx)", get(a, nvme->namespace_id), get(b, nvme->ieee_extended_unique_identifier)); default: return unparse_raw(buffer, buffer_size, (uint8_t *)path, path->length); } return 0; }