| 79 | #define MAX_SYSCTL_TRY 5 |
| 80 | |
| 81 | int |
| 82 | getifaddrs(struct ifaddrs **pif) |
| 83 | { |
| 84 | int icnt = 1; |
| 85 | int dcnt = 0; |
| 86 | int ncnt = 0; |
| 87 | int ntry = 0; |
| 88 | int mib[6]; |
| 89 | size_t needed; |
| 90 | char *buf; |
| 91 | char *next; |
| 92 | struct ifaddrs *cif; |
| 93 | char *p, *p0; |
| 94 | struct rt_msghdr *rtm; |
| 95 | struct if_msghdrl *ifm; |
| 96 | struct ifa_msghdrl *ifam; |
| 97 | struct sockaddr_dl *dl; |
| 98 | struct sockaddr *sa; |
| 99 | struct ifaddrs *ifa, *ift; |
| 100 | struct if_data *if_data; |
| 101 | u_short idx = 0; |
| 102 | int i; |
| 103 | size_t len, alen; |
| 104 | char *data; |
| 105 | char *names; |
| 106 | |
| 107 | mib[0] = CTL_NET; |
| 108 | mib[1] = PF_ROUTE; |
| 109 | mib[2] = 0; /* protocol */ |
| 110 | mib[3] = 0; /* wildcard address family */ |
| 111 | mib[4] = NET_RT_IFLISTL;/* extra fields for extensible msghdr structs */ |
| 112 | mib[5] = 0; /* no flags */ |
| 113 | do { |
| 114 | /* |
| 115 | * We'll try to get addresses several times in case that |
| 116 | * the number of addresses is unexpectedly increased during |
| 117 | * the two sysctl calls. This should rarely happen, but we'll |
| 118 | * try to do our best for applications that assume success of |
| 119 | * this library (which should usually be the case). |
| 120 | * Portability note: since FreeBSD does not add margin of |
| 121 | * memory at the first sysctl, the possibility of failure on |
| 122 | * the second sysctl call is a bit higher. |
| 123 | */ |
| 124 | |
| 125 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) |
| 126 | return (-1); |
| 127 | if ((buf = malloc(needed)) == NULL) |
| 128 | return (-1); |
| 129 | if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { |
| 130 | if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { |
| 131 | free(buf); |
| 132 | return (-1); |
| 133 | } |
| 134 | free(buf); |
| 135 | buf = NULL; |
| 136 | } |
| 137 | } while (buf == NULL); |
| 138 |
no test coverage detected