| 79 | */ |
| 80 | |
| 81 | struct if_nameindex * |
| 82 | if_nameindex(void) |
| 83 | { |
| 84 | struct ifaddrs *ifaddrs, *ifa; |
| 85 | unsigned int ni; |
| 86 | int nbytes; |
| 87 | struct if_nameindex *ifni, *ifni2; |
| 88 | char *cp; |
| 89 | |
| 90 | if (getifaddrs(&ifaddrs) < 0) |
| 91 | return(NULL); |
| 92 | |
| 93 | /* |
| 94 | * First, find out how many interfaces there are, and how |
| 95 | * much space we need for the string names. |
| 96 | */ |
| 97 | ni = 0; |
| 98 | nbytes = 0; |
| 99 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { |
| 100 | if (ifa->ifa_addr && |
| 101 | ifa->ifa_addr->sa_family == AF_LINK) { |
| 102 | nbytes += strlen(ifa->ifa_name) + 1; |
| 103 | ni++; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | /* |
| 108 | * Next, allocate a chunk of memory, use the first part |
| 109 | * for the array of structures, and the last part for |
| 110 | * the strings. |
| 111 | */ |
| 112 | cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes); |
| 113 | ifni = (struct if_nameindex *)cp; |
| 114 | if (ifni == NULL) |
| 115 | goto out; |
| 116 | cp += (ni + 1) * sizeof(struct if_nameindex); |
| 117 | |
| 118 | /* |
| 119 | * Now just loop through the list of interfaces again, |
| 120 | * filling in the if_nameindex array and making copies |
| 121 | * of all the strings. |
| 122 | */ |
| 123 | ifni2 = ifni; |
| 124 | for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { |
| 125 | if (ifa->ifa_addr && |
| 126 | ifa->ifa_addr->sa_family == AF_LINK) { |
| 127 | ifni2->if_index = |
| 128 | LLINDEX((struct sockaddr_dl*)ifa->ifa_addr); |
| 129 | ifni2->if_name = cp; |
| 130 | strcpy(cp, ifa->ifa_name); |
| 131 | ifni2++; |
| 132 | cp += strlen(cp) + 1; |
| 133 | } |
| 134 | } |
| 135 | /* |
| 136 | * Finally, don't forget to terminate the array. |
| 137 | */ |
| 138 | ifni2->if_index = 0; |
nothing calls this directly
no test coverage detected