summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-10-11 10:11:51 +0300
committerMarcel Holtmann <marcel@holtmann.org>2012-10-11 15:30:21 +0200
commit635f1e814e4e5a0d4f8356475dff32515e78f692 (patch)
treeff7b73473f6c629b09dd14970279b817b6fb2548
parent51ca65aa0586f7e96dde4bbccdf0fef170d1a3e9 (diff)
downloadconnman-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.c47
-rw-r--r--gdhcp/common.c20
-rw-r--r--gdhcp/common.h17
-rw-r--r--gdhcp/ipv4ll.c4
-rw-r--r--gdhcp/server.c41
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);