• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/odhcpd/src/dhcpv6-pxe.c

  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