gdhcp: Use host byte order internally
authorJukka Rissanen <jukka.rissanen@linux.intel.com>
Thu, 11 Oct 2012 07:11:51 +0000 (10:11 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 11 Oct 2012 13:30:21 +0000 (15:30 +0200)
Convert to network byte order just before sending the packet.

gdhcp/client.c
gdhcp/common.c
gdhcp/common.h
gdhcp/ipv4ll.c
gdhcp/server.c

index cf04ced..7340f3a 100644 (file)
@@ -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;
 
index 8d5c284..55fddcb 100644 (file)
@@ -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;
index 13f49d8..e2bfc6c 100644 (file)
 
 #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
 
index 4c09572..007ffe6 100644 (file)
@@ -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));
 }
 
 /**
index 9ac09b5..2de7db6 100644 (file)
@@ -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);