From: Roy Marples Date: Fri, 6 May 2016 13:02:41 +0000 (+0000) Subject: Move dhcp6's read lease code into dhcp-common. X-Git-Tag: v6.11.0~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=416a319e23031e0dff2d5c5f95d73ddcde052cd4;p=thirdparty%2Fdhcpcd.git Move dhcp6's read lease code into dhcp-common. While here, fix MTU min/max. --- diff --git a/dhcp-common.c b/dhcp-common.c index d8028ce7..74336fd6 100644 --- a/dhcp-common.c +++ b/dhcp-common.c @@ -1056,3 +1056,39 @@ dhcp_zero_index(struct dhcp_opt *opt) for (i = 0, o = opt->encopts; i < opt->encopts_len; i++, o++) dhcp_zero_index(o); } + +size_t +dhcp_read_lease_fd(int fd, uint8_t **lease) +{ + uint8_t *buf, *nbuf; + size_t len, new_len; + ssize_t bytes; + + if ((buf = malloc(BUFSIZ)) == NULL) + goto out; + + len = 0; + for (;;) { + bytes = read(fd, buf + len, BUFSIZ); + if (bytes == -1) + break; + if (bytes < BUFSIZ) { + *lease = buf; + return len + (size_t)bytes; + } + new_len = len + (BUFSIZ * 2); + if (new_len > UINT32_MAX || new_len < len) { + errno = E2BIG; + break; + } + if ((nbuf = realloc(buf, new_len)) == NULL) + break; + buf = nbuf; + len += BUFSIZ; + } + + free(buf); +out: + *lease = NULL; + return 0; +} diff --git a/dhcp-common.h b/dhcp-common.h index f576a172..61eccf18 100644 --- a/dhcp-common.h +++ b/dhcp-common.h @@ -37,8 +37,9 @@ #include "dhcpcd.h" /* Max MTU - defines dhcp option length */ -#define MTU_MAX 1500 -#define MTU_MIN 576 +#define IP_UDP_SIZE 28 +#define MTU_MAX 1500 - IP_UDP_SIZE +#define MTU_MIN 576 + IP_UDP_SIZE #define OT_REQUEST (1 << 0) #define OT_UINT8 (1 << 1) @@ -117,5 +118,6 @@ size_t dhcp_envoption(struct dhcpcd_ctx *, const uint8_t *, size_t, struct dhcp_opt **), const uint8_t *od, size_t ol); void dhcp_zero_index(struct dhcp_opt *); +size_t dhcp_read_lease_fd(int, uint8_t **); #endif diff --git a/dhcp6.c b/dhcp6.c index d5457e37..3c1f060f 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2162,18 +2162,16 @@ dhcp6_readlease(struct interface *ifp, int validate) struct dhcp6_state *state; struct stat st; int fd; - ssize_t bytes; + uint8_t *lease; const struct dhcp6_option *o; struct timespec acquired; time_t now; int retval; - size_t newlen; - void *newnew; bool fd_opened; state = D6_STATE(ifp); if (state->leasefile[0] == '\0') { - logger(ifp->ctx, LOG_DEBUG, "reading standard input"); + logger(ifp->ctx, LOG_DEBUG, "reading standard input"); fd = fileno(stdin); fd_opened = false; } else { @@ -2188,39 +2186,13 @@ dhcp6_readlease(struct interface *ifp, int validate) } if (fd == -1) return -1; - state->new_len = 0; - if ((state->new = malloc(BUFSIZ)) == NULL) { - if (fd_opened) - close(fd); - return -1; - } retval = -1; - /* DHCPv6 messages have no real maximum size. - * As we could be reading from stdin, we loop like so. - * state->new_len refers to the buffer position, - * but the buffer itself always BUFSIZ bigger. */ - for (;;) { - bytes = read(fd, (char *)state->new + state->new_len, BUFSIZ); - if (bytes == -1) - break; - if (bytes < BUFSIZ) { - state->new_len += (size_t)bytes; - retval = 0; - break; - } - newlen = state->new_len + (BUFSIZ * 2); - if (newlen > UINT32_MAX || newlen < state->new_len) { - errno = E2BIG; - break; - } - if ((newnew = realloc(state->new, newlen)) == NULL) - break; - state->new = newnew; - state->new_len += BUFSIZ; - } + lease = NULL; + state->new_len = dhcp_read_lease_fd(fd, &lease); + state->new = (struct dhcp6_message *)lease; if (fd_opened) close(fd); - if (retval == -1) + if (state->new_len == 0) goto ex; if (ifp->ctx->options & DHCPCD_DUMPLEASE || @@ -2234,7 +2206,6 @@ dhcp6_readlease(struct interface *ifp, int validate) goto auth; } - retval = -1; clock_gettime(CLOCK_MONOTONIC, &acquired); if ((now = time(NULL)) == -1) goto ex;