| 135 | }; |
| 136 | |
| 137 | static void |
| 138 | in_getaddr(const char *s, int which) |
| 139 | { |
| 140 | struct sockaddr_in *sin = sintab[which]; |
| 141 | #ifndef FSTACK |
| 142 | struct hostent *hp; |
| 143 | struct netent *np; |
| 144 | #endif |
| 145 | |
| 146 | sin->sin_len = sizeof(*sin); |
| 147 | sin->sin_family = AF_INET; |
| 148 | |
| 149 | if (which == ADDR) { |
| 150 | char *p = NULL; |
| 151 | |
| 152 | if((p = strrchr(s, '/')) != NULL) { |
| 153 | const char *errstr; |
| 154 | /* address is `name/masklen' */ |
| 155 | int masklen; |
| 156 | struct sockaddr_in *min = sintab[MASK]; |
| 157 | *p = '\0'; |
| 158 | if (!isdigit(*(p + 1))) |
| 159 | errstr = "invalid"; |
| 160 | else |
| 161 | masklen = (int)strtonum(p + 1, 0, 32, &errstr); |
| 162 | if (errstr != NULL) { |
| 163 | *p = '/'; |
| 164 | errx(1, "%s: bad value (width %s)", s, errstr); |
| 165 | } |
| 166 | min->sin_family = AF_INET; |
| 167 | min->sin_len = sizeof(*min); |
| 168 | min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & |
| 169 | 0xffffffff); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | if (inet_aton(s, &sin->sin_addr)) |
| 174 | return; |
| 175 | #ifdef FSTACK |
| 176 | else |
| 177 | errx(1, "%s: bad value", s); |
| 178 | #else |
| 179 | if ((hp = gethostbyname(s)) != NULL) |
| 180 | bcopy(hp->h_addr, (char *)&sin->sin_addr, |
| 181 | MIN((size_t)hp->h_length, sizeof(sin->sin_addr))); |
| 182 | else if ((np = getnetbyname(s)) != NULL) |
| 183 | sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); |
| 184 | else |
| 185 | errx(1, "%s: bad value", s); |
| 186 | #endif |
| 187 | } |
| 188 | |
| 189 | static void |
| 190 | in_status_tunnel(int s) |