Provide a function for fetching random values, either by reading
/dev/urandom or using libc. The caller is responsible for seeding
the libc random function prior to use, should a fallback to libc
function take place.
---
 gdhcp/common.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 gdhcp/gdhcp.h  |  4 ++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/gdhcp/common.c b/gdhcp/common.c
index 45278a8..4a7270b 100644
--- a/gdhcp/common.c
+++ b/gdhcp/common.c
@@ -35,6 +35,7 @@
 #include <netpacket/packet.h>
 #include <net/ethernet.h>
 #include <arpa/inet.h>
+#include <fcntl.h>
 
 #include "gdhcp.h"
 #include "common.h"
@@ -58,6 +59,42 @@ 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(*val)) < 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;
@@ -356,12 +393,14 @@ void dhcp_init_header(struct dhcp_packet *packet, char 
type)
 void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type)
 {
        int id;
+       uint64_t rand;
 
        memset(packet, 0, sizeof(*packet));
 
        packet->message = type;
 
-       id = random();
+       dhcp_get_random(&rand);
+       id = rand;
 
        packet->transaction_id[0] = (id >> 16) & 0xff;
        packet->transaction_id[1] = (id >> 8) & 0xff;
diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
index f3e47bf..ac24454 100644
--- a/gdhcp/gdhcp.h
+++ b/gdhcp/gdhcp.h
@@ -223,6 +223,10 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
                                                unsigned int lease_time);
 void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
                                GDHCPSaveLeaseFunc func, gpointer user_data);
+
+int dhcp_get_random(uint64_t *val);
+void dhcp_cleanup_random(void);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.1.1

_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to