diff options
Diffstat (limited to 'crypto/heimdal/lib/roken/getifaddrs.c')
-rw-r--r-- | crypto/heimdal/lib/roken/getifaddrs.c | 112 |
1 files changed, 90 insertions, 22 deletions
diff --git a/crypto/heimdal/lib/roken/getifaddrs.c b/crypto/heimdal/lib/roken/getifaddrs.c index e8c53f8..485c0d6 100644 --- a/crypto/heimdal/lib/roken/getifaddrs.c +++ b/crypto/heimdal/lib/roken/getifaddrs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 2000 - 2002, 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: getifaddrs.c,v 1.9 2002/09/05 03:36:23 assar Exp $"); +RCSID("$Id: getifaddrs.c 21745 2007-07-31 16:11:25Z lha $"); #endif #include "roken.h" @@ -56,6 +56,21 @@ struct mbuf; #include <ifaddrs.h> +#ifdef __hpux +#define lifconf if_laddrconf +#define lifc_len iflc_len +#define lifc_buf iflc_buf +#define lifc_req iflc_req + +#define lifreq if_laddrreq +#define lifr_addr iflr_addr +#define lifr_name iflr_name +#define lifr_dstaddr iflr_dstaddr +#define lifr_broadaddr iflr_broadaddr +#define lifr_flags iflr_flags +#define lifr_index iflr_index +#endif + #ifdef AF_NETLINK /* @@ -108,6 +123,7 @@ struct mbuf; #include <linux/rtnetlink.h> #include <sys/types.h> #include <sys/socket.h> +#include <sys/poll.h> #include <netpacket/packet.h> #include <net/ethernet.h> /* the L2 protocols */ #include <sys/uio.h> @@ -172,6 +188,7 @@ ifa_sa_len(sa_family_t family, int len) size = (size_t)(((struct sockaddr *)NULL)->sa_data) + len; if (size < sizeof(struct sockaddr)) size = sizeof(struct sockaddr); + break; } return size; } @@ -377,13 +394,30 @@ nl_getlist(int sd, int seq, struct nlmsghdr *nlh = NULL; int status; int done = 0; + int tries = 3; + try_again: status = nl_sendreq(sd, request, NLM_F_ROOT|NLM_F_MATCH, &seq); if (status < 0) return status; if (seq == 0) seq = (int)time(NULL); while(!done){ + struct pollfd pfd; + + pfd.fd = sd; + pfd.events = POLLIN | POLLPRI; + pfd.revents = 0; + status = poll(&pfd, 1, 1000); + if (status < 0) + return status; + else if (status == 0) { + seq++; + if (tries-- > 0) + goto try_again; + return -1; + } + status = nl_getmsg(sd, request, seq, &nlh, &done); if (status < 0) return status; @@ -416,16 +450,17 @@ nl_getlist(int sd, int seq, static void free_nlmsglist(struct nlmsg_list *nlm0) { - struct nlmsg_list *nlm; + struct nlmsg_list *nlm, *nlm_next; int saved_errno; if (!nlm0) return; saved_errno = errno; - for (nlm=nlm0; nlm; nlm=nlm->nlm_next){ + for (nlm=nlm0; nlm; nlm=nlm_next){ if (nlm->nlh) free(nlm->nlh); + nlm_next=nlm->nlm_next; + free(nlm); } - free(nlm0); __set_errno(saved_errno); } @@ -466,7 +501,8 @@ nl_open(void) } /* ====================================================================== */ -int getifaddrs(struct ifaddrs **ifap) +int ROKEN_LIB_FUNCTION +rk_getifaddrs(struct ifaddrs **ifap) { int sd; struct nlmsg_list *nlmsg_list, *nlmsg_end, *nlm; @@ -669,6 +705,7 @@ int getifaddrs(struct ifaddrs **ifap) case IFLA_QDISC: break; default: + break; } break; case RTM_NEWADDR: @@ -709,6 +746,7 @@ int getifaddrs(struct ifaddrs **ifap) case IFA_CACHEINFO: break; default: + break; } } } @@ -818,14 +856,6 @@ int getifaddrs(struct ifaddrs **ifap) return 0; } -/* ---------------------------------------------------------------------- */ -void -freeifaddrs(struct ifaddrs *ifa) -{ - free(ifa); -} - - #else /* !AF_NETLINK */ /* @@ -919,8 +949,16 @@ getifaddrs2(struct ifaddrs **ifap, (*end)->ifa_next = NULL; (*end)->ifa_name = strdup(ifr->ifr_name); + if ((*end)->ifa_name == NULL) { + ret = ENOMEM; + goto error_out; + } (*end)->ifa_flags = ifreq.ifr_flags; (*end)->ifa_addr = malloc(salen); + if ((*end)->ifa_addr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_addr, sa, salen); (*end)->ifa_netmask = NULL; @@ -928,10 +966,18 @@ getifaddrs2(struct ifaddrs **ifap, /* fix these when we actually need them */ if(ifreq.ifr_flags & IFF_BROADCAST) { (*end)->ifa_broadaddr = malloc(sizeof(ifr->ifr_broadaddr)); + if ((*end)->ifa_broadaddr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_broadaddr, &ifr->ifr_broadaddr, sizeof(ifr->ifr_broadaddr)); } else if(ifreq.ifr_flags & IFF_POINTOPOINT) { (*end)->ifa_dstaddr = malloc(sizeof(ifr->ifr_dstaddr)); + if ((*end)->ifa_dstaddr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_dstaddr, &ifr->ifr_dstaddr, sizeof(ifr->ifr_dstaddr)); } else @@ -950,7 +996,7 @@ getifaddrs2(struct ifaddrs **ifap, free(buf); return 0; error_out: - freeifaddrs(start); + rk_freeifaddrs(start); close(fd); free(buf); errno = ret; @@ -988,8 +1034,10 @@ getlifaddrs2(struct ifaddrs **ifap, ret = ENOMEM; goto error_out; } +#ifndef __hpux ifconf.lifc_family = AF_UNSPEC; ifconf.lifc_flags = 0; +#endif ifconf.lifc_len = buf_size; ifconf.lifc_buf = buf; @@ -1040,11 +1088,23 @@ getlifaddrs2(struct ifaddrs **ifap, } *end = malloc(sizeof(**end)); + if (*end == NULL) { + ret = ENOMEM; + goto error_out; + } (*end)->ifa_next = NULL; (*end)->ifa_name = strdup(ifr->lifr_name); + if ((*end)->ifa_name == NULL) { + ret = ENOMEM; + goto error_out; + } (*end)->ifa_flags = ifreq.lifr_flags; (*end)->ifa_addr = malloc(salen); + if ((*end)->ifa_addr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_addr, sa, salen); (*end)->ifa_netmask = NULL; @@ -1052,10 +1112,18 @@ getlifaddrs2(struct ifaddrs **ifap, /* fix these when we actually need them */ if(ifreq.ifr_flags & IFF_BROADCAST) { (*end)->ifa_broadaddr = malloc(sizeof(ifr->ifr_broadaddr)); + if ((*end)->ifa_broadaddr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_broadaddr, &ifr->ifr_broadaddr, sizeof(ifr->ifr_broadaddr)); } else if(ifreq.ifr_flags & IFF_POINTOPOINT) { (*end)->ifa_dstaddr = malloc(sizeof(ifr->ifr_dstaddr)); + if ((*end)->ifa_dstaddr == NULL) { + ret = ENOMEM; + goto error_out; + } memcpy((*end)->ifa_dstaddr, &ifr->ifr_dstaddr, sizeof(ifr->ifr_dstaddr)); } else @@ -1074,7 +1142,7 @@ getlifaddrs2(struct ifaddrs **ifap, free(buf); return 0; error_out: - freeifaddrs(start); + rk_freeifaddrs(start); close(fd); free(buf); errno = ret; @@ -1082,8 +1150,8 @@ getlifaddrs2(struct ifaddrs **ifap, } #endif /* defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS) */ -int -getifaddrs(struct ifaddrs **ifap) +int ROKEN_LIB_FUNCTION +rk_getifaddrs(struct ifaddrs **ifap) { int ret = -1; errno = ENXIO; @@ -1110,8 +1178,10 @@ getifaddrs(struct ifaddrs **ifap) return ret; } -void -freeifaddrs(struct ifaddrs *ifp) +#endif /* !AF_NETLINK */ + +void ROKEN_LIB_FUNCTION +rk_freeifaddrs(struct ifaddrs *ifp) { struct ifaddrs *p, *q; @@ -1131,8 +1201,6 @@ freeifaddrs(struct ifaddrs *ifp) } } -#endif /* !AF_NETLINK */ - #ifdef TEST void |