]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix some valgrind errors, and work on Linux again.
authorRoy Marples <roy@marples.name>
Thu, 15 May 2008 11:12:44 +0000 (11:12 +0000)
committerRoy Marples <roy@marples.name>
Thu, 15 May 2008 11:12:44 +0000 (11:12 +0000)
bpf.c
client.c
net.c
net.h
socket.c

diff --git a/bpf.c b/bpf.c
index 7d42953318ab82107633ec2306ca1e394629b90e..46a08c55fd512eccc12e9a7b3521664903ea498a 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -153,22 +153,24 @@ get_packet(struct interface *iface, void *data, ssize_t len)
 {
        struct bpf_hdr packet;
        struct ether_header hw;
-       ssize_t cur_len;
+       ssize_t bytes;
        const unsigned char *payload, *d;
 
+       if ((size_t)len > iface->buffer_size) {
+               errno = ENOBUFS;
+               return -1;
+       }
        for (;;) {
                if (iface->buffer_len == 0) {
-                       cur_len = read(iface->fd, iface->buffer,
-                                      iface->buffer_size);
-                       if (cur_len == -1)
+                       bytes = read(iface->fd, iface->buffer,
+                                    iface->buffer_size);
+                       if (bytes == -1)
                                return errno == EAGAIN ? 0 : -1;
-                       else if ((size_t)cur_len < sizeof(packet))
+                       else if ((size_t)bytes < sizeof(packet))
                                return -1;
-                       iface->buffer_len = cur_len;
+                       iface->buffer_len = bytes;
                }
-
-               cur_len = -1;
-
+               bytes = -1;
                memcpy(&packet, iface->buffer + iface->buffer_pos,
                       sizeof(packet));
                if (packet.bh_caplen != packet.bh_datalen)
@@ -179,19 +181,23 @@ get_packet(struct interface *iface, void *data, ssize_t len)
                memcpy(&hw, iface->buffer + packet.bh_hdrlen, sizeof(hw));
                payload = iface->buffer + packet.bh_hdrlen + sizeof(hw);
                if (hw.ether_type == htons(ETHERTYPE_ARP)) {
-                       cur_len = packet.bh_caplen - sizeof(hw);
-                       memcpy(data, payload, len);
+                       bytes = packet.bh_caplen - sizeof(hw);
+                       if (bytes > len)
+                               bytes = len;
+                       memcpy(data, payload, bytes);
                } else if (valid_udp_packet(payload) >= 0) {
-                       cur_len = get_udp_data(&d, payload);
-                       memcpy(data, d, cur_len);
+                       bytes = get_udp_data(&d, payload);
+                       if (bytes > len)
+                               bytes = len;
+                       memcpy(data, d, bytes);
                } else
-                       cur_len = -1;
+                       bytes = -1;
 next:
                iface->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
                                                   packet.bh_caplen);
                if (iface->buffer_pos >= iface->buffer_len)
                        iface->buffer_len = iface->buffer_pos = 0;
-               if (cur_len != -1)
-                       return cur_len;
+               if (bytes != -1)
+                       return bytes;
        }
 }
index 9639e85c81c1892d51851fa1bb70915ac87bf23e..9d14334807b3e3bb18ad50963f5dd0c59c6faf2f 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1188,7 +1188,8 @@ handle_packet(struct if_state *state, const struct options *options)
         * the first one fails for any reason, we can use the next. */
 
        dhcp = xmalloc(sizeof(*dhcp));
