X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdhcp%2Fserver.c;h=52ea2a55b23091cdc9fd38d3c13ccd2e7f92a2d6;hb=cbc442527ed68fe86c882fd66aa1815124ec27dc;hp=a342985c9c88e2d8fb3bd07e670d2c1b9564b0ff;hpb=df3f9d6c21d9fa44ca1d8a419c2fcf69a05a2c84;p=platform%2Fupstream%2Fconnman.git diff --git a/gdhcp/server.c b/gdhcp/server.c old mode 100644 new mode 100755 index a342985..52ea2a5 --- a/gdhcp/server.c +++ b/gdhcp/server.c @@ -51,12 +51,12 @@ 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; @@ -65,6 +65,7 @@ struct _GDHCPServer { 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; }; @@ -80,7 +81,7 @@ static inline void debug(GDHCPServer *server, const char *format, ...) char str[256]; va_list ap; - if (server->debug_func == NULL) + if (!server->debug_func) return; va_start(ap, format); @@ -140,17 +141,17 @@ static int get_lease(GDHCPServer *dhcp_server, uint32_t yiaddr, 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); @@ -161,7 +162,7 @@ static int get_lease(GDHCPServer *dhcp_server, uint32_t yiaddr, return 0; } - if (lease_mac != NULL) { + if (lease_mac) { dhcp_server->lease_list = g_list_remove(dhcp_server->lease_list, lease_mac); @@ -173,7 +174,7 @@ static int get_lease(GDHCPServer *dhcp_server, uint32_t yiaddr, } *lease = g_try_new0(struct dhcp_lease, 1); - if (*lease == NULL) + if (!*lease) return -ENOMEM; return 0; @@ -200,7 +201,7 @@ static struct dhcp_lease *add_lease(GDHCPServer *dhcp_server, uint32_t expire, 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; @@ -224,18 +225,18 @@ static struct dhcp_lease *find_lease_by_nip(GDHCPServer *dhcp_server, } /* 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, @@ -254,28 +255,27 @@ 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; @@ -358,18 +358,18 @@ GDHCPServer *g_dhcp_server_new(GDHCPType type, } 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; } @@ -396,7 +396,7 @@ GDHCPServer *g_dhcp_server_new(GDHCPType type, 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; @@ -413,7 +413,7 @@ error: } -static uint8_t check_packet_type(struct dhcp_packet *packet) +static uint8_t check_packet_type(struct dhcp_packet *packet, uint16_t packet_len) { uint8_t *type; @@ -423,9 +423,9 @@ static uint8_t check_packet_type(struct dhcp_packet *packet) if (packet->op != BOOTREQUEST) return 0; - type = dhcp_get_option(packet, DHCP_MESSAGE_TYPE); + type = dhcp_get_option(packet, packet_len, DHCP_MESSAGE_TYPE); - if (type == NULL) + if (!type) return 0; if (*type < DHCP_MINTYPE) @@ -450,7 +450,8 @@ static void init_packet(GDHCPServer *dhcp_server, struct dhcp_packet *packet, 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) @@ -460,7 +461,7 @@ 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) { @@ -470,8 +471,8 @@ static void add_option(gpointer key, gpointer value, gpointer user_data) 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; @@ -485,28 +486,28 @@ static void add_server_options(GDHCPServer *dhcp_server, 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, @@ -529,7 +530,7 @@ 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, @@ -543,12 +544,12 @@ 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); @@ -559,14 +560,14 @@ static void send_offer(GDHCPServer *dhcp_server, 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; @@ -579,7 +580,7 @@ static void save_lease(GDHCPServer *dhcp_server) { 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) { @@ -590,28 +591,31 @@ static void save_lease(GDHCPServer *dhcp_server) } 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, @@ -626,7 +630,7 @@ 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, @@ -647,6 +651,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, struct dhcp_lease *lease; uint32_t requested_nip = 0; uint8_t type, *server_id_option, *request_ip_option; + uint16_t packet_len; int re; if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { @@ -657,87 +662,87 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, re = dhcp_recv_l3_packet(&packet, dhcp_server->listener_sockfd); if (re < 0) return TRUE; + packet_len = (uint16_t)(unsigned int)re; - type = check_packet_type(&packet); + type = check_packet_type(&packet, packet_len); if (type == 0) return TRUE; - server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID); + server_id_option = dhcp_get_option(&packet, packet_len, 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); + request_ip_option = dhcp_get_option(&packet, packet_len, 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 (server_id_option || lease == NULL) { - debug(dhcp_server, "Sending NAK"); - send_NAK(dhcp_server, &packet); - } + 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) { + 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; } @@ -750,7 +755,7 @@ int g_dhcp_server_start(GDHCPServer *dhcp_server) GIOChannel *listener_channel; int listener_sockfd; - if (dhcp_server->started == TRUE) + if (dhcp_server->started) return 0; listener_sockfd = dhcp_l3_socket(SERVER_PORT, @@ -759,7 +764,7 @@ int g_dhcp_server_start(GDHCPServer *dhcp_server) return -EIO; listener_channel = g_io_channel_unix_new(listener_sockfd); - if (listener_channel == NULL) { + if (!listener_channel) { close(listener_sockfd); return -EIO; } @@ -785,7 +790,7 @@ int g_dhcp_server_set_option(GDHCPServer *dhcp_server, { struct in_addr nip; - if (option_value == NULL) + if (!option_value) return -EINVAL; debug(dhcp_server, "option_code %d option_value %s", @@ -810,15 +815,24 @@ int g_dhcp_server_set_option(GDHCPServer *dhcp_server, 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); @@ -843,7 +857,7 @@ void g_dhcp_server_stop(GDHCPServer *dhcp_server) 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) @@ -860,12 +874,6 @@ void g_dhcp_server_unref(GDHCPServer *dhcp_server) g_free(dhcp_server); } -void g_dhcp_server_load_lease(GDHCPServer *dhcp_server, unsigned int expire, - unsigned char *mac, unsigned int lease_ip) -{ - add_lease(dhcp_server, expire, mac, lease_ip); -} - int g_dhcp_server_set_ip_range(GDHCPServer *dhcp_server, const char *start_ip, const char *end_ip) { @@ -884,9 +892,10 @@ int g_dhcp_server_set_ip_range(GDHCPServer *dhcp_server, 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; @@ -895,7 +904,7 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server, unsigned int lease_t 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;