diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-10-11 10:11:51 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-10-11 15:30:21 +0200 |
commit | 635f1e814e4e5a0d4f8356475dff32515e78f692 (patch) | |
tree | ff7b73473f6c629b09dd14970279b817b6fb2548 | |
parent | 51ca65aa0586f7e96dde4bbccdf0fef170d1a3e9 (diff) | |
download | connman-635f1e814e4e5a0d4f8356475dff32515e78f692.tar.gz connman-635f1e814e4e5a0d4f8356475dff32515e78f692.tar.bz2 connman-635f1e814e4e5a0d4f8356475dff32515e78f692.zip |
gdhcp: Use host byte order internally
Convert to network byte order just before sending the packet.
-rw-r--r-- | gdhcp/client.c | 47 | ||||
-rw-r--r-- | gdhcp/common.c | 20 | ||||
-rw-r--r-- | gdhcp/common.h | 17 | ||||
-rw-r--r-- | gdhcp/ipv4ll.c | 4 | ||||
-rw-r--r-- | gdhcp/server.c | 41 |
5 files changed, 58 insertions, 71 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c index cf04ced7..7340f3a0 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -367,7 +367,7 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested) /* Explicitly saying that we want RFC-compliant packets helps * some buggy DHCP servers to NOT send bigger packets */ - dhcp_add_simple_option(&packet, DHCP_MAX_SIZE, htons(576)); + dhcp_add_simple_option(&packet, DHCP_MAX_SIZE, 576); add_request_options(dhcp_client, &packet); @@ -410,7 +410,7 @@ static int send_renew(GDHCPClient *dhcp_client) init_packet(dhcp_client , &packet, DHCPREQUEST); packet.xid = dhcp_client->xid; - packet.ciaddr = dhcp_client->requested_ip; + packet.ciaddr = htonl(dhcp_client->requested_ip); add_request_options(dhcp_client, &packet); @@ -429,7 +429,7 @@ static int send_rebound(GDHCPClient *dhcp_client) init_packet(dhcp_client , &packet, DHCPREQUEST); packet.xid = dhcp_client->xid; - packet.ciaddr = dhcp_client->requested_ip; + packet.ciaddr = htonl(dhcp_client->requested_ip); add_request_options(dhcp_client, &packet); @@ -449,7 +449,7 @@ static int send_release(GDHCPClient *dhcp_client, init_packet(dhcp_client, &packet, DHCPRELEASE); packet.xid = rand(); - packet.ciaddr = ciaddr; + packet.ciaddr = htonl(ciaddr); dhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); @@ -1134,7 +1134,7 @@ static int ipv4ll_recv_arp_packet(GDHCPClient *dhcp_client) arp.arp_op != htons(ARPOP_REQUEST)) return -EINVAL; - ip_requested = ntohl(dhcp_client->requested_ip); + ip_requested = htonl(dhcp_client->requested_ip); source_conflict = !memcmp(arp.arp_spa, &ip_requested, sizeof(ip_requested)); @@ -1333,15 +1333,14 @@ static void start_request(GDHCPClient *dhcp_client) static uint32_t get_lease(struct dhcp_packet *packet) { - uint8_t *option_u8; + uint8_t *option; uint32_t lease_seconds; - option_u8 = dhcp_get_option(packet, DHCP_LEASE_TIME); - if (option_u8 == NULL) + option = dhcp_get_option(packet, DHCP_LEASE_TIME); + if (option == NULL) return 3600; - lease_seconds = dhcp_get_unaligned((uint32_t *) option_u8); - lease_seconds = ntohl(lease_seconds); + lease_seconds = get_be32(option); /* paranoia: must not be prone to overflows */ lease_seconds &= 0x0fffffff; if (lease_seconds < 10) @@ -1518,16 +1517,13 @@ static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type) dest += sprint_nip(dest, "", option); break; case OPTION_U16: { - uint16_t val_u16 = dhcp_get_unaligned( - (uint16_t *) option); - dest += sprintf(dest, "%u", ntohs(val_u16)); + uint16_t val_u16 = get_be16(option); + dest += sprintf(dest, "%u", val_u16); break; } case OPTION_U32: { - uint32_t val_u32 = dhcp_get_unaligned( - (uint32_t *) option); - dest += sprintf(dest, type == OPTION_U32 ? "%lu" : - "%ld", (unsigned long) ntohl(val_u32)); + uint32_t val_u32 = get_be32(option); + dest += sprintf(dest, "%u", val_u32); break; } case OPTION_STRING: @@ -1821,7 +1817,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, GDHCPClient *dhcp_client = user_data; struct dhcp_packet packet; struct dhcpv6_packet *packet6 = NULL; - uint8_t *message_type = NULL, *client_id = NULL, *option_u8, + uint8_t *message_type = NULL, *client_id = NULL, *option, *server_id = NULL; uint16_t option_len = 0, status = 0; gpointer pkt; @@ -1882,15 +1878,15 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, return TRUE; } - option_u8 = dhcpv6_get_option(packet6, pkt_len, + option = dhcpv6_get_option(packet6, pkt_len, G_DHCPV6_STATUS_CODE, &option_len, NULL); - if (option_u8 != 0 && option_len > 0) { - status = option_u8[0]<<8 | option_u8[1]; + if (option != 0 && option_len > 0) { + status = option[0]<<8 | option[1]; if (status != 0) { debug(dhcp_client, "error code %d", status); if (option_len > 2) { gchar *txt = g_strndup( - (gchar *)&option_u8[2], + (gchar *)&option[2], option_len - 2); debug(dhcp_client, "error text: %s", txt); @@ -1923,10 +1919,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, dhcp_client->timeout = 0; dhcp_client->retry_times = 0; - option_u8 = dhcp_get_option(&packet, DHCP_SERVER_ID); - dhcp_client->server_ip = - dhcp_get_unaligned((uint32_t *) option_u8); - dhcp_client->requested_ip = packet.yiaddr; + option = dhcp_get_option(&packet, DHCP_SERVER_ID); + dhcp_client->server_ip = get_be32(option); + dhcp_client->requested_ip = ntohl(packet.yiaddr); dhcp_client->state = REQUESTING; diff --git a/gdhcp/common.c b/gdhcp/common.c index 8d5c284b..55fddcbf 100644 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -280,11 +280,21 @@ void dhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, len = dhcp_option_lengths[type & OPTION_TYPE_MASK]; option[OPT_LEN] = len; -#if __BYTE_ORDER == __BIG_ENDIAN - data <<= 8 * (4 - len); -#endif + switch (len) { + case 1: + option[OPT_DATA] = data; + break; + case 2: + put_be16(data, option + OPT_DATA); + break; + case 4: + put_be32(data, option + OPT_DATA); + break; + default: + printf("Invalid option len %d for code 0x%x\n", len, code); + return; + } - dhcp_put_unaligned(data, (uint32_t *)(option + OPT_DATA)); dhcp_add_binary_option(packet, option); return; @@ -575,7 +585,7 @@ int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, memset(&client, 0, sizeof(client)); client.sin_family = AF_INET; client.sin_port = htons(source_port); - client.sin_addr.s_addr = source_ip; + client.sin_addr.s_addr = htonl(source_ip); if (bind(fd, (struct sockaddr *) &client, sizeof(client)) < 0) { close(fd); return -errno; diff --git a/gdhcp/common.h b/gdhcp/common.h index 13f49d8e..e2bfc6c8 100644 --- a/gdhcp/common.h +++ b/gdhcp/common.h @@ -24,24 +24,9 @@ #include <glib.h> +#include "unaligned.h" #include "gdhcp.h" -#define dhcp_get_unaligned(ptr) \ -({ \ - struct __attribute__((packed)) { \ - typeof(*(ptr)) __v; \ - } *__p = (void *) (ptr); \ - __p->__v; \ -}) - -#define dhcp_put_unaligned(val, ptr) \ -do { \ - struct __attribute__((packed)) { \ - typeof(*(ptr)) __v; \ - } *__p = (void *) (ptr); \ - __p->__v = (val); \ -} while (0) - #define CLIENT_PORT 68 #define SERVER_PORT 67 diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c index 4c095722..007ffe6b 100644 --- a/gdhcp/ipv4ll.c +++ b/gdhcp/ipv4ll.c @@ -36,7 +36,7 @@ #include "ipv4ll.h" /** - * Return a random link local IP + * Return a random link local IP (in host byte order) */ uint32_t ipv4ll_random_ip(int seed) { @@ -53,7 +53,7 @@ uint32_t ipv4ll_random_ip(int seed) tmp = rand(); tmp = tmp & IN_CLASSB_HOST; } while (tmp > (IN_CLASSB_HOST - 0x0200)); - return ((LINKLOCAL_ADDR + 0x0100) + tmp); + return ntohl(((LINKLOCAL_ADDR + 0x0100) + tmp)); } /** diff --git a/gdhcp/server.c b/gdhcp/server.c index 9ac09b54..2de7db69 100644 --- a/gdhcp/server.c +++ b/gdhcp/server.c @@ -140,7 +140,7 @@ 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) { @@ -148,7 +148,7 @@ static int get_lease(GDHCPServer *dhcp_server, uint32_t yiaddr, 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) *lease = lease_nip; @@ -200,7 +200,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; @@ -254,13 +254,12 @@ 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)); + lease = find_lease_by_nip(dhcp_server, ip_addr); if (lease != NULL) continue; if (arp_check(htonl(ip_addr), safe_mac) == TRUE) - return htonl(ip_addr); + return ip_addr; } /* The last lease is the oldest one */ @@ -471,7 +470,7 @@ static void add_option(gpointer key, gpointer value, gpointer user_data) return; dhcp_add_simple_option(packet, (uint8_t) option_code, - nip.s_addr); + ntohl(nip.s_addr)); break; default: return; @@ -493,10 +492,10 @@ static gboolean check_requested_nip(GDHCPServer *dhcp_server, if (requested_nip == 0) return FALSE; - if (ntohl(requested_nip) < dhcp_server->start_ip) + if (requested_nip < dhcp_server->start_ip) return FALSE; - if (ntohl(requested_nip) > dhcp_server->end_ip) + if (requested_nip > dhcp_server->end_ip) return FALSE; lease = find_lease_by_nip(dhcp_server, requested_nip); @@ -543,12 +542,12 @@ static void send_offer(GDHCPServer *dhcp_server, init_packet(dhcp_server, &packet, client_packet, DHCPOFFER); if (lease) - packet.yiaddr = lease->lease_nip; + packet.yiaddr = htonl(lease->lease_nip); else if (check_requested_nip(dhcp_server, requested_nip) == TRUE) - packet.yiaddr = 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); @@ -566,7 +565,7 @@ static void send_offer(GDHCPServer *dhcp_server, } dhcp_add_simple_option(&packet, DHCP_LEASE_TIME, - htonl(dhcp_server->lease_seconds)); + dhcp_server->lease_seconds); add_server_options(dhcp_server, &packet); addr.s_addr = packet.yiaddr; @@ -590,22 +589,22 @@ 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_simple_option(&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)); @@ -664,8 +663,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, 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_be32(server_id_option); if (server_nid != dhcp_server->server_nip) return TRUE; @@ -673,8 +671,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, 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); |