ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/src/match.c
(Generate patch)

Comparing ircd-hybrid-7.2/src/match.c (file contents):
Revision 34 by lusky, Sun Oct 2 21:05:51 2005 UTC vs.
Revision 371 by michael, Tue Jan 10 10:45:48 2006 UTC

# Line 192 | Line 192 | match_chan(const char *mask, const char
192    return *mask ? (*mask == *name && match_esc(mask + 1, name + 1)) : !*name;
193   }
194  
195 static inline int
196 comp_with_mask(void *addr, void *dest, unsigned int mask)
197 {
198  if (memcmp(addr, dest, mask / 8) == 0)
199  {
200    int n = mask / 8;
201    int m = ((-1) << (8 - (mask % 8)));
202
203    if (mask % 8 == 0 ||
204       (((unsigned char *) addr)[n] & m) == (((unsigned char *) dest)[n] & m))  
205      return 1;
206  }
207
208  return 0;
209 }
210
211 /* match_cidr()
212 *
213 * Input - mask, address
214 * Output - 1 = Matched 0 = Did not match
215 */
216 int
217 match_cidr(const char *s1, const char *s2)
218 {
219  struct irc_ssaddr ipaddr, maskaddr;
220  char address[NICKLEN + USERLEN + HOSTLEN + 6];
221  char mask[NICKLEN + USERLEN + HOSTLEN + 6];
222  char *ipmask, *ip, *len;
223  int cidrlen, offset;
224  struct addrinfo hints, *res;
225  
226  /* Unlikely to ever overflow, but we may as well be consistant - stu */
227  strlcpy(mask, s1, sizeof(mask));
228  strlcpy(address, s2, sizeof(address));
229  
230  ipmask = strrchr(mask, '@');
231  if (ipmask == NULL)
232    return 0;
233  
234  *ipmask++ = '\0';
235  
236  ip = strrchr(address, '@');
237  if (ip == NULL)
238    return 0;
239  *ip++ = '\0';
240  
241  len = strrchr(ipmask, '/');
242  if (len == NULL)
243    return 0;
244  
245  *len++ = '\0';
246  
247  cidrlen = atoi(len);
248  if (cidrlen == 0)
249    return 0;
250
251  memset(&hints, 0, sizeof(hints));
252  hints.ai_family = AF_UNSPEC;
253  hints.ai_flags = AI_NUMERICHOST;
254
255  irc_getaddrinfo(ip, NULL, &hints, &res);
256  if (!res)
257    return 0;
258
259 #ifdef INET6
260  if (res->ai_family == AF_INET)
261    offset = offsetof(struct sockaddr_in, sin_addr);
262  else if (res->ai_family == AF_INET6)
263    offset = offsetof(struct sockaddr_in6, sin6_addr);
264  else
265    return 0;
266 #else
267  offset = offsetof(struct sockaddr_in, sin_addr);
268 #endif
269
270  memcpy(&ipaddr, res->ai_addr, res->ai_addrlen);
271  ipaddr.ss_len = res->ai_addrlen;
272  irc_freeaddrinfo(res);
273
274  if (cidrlen > ipaddr.ss_len * 8)
275    return 0;
276
277  irc_getaddrinfo(ipmask, NULL, &hints, &res);
278  if (!res)
279    return 0;
280
281  memcpy(&maskaddr, res->ai_addr, res->ai_addrlen);
282  maskaddr.ss_len = res->ai_addrlen;
283  irc_freeaddrinfo(res);
284
285  if (maskaddr.ss_len != ipaddr.ss_len)
286    return 0;
287
288  return (comp_with_mask(((char *) &ipaddr) + offset, ((char *) &maskaddr) +
289    offset, cidrlen) && match(mask, address));
290 }
291
195   /* collapse()
196   *
197   * collapses a string containing multiple *'s.

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)