summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorclaudio <>2008-11-24 20:08:49 +0000
committerclaudio <>2008-11-24 20:08:49 +0000
commit1cb9fdc86cd93809f9606b4865b35475b00b7933 (patch)
tree5e3df59e7fdbdee8b5350d4479dc16f459c64429 /src
parent4483ecc8aa0fe10a3c5ed81f2f06c03dfbc1241c (diff)
downloadopenbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.tar.gz
openbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.tar.bz2
openbsd-1cb9fdc86cd93809f9606b4865b35475b00b7933.zip
Correctly jump over routing headers and calculate the size of the if_data
struct in the if_msghdr instead of using sizeof() blindly. This allows us to grow if_data without causing issues for the getifaddrs() users. OK deraadt@ (who needs this for some cool upcomming stuff)
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/net/getifaddrs.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c
index 0db89f6c19..6f7ea15721 100644
--- a/src/lib/libc/net/getifaddrs.c
+++ b/src/lib/libc/net/getifaddrs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getifaddrs.c,v 1.9 2002/08/09 06:12:25 itojun Exp $ */ 1/* $OpenBSD: getifaddrs.c,v 1.10 2008/11/24 20:08:49 claudio Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1995, 1999 4 * Copyright (c) 1995, 1999
@@ -36,6 +36,7 @@
36 36
37#include <errno.h> 37#include <errno.h>
38#include <ifaddrs.h> 38#include <ifaddrs.h>
39#include <stddef.h>
39#include <stdlib.h> 40#include <stdlib.h>
40#include <string.h> 41#include <string.h>
41#include <unistd.h> 42#include <unistd.h>
@@ -61,7 +62,7 @@ getifaddrs(struct ifaddrs **pif)
61 struct sockaddr_dl *dl; 62 struct sockaddr_dl *dl;
62 struct sockaddr *sa; 63 struct sockaddr *sa;
63 u_short index = 0; 64 u_short index = 0;
64 size_t len, alen; 65 size_t len, alen, dlen;
65 struct ifaddrs *ifa, *ift; 66 struct ifaddrs *ifa, *ift;
66 int i; 67 int i;
67 char *data; 68 char *data;
@@ -92,7 +93,8 @@ getifaddrs(struct ifaddrs **pif)
92 if (ifm->ifm_addrs & RTA_IFP) { 93 if (ifm->ifm_addrs & RTA_IFP) {
93 index = ifm->ifm_index; 94 index = ifm->ifm_index;
94 ++icnt; 95 ++icnt;
95 dl = (struct sockaddr_dl *)(ifm + 1); 96 dl = (struct sockaddr_dl *)(next +
97 rtm->rtm_hdrlen);
96 dcnt += SA_RLEN((struct sockaddr *)dl) + 98 dcnt += SA_RLEN((struct sockaddr *)dl) +
97 ALIGNBYTES; 99 ALIGNBYTES;
98 dcnt += sizeof(ifm->ifm_data); 100 dcnt += sizeof(ifm->ifm_data);
@@ -109,7 +111,7 @@ getifaddrs(struct ifaddrs **pif)
109#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) 111#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD)
110 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 112 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
111 break; 113 break;
112 p = (char *)(ifam + 1); 114 p = next + rtm->rtm_hdrlen;
113 ++icnt; 115 ++icnt;
114 /* Scan to look for length of address */ 116 /* Scan to look for length of address */
115 alen = 0; 117 alen = 0;
@@ -169,7 +171,8 @@ getifaddrs(struct ifaddrs **pif)
169 ifm = (struct if_msghdr *)rtm; 171 ifm = (struct if_msghdr *)rtm;
170 if (ifm->ifm_addrs & RTA_IFP) { 172 if (ifm->ifm_addrs & RTA_IFP) {
171 index = ifm->ifm_index; 173 index = ifm->ifm_index;
172 dl = (struct sockaddr_dl *)(ifm + 1); 174 dl = (struct sockaddr_dl *)(next +
175 rtm->rtm_hdrlen);
173 176
174 cif = ift; 177 cif = ift;
175 ift->ifa_name = names; 178 ift->ifa_name = names;
@@ -185,7 +188,11 @@ getifaddrs(struct ifaddrs **pif)
185 188
186 /* ifm_data needs to be aligned */ 189 /* ifm_data needs to be aligned */
187 ift->ifa_data = data = (void *)ALIGN(data); 190 ift->ifa_data = data = (void *)ALIGN(data);
188 memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); 191 dlen = rtm->rtm_hdrlen -
192 offsetof(struct if_msghdr, ifm_data);
193 if (dlen > sizeof(ifm->ifm_data))
194 dlen = sizeof(ifm->ifm_data);
195 memcpy(data, &ifm->ifm_data, dlen);
189 data += sizeof(ifm->ifm_data); 196 data += sizeof(ifm->ifm_data);
190 197
191 ift = (ift->ifa_next = ift + 1); 198 ift = (ift->ifa_next = ift + 1);
@@ -203,7 +210,7 @@ getifaddrs(struct ifaddrs **pif)
203 ift->ifa_name = cif->ifa_name; 210 ift->ifa_name = cif->ifa_name;
204 ift->ifa_flags = cif->ifa_flags; 211 ift->ifa_flags = cif->ifa_flags;
205 ift->ifa_data = NULL; 212 ift->ifa_data = NULL;
206 p = (char *)(ifam + 1); 213 p = next + rtm->rtm_hdrlen;
207 /* Scan to look for length of address */ 214 /* Scan to look for length of address */
208 alen = 0; 215 alen = 0;
209 for (p0 = p, i = 0; i < RTAX_MAX; i++) { 216 for (p0 = p, i = 0; i < RTAX_MAX; i++) {