580 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			580 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
| /* Copyright 2021 Google LLC
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
|       http://www.apache.org/licenses/LICENSE-2.0
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| #include "dnsmasq.h"
 | |
| 
 | |
| extern void fuzz_blockdata_cleanup();
 | |
| 
 | |
| // Simple garbage collector 
 | |
| #define GB_SIZE 100
 | |
| 
 | |
| void *pointer_arr[GB_SIZE];
 | |
| static int pointer_idx = 0;
 | |
| 
 | |
| // If the garbage collector is used then this must be called as first thing
 | |
| // during a fuzz run.
 | |
| void gb_init() {
 | |
|   pointer_idx = 0;
 | |
| 
 | |
|    for (int i = 0; i < GB_SIZE; i++) {
 | |
|      pointer_arr[i] = NULL;
 | |
|    }
 | |
| }
 | |
| 
 | |
| void gb_cleanup() {
 | |
|   for(int i = 0; i < GB_SIZE; i++) {
 | |
|     if (pointer_arr[i] != NULL) {
 | |
|       free(pointer_arr[i]);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| char *get_null_terminated(const uint8_t **data, size_t *size) {
 | |
| #define STR_SIZE 75
 | |
|   if (*size < STR_SIZE || (int)*size < 0) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   char *new_s = malloc(STR_SIZE + 1);
 | |
|   memcpy(new_s, *data, STR_SIZE);
 | |
|   new_s[STR_SIZE] = '\0';
 | |
| 
 | |
|   *data = *data+STR_SIZE;
 | |
|   *size -= STR_SIZE;
 | |
|   return new_s;
 | |
| }
 | |
| 
 | |
| char *gb_get_random_data(const uint8_t **data, size_t *size, size_t to_get) {
 | |
|   if (*size < to_get || (int)*size < 0) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   char *new_s = malloc(to_get);
 | |
|   memcpy(new_s, *data, to_get);
 | |
| 
 | |
|   pointer_arr[pointer_idx++] = (void*)new_s;
 | |
|   
 | |
|   *data = *data + to_get;
 | |
|   *size -= to_get;
 | |
| 
 | |
|   return new_s;
 | |
| }
 | |
| 
 | |
| char *gb_get_null_terminated(const uint8_t **data, size_t *size) {
 | |
| 
 | |
|   char *nstr = get_null_terminated(data, size);
 | |
|   if (nstr == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
|   pointer_arr[pointer_idx++] = (void*)nstr;
 | |
|   return nstr;
 | |
| }
 | |
| 
 | |
| char *gb_alloc_data(size_t len) {
 | |
|   char *ptr = calloc(1, len);
 | |
|   pointer_arr[pointer_idx++] = (void*)ptr;
 | |
|   
 | |
|   return ptr;
 | |
| }
 | |
| 
 | |
| short get_short(const uint8_t **data, size_t *size) {
 | |
|   if (*size <= 0) return 0;
 | |
|   short c = (short)(*data)[0];
 | |
|   *data += 1;
 | |
|   *size-=1;
 | |
|   return c;
 | |
| }
 | |
| 
 | |
| int get_int(const uint8_t **data, size_t *size) {
 | |
|   if (*size <= 4) return 0;
 | |
|   const uint8_t *ptr = *data;
 | |
|   int val = *((int*)ptr);
 | |
|   *data += 4;
 | |
|   *size -= 4;
 | |
|   return val;
 | |
| }
 | |
| // end simple garbage collector.
 | |
| 
 | |
| const uint8_t *syscall_data = NULL;
 | |
| size_t syscall_size = 0;
 | |
| 
 | |
| 
 | |
| int fuzz_ioctl(int fd, unsigned long request, void *arg) {
 | |
|   int fd2 = fd;
 | |
|   unsigned long request2 = request;
 | |
|   void *arg_ptr = arg;
 | |
| 
 | |
|   // SIOCGSTAMP
 | |
|   if (request == SIOCGSTAMP) {
 | |
|     struct timeval *tv = (struct timeval*)arg_ptr;
 | |
|     if (tv == NULL) {
 | |
|       return 0;
 | |
|     }
 | |
| 
 | |
|     char *rand_tv = gb_get_random_data(&syscall_data, &syscall_size, sizeof(struct timeval));
 | |
|     if (rand_tv == NULL) {
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|     memcpy(tv, rand_tv, sizeof(struct timeval));
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   if (request == SIOCGIFNAME) {
 | |
|     //printf("We got a SIOCGIFNAME\n");
 | |
|     struct ifreq *ifr = (struct ifreq*)arg_ptr;
 | |
|     if (ifr == NULL) {
 | |
|       return -1;
 | |
|     }
 | |
|     for (int i = 0; i < IF_NAMESIZE; i++) {
 | |
|       if (syscall_size > 0 && syscall_data != NULL) {
 | |
|         ifr->ifr_name[i] = (char)*syscall_data;
 | |
|         syscall_data += 1;
 | |
|         syscall_size -= 1;
 | |
|       }
 | |
|       else {
 | |
|         ifr->ifr_name[i] = 'A';
 | |
|       }
 | |
|     }
 | |
|     ifr->ifr_name[IF_NAMESIZE-1] = '\0';
 | |
|     return 0;
 | |
|     //return -1;
 | |
|   }
 | |
|   if (request == SIOCGIFFLAGS) {
 | |
|     return 0;
 | |
|   }
 | |
|   if (request == SIOCGIFADDR) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   // 
 | |
|   int retval = ioctl(fd2, request2, arg_ptr); 
 | |
|   return retval;
 | |
| }
 | |
| 
 | |
| 
 | |
| // Sysytem call wrappers
 | |
| static char v = 0;
 | |
| ssize_t fuzz_recvmsg(int sockfd, struct msghdr *msg, int flags) {
 | |
|   
 | |
|   struct iovec *target = msg->msg_iov;
 | |
| 
 | |
|   //printf("recvmsg 1 \n");
 | |
|   if (syscall_size > 1) {
 | |
|     char r = *syscall_data;
 | |
|     syscall_data += 1;
 | |
|     syscall_size -= 1;
 | |
| 
 | |
|     if (r == 12) {
 | |
|       //printf("recvmsg 2\n");
 | |
|       return -1;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   int j = 0;
 | |
|   if (msg->msg_control != NULL) {
 | |
|     for (;j < CMSG_SPACE(sizeof(struct in_pktinfo)); j++)
 | |
|     {
 | |
|       if (syscall_size > 0 && syscall_data != NULL) {
 | |
|         ((char*)msg->msg_control)[j] = *syscall_data;
 | |
|         syscall_data += 1;
 | |
|         syscall_size -= 1;
 | |
|       }
 | |
|       else {
 | |
|         ((char*)msg->msg_control)[j] = 'A';
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   int i = 0;
 | |
|   for (; i < target->iov_len; i++) {
 | |
|     if (syscall_size > 0 && syscall_data != NULL) {
 | |
|       ((char*)target->iov_base)[i] = *syscall_data;
 | |
|       syscall_data += 1;
 | |
|       syscall_size -= 1;
 | |
|     }
 | |
|     else {
 | |
|       ((char*)target->iov_base)[i] = 'A';
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (msg->msg_namelen > 0) {
 | |
|     memset(msg->msg_name, 0, msg->msg_namelen);
 | |
|   }
 | |
| 
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| 
 | |
| // dnsmasq specific stuff
 | |
| int init_daemon(const uint8_t **data2, size_t *size2) {
 | |
|   const uint8_t *data = *data2;
 | |
|   size_t size = *size2;
 | |
| 
 | |
|   int retval = 0;
 | |
| 
 | |
| #define CLEAN_IF_NULL(arg) if (arg == NULL) goto cleanup;
 | |
| 
 | |
|   // Initialize daemon
 | |
|   daemon = (struct daemon*)gb_alloc_data(sizeof(struct daemon));
 | |
|   CLEAN_IF_NULL(daemon)
 | |
| 
 | |
|   // daemon misc
 | |
|   daemon->max_ttl = get_int(&data, &size);
 | |
|   daemon->neg_ttl = get_int(&data, &size);
 | |
|   daemon->local_ttl = get_int(&data, &size);
 | |
|   daemon->min_cache_ttl = get_int(&data, &size);
 | |
| 
 | |
|   // daemon->namebuff.
 | |
|   char *daemon_namebuff = gb_get_null_terminated(&data, &size);
 | |
|   daemon->namebuff = daemon_namebuff;
 | |
| 
 | |
|   // daemon->naptr
 | |
|   struct naptr *naptr_ptr = (struct naptr*)gb_alloc_data(sizeof(struct naptr));
 | |
|   char *naptr_name = gb_get_null_terminated(&data, &size);
 | |
|   char *naptr_replace = gb_get_null_terminated(&data, &size);
 | |
|   char *naptr_regexp = gb_get_null_terminated(&data, &size);
 | |
|   char *naptr_services = gb_get_null_terminated(&data, &size);
 | |
|   char *naptr_flags = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(naptr_ptr)
 | |
|   CLEAN_IF_NULL(naptr_name)
 | |
|   CLEAN_IF_NULL(naptr_replace)
 | |
|   CLEAN_IF_NULL(naptr_regexp)
 | |
|   CLEAN_IF_NULL(naptr_services)
 | |
|   CLEAN_IF_NULL(naptr_flags)
 | |
| 
 | |
|   naptr_ptr->name = naptr_name;
 | |
|   naptr_ptr->replace = naptr_replace;
 | |
|   naptr_ptr->regexp = naptr_regexp;
 | |
|   naptr_ptr->services = naptr_services;
 | |
|   naptr_ptr->flags = naptr_flags;
 | |
| 
 | |
|   daemon->naptr = naptr_ptr;
 | |
| 
 | |
|   // daemon->int_names
 | |
|   struct interface_name *int_namses = (struct interface_name*)gb_alloc_data(sizeof(struct interface_name));
 | |
| 
 | |
|   char *int_name = gb_get_null_terminated(&data, &size);
 | |
|   char *int_intr = gb_get_null_terminated(&data, &size);
 | |
|   CLEAN_IF_NULL(int_namses)
 | |
|   CLEAN_IF_NULL(int_name)
 | |
|   CLEAN_IF_NULL(int_intr)
 | |
|   int_namses->name = int_name;
 | |
|   int_namses->intr = int_intr;
 | |
| 
 | |
|   struct addrlist *d_addrlist = (struct addrlist*)gb_alloc_data(sizeof(struct addrlist));
 | |
|   CLEAN_IF_NULL(d_addrlist)
 | |
|   d_addrlist->flags = get_int(&data, &size);
 | |
|   d_addrlist->prefixlen = get_int(&data, &size);
 | |
|   int_namses->addr = d_addrlist;
 | |
| 
 | |
|   daemon->int_names = int_namses;
 | |
| 
 | |
|   if (size > *size2) {
 | |
|     goto cleanup;
 | |
|   }
 | |
| 
 | |
|   // daemon->addrbuf
 | |
|   char *adbuf = gb_alloc_data(200);
 | |
|   CLEAN_IF_NULL(adbuf)
 | |
|   daemon->addrbuff = adbuf;
 | |
| 
 | |
|   // daemon->auth_zones
 | |
|   struct auth_zone *d_az = (struct auth_zone*)gb_alloc_data(sizeof(struct auth_zone));
 | |
|   char *auth_domain = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(d_az)
 | |
|   CLEAN_IF_NULL(auth_domain)
 | |
|   d_az->domain = auth_domain;
 | |
|   daemon->auth_zones = d_az;
 | |
| 
 | |
|   // deamon->mxnames
 | |
|   struct mx_srv_record *mx_srv_rec = (struct mx_srv_record*)gb_alloc_data(sizeof(struct mx_srv_record));
 | |
|   char *mx_name = gb_get_null_terminated(&data, &size);
 | |
|   char *mx_target = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(mx_srv_rec)
 | |
|   CLEAN_IF_NULL(mx_target)
 | |
|   CLEAN_IF_NULL(mx_name)
 | |
| 
 | |
|   mx_srv_rec->next = daemon->mxnames;
 | |
|   daemon->mxnames = mx_srv_rec;
 | |
|   mx_srv_rec->name = mx_name;
 | |
|   mx_srv_rec->target = mx_target;
 | |
|   mx_srv_rec->issrv = get_int(&data, &size);
 | |
|   mx_srv_rec->weight = get_int(&data, &size);
 | |
|   mx_srv_rec->priority = get_int(&data, &size);
 | |
|   mx_srv_rec->srvport = get_int(&data, &size);
 | |
|   //data += 40;
 | |
|   //size -= 40;
 | |
| 
 | |
|   if (size > *size2) {
 | |
|     goto cleanup;
 | |
|   }
 | |
| 
 | |
|   // daemon->txt
 | |
|   struct txt_record *txt_record = (struct txt_record *)gb_alloc_data(sizeof(struct txt_record));
 | |
|   char *txt_record_name =  gb_get_null_terminated(&data, &size);
 | |
|   char *txt_record_txt = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(txt_record)
 | |
|   CLEAN_IF_NULL(txt_record_name)
 | |
|   CLEAN_IF_NULL(txt_record_txt)
 | |
| 
 | |
|   txt_record->name = txt_record_name;
 | |
|   txt_record->txt = (unsigned char*)txt_record_txt;
 | |
|   txt_record->class2 = (get_short(&data, &size) % 10);
 | |
|   daemon->txt = txt_record;
 | |
| 
 | |
|   // daemon->rr
 | |
|   struct txt_record *rr_record = (struct txt_record *)gb_alloc_data(sizeof(struct txt_record));
 | |
|   char *rr_record_name =  gb_get_null_terminated(&data, &size);
 | |
|   char *rr_record_txt = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(rr_record)
 | |
|   CLEAN_IF_NULL(rr_record_name)
 | |
|   CLEAN_IF_NULL(rr_record_txt)
 | |
| 
 | |
|   rr_record->name = rr_record_name;
 | |
|   rr_record->txt = (unsigned char*)rr_record_txt;
 | |
|   rr_record->class2 = (get_short(&data, &size) % 10);
 | |
|   daemon->rr = rr_record;
 | |
| 
 | |
|   if (size > *size2) {
 | |
|     goto cleanup;
 | |
|   }
 | |
| 
 | |
|   // daemon->relay4
 | |
|   //struct dhcp_relay *dr = (struct dhcp_relay*)gb_alloc_data(sizeof(struct dhcp_relay));
 | |
|   struct dhcp_relay *dr = (struct dhcp_relay*)gb_get_random_data(&data, &size, sizeof(struct dhcp_relay));
 | |
|   char *dr_interface = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(dr)
 | |
|   CLEAN_IF_NULL(dr_interface)
 | |
|   dr->interface = dr_interface;
 | |
|   dr->next = NULL;
 | |
|   dr->current = NULL;
 | |
|   daemon->relay4 = dr;
 | |
| 
 | |
|   // deamon->bridges
 | |
|   struct dhcp_bridge *db = (struct dhcp_bridge*)gb_alloc_data(sizeof(struct dhcp_bridge));
 | |
|   char *db_interface = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(db)
 | |
|   CLEAN_IF_NULL(db_interface)
 | |
| 
 | |
|   if (strlen(db_interface) > IF_NAMESIZE) {
 | |
|     for (int i = 0; i < IF_NAMESIZE; i++) {
 | |
|       db->iface[i] = db_interface[i];
 | |
|     }
 | |
|   } else {
 | |
|     for (int i = 0; i < strlen(db_interface); i++) {
 | |
|       db->iface[i] = db_interface[i];
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
|   struct dhcp_bridge *db_alias = (struct dhcp_bridge*)gb_alloc_data(sizeof(struct dhcp_bridge));
 | |
|   //struct dhcp_bridge *db_alias = (struct dhcp_bridge*)gb_get_random_data(&data, &size, sizeof(struct dhcp_bridge));
 | |
|   char *db_alias_interface = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(db_alias)
 | |
|   CLEAN_IF_NULL(db_alias_interface)
 | |
| 
 | |
|   if (strlen(db_alias_interface) > IF_NAMESIZE) {
 | |
|     for (int i = 0; i < IF_NAMESIZE; i++) {
 | |
|       db_alias->iface[i] = db_alias_interface[i];
 | |
|     }
 | |
|   } else {
 | |
|     for (int i = 0; i < strlen(db_alias_interface); i++) {
 | |
|       db_alias->iface[i] = db_alias_interface[i];
 | |
|     }
 | |
|   }
 | |
|   db->alias = db_alias;
 | |
|   daemon->bridges = db;
 | |
| 
 | |
|   // daemon->if_names
 | |
|   struct iname *in = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
 | |
|   char *iname_name = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(in)
 | |
|   CLEAN_IF_NULL(iname_name)
 | |
| 
 | |
|   in->name = iname_name;
 | |
|   in->next = NULL;
 | |
| 
 | |
|   daemon->if_names = in;
 | |
| 
 | |
|   // daemon->if_addrs
 | |
|   struct iname *in_addr = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
 | |
|   char *iname_name_addr = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(in_addr)
 | |
|   CLEAN_IF_NULL(iname_name_addr)
 | |
| 
 | |
|   in_addr->name = iname_name_addr;
 | |
|   in_addr->next = NULL;
 | |
| 
 | |
|   daemon->if_addrs = in_addr;
 | |
| 
 | |
|   // daemon->if_except
 | |
|   struct iname *in_except = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
 | |
|   char *iname_name_except = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(in_except)
 | |
|   CLEAN_IF_NULL(iname_name_except)
 | |
| 
 | |
|   in_except->name = iname_name_except;
 | |
|   in_except->next = NULL;
 | |
| 
 | |
|   daemon->if_except = in_except;
 | |
| 
 | |
|   // daemon->dhcp_except
 | |
|   struct iname *except = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
 | |
|   char *name_except = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(except)
 | |
|   CLEAN_IF_NULL(name_except)
 | |
| 
 | |
|   except->name = name_except;
 | |
|   except->next = NULL;
 | |
| 
 | |
|   daemon->dhcp_except = except;
 | |
| 
 | |
|   // daemon->authinterface
 | |
|   struct iname *auth_interface = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
 | |
|   char *auth_name = gb_get_null_terminated(&data, &size);
 | |
|   
 | |
|   CLEAN_IF_NULL(auth_interface)
 | |
|   CLEAN_IF_NULL(auth_name)
 | |
| 
 | |
|   auth_interface->name = auth_name;
 | |
|   auth_interface->next = NULL;
 | |
| 
 | |
|   daemon->authinterface = auth_interface;
 | |
| 
 | |
| 
 | |
|   // daemon->cnames
 | |
|   struct cname *cn = (struct cname*)gb_alloc_data(sizeof(struct cname));
 | |
|   char *cname_alias = gb_get_null_terminated(&data, &size);
 | |
|   char *cname_target = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(cn)
 | |
|   CLEAN_IF_NULL(cname_alias)
 | |
|   CLEAN_IF_NULL(cname_target)
 | |
| 
 | |
|   cn->alias = cname_alias;
 | |
|   cn->target = cname_target;
 | |
|   daemon->cnames = cn;
 | |
| 
 | |
| 
 | |
|   // daemon->ptr
 | |
|   struct ptr_record *ptr = (struct ptr_record *)gb_alloc_data(sizeof(struct ptr_record));
 | |
|   CLEAN_IF_NULL(ptr)
 | |
| 
 | |
|   char *ptr_name = gb_get_null_terminated(&data, &size);
 | |
|   CLEAN_IF_NULL(ptr_name)
 | |
|   ptr->name = ptr_name;
 | |
|   daemon->ptr = ptr;
 | |
| 
 | |
|   if (size > *size2) {
 | |
|     goto cleanup;
 | |
|   }
 | |
| 
 | |
|   // daemon->dhcp
 | |
|   struct dhcp_context *dhcp_c = (struct dhcp_context *) gb_get_random_data(&data, &size, sizeof(struct dhcp_context));
 | |
|   
 | |
|   char *dhcp_c_temp_in = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   struct dhcp_netid *dhcp_c_netid = (struct dhcp_netid *) gb_alloc_data(sizeof(struct dhcp_netid));
 | |
|   char *dhcp_netid_net = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(dhcp_c)
 | |
|   CLEAN_IF_NULL(dhcp_c_temp_in)
 | |
|   CLEAN_IF_NULL(dhcp_c_netid)
 | |
|   CLEAN_IF_NULL(dhcp_netid_net)
 | |
| 
 | |
|   dhcp_c->next = NULL;
 | |
|   dhcp_c->current = NULL;
 | |
|   dhcp_c_netid->net = dhcp_netid_net;
 | |
|   dhcp_c->filter = dhcp_c_netid;
 | |
|   dhcp_c->template_interface = dhcp_c_temp_in;
 | |
| 
 | |
|   daemon->dhcp = dhcp_c;
 | |
| 
 | |
| 
 | |
|   // daemon->dhcp6
 | |
|   struct dhcp_context *dhcp6_c = (struct dhcp_context *) gb_get_random_data(&data, &size, sizeof(struct dhcp_context));
 | |
|   
 | |
|   char *dhcp6_c_temp_in = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   struct dhcp_netid *dhcp6_c_netid = (struct dhcp_netid *) gb_alloc_data(sizeof(struct dhcp_netid));
 | |
|   char *dhcp6_netid_net = gb_get_null_terminated(&data, &size);
 | |
| 
 | |
|   CLEAN_IF_NULL(dhcp6_c)
 | |
|   CLEAN_IF_NULL(dhcp6_c_temp_in)
 | |
|   CLEAN_IF_NULL(dhcp6_c_netid)
 | |
|   CLEAN_IF_NULL(dhcp6_netid_net)
 | |
| 
 | |
|   dhcp6_c->next = NULL;
 | |
|   dhcp6_c->current = NULL;
 | |
|   dhcp6_c_netid->net = dhcp6_netid_net;
 | |
|   dhcp6_c->filter = dhcp6_c_netid;
 | |
|   dhcp6_c->template_interface = dhcp6_c_temp_in;
 | |
| 
 | |
|   daemon->dhcp6 = dhcp6_c;
 | |
| 
 | |
|   // daemon->doing_dhcp6
 | |
|   daemon->doing_dhcp6 = 1;
 | |
| 
 | |
|   // daemon->dhcp_buffs
 | |
|   char *dhcp_buff = gb_alloc_data(DHCP_BUFF_SZ);
 | |
|   char *dhcp_buff2 = gb_alloc_data(DHCP_BUFF_SZ);
 | |
|   char *dhcp_buff3 = gb_alloc_data(DHCP_BUFF_SZ);
 | |
| 
 | |
|   CLEAN_IF_NULL(dhcp_buff)
 | |
|   CLEAN_IF_NULL(dhcp_buff2)
 | |
|   CLEAN_IF_NULL(dhcp_buff3)
 | |
| 
 | |
|   daemon->dhcp_buff = dhcp_buff;
 | |
|   daemon->dhcp_buff2 = dhcp_buff2;
 | |
|   daemon->dhcp_buff3 = dhcp_buff3;
 | |
| 
 | |
| 
 | |
| 
 | |
|   // daemon->ignore_addr
 | |
|   struct bogus_addr *bb = (struct bogus_addr *)gb_alloc_data(sizeof(struct bogus_addr));
 | |
|   CLEAN_IF_NULL(bb)
 | |
| 
 | |
|   daemon->ignore_addr = bb;
 | |
| 
 | |
|   // daemon->doctors
 | |
|   if (size > *size2) {
 | |
|     goto cleanup;
 | |
|   }
 | |
| 
 | |
|   struct doctor *doctors = (struct doctor *)gb_alloc_data(sizeof(struct doctor));
 | |
|   CLEAN_IF_NULL(doctors)
 | |
| 
 | |
|   doctors->next = NULL;
 | |
|   daemon->doctors = doctors;
 | |
| 
 | |
|   retval = 0;
 | |
|   goto ret;
 | |
| cleanup:
 | |
|   retval = -1;
 | |
| 
 | |
| ret:
 | |
|   return retval;
 | |
| }
 |