diff options
author | David Cantrell <dcantrell@redhat.com> | 2007-03-06 21:13:21 +0000 |
---|---|---|
committer | David Cantrell <dcantrell@redhat.com> | 2007-03-06 21:13:21 +0000 |
commit | 0c522cc5943e5f87b5f5cccd24b315547c412355 (patch) | |
tree | 97dc52995e9ae4027b02636c9c7de78df1d27f00 /isys | |
parent | c6b124809a07724adc1263fd3a088e2222ae2a3a (diff) | |
download | anaconda-0c522cc5943e5f87b5f5cccd24b315547c412355.tar.gz anaconda-0c522cc5943e5f87b5f5cccd24b315547c412355.tar.xz anaconda-0c522cc5943e5f87b5f5cccd24b315547c412355.zip |
* isys/nl.c (netlink_init_interfaces_list): Handle netlink messages
for RTM_GETLINK that are larger than 4K. This allows us to handle a
variable number of network devices in the system (#230525).
Diffstat (limited to 'isys')
-rw-r--r-- | isys/nl.c | 38 |
1 files changed, 31 insertions, 7 deletions
@@ -258,7 +258,8 @@ int netlink_get_interface_ip(int index, int family, void *addr) { */ int netlink_init_interfaces_list(void) { int sock, ret, len, alen, r; - char buf[4096]; + char chunk[4096]; + char *buf = NULL; struct nlmsghdr *nlh; struct ifinfomsg *ifi; struct rtattr *rta; @@ -267,25 +268,48 @@ int netlink_init_interfaces_list(void) { /* get a socket */ if ((sock = netlink_create_socket()) == -1) { - perror("netlink_create_socket in netlink_init_interfaces_table"); + perror("netlink_create_socket in netlink_init_interfaces_list"); close(sock); return -1; } /* send dump request */ if (netlink_send_dump_request(sock, RTM_GETLINK, AF_NETLINK) == -1) { - perror("netlink_send_dump_request in netlink_init_interfaces_table"); + perror("netlink_send_dump_request in netlink_init_interfaces_list"); close(sock); return -1; } /* read back messages */ - memset(buf, 0, sizeof(buf)); - ret = recvfrom(sock, buf, sizeof(buf), 0, NULL, 0); + if ((buf = calloc(4096, sizeof(char))) == NULL) { + perror("malloc on buf in netlink_init_interfaces_list"); + close(sock); + return -1; + } + + ret = recvfrom(sock, chunk, sizeof(chunk), MSG_DONTWAIT, NULL, 0); if (ret < 0) { - perror("recvfrom in netlink_init_interfaces_table"); + perror("recvfrom in netlink_init_interfaces_list"); close(sock); return -1; + } else { + buf = strncat(buf, chunk, strlen(chunk)); + } + + /* read remaining part of message */ + while (ret != -1) { + ret = recvfrom(sock, chunk, sizeof(chunk), MSG_DONTWAIT, NULL, 0); + + if (ret > 0) { + buf = realloc(buf, strlen(buf) + ret + 1); + if (buf == NULL) { + perror("realloc on buf in netlink_init_interfaces_list"); + close(sock); + return -1; + } + + buf = strncat(buf, chunk, strlen(chunk)); + } } nlh = (struct nlmsghdr *) buf; @@ -327,7 +351,7 @@ int netlink_init_interfaces_list(void) { /* make some room! */ intfinfo = malloc(sizeof(struct _interface_info_t)); if (intfinfo == NULL) { - perror("malloc in netlink_init_interfaces_table"); + perror("malloc in netlink_init_interfaces_list"); close(sock); return -1; } |