-       do {    
+       do {
+               memset(dhcp, 0, sizeof(*dhcp));
                bytes = get_packet(iface, dhcp, sizeof(*dhcp));
                if (bytes == -1)
                        break;
@@ -1287,6 +1288,7 @@ eexit:
                do_socket(state, SOCKET_CLOSED);
                free_routes(iface->routes);
                free(iface->clientid);
+               free(iface->buffer);
                free(iface);
        }
 
diff --git a/net.c b/net.c
index b79af24322bed041fb1e9d83eeaec0ea8aa0d4c4..6f7a7dec40fb25c32b4edc2c5594f1c501bee0d9 100644 (file)
--- a/net.c
+++ b/net.c
@@ -285,7 +285,6 @@ read_interface(const char *ifname, _unused int metric)
        unsigned char *hwaddr = NULL;
        size_t hwlen = 0;
        sa_family_t family = 0;
-       unsigned short mtu;
 #ifdef __linux__
        char *p;
 #endif
@@ -340,7 +339,6 @@ read_interface(const char *ifname, _unused int metric)
                if (ioctl(s, SIOCSIFMTU, &ifr) == -1)
                        goto eexit;
        }
-       mtu = ifr.ifr_mtu;
 
        strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
 #ifdef __linux__
diff --git a/net.h b/net.h
index 8e5d2b3734e91540fe12bb1e964ec2f306a1a397..e7ed5941082760edae2cb27f37bbbcceb905c6ff 100644 (file)
--- a/net.h
+++ b/net.h
@@ -105,7 +105,7 @@ struct interface
 
        int fd;
        int udp_fd;
-       size_t buffer_size, buffer_pos, buffer_len;
+       size_t buffer_size, buffer_len, buffer_pos;
        unsigned char *buffer;
 
 #ifdef __linux__
index 136a609b9a54efd434680886a873f50161a9a22b..ecf8f321599eb931c894c04e9c3c5c6a18ad145e 100644 (file)
--- a/socket.c
+++ b/socket.c
 #include "net.h"
 #include "bpf-filter.h"
 
-/* A suitably large buffer for all transactions.
- * BPF buffer size is set by the kernel, so no define. */
-#ifdef __linux__
-# define BUFFER_LENGTH 4096
-#endif
+/* A suitably large buffer for all transactions. */
+#define BUFFER_LENGTH 4096
 
 /* Broadcast address for IPoIB */
 static const uint8_t ipv4_bcast_addr[] = {
@@ -91,7 +88,7 @@ setup_packet_filters(void)
 int
 open_socket(struct interface *iface, int protocol)
 {
-       int flags, s;
+       int s;
        union sockunion {
                struct sockaddr sa;
                struct sockaddr_in sin;
@@ -132,7 +129,9 @@ open_socket(struct interface *iface, int protocol)
                close(iface->fd);
        iface->fd = s;
        iface->socket_protocol = protocol;
-       iface->buffer_length = 0;
+       iface->buffer_size = BUFFER_LENGTH;
+       iface->buffer = xmalloc(iface->buffer_size);
+       iface->buffer_len = iface->buffer_pos = 0;
        return s;
 
 eexit:
@@ -168,29 +167,27 @@ send_raw_packet(const struct interface *iface, int type,
        return sendto(iface->fd, data, len, 0, &su.sa, sizeof(su));
 }
 
-/* Linux has no need for the buffer as we can read as much as we want.
- * We only have the buffer listed to keep the same API. */
 ssize_t
 get_packet(struct interface *iface, void *data, ssize_t len)
 {
        ssize_t bytes;
-       struct timespec ts;
        const uint8_t *p;
 
-       memset(data, 0, len);
-       bytes = read(iface->fd, data, len);
+       bytes = read(iface->fd, iface->buffer, iface->buffer_size);
 
        if (bytes == -1)
-               return errno == EGAIN ? 0 : -1;
+               return errno == EAGAIN ? 0 : -1;
 
        /* If it's an ARP reply, then just send it back */
        if (iface->socket_protocol == ETHERTYPE_ARP)
                return bytes;
 
-       if (valid_udp_packet(data) != 0)
+       if (valid_udp_packet(iface->buffer) != 0)
                return -1;
 
-       bytes = get_udp_data(&p, buffer);
-       memmove(data, p, bytes);
+       bytes = get_udp_data(&p, iface->buffer);
+       if (bytes > len)
+               bytes = len;
+       memcpy(data, p, bytes);
        return bytes;
 }