/*
 * setters.c
 * This file is part of Network-inador
 *
 * Copyright (C) 2025 - Félix Arreola Rodríguez
 *
 * Network-inador is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Network-inador is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Network-inador; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 * Boston, MA  02110-1301  USA
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include <arpa/inet.h>

#include "network-inador-private.h"
#include "flist.h"
#include "routes.h"
#include "resolv_conf_defs.h"

void *network_inador_route_append_nexthop (void *list, uint8_t family, void *gw, uint32_t out_iface, uint8_t weight, uint8_t flags) {
	RouteNH *nexthop;
	int family_size;
	
	nexthop = (RouteNH *) malloc (sizeof (RouteNH));
	memset (nexthop, 0, sizeof (RouteNH));
	
	if (family == AF_INET) {
		family_size = sizeof (struct in_addr);
	} else if (family == AF_INET6) {
		family_size = sizeof (struct in6_addr);
	}
	
	nexthop->family = family;
	if (gw != NULL) {
		nexthop->has_gw = 1;
		
		memcpy (&nexthop->gw, gw, family_size);
	}
	
	memcpy (&nexthop->out_index, &out_iface, 4);
	nexthop->nh_weight = weight;
	nexthop->nh_flags = flags;
	
	list = f_list_append (list, nexthop);
	
	return list;
}

void network_inador_route_free_all_nexthops (void *list) {
	f_list_free_full ((FList *) list, free);
}

void *network_inador_resolvconf_append_ns_entry (void *list, int family, void *addr, int iface_index, const char *owner_prog) {
	ResolvConfEntry *entry;
	int family_size;
	
	entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
	memset (entry, 0, sizeof (ResolvConfEntry));
	
	if (family == AF_INET) {
		family_size = sizeof (struct in_addr);
	} else if (family == AF_INET6) {
		family_size = sizeof (struct in6_addr);
	}
	
	entry->resolv_type = RESOLV_TYPE_NAMESERVER;
	entry->origin = RESOLV_ORIGIN_RESOLVCONF;
	entry->ns_family = family;
	
	memcpy (&entry->nameserver, addr, family_size);
	inet_ntop (family, addr, entry->value, sizeof (entry->value));
	
	entry->owner_interface_index = iface_index;
	strncpy (entry->owner_prog, owner_prog, sizeof (entry->owner_prog));
	
	list = f_list_append (list, entry);
	
	return list;
}

void network_inador_resolvconf_free_all_entries (void *list) {
	f_list_free_full ((FList *) list, free);
}