struct _GDHCPServer {
int ref_count;
GDHCPType type;
- gboolean started;
+ bool started;
int ifindex;
char *interface;
uint32_t start_ip;
uint32_t end_ip;
- uint32_t server_nip;
+ uint32_t server_nip; /* our address in network byte order */
uint32_t lease_seconds;
int listener_sockfd;
guint listener_watch;
GHashTable *nip_lease_hash;
GHashTable *option_hash; /* Options send to client */
GDHCPSaveLeaseFunc save_lease_func;
+ GDHCPLeaseAddedCb lease_added_cb;
GDHCPDebugFunc debug_func;
gpointer debug_data;
};
char str[256];
va_list ap;
- if (server->debug_func == NULL)
+ if (!server->debug_func)
return;
va_start(ap, format);
lease_mac = find_lease_by_mac(dhcp_server, mac);
lease_nip = g_hash_table_lookup(dhcp_server->nip_lease_hash,
- GINT_TO_POINTER((int) yiaddr));
+ GINT_TO_POINTER((int) ntohl(yiaddr)));
debug(dhcp_server, "lease_mac %p lease_nip %p", lease_mac, lease_nip);
- if (lease_nip != NULL) {
+ if (lease_nip) {
dhcp_server->lease_list =
g_list_remove(dhcp_server->lease_list,
lease_nip);
g_hash_table_remove(dhcp_server->nip_lease_hash,
- GINT_TO_POINTER((int) yiaddr));
+ GINT_TO_POINTER((int) ntohl(yiaddr)));
- if (lease_mac == NULL)
+ if (!lease_mac)
*lease = lease_nip;
else if (lease_nip != lease_mac) {
remove_lease(dhcp_server, lease_mac);
return 0;
}
- if (lease_mac != NULL) {
+ if (lease_mac) {
dhcp_server->lease_list =
g_list_remove(dhcp_server->lease_list,
lease_mac);
}
*lease = g_try_new0(struct dhcp_lease, 1);
- if (*lease == NULL)
+ if (!*lease)
return -ENOMEM;
return 0;
memset(lease, 0, sizeof(*lease));
memcpy(lease->lease_mac, chaddr, ETH_ALEN);
- lease->lease_nip = yiaddr;
+ lease->lease_nip = ntohl(yiaddr);
if (expire == 0)
lease->expire = time(NULL) + dhcp_server->lease_seconds;
}
/* Check if the IP is taken; if it is, add it to the lease table */
-static gboolean arp_check(uint32_t nip, const uint8_t *safe_mac)
+static bool arp_check(uint32_t nip, const uint8_t *safe_mac)
{
/* TODO: Add ARP checking */
- return TRUE;
+ return true;
}
-static gboolean is_expired_lease(struct dhcp_lease *lease)
+static bool is_expired_lease(struct dhcp_lease *lease)
{
if (lease->expire < time(NULL))
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static uint32_t find_free_or_expired_nip(GDHCPServer *dhcp_server,
if ((ip_addr & 0xff) == 0xff)
continue;
- lease = find_lease_by_nip(dhcp_server,
- (uint32_t) htonl(ip_addr));
- if (lease != NULL)
+ lease = find_lease_by_nip(dhcp_server, ip_addr);
+ if (lease)
continue;
- if (arp_check(htonl(ip_addr), safe_mac) == TRUE)
- return htonl(ip_addr);
+ if (arp_check(htonl(ip_addr), safe_mac))
+ return ip_addr;
}
/* The last lease is the oldest one */
list = g_list_last(dhcp_server->lease_list);
- if (list == NULL)
+ if (!list)
return 0;
lease = list->data;
- if (lease == NULL)
+ if (!lease)
return 0;
- if (is_expired_lease(lease) == FALSE)
+ if (!is_expired_lease(lease))
return 0;
- if (arp_check(lease->lease_nip, safe_mac) == FALSE)
+ if (!arp_check(lease->lease_nip, safe_mac))
return 0;
return lease->lease_nip;
}
dhcp_server = g_try_new0(GDHCPServer, 1);
- if (dhcp_server == NULL) {
+ if (!dhcp_server) {
*error = G_DHCP_SERVER_ERROR_NOMEM;
return NULL;
}
dhcp_server->interface = get_interface_name(ifindex);
- if (dhcp_server->interface == NULL) {
+ if (!dhcp_server->interface) {
*error = G_DHCP_SERVER_ERROR_INTERFACE_UNAVAILABLE;
goto error;
}
- if (interface_is_up(ifindex) == FALSE) {
+ if (!interface_is_up(ifindex)) {
*error = G_DHCP_SERVER_ERROR_INTERFACE_DOWN;
goto error;
}
dhcp_server->ref_count = 1;
dhcp_server->ifindex = ifindex;
dhcp_server->listener_sockfd = -1;
- dhcp_server->listener_watch = -1;
+ dhcp_server->listener_watch = 0;
dhcp_server->listener_channel = NULL;
dhcp_server->save_lease_func = NULL;
dhcp_server->debug_func = NULL;
type = dhcp_get_option(packet, DHCP_MESSAGE_TYPE);
- if (type == NULL)
+ if (!type)
return 0;
if (*type < DHCP_MINTYPE)
packet->flags = client_packet->flags;
packet->gateway_nip = client_packet->gateway_nip;
packet->ciaddr = client_packet->ciaddr;
- dhcp_add_simple_option(packet, DHCP_SERVER_ID, dhcp_server->server_nip);
+ dhcp_add_option_uint32(packet, DHCP_SERVER_ID,
+ ntohl(dhcp_server->server_nip));
}
static void add_option(gpointer key, gpointer value, gpointer user_data)
struct in_addr nip;
struct dhcp_packet *packet = user_data;
- if (option_value == NULL)
+ if (!option_value)
return;
switch (option_code) {
if (inet_aton(option_value, &nip) == 0)
return;
- dhcp_add_simple_option(packet, (uint8_t) option_code,
- nip.s_addr);
+ dhcp_add_option_uint32(packet, (uint8_t) option_code,
+ ntohl(nip.s_addr));
break;
default:
return;
add_option, packet);
}
-static gboolean check_requested_nip(GDHCPServer *dhcp_server,
+static bool check_requested_nip(GDHCPServer *dhcp_server,
uint32_t requested_nip)
{
struct dhcp_lease *lease;
if (requested_nip == 0)
- return FALSE;
+ return false;
- if (ntohl(requested_nip) < dhcp_server->start_ip)
- return FALSE;
+ if (requested_nip < dhcp_server->start_ip)
+ return false;
- if (ntohl(requested_nip) > dhcp_server->end_ip)
- return FALSE;
+ if (requested_nip > dhcp_server->end_ip)
+ return false;
lease = find_lease_by_nip(dhcp_server, requested_nip);
- if (lease == NULL)
- return TRUE;
+ if (!lease)
+ return true;
- if (is_expired_lease(lease) == FALSE)
- return FALSE;
+ if (!is_expired_lease(lease))
+ return false;
- return TRUE;
+ return true;
}
static void send_packet_to_client(GDHCPServer *dhcp_server,
dhcp_send_raw_packet(dhcp_pkt,
dhcp_server->server_nip, SERVER_PORT,
ciaddr, CLIENT_PORT, chaddr,
- dhcp_server->ifindex);
+ dhcp_server->ifindex, false);
}
static void send_offer(GDHCPServer *dhcp_server,
init_packet(dhcp_server, &packet, client_packet, DHCPOFFER);
if (lease)
- packet.yiaddr = lease->lease_nip;
- else if (check_requested_nip(dhcp_server, requested_nip) == TRUE)
- packet.yiaddr = requested_nip;
+ packet.yiaddr = htonl(lease->lease_nip);
+ else if (check_requested_nip(dhcp_server, requested_nip))
+ packet.yiaddr = htonl(requested_nip);
else
- packet.yiaddr = find_free_or_expired_nip(
- dhcp_server, client_packet->chaddr);
+ packet.yiaddr = htonl(find_free_or_expired_nip(
+ dhcp_server, client_packet->chaddr));
debug(dhcp_server, "find yiaddr %u", packet.yiaddr);
lease = add_lease(dhcp_server, OFFER_TIME,
packet.chaddr, packet.yiaddr);
- if (lease == NULL) {
+ if (!lease) {
debug(dhcp_server,
"Err: No free IP addresses. OFFER abandoned");
return;
}
- dhcp_add_simple_option(&packet, DHCP_LEASE_TIME,
- htonl(dhcp_server->lease_seconds));
+ dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME,
+ dhcp_server->lease_seconds);
add_server_options(dhcp_server, &packet);
addr.s_addr = packet.yiaddr;
{
GList *list;
- if (dhcp_server->save_lease_func == NULL)
+ if (!dhcp_server->save_lease_func)
return;
for (list = dhcp_server->lease_list; list; list = list->next) {
}
static void send_ACK(GDHCPServer *dhcp_server,
- struct dhcp_packet *client_packet, uint32_t yiaddr)
+ struct dhcp_packet *client_packet, uint32_t dest)
{
struct dhcp_packet packet;
uint32_t lease_time_sec;
struct in_addr addr;
init_packet(dhcp_server, &packet, client_packet, DHCPACK);
- packet.yiaddr = yiaddr;
+ packet.yiaddr = htonl(dest);
lease_time_sec = dhcp_server->lease_seconds;
- dhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));
+ dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME, lease_time_sec);
add_server_options(dhcp_server, &packet);
- addr.s_addr = yiaddr;
+ addr.s_addr = htonl(dest);
debug(dhcp_server, "Sending ACK to %s", inet_ntoa(addr));
send_packet_to_client(dhcp_server, &packet);
add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);
+
+ if (dhcp_server->lease_added_cb)
+ dhcp_server->lease_added_cb(packet.chaddr, packet.yiaddr);
}
static void send_NAK(GDHCPServer *dhcp_server,
dhcp_send_raw_packet(&packet,
dhcp_server->server_nip, SERVER_PORT,
INADDR_BROADCAST, CLIENT_PORT, MAC_BCAST_ADDR,
- dhcp_server->ifindex);
+ dhcp_server->ifindex, false);
}
static void send_inform(GDHCPServer *dhcp_server,
server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID);
if (server_id_option) {
- uint32_t server_nid = dhcp_get_unaligned(
- (uint32_t *) server_id_option);
+ uint32_t server_nid =
+ get_unaligned((const uint32_t *) server_id_option);
if (server_nid != dhcp_server->server_nip)
return TRUE;
request_ip_option = dhcp_get_option(&packet, DHCP_REQUESTED_IP);
if (request_ip_option)
- requested_nip = dhcp_get_unaligned(
- (uint32_t *) request_ip_option);
+ requested_nip = get_be32(request_ip_option);
lease = find_lease_by_mac(dhcp_server, packet.chaddr);
switch (type) {
- case DHCPDISCOVER:
- debug(dhcp_server, "Received DISCOVER");
+ case DHCPDISCOVER:
+ debug(dhcp_server, "Received DISCOVER");
- send_offer(dhcp_server, &packet, lease, requested_nip);
+ send_offer(dhcp_server, &packet, lease, requested_nip);
break;
- case DHCPREQUEST:
- debug(dhcp_server, "Received REQUEST NIP %d",
+ case DHCPREQUEST:
+ debug(dhcp_server, "Received REQUEST NIP %d",
requested_nip);
- if (requested_nip == 0) {
- requested_nip = packet.ciaddr;
- if (requested_nip == 0)
- break;
- }
-
- if (lease && requested_nip == lease->lease_nip) {
- debug(dhcp_server, "Sending ACK");
- send_ACK(dhcp_server, &packet,
- lease->lease_nip);
+ if (requested_nip == 0) {
+ requested_nip = ntohl(packet.ciaddr);
+ if (requested_nip == 0)
break;
- }
+ }
+
+ if (lease && requested_nip == lease->lease_nip) {
+ debug(dhcp_server, "Sending ACK");
+ send_ACK(dhcp_server, &packet,
+ lease->lease_nip);
+ break;
+ }
- if (server_id_option || lease == NULL) {
- debug(dhcp_server, "Sending NAK");
- send_NAK(dhcp_server, &packet);
- }
+ if (server_id_option || !lease) {
+ debug(dhcp_server, "Sending NAK");
+ send_NAK(dhcp_server, &packet);
+ }
break;
- case DHCPDECLINE:
- debug(dhcp_server, "Received DECLINE");
+ case DHCPDECLINE:
+ debug(dhcp_server, "Received DECLINE");
- if (server_id_option == NULL)
- break;
+ if (!server_id_option)
+ break;
- if (request_ip_option == NULL)
- break;
+ if (!request_ip_option)
+ break;
- if (lease == NULL)
- break;
+ if (!lease)
+ break;
- if (requested_nip == lease->lease_nip)
- remove_lease(dhcp_server, lease);
+ if (requested_nip == lease->lease_nip)
+ remove_lease(dhcp_server, lease);
break;
- case DHCPRELEASE:
- debug(dhcp_server, "Received RELEASE");
+ case DHCPRELEASE:
+ debug(dhcp_server, "Received RELEASE");
- if (server_id_option == NULL)
- break;
+ if (!server_id_option)
+ break;
- if (lease == NULL)
- break;
+ if (!lease)
+ break;
- if (packet.ciaddr == lease->lease_nip)
- lease_set_expire(dhcp_server, lease,
- time(NULL));
+ if (packet.ciaddr == lease->lease_nip)
+ lease_set_expire(dhcp_server, lease,
+ time(NULL));
break;
- case DHCPINFORM:
- debug(dhcp_server, "Received INFORM");
- send_inform(dhcp_server, &packet);
+ case DHCPINFORM:
+ debug(dhcp_server, "Received INFORM");
+ send_inform(dhcp_server, &packet);
break;
}
GIOChannel *listener_channel;
int listener_sockfd;
- if (dhcp_server->started == TRUE)
+ if (dhcp_server->started)
return 0;
listener_sockfd = dhcp_l3_socket(SERVER_PORT,
return -EIO;
listener_channel = g_io_channel_unix_new(listener_sockfd);
- if (listener_channel == NULL) {
+ if (!listener_channel) {
close(listener_sockfd);
return -EIO;
}
{
struct in_addr nip;
- if (option_value == NULL)
+ if (!option_value)
return -EINVAL;
debug(dhcp_server, "option_code %d option_value %s",
void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
GDHCPSaveLeaseFunc func, gpointer user_data)
{
- if (dhcp_server == NULL)
+ if (!dhcp_server)
return;
dhcp_server->save_lease_func = func;
}
+void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server,
+ GDHCPLeaseAddedCb cb)
+{
+ if (!dhcp_server)
+ return;
+
+ dhcp_server->lease_added_cb = cb;
+}
+
GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server)
{
- if (dhcp_server == NULL)
+ if (!dhcp_server)
return NULL;
__sync_fetch_and_add(&dhcp_server->ref_count, 1);
void g_dhcp_server_unref(GDHCPServer *dhcp_server)
{
- if (dhcp_server == NULL)
+ if (!dhcp_server)
return;
if (__sync_fetch_and_sub(&dhcp_server->ref_count, 1) != 1)
return 0;
}
-void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server, unsigned int lease_time)
+void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
+ unsigned int lease_time)
{
- if (dhcp_server == NULL)
+ if (!dhcp_server)
return;
dhcp_server->lease_seconds = lease_time;
void g_dhcp_server_set_debug(GDHCPServer *dhcp_server,
GDHCPDebugFunc func, gpointer user_data)
{
- if (dhcp_server == NULL)
+ if (!dhcp_server)
return;
dhcp_server->debug_func = func;