| 100 | } |
| 101 | |
| 102 | static int match_address(const char *addr, char *tok) |
| 103 | { |
| 104 | char *p; |
| 105 | struct addrinfo hints, *resa, *rest; |
| 106 | int gai; |
| 107 | int ret = 0; |
| 108 | int addrlen = 0; |
| 109 | #ifdef HAVE_STRTOL |
| 110 | long int bits; |
| 111 | #else |
| 112 | int bits; |
| 113 | #endif |
| 114 | char mask[16]; |
| 115 | char *a = NULL, *t = NULL; |
| 116 | |
| 117 | if (!addr || !*addr) |
| 118 | return 0; |
| 119 | |
| 120 | p = strchr(tok,'/'); |
| 121 | if (p) |
| 122 | *p = '\0'; |
| 123 | |
| 124 | /* Fail quietly if tok is a hostname, not an address. */ |
| 125 | if (tok[strspn(tok, ".0123456789")] && strchr(tok, ':') == NULL) { |
| 126 | if (p) |
| 127 | *p = '/'; |
| 128 | return 0; |
| 129 | } |
| 130 | |
| 131 | memset(&hints, 0, sizeof(hints)); |
| 132 | hints.ai_family = PF_UNSPEC; |
| 133 | hints.ai_socktype = SOCK_STREAM; |
| 134 | #ifdef AI_NUMERICHOST |
| 135 | hints.ai_flags = AI_NUMERICHOST; |
| 136 | #endif |
| 137 | |
| 138 | if (getaddrinfo(addr, NULL, &hints, &resa) != 0) { |
| 139 | if (p) |
| 140 | *p = '/'; |
| 141 | return 0; |
| 142 | } |
| 143 | |
| 144 | gai = getaddrinfo(tok, NULL, &hints, &rest); |
| 145 | if (p) |
| 146 | *p++ = '/'; |
| 147 | if (gai != 0) { |
| 148 | rprintf(FLOG, "error matching address %s: %s\n", |
| 149 | tok, gai_strerror(gai)); |
| 150 | freeaddrinfo(resa); |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | if (rest->ai_family != resa->ai_family) { |
| 155 | ret = 0; |
| 156 | goto out; |
| 157 | } |
| 158 | |
| 159 | switch(resa->ai_family) { |
no test coverage detected