1 #include <unistd.h> 2 #include <stddef.h> 3 4 #include <libubox/list.h> 5 6 #include "dhcpv6.h" 7 #include "dhcpv6-pxe.h" 8 9 struct ipv6_pxe_entry { 10 struct list_head list; // List head for linking 11 uint32_t arch; 12 13 // Ready to send 14 struct __attribute__((packed)) { 15 uint16_t type; // In network endianess 16 uint16_t len; // In network endianess, without /0 17 char payload[]; // Null-terminated here 18 } bootfile_url; 19 }; 20 21 static struct ipv6_pxe_entry* ipv6_pxe_default = NULL; 22 LIST_HEAD(ipv6_pxe_list); 23 24 const struct ipv6_pxe_entry* ipv6_pxe_entry_new(uint32_t arch, const char* url) { 25 size_t url_len = strlen(url); 26 struct ipv6_pxe_entry* ipe = malloc(sizeof(struct ipv6_pxe_entry) + url_len + 1); 27 if (!ipe) 28 return NULL; 29 30 memcpy(ipe->bootfile_url.payload, url, url_len + 1); 31 ipe->bootfile_url.len = htons(url_len); 32 ipe->bootfile_url.type = htons(DHCPV6_OPT_BOOTFILE_URL); 33 34 if (arch == 0xFFFFFFFF) { 35 ipv6_pxe_default = ipe; 36 } 37 else { 38 ipe->arch = arch; 39 list_add(&ipe->list, &ipv6_pxe_list); 40 } 41 42 return ipe; 43 } 44 45 const struct ipv6_pxe_entry* ipv6_pxe_of_arch(uint16_t arch) { 46 struct ipv6_pxe_entry* entry; 47 list_for_each_entry(entry, &ipv6_pxe_list, list) { 48 if (arch == entry->arch) 49 return entry; 50 } 51 52 return ipv6_pxe_default; 53 } 54 55 void ipv6_pxe_serve_boot_url(uint16_t arch, struct iovec* iov) { 56 const struct ipv6_pxe_entry* entry = ipv6_pxe_of_arch(arch); 57 58 if (entry == NULL) { 59 // No IPv6 PxE bootfile defined 60 iov->iov_base = NULL; 61 iov->iov_len = 0; 62 } 63 else { 64 iov->iov_base = (void*)&(entry->bootfile_url); 65 iov->iov_len = 4 + ntohs(entry->bootfile_url.len); 66 syslog(LOG_INFO, "Serve IPv6 PxE, arch = %d, url = %s", arch, entry->bootfile_url.payload); 67 } 68 } 69 70 void ipv6_pxe_dump(void) { 71 struct ipv6_pxe_entry* entry; 72 int count = 0; 73 74 if (ipv6_pxe_default) 75 count++; 76 77 list_for_each_entry(entry, &ipv6_pxe_list, list) { 78 count++; 79 } 80 81 if (count) { 82 syslog(LOG_INFO, "IPv6 PxE URLs:\n"); 83 84 list_for_each_entry(entry, &ipv6_pxe_list, list) { 85 syslog(LOG_INFO, " arch %04d = %s\n", entry->arch, entry->bootfile_url.payload); 86 } 87 88 if (ipv6_pxe_default) 89 syslog(LOG_INFO, " Default = %s\n", ipv6_pxe_default->bootfile_url.payload); 90 } 91 } 92 93 void ipv6_pxe_clear(void) { 94 struct ipv6_pxe_entry* entry, * temp; 95 list_for_each_entry_safe(entry, temp, &ipv6_pxe_list, list) { 96 list_del(&entry->list); 97 free(entry); 98 } 99 100 if (ipv6_pxe_default) { 101 free(ipv6_pxe_default); 102 ipv6_pxe_default = NULL; 103 } 104 } 105
This page was automatically generated by LXR 0.3.1. • OpenWrt