diff options
author | taesubkim <taesub.kim@samsung.com> | 2016-04-26 15:47:01 +0900 |
---|---|---|
committer | taesubkim <taesub.kim@samsung.com> | 2016-04-26 16:14:46 +0900 |
commit | 22633ced6225d294ce8483efbf2b39ea0c0c1b65 (patch) | |
tree | 8c5f2312feec413068a18e57a80321b31b4f7b74 /gdhcp/common.c | |
parent | bcae74da8fa2958b3fec9153fc33e41f0e0317bf (diff) | |
download | connman-22633ced6225d294ce8483efbf2b39ea0c0c1b65.tar.gz connman-22633ced6225d294ce8483efbf2b39ea0c0c1b65.tar.bz2 connman-22633ced6225d294ce8483efbf2b39ea0c0c1b65.zip |
Imported Upstream version 1.29upstream/1.29
Change-Id: I2958446c35966d9ed72df0120b80561be7d89f54
Signed-off-by: Taesub Kim <taesub.kim@samsung.com>
Diffstat (limited to 'gdhcp/common.c')
-rw-r--r-- | gdhcp/common.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/gdhcp/common.c b/gdhcp/common.c index 45278a88..f3d4677e 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(uint64_t)) < 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; @@ -434,19 +473,14 @@ uint16_t dhcp_checksum(void *addr, int count) static const struct in6_addr in6addr_all_dhcp_relay_agents_and_servers_mc = IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_MC_INIT; -/* from netinet/in.h */ -struct in6_pktinfo { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ -}; - int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) { struct msghdr m; struct iovec v; struct in6_pktinfo *pktinfo; struct cmsghdr *cmsg; - int fd, ret; + int fd, ret, opt = 1; + struct sockaddr_in6 src; struct sockaddr_in6 dst; void *control_buf; size_t control_buf_len; @@ -455,6 +489,17 @@ int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len) if (fd < 0) return -errno; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + memset(&src, 0, sizeof(src)); + src.sin6_family = AF_INET6; + src.sin6_port = htons(DHCPV6_CLIENT_PORT); + + if (bind(fd, (struct sockaddr *) &src, sizeof(src)) <0) { + close(fd); + return -errno; + } + memset(&dst, 0, sizeof(dst)); dst.sin6_family = AF_INET6; dst.sin6_port = htons(DHCPV6_SERVER_PORT); |