diff options
author | Nishant Chaprana <n.chaprana@samsung.com> | 2019-09-17 19:00:55 +0530 |
---|---|---|
committer | Nishant Chaprana <n.chaprana@samsung.com> | 2019-09-18 19:23:41 +0530 |
commit | 26cc90dfaf2ad149b702626f9552c81abbb26862 (patch) | |
tree | 2524c8994cf58358350fde67dfba5c3b8cb58f7d /gdhcp | |
parent | 9e3beb21876b6e63bd8acf53e751480d7a1cc16f (diff) | |
parent | 6b2381a2adabea7d8309ff158ef675ff88184305 (diff) | |
download | connman-26cc90dfaf2ad149b702626f9552c81abbb26862.tar.gz connman-26cc90dfaf2ad149b702626f9552c81abbb26862.tar.bz2 connman-26cc90dfaf2ad149b702626f9552c81abbb26862.zip |
Imported Upstream version 1.37submit/tizen/20190920.082459
Change-Id: Idb47c1ddbedc9f97181b8e9a5eeac04ddd832a2c
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'gdhcp')
-rwxr-xr-x | gdhcp/client.c | 246 | ||||
-rwxr-xr-x | gdhcp/common.c | 110 | ||||
-rwxr-xr-x | gdhcp/common.h | 6 | ||||
-rwxr-xr-x | gdhcp/gdhcp.h | 9 | ||||
-rwxr-xr-x | gdhcp/ipv4ll.c | 86 | ||||
-rwxr-xr-x | gdhcp/server.c | 33 |
6 files changed, 180 insertions, 310 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c index 5a455f08..22bbc8e2 100755 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -23,7 +23,6 @@ #include <config.h> #endif -#define _GNU_SOURCE #include <stdio.h> #include <errno.h> #include <unistd.h> @@ -43,9 +42,10 @@ #include <glib.h> +#include "../src/connman.h" +#include "../src/shared/arp.h" #include "gdhcp.h" #include "common.h" -#include "ipv4ll.h" #define DISCOVER_TIMEOUT 5 #define DISCOVER_RETRIES 6 @@ -86,6 +86,7 @@ typedef enum _dhcp_client_state { REBOOTING, REQUESTING, BOUND, + DECLINED, RENEWING, REBINDING, RELEASED, @@ -130,6 +131,7 @@ struct _GDHCPClient { GList *request_list; GHashTable *code_value_hash; GHashTable *send_value_hash; + GHashTable *secs_bcast_hash; GDHCPClientEventFunc lease_available_cb; gpointer lease_available_data; GDHCPClientEventFunc ipv4ll_available_cb; @@ -489,10 +491,40 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested) * versa. In the receiving side we then find out what kind of packet * the server can send. */ + dhcp_client->request_bcast = dhcp_client->retry_times % 2; + + if (dhcp_client->request_bcast) + g_hash_table_add(dhcp_client->secs_bcast_hash, + GINT_TO_POINTER(packet.secs)); + return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, dhcp_client->ifindex, - dhcp_client->retry_times % 2); + dhcp_client->request_bcast); +} + +int g_dhcp_client_decline(GDHCPClient *dhcp_client, uint32_t requested) +{ + struct dhcp_packet packet; + + dhcp_client->state = DECLINED; + dhcp_client->retry_times = 0; + + debug(dhcp_client, "sending DHCP decline"); + + init_packet(dhcp_client, &packet, DHCPDECLINE); + + packet.xid = dhcp_client->xid; + packet.secs = dhcp_attempt_secs(dhcp_client); + + if (requested) + dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP, requested); + + add_send_options(dhcp_client, &packet); + + return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, + INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, + dhcp_client->ifindex, true); } static int send_request(GDHCPClient *dhcp_client) @@ -547,7 +579,7 @@ static int send_release(GDHCPClient *dhcp_client, debug(dhcp_client, "sending DHCP release request"); init_packet(dhcp_client, &packet, DHCPRELEASE); - dhcp_get_random(&rand); + __connman_util_get_random(&rand); packet.xid = rand; packet.ciaddr = htonl(ciaddr); @@ -570,7 +602,7 @@ static gboolean send_probe_packet(gpointer dhcp_data) /* if requested_ip is not valid, pick a new address*/ if (dhcp_client->requested_ip == 0) { debug(dhcp_client, "pick a new random address"); - dhcp_client->requested_ip = ipv4ll_random_ip(); + dhcp_client->requested_ip = arp_random_ip(); } debug(dhcp_client, "sending IPV4LL probe request"); @@ -579,12 +611,12 @@ static gboolean send_probe_packet(gpointer dhcp_data) dhcp_client->state = IPV4LL_PROBE; switch_listening_mode(dhcp_client, L_ARP); } - ipv4ll_send_arp_packet(dhcp_client->mac_address, 0, + arp_send_packet(dhcp_client->mac_address, 0, dhcp_client->requested_ip, dhcp_client->ifindex); if (dhcp_client->retry_times < PROBE_NUM) { /*add a random timeout in range of PROBE_MIN to PROBE_MAX*/ - timeout = ipv4ll_random_delay_ms(PROBE_MAX-PROBE_MIN); + timeout = __connman_util_random_delay_ms(PROBE_MAX-PROBE_MIN); timeout += PROBE_MIN*1000; } else timeout = (ANNOUNCE_WAIT * 1000); @@ -608,7 +640,7 @@ static gboolean send_announce_packet(gpointer dhcp_data) debug(dhcp_client, "sending IPV4LL announce request"); - ipv4ll_send_arp_packet(dhcp_client->mac_address, + arp_send_packet(dhcp_client->mac_address, dhcp_client->requested_ip, dhcp_client->requested_ip, dhcp_client->ifindex); @@ -633,38 +665,6 @@ static gboolean send_announce_packet(gpointer dhcp_data) return TRUE; } -static void get_interface_mac_address(int index, uint8_t *mac_address) -{ - struct ifreq ifr; - int sk, err; - - sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (sk < 0) { - perror("Open socket error"); - return; - } - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = index; - - err = ioctl(sk, SIOCGIFNAME, &ifr); - if (err < 0) { - perror("Get interface name error"); - goto done; - } - - err = ioctl(sk, SIOCGIFHWADDR, &ifr); - if (err < 0) { - perror("Get mac address error"); - goto done; - } - - memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6); - -done: - close(sk); -} - void g_dhcpv6_client_set_retransmit(GDHCPClient *dhcp_client) { if (!dhcp_client) @@ -695,7 +695,7 @@ int g_dhcpv6_create_duid(GDHCPDuidType duid_type, int index, int type, (*duid)[0] = 0; (*duid)[1] = 1; - get_interface_mac_address(index, &(*duid)[2 + 2 + 4]); + __connman_inet_get_interface_mac_address(index, &(*duid)[2 + 2 + 4]); (*duid)[2] = 0; (*duid)[3] = type; duid_time = time(NULL) - DUID_TIME_EPOCH; @@ -714,7 +714,7 @@ int g_dhcpv6_create_duid(GDHCPDuidType duid_type, int index, int type, (*duid)[0] = 0; (*duid)[1] = 3; - get_interface_mac_address(index, &(*duid)[2 + 2]); + __connman_inet_get_interface_mac_address(index, &(*duid)[2 + 2]); (*duid)[2] = 0; (*duid)[3] = type; break; @@ -839,7 +839,7 @@ void g_dhcpv6_client_create_iaid(GDHCPClient *dhcp_client, int index, { uint8_t buf[6]; - get_interface_mac_address(index, buf); + __connman_inet_get_interface_mac_address(index, buf); memcpy(iaid, &buf[2], 4); dhcp_client->iaid = iaid[0] << 24 | @@ -1206,7 +1206,7 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, goto error; } - get_interface_mac_address(ifindex, dhcp_client->mac_address); + __connman_inet_get_interface_mac_address(ifindex, dhcp_client->mac_address); dhcp_client->listener_sockfd = -1; dhcp_client->listen_mode = L_NONE; @@ -1226,6 +1226,8 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, g_direct_equal, NULL, remove_option_value); dhcp_client->send_value_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + dhcp_client->secs_bcast_hash = g_hash_table_new(g_direct_hash, + g_direct_equal); dhcp_client->request_list = NULL; dhcp_client->require_list = NULL; dhcp_client->duid = NULL; @@ -1401,10 +1403,10 @@ static void ipv4ll_start(GDHCPClient *dhcp_client) dhcp_client->retry_times = 0; dhcp_client->requested_ip = 0; - dhcp_client->requested_ip = ipv4ll_random_ip(); + dhcp_client->requested_ip = arp_random_ip(); /*first wait a random delay to avoid storm of arp request on boot*/ - timeout = ipv4ll_random_delay_ms(PROBE_WAIT); + timeout = __connman_util_random_delay_ms(PROBE_WAIT); dhcp_client->retry_times++; dhcp_client->timeout = g_timeout_add_full(G_PRIORITY_HIGH, @@ -1441,6 +1443,7 @@ static int ipv4ll_recv_arp_packet(GDHCPClient *dhcp_client) uint32_t ip_requested; int source_conflict; int target_conflict; + guint timeout_ms; memset(&arp, 0, sizeof(arp)); bytes = read(dhcp_client->listener_sockfd, &arp, sizeof(arp)); @@ -1451,6 +1454,9 @@ static int ipv4ll_recv_arp_packet(GDHCPClient *dhcp_client) arp.arp_op != htons(ARPOP_REQUEST)) return -EINVAL; + if (memcmp(arp.arp_sha, dhcp_client->mac_address, ETH_ALEN) == 0) + return 0; + ip_requested = htonl(dhcp_client->requested_ip); source_conflict = !memcmp(arp.arp_spa, &ip_requested, sizeof(ip_requested)); @@ -1486,23 +1492,20 @@ static int ipv4ll_recv_arp_packet(GDHCPClient *dhcp_client) ipv4ll_stop(dhcp_client); - if (dhcp_client->conflicts < MAX_CONFLICTS) { - /*restart whole state machine*/ - dhcp_client->retry_times++; - dhcp_client->timeout = - g_timeout_add_full(G_PRIORITY_HIGH, - ipv4ll_random_delay_ms(PROBE_WAIT), - send_probe_packet, - dhcp_client, - NULL); - } - /* Here we got a lot of conflicts, RFC3927 states that we have + /* If we got a lot of conflicts, RFC3927 states that we have * to wait RATE_LIMIT_INTERVAL before retrying, - * but we just report failure. */ - else if (dhcp_client->no_lease_cb) - dhcp_client->no_lease_cb(dhcp_client, - dhcp_client->no_lease_data); + if (dhcp_client->conflicts < MAX_CONFLICTS) + timeout_ms = __connman_util_random_delay_ms(PROBE_WAIT); + else + timeout_ms = RATE_LIMIT_INTERVAL * 1000; + dhcp_client->retry_times++; + dhcp_client->timeout = + g_timeout_add_full(G_PRIORITY_HIGH, + timeout_ms, + send_probe_packet, + dhcp_client, + NULL); return 0; } @@ -1569,6 +1572,12 @@ static gboolean request_timeout(gpointer user_data) return FALSE; } +static void listener_watch_destroy(gpointer user_data) +{ + GDHCPClient *dhcp_client = user_data; + g_dhcp_client_unref(dhcp_client); +} + static gboolean listener_event(GIOChannel *channel, GIOCondition condition, gpointer user_data); @@ -1607,7 +1616,7 @@ static int switch_listening_mode(GDHCPClient *dhcp_client, dhcp_client->interface, AF_INET); } else if (listen_mode == L_ARP) - listener_sockfd = ipv4ll_arp_socket(dhcp_client->ifindex); + listener_sockfd = arp_socket(dhcp_client->ifindex); else return -EIO; @@ -1628,8 +1637,8 @@ static int switch_listening_mode(GDHCPClient *dhcp_client, dhcp_client->listener_watch = g_io_add_watch_full(listener_channel, G_PRIORITY_HIGH, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP, - listener_event, dhcp_client, - NULL); + listener_event, g_dhcp_client_ref(dhcp_client), + listener_watch_destroy); g_io_channel_unref(listener_channel); return 0; @@ -1727,7 +1736,7 @@ static gboolean continue_rebound(gpointer user_data) /*recalculate remaining rebind time*/ dhcp_client->T2 >>= 1; if (dhcp_client->T2 > 60) { - dhcp_get_random(&rand); + __connman_util_get_random(&rand); dhcp_client->t2_timeout = g_timeout_add_full(G_PRIORITY_HIGH, dhcp_client->T2 * 1000 + (rand % 2000) - 1000, @@ -1775,7 +1784,7 @@ static gboolean continue_renew (gpointer user_data) dhcp_client->T1 >>= 1; if (dhcp_client->T1 > 60) { - dhcp_get_random(&rand); + __connman_util_get_random(&rand); dhcp_client->t1_timeout = g_timeout_add_full(G_PRIORITY_HIGH, dhcp_client->T1 * 1000 + (rand % 2000) - 1000, continue_renew, @@ -1860,6 +1869,71 @@ static char *get_ip(uint32_t ip) return g_strdup(inet_ntoa(addr)); } +/* get a rough idea of how long an option will be */ +static const uint8_t len_of_option_as_string[] = { + [OPTION_IP] = sizeof("255.255.255.255 "), + [OPTION_STRING] = 1, + [OPTION_U8] = sizeof("255 "), + [OPTION_U16] = sizeof("65535 "), + [OPTION_U32] = sizeof("4294967295 "), +}; + +static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) +{ + return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); +} + +/* Create "opt_value1 option_value2 ..." string */ +static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type) +{ + unsigned upper_length; + int len, optlen; + char *dest, *ret; + + len = option[OPT_LEN - OPT_DATA]; + type &= OPTION_TYPE_MASK; + optlen = dhcp_option_lengths[type]; + if (optlen == 0) + return NULL; + upper_length = len_of_option_as_string[type] * + ((unsigned)len / (unsigned)optlen); + dest = ret = g_malloc(upper_length + 1); + if (!ret) + return NULL; + + while (len >= optlen) { + switch (type) { + case OPTION_IP: + dest += sprint_nip(dest, "", option); + break; + case OPTION_U16: { + uint16_t val_u16 = get_be16(option); + dest += sprintf(dest, "%u", val_u16); + break; + } + case OPTION_U32: { + uint32_t val_u32 = get_be32(option); + dest += sprintf(dest, "%u", val_u32); + break; + } + case OPTION_STRING: + memcpy(dest, option, len); + dest[len] = '\0'; + return ret; + default: + break; + } + option += optlen; + len -= optlen; + if (len <= 0) + break; + *dest++ = ' '; + *dest = '\0'; + } + + return ret; +} + static GList *get_option_value_list(char *value, GDHCPOptionType type) { char *pos = value; @@ -2351,14 +2425,28 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, dhcp_client->state = REQUESTING; - if (dst_addr.sin_addr.s_addr == INADDR_BROADCAST) - dhcp_client->request_bcast = true; - else - dhcp_client->request_bcast = false; + /* + * RFC2131: + * + * If unicasting is not possible, the message MAY be + * sent as an IP broadcast using an IP broadcast address + * (preferably 0xffffffff) as the IP destination address + * and the link-layer broadcast address as the link-layer + * destination address. + * + * For interoperability reasons, if the response is an IP + * broadcast, let's reuse broadcast flag from DHCPDISCOVER + * to which the server has responded. Some servers are picky + * about this flag. + */ + dhcp_client->request_bcast = + dst_addr.sin_addr.s_addr == INADDR_BROADCAST && + g_hash_table_contains(dhcp_client->secs_bcast_hash, + GINT_TO_POINTER(packet.secs)); - debug(dhcp_client, "init ip %s -> %sadding broadcast flag", - inet_ntoa(dst_addr.sin_addr), - dhcp_client->request_bcast ? "" : "not "); + debug(dhcp_client, "init ip %s secs %hu -> broadcast flag %s", + inet_ntoa(dst_addr.sin_addr), packet.secs, + dhcp_client->request_bcast ? "on" : "off"); start_request(dhcp_client); @@ -2715,6 +2803,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) int re; uint32_t addr; uint64_t rand; + ClientState oldstate = dhcp_client->state; #if defined TIZEN_EXT int discover_retry = 0; @@ -2829,9 +2918,9 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) } #if defined TIZEN_EXT - if (dhcp_client->retry_times == discover_retry) { + if (dhcp_client->retry_times == discover_retry) { #else - if (dhcp_client->retry_times == DISCOVER_RETRIES) { + if (dhcp_client->retry_times == DISCOVER_RETRIES) { #endif if (dhcp_client->no_lease_cb) dhcp_client->no_lease_cb(dhcp_client, @@ -2849,12 +2938,13 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) if (re != 0) return re; - dhcp_get_random(&rand); + __connman_util_get_random(&rand); dhcp_client->xid = rand; dhcp_client->start = time(NULL); + g_hash_table_remove_all(dhcp_client->secs_bcast_hash); } - if (!last_address) { + if (!last_address || oldstate == DECLINED) { addr = 0; } else { addr = ntohl(inet_addr(last_address)); @@ -3073,6 +3163,7 @@ char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client) case REBOOTING: case REQUESTING: case RELEASED: + case DECLINED: case IPV4LL_PROBE: case IPV4LL_ANNOUNCE: case INFORMATION_REQ: @@ -3270,6 +3361,7 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) g_hash_table_destroy(dhcp_client->code_value_hash); g_hash_table_destroy(dhcp_client->send_value_hash); + g_hash_table_destroy(dhcp_client->secs_bcast_hash); g_free(dhcp_client); #if defined TIZEN_EXT diff --git a/gdhcp/common.c b/gdhcp/common.c index b8c5091a..8f7a65cc 100755 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -39,6 +39,7 @@ #include "gdhcp.h" #include "common.h" +#include "../src/connman.h" static const DHCPOption client_options[] = { { OPTION_IP, 0x01 }, /* subnet-mask */ @@ -60,42 +61,6 @@ static const DHCPOption client_options[] = { { OPTION_UNKNOWN, 0x00 }, }; -#define URANDOM "/dev/urandom" -static int random_fd = -1; - -int dhcp_get_random(uint64_t *val) -{ - int r; - - if (random_fd < 0) { - random_fd = open(URANDOM, O_RDONLY); - if (random_fd < 0) { - r = -errno; - *val = random(); - - return r; - } - } - - if (read(random_fd, val, sizeof(uint64_t)) < 0) { - r = -errno; - *val = random(); - - return r; - } - - return 0; -} - -void dhcp_cleanup_random(void) -{ - if (random_fd < 0) - return; - - close(random_fd); - random_fd = -1; -} - GDHCPOptionType dhcp_get_code_type(uint8_t code) { int i; @@ -182,71 +147,6 @@ int dhcp_end_option(uint8_t *optionptr) return i; } -/* get a rough idea of how long an option will be */ -static const uint8_t len_of_option_as_string[] = { - [OPTION_IP] = sizeof("255.255.255.255 "), - [OPTION_STRING] = 1, - [OPTION_U8] = sizeof("255 "), - [OPTION_U16] = sizeof("65535 "), - [OPTION_U32] = sizeof("4294967295 "), -}; - -static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) -{ - return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); -} - -/* Create "opt_value1 option_value2 ..." string */ -char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type) -{ - unsigned upper_length; - int len, optlen; - char *dest, *ret; - - len = option[OPT_LEN - OPT_DATA]; - type &= OPTION_TYPE_MASK; - optlen = dhcp_option_lengths[type]; - if (optlen == 0) - return NULL; - upper_length = len_of_option_as_string[type] * - ((unsigned)len / (unsigned)optlen); - dest = ret = g_malloc(upper_length + 1); - if (ret == NULL) - return NULL; - - while (len >= optlen) { - switch (type) { - case OPTION_IP: - dest += sprint_nip(dest, "", option); - break; - case OPTION_U16: { - uint16_t val_u16 = get_be16(option); - dest += sprintf(dest, "%u", val_u16); - break; - } - case OPTION_U32: { - uint32_t val_u32 = get_be32(option); - dest += sprintf(dest, "%u", val_u32); - break; - } - case OPTION_STRING: - memcpy(dest, option, len); - dest[len] = '\0'; - return ret; - default: - break; - } - option += optlen; - len -= optlen; - if (len <= 0) - break; - *dest++ = ' '; - *dest = '\0'; - } - - return ret; -} - uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, int code, uint16_t *option_len, int *option_count) { @@ -397,8 +297,6 @@ void dhcp_add_option_uint32(struct dhcp_packet *packet, uint8_t code, put_be32(data, option + OPT_DATA); dhcp_add_binary_option(packet, option); - - return; } void dhcp_add_option_uint16(struct dhcp_packet *packet, uint8_t code, @@ -414,8 +312,6 @@ void dhcp_add_option_uint16(struct dhcp_packet *packet, uint8_t code, put_be16(data, option + OPT_DATA); dhcp_add_binary_option(packet, option); - - return; } void dhcp_add_option_uint8(struct dhcp_packet *packet, uint8_t code, @@ -431,8 +327,6 @@ void dhcp_add_option_uint8(struct dhcp_packet *packet, uint8_t code, option[OPT_DATA] = data; dhcp_add_binary_option(packet, option); - - return; } void dhcp_init_header(struct dhcp_packet *packet, char type) @@ -465,7 +359,7 @@ void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type) packet->message = type; - dhcp_get_random(&rand); + __connman_util_get_random(&rand); id = rand; packet->transaction_id[0] = (id >> 16) & 0xff; diff --git a/gdhcp/common.h b/gdhcp/common.h index 7da13135..6899499e 100755 --- a/gdhcp/common.h +++ b/gdhcp/common.h @@ -19,6 +19,7 @@ * */ +#include <config.h> #include <netinet/udp.h> #include <netinet/ip.h> @@ -170,15 +171,14 @@ static const uint8_t dhcp_option_lengths[] = { [OPTION_U32] = 4, }; -/* already defined within netinet/in.h if using GNU compiler */ -#ifndef __USE_GNU +/* already defined within netinet/in.h if using glibc or musl */ +#ifndef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR struct in6_pktinfo { struct in6_addr ipi6_addr; /* src/dst IPv6 address */ unsigned int ipi6_ifindex; /* send/recv interface index */ }; #endif -char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type); uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code); uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, int code, uint16_t *option_len, int *option_count); diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index f51a8b05..d9944882 100755 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -134,6 +134,7 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, int index, int g_dhcp_client_start(GDHCPClient *client, const char *last_address); void g_dhcp_client_stop(GDHCPClient *client); +int g_dhcp_client_decline(GDHCPClient *client, uint32_t requested); GDHCPClient *g_dhcp_client_ref(GDHCPClient *client); void g_dhcp_client_unref(GDHCPClient *client); @@ -216,9 +217,6 @@ struct _GDHCPServer; typedef struct _GDHCPServer GDHCPServer; -typedef void (*GDHCPSaveACKLeaseFunc) (char *hostname, - unsigned char *mac, unsigned int nip); - GDHCPServer *g_dhcp_server_new(GDHCPType type, int ifindex, GDHCPServerError *error); int g_dhcp_server_start(GDHCPServer *server); @@ -239,11 +237,6 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server, GDHCPSaveLeaseFunc func, gpointer user_data); void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, GDHCPLeaseAddedCb cb); -void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server, - GDHCPSaveACKLeaseFunc func, gpointer user_data); - -int dhcp_get_random(uint64_t *val); -void dhcp_cleanup_random(void); #if defined TIZEN_EXT void g_dhcp_client_set_address_known(GDHCPClient *client, gboolean known); diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c index d9001987..de4e0764 100755 --- a/gdhcp/ipv4ll.c +++ b/gdhcp/ipv4ll.c @@ -35,6 +35,7 @@ #include <glib.h> #include "ipv4ll.h" #include "common.h" +#include "../src/connman.h" /** * Return a random link local IP (in host byte order) @@ -45,93 +46,10 @@ uint32_t ipv4ll_random_ip(void) uint64_t rand; do { - dhcp_get_random(&rand); + __connman_util_get_random(&rand); tmp = rand; tmp = tmp & IN_CLASSB_HOST; } while (tmp > (IN_CLASSB_HOST - 0x0200)); return ((LINKLOCAL_ADDR + 0x0100) + tmp); } -/** - * Return a random delay in range of zero to secs*1000 - */ -guint ipv4ll_random_delay_ms(guint secs) -{ - uint64_t rand; - - dhcp_get_random(&rand); - return rand % (secs * 1000); -} - -int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, - uint32_t target_ip, int ifindex) -{ - struct sockaddr_ll dest; - struct ether_arp p; - uint32_t ip_source; - uint32_t ip_target; - int fd, n; - - fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - return -errno; - - memset(&dest, 0, sizeof(dest)); - memset(&p, 0, sizeof(p)); - - dest.sll_family = AF_PACKET; - dest.sll_protocol = htons(ETH_P_ARP); - dest.sll_ifindex = ifindex; - dest.sll_halen = ETH_ALEN; - memset(dest.sll_addr, 0xFF, ETH_ALEN); - if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) { - int err = errno; - close(fd); - return -err; - } - - ip_source = htonl(source_ip); - ip_target = htonl(target_ip); - p.arp_hrd = htons(ARPHRD_ETHER); - p.arp_pro = htons(ETHERTYPE_IP); - p.arp_hln = ETH_ALEN; - p.arp_pln = 4; - p.arp_op = htons(ARPOP_REQUEST); - - memcpy(&p.arp_sha, source_eth, ETH_ALEN); - memcpy(&p.arp_spa, &ip_source, sizeof(p.arp_spa)); - memcpy(&p.arp_tpa, &ip_target, sizeof(p.arp_tpa)); - - n = sendto(fd, &p, sizeof(p), 0, - (struct sockaddr*) &dest, sizeof(dest)); - if (n < 0) - n = -errno; - - close(fd); - - return n; -} - -int ipv4ll_arp_socket(int ifindex) -{ - int fd; - struct sockaddr_ll sock; - - fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - return fd; - - memset(&sock, 0, sizeof(sock)); - - sock.sll_family = AF_PACKET; - sock.sll_protocol = htons(ETH_P_ARP); - sock.sll_ifindex = ifindex; - - if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) { - int err = errno; - close(fd); - return -err; - } - - return fd; -} diff --git a/gdhcp/server.c b/gdhcp/server.c index 44ce771a..85405f19 100755 --- a/gdhcp/server.c +++ b/gdhcp/server.c @@ -66,7 +66,6 @@ struct _GDHCPServer { GHashTable *option_hash; /* Options send to client */ GDHCPSaveLeaseFunc save_lease_func; GDHCPLeaseAddedCb lease_added_cb; - GDHCPSaveACKLeaseFunc save_ack_lease_func; GDHCPDebugFunc debug_func; gpointer debug_data; }; @@ -397,10 +396,9 @@ 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->save_ack_lease_func = NULL; dhcp_server->debug_func = NULL; dhcp_server->debug_data = NULL; @@ -652,12 +650,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, struct dhcp_packet packet; struct dhcp_lease *lease; uint32_t requested_nip = 0; - uint8_t type, *server_id_option, *request_ip_option, *host_name; + uint8_t type, *server_id_option, *request_ip_option; int re; - GDHCPOptionType option_type; - char *option_value; - if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { dhcp_server->listener_watch = 0; return FALSE; @@ -696,28 +691,15 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, debug(dhcp_server, "Received REQUEST NIP %d", requested_nip); if (requested_nip == 0) { - requested_nip = packet.ciaddr; + requested_nip = ntohl(packet.ciaddr); if (requested_nip == 0) break; } if (lease && requested_nip == lease->lease_nip) { debug(dhcp_server, "Sending ACK"); - - host_name = dhcp_get_option(&packet, DHCP_HOST_NAME); - option_type = dhcp_get_code_type(DHCP_HOST_NAME); - option_value = malloc_option_value_string(host_name, - option_type); send_ACK(dhcp_server, &packet, lease->lease_nip); - - if (dhcp_server->save_ack_lease_func) - dhcp_server->save_ack_lease_func( - option_value, - lease->lease_mac, - lease->lease_nip); - g_free(option_value); - break; } @@ -846,15 +828,6 @@ void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server, dhcp_server->lease_added_cb = cb; } -void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server, - GDHCPSaveACKLeaseFunc func, gpointer user_data) -{ - if (dhcp_server == NULL) - return; - - dhcp_server->save_ack_lease_func = func; -} - GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server) { if (!dhcp_server) |