From 6aa4055ef0544ae85457c25c510fe3db04949c43 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Fri, 7 Aug 2015 17:11:34 +0900 Subject: Base Code merged to SPIN 2.4 Signed-off-by: hyunuktak Change-Id: I84a42375b5c59739e4caca1f726699ea7647ef17 --- gdhcp/common.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 8 deletions(-) mode change 100644 => 100755 gdhcp/common.c (limited to 'gdhcp/common.c') diff --git a/gdhcp/common.c b/gdhcp/common.c old mode 100644 new mode 100755 index ac6b1250..6d457ac5 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -35,6 +35,7 @@ #include #include #include +#include #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; @@ -421,12 +458,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; @@ -499,19 +538,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; @@ -520,6 +554,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); -- cgit v1.2.3