• 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 _o_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                 /* The "default" entry lives outside ipv6_pxe_list; if config
 36                  * already supplied one (e.g. two boot6 sections without an
 37                  * arch), free the previous one before replacing it, otherwise
 38                  * it would leak until ipv6_pxe_clear() runs. */
 39                 free(ipv6_pxe_default);
 40                 ipv6_pxe_default = ipe;
 41         }
 42         else {
 43                 ipe->arch = arch;
 44                 list_add(&ipe->list, &ipv6_pxe_list);
 45         }
 46 
 47         return ipe;
 48 }
 49 
 50 const struct ipv6_pxe_entry* ipv6_pxe_of_arch(uint16_t arch) {
 51         struct ipv6_pxe_entry* entry;
 52         list_for_each_entry(entry, &ipv6_pxe_list, list) {
 53                 if (arch == entry->arch)
 54                         return entry;
 55         }
 56 
 57         return ipv6_pxe_default;
 58 }
 59 
 60 void ipv6_pxe_serve_boot_url(uint16_t arch, struct iovec* iov) {
 61         const struct ipv6_pxe_entry* entry = ipv6_pxe_of_arch(arch);
 62 
 63         if (entry == NULL) {
 64                 // No IPv6 PxE bootfile defined
 65                 iov->iov_base = NULL;
 66                 iov->iov_len = 0;
 67         }
 68         else {
 69                 iov->iov_base = (void*)&(entry->bootfile_url);
 70                 iov->iov_len = 4 + ntohs(entry->bootfile_url.len);
 71                 info("Serve IPv6 PxE, arch = %d, url = %s", arch, entry->bootfile_url.payload);
 72         }
 73 }
 74 
 75 void ipv6_pxe_dump(void) {
 76         struct ipv6_pxe_entry* entry;
 77         int count = 0;
 78 
 79         if (ipv6_pxe_default)
 80                 count++;
 81 
 82         list_for_each_entry(entry, &ipv6_pxe_list, list) {
 83                 count++;
 84         }
 85 
 86         if (count) {
 87                 info("IPv6 PxE URLs:\n");
 88 
 89                 list_for_each_entry(entry, &ipv6_pxe_list, list)
 90                         info("\tarch %04d = %s\n", entry->arch, entry->bootfile_url.payload);
 91 
 92                 if (ipv6_pxe_default)
 93                         info("\tDefault   = %s\n", ipv6_pxe_default->bootfile_url.payload);
 94         }
 95 }
 96 
 97 void ipv6_pxe_clear(void) {
 98         struct ipv6_pxe_entry* entry, * temp;
 99         list_for_each_entry_safe(entry, temp, &ipv6_pxe_list, list) {
100                 list_del(&entry->list);
101                 free(entry);
102         }
103 
104         if (ipv6_pxe_default) {
105                 free(ipv6_pxe_default);
106                 ipv6_pxe_default = NULL;
107         }
108 }
109 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt