Pārlūkot izejas kodu

dhcpclient/BDHCPClientCore: fix aliasing issues

ambrop7 13 gadi atpakaļ
vecāks
revīzija
07e187dcff
3 mainītis faili ar 122 papildinājumiem un 82 dzēšanām
  1. 1 0
      dhcpclient/BDHCPClient.c
  2. 119 79
      dhcpclient/BDHCPClientCore.c
  3. 2 3
      dhcpclient/BDHCPClientCore.h

+ 1 - 0
dhcpclient/BDHCPClient.c

@@ -41,6 +41,7 @@
 #include <misc/ethernet_proto.h>
 #include <misc/ipv4_proto.h>
 #include <misc/udp_proto.h>
+#include <misc/dhcp_proto.h>
 #include <base/BLog.h>
 
 #include <dhcpclient/BDHCPClient.h>

+ 119 - 79
dhcpclient/BDHCPClientCore.c

@@ -34,6 +34,7 @@
 #include <misc/minmax.h>
 #include <misc/balloc.h>
 #include <misc/bsize.h>
+#include <misc/dhcp_proto.h>
 #include <base/BLog.h>
 
 #include <dhcpclient/BDHCPClientCore.h>
@@ -85,86 +86,114 @@ static void send_message (
     }
     
     // write header
-    memset(o->send_buf, 0, sizeof(*o->send_buf));
-    o->send_buf->op = hton8(DHCP_OP_BOOTREQUEST);
-    o->send_buf->htype = hton8(DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET);
-    o->send_buf->hlen = hton8(6);
-    o->send_buf->xid = xid;
-    o->send_buf->secs = hton16(0);
-    memcpy(o->send_buf->chaddr, o->client_mac_addr, sizeof(o->client_mac_addr));
-    o->send_buf->magic = hton32(DHCP_MAGIC);
+    struct dhcp_header header;
+    memset(&header, 0, sizeof(header));
+    header.op = hton8(DHCP_OP_BOOTREQUEST);
+    header.htype = hton8(DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET);
+    header.hlen = hton8(6);
+    header.xid = xid;
+    header.secs = hton16(0);
+    memcpy(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr));
+    header.magic = hton32(DHCP_MAGIC);
+    memcpy(o->send_buf, &header, sizeof(header));
     
     // write options
     
-    struct dhcp_option_header *out = (void *)(o->send_buf + 1);
+    char *out = o->send_buf + sizeof(header);
+    struct dhcp_option_header oh;
     
     // DHCP message type
-    out->type = hton8(DHCP_OPTION_DHCP_MESSAGE_TYPE);
-    out->len = hton8(sizeof(struct dhcp_option_dhcp_message_type));
-    ((struct dhcp_option_dhcp_message_type *)(out + 1))->type = hton8(type);
-    out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+    {
+        oh.type = hton8(DHCP_OPTION_DHCP_MESSAGE_TYPE);
+        oh.len = hton8(sizeof(struct dhcp_option_dhcp_message_type));
+        struct dhcp_option_dhcp_message_type opt;
+        opt.type = hton8(type);
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), &opt, sizeof(opt));
+        out += sizeof(oh) + sizeof(opt);
+    }
     
     if (have_requested_ip_address) {
         // requested IP address
-        out->type = hton8(DHCP_OPTION_REQUESTED_IP_ADDRESS);
-        out->len = hton8(sizeof(struct dhcp_option_addr));
-        ((struct dhcp_option_addr *)(out + 1))->addr = requested_ip_address;
-        out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+        oh.type = hton8(DHCP_OPTION_REQUESTED_IP_ADDRESS);
+        oh.len = hton8(sizeof(struct dhcp_option_addr));
+        struct dhcp_option_addr opt;
+        opt.addr = requested_ip_address;
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), &opt, sizeof(opt));
+        out += sizeof(oh) + sizeof(opt);
     }
     
     if (have_dhcp_server_identifier) {
         // DHCP server identifier
-        out->type = hton8(DHCP_OPTION_DHCP_SERVER_IDENTIFIER);
-        out->len = hton8(sizeof(struct dhcp_option_dhcp_server_identifier));
-        ((struct dhcp_option_dhcp_server_identifier *)(out + 1))->id = dhcp_server_identifier;
-        out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+        oh.type = hton8(DHCP_OPTION_DHCP_SERVER_IDENTIFIER);
+        oh.len = hton8(sizeof(struct dhcp_option_dhcp_server_identifier));
+        struct dhcp_option_dhcp_server_identifier opt;
+        opt.id = dhcp_server_identifier;
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), &opt, sizeof(opt));
+        out += sizeof(oh) + sizeof(opt);
     }
     
     // maximum message size
-    out->type = hton8(DHCP_OPTION_MAXIMUM_MESSAGE_SIZE);
-    out->len = hton8(sizeof(struct dhcp_option_maximum_message_size));
-    ((struct dhcp_option_maximum_message_size *)(out + 1))->size = hton16(IP_UDP_HEADERS_SIZE + PacketRecvInterface_GetMTU(o->recv_if));
-    out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+    {
+        oh.type = hton8(DHCP_OPTION_MAXIMUM_MESSAGE_SIZE);
+        oh.len = hton8(sizeof(struct dhcp_option_maximum_message_size));
+        struct dhcp_option_maximum_message_size opt;
+        opt.size = hton16(IP_UDP_HEADERS_SIZE + PacketRecvInterface_GetMTU(o->recv_if));
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), &opt, sizeof(opt));
+        out += sizeof(oh) + sizeof(opt);
+    }
     
     // parameter request list
-    out->type = hton8(DHCP_OPTION_PARAMETER_REQUEST_LIST);
-    out->len = hton8(4);
-    ((uint8_t *)(out + 1))[0] = DHCP_OPTION_SUBNET_MASK;
-    ((uint8_t *)(out + 1))[1] = DHCP_OPTION_ROUTER;
-    ((uint8_t *)(out + 1))[2] = DHCP_OPTION_DOMAIN_NAME_SERVER;
-    ((uint8_t *)(out + 1))[3] = DHCP_OPTION_IP_ADDRESS_LEASE_TIME;
-    out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+    {
+        oh.type = hton8(DHCP_OPTION_PARAMETER_REQUEST_LIST);
+        oh.len = hton8(4);
+        uint8_t opt[4];
+        opt[0] = DHCP_OPTION_SUBNET_MASK;
+        opt[1] = DHCP_OPTION_ROUTER;
+        opt[2] = DHCP_OPTION_DOMAIN_NAME_SERVER;
+        opt[3] = DHCP_OPTION_IP_ADDRESS_LEASE_TIME;
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), &opt, sizeof(opt));
+        out += sizeof(oh) + sizeof(opt);
+    }
     
     if (o->hostname) {
         // host name
-        out->type = hton8(DHCP_OPTION_HOST_NAME);
-        out->len = hton8(strlen(o->hostname));
-        memcpy(out + 1, o->hostname, strlen(o->hostname));
-        out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+        oh.type = hton8(DHCP_OPTION_HOST_NAME);
+        oh.len = hton8(strlen(o->hostname));
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), o->hostname, strlen(o->hostname));
+        out += sizeof(oh) + strlen(o->hostname);
     }
     
     if (o->vendorclassid) {
         // vendor class identifier
-        out->type = hton8(DHCP_OPTION_VENDOR_CLASS_IDENTIFIER);
-        out->len = hton8(strlen(o->vendorclassid));
-        memcpy(out + 1, o->vendorclassid, strlen(o->vendorclassid));
-        out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+        oh.type = hton8(DHCP_OPTION_VENDOR_CLASS_IDENTIFIER);
+        oh.len = hton8(strlen(o->vendorclassid));
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), o->vendorclassid, strlen(o->vendorclassid));
+        out += sizeof(oh) + strlen(o->vendorclassid);
     }
     
     if (o->clientid) {
         // client identifier
-        out->type = hton8(DHCP_OPTION_CLIENT_IDENTIFIER);
-        out->len = hton8(o->clientid_len);
-        memcpy(out + 1, o->clientid, o->clientid_len);
-        out = (void *)((uint8_t *)(out + 1) + ntoh8(out->len));
+        oh.type = hton8(DHCP_OPTION_CLIENT_IDENTIFIER);
+        oh.len = hton8(o->clientid_len);
+        memcpy(out, &oh, sizeof(oh));
+        memcpy(out + sizeof(oh), o->clientid, o->clientid_len);
+        out += sizeof(oh) + o->clientid_len;
     }
     
     // end option
-    *((uint8_t *)out) = 0xFF;
-    out = (void *)((uint8_t *)out + 1);
+    uint8_t end = 0xFF;
+    memcpy(out, &end, sizeof(end));
+    out += sizeof(end);
     
     // send it
-    PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)o->send_buf, (uint8_t *)out - (uint8_t *)o->send_buf);
+    PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)o->send_buf, out - o->send_buf);
     o->sending = 1;
 }
 
@@ -190,38 +219,41 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
     
     // check header
     
-    if (data_len < sizeof(*o->recv_buf)) {
+    if (data_len < sizeof(struct dhcp_header)) {
         return;
     }
     
-    if (ntoh8(o->recv_buf->op) != DHCP_OP_BOOTREPLY) {
+    struct dhcp_header header;
+    memcpy(&header, o->recv_buf, sizeof(header));
+    
+    if (ntoh8(header.op) != DHCP_OP_BOOTREPLY) {
         return;
     }
     
-    if (ntoh8(o->recv_buf->htype) != DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET) {
+    if (ntoh8(header.htype) != DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET) {
         return;
     }
     
-    if (ntoh8(o->recv_buf->hlen) != 6) {
+    if (ntoh8(header.hlen) != 6) {
         return;
     }
     
-    if (o->recv_buf->xid != o->xid) {
+    if (header.xid != o->xid) {
         return;
     }
     
-    if (memcmp(o->recv_buf->chaddr, o->client_mac_addr, sizeof(o->client_mac_addr))) {
+    if (memcmp(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr))) {
         return;
     }
     
-    if (ntoh32(o->recv_buf->magic) != DHCP_MAGIC) {
+    if (ntoh32(header.magic) != DHCP_MAGIC) {
         return;
     }
     
     // parse and check options
     
-    uint8_t *pos = (uint8_t *)o->recv_buf + sizeof(*o->recv_buf);
-    int len = data_len - sizeof(*o->recv_buf);
+    uint8_t *pos = (uint8_t *)o->recv_buf + sizeof(header);
+    int len = data_len - sizeof(header);
     
     int have_end = 0;
     
@@ -266,17 +298,18 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
         if (len < sizeof(struct dhcp_option_header)) {
             return;
         }
-        struct dhcp_option_header *opt = (void *)pos;
-        pos += sizeof(*opt);
-        len -= sizeof(*opt);
-        int opt_type = ntoh8(opt->type);
-        int opt_len = ntoh8(opt->len);
+        struct dhcp_option_header opt;
+        memcpy(&opt, pos, sizeof(opt));
+        pos += sizeof(opt);
+        len -= sizeof(opt);
+        int opt_type = ntoh8(opt.type);
+        int opt_len = ntoh8(opt.len);
         
         // check option payload
         if (opt_len > len) {
             return;
         }
-        void *optval = pos;
+        uint8_t *optval = pos;
         pos += opt_len;
         len -= opt_len;
         
@@ -285,18 +318,20 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
                 if (opt_len != sizeof(struct dhcp_option_dhcp_message_type)) {
                     return;
                 }
-                struct dhcp_option_dhcp_message_type *val = optval;
+                struct dhcp_option_dhcp_message_type val;
+                memcpy(&val, optval, sizeof(val));
                 
-                dhcp_message_type = ntoh8(val->type);
+                dhcp_message_type = ntoh8(val.type);
             } break;
             
             case DHCP_OPTION_DHCP_SERVER_IDENTIFIER: {
                 if (opt_len != sizeof(struct dhcp_option_dhcp_server_identifier)) {
                     return;
                 }
-                struct dhcp_option_dhcp_server_identifier *val = optval;
+                struct dhcp_option_dhcp_server_identifier val;
+                memcpy(&val, optval, sizeof(val));
                 
-                dhcp_server_identifier = val->id;
+                dhcp_server_identifier = val.id;
                 have_dhcp_server_identifier = 1;
             } break;
             
@@ -304,9 +339,10 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
                 if (opt_len != sizeof(struct dhcp_option_time)) {
                     return;
                 }
-                struct dhcp_option_time *val = optval;
+                struct dhcp_option_time val;
+                memcpy(&val, optval, sizeof(val));
                 
-                ip_address_lease_time = ntoh32(val->time);
+                ip_address_lease_time = ntoh32(val.time);
                 have_ip_address_lease_time = 1;
             } break;
             
@@ -314,9 +350,10 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
                 if (opt_len != sizeof(struct dhcp_option_addr)) {
                     return;
                 }
-                struct dhcp_option_addr *val = optval;
+                struct dhcp_option_addr val;
+                memcpy(&val, optval, sizeof(val));
                 
-                subnet_mask = val->addr;
+                subnet_mask = val.addr;
                 have_subnet_mask = 1;
             } break;
             
@@ -324,22 +361,25 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
                 if (opt_len != sizeof(struct dhcp_option_addr)) {
                     return;
                 }
-                struct dhcp_option_addr *val = optval;
+                struct dhcp_option_addr val;
+                memcpy(&val, optval, sizeof(val));
                 
-                router = val->addr;
+                router = val.addr;
                 have_router = 1;
             } break;
             
             case DHCP_OPTION_DOMAIN_NAME_SERVER: {
-                if (opt_len % 4) {
+                if (opt_len % sizeof(struct dhcp_option_addr)) {
                     return;
                 }
                 
-                int num_servers = opt_len / 4;
+                int num_servers = opt_len / sizeof(struct dhcp_option_addr);
                 
                 int i;
                 for (i = 0; i < num_servers && i < BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS; i++) {
-                    domain_name_servers[i] = ((struct dhcp_option_addr *)optval + i)->addr;
+                    struct dhcp_option_addr addr;
+                    memcpy(&addr, optval + i * sizeof(addr), sizeof(addr));
+                    domain_name_servers[i] = addr.addr;
                 }
                 
                 domain_name_servers_count = i;
@@ -423,7 +463,7 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
         return;
     }
     
-    if (ntoh32(o->recv_buf->yiaddr) == 0) {
+    if (ntoh32(header.yiaddr) == 0) {
         return;
     }
     
@@ -439,7 +479,7 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
         BLog(BLOG_INFO, "received OFFER");
         
         // remember offer
-        o->offered.yiaddr = o->recv_buf->yiaddr;
+        o->offered.yiaddr = header.yiaddr;
         o->offered.dhcp_server_identifier = dhcp_server_identifier;
         
         // send request
@@ -458,7 +498,7 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
         o->request_count = 1;
     }
     else if (o->state == STATE_SENT_REQUEST && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) {
-        if (o->recv_buf->yiaddr != o->offered.yiaddr) {
+        if (header.yiaddr != o->offered.yiaddr) {
             return;
         }
         
@@ -493,7 +533,7 @@ static void recv_handler_done (BDHCPClientCore *o, int data_len)
         return;
     }
     else if (o->state == STATE_RENEWING && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) {
-        if (o->recv_buf->yiaddr != o->offered.yiaddr) {
+        if (header.yiaddr != o->offered.yiaddr) {
             return;
         }
         

+ 2 - 3
dhcpclient/BDHCPClientCore.h

@@ -37,7 +37,6 @@
 #include <stdint.h>
 #include <stddef.h>
 
-#include <misc/dhcp_proto.h>
 #include <system/BReactor.h>
 #include <base/DebugObject.h>
 #include <random/BRandom2.h>
@@ -72,8 +71,8 @@ typedef struct {
     char *vendorclassid;
     uint8_t *clientid;
     size_t clientid_len;
-    struct dhcp_header *send_buf;
-    struct dhcp_header *recv_buf;
+    char *send_buf;
+    char *recv_buf;
     int sending;
     BTimer reset_timer;
     BTimer request_timer;