int is_direct_address (const struct in_addr addr) { int i, neg; struct in_addr iaddr; /* Note: assume IPV4 address !! */ for (i=0; i<n_direct_addr_list; i++ ) { if (direct_addr_list[i].name != NULL) continue; /* it's name entry */ neg = direct_addr_list[i].negative; iaddr = addr; mask_addr( &iaddr, &direct_addr_list[i].mask, sizeof(struct in_addr)); if (cmp_addr(&iaddr, &direct_addr_list[i].addr, sizeof(struct in_addr)) == 0) { char *a, *m; a = strdup(inet_ntoa(direct_addr_list[i].addr)); m = strdup(inet_ntoa(direct_addr_list[i].mask)); g_debug("match with: %s/%s%s\n", a, m, neg? " (negative)": ""); free(a); free(m); return !neg? 1: 0; } } g_debug("not matched, addr to be relayed: %s\n", inet_ntoa(addr)); return 0; /* not direct */ }
byte* Rom_Data::at_addr( int addr ) { int offset = mask_addr( addr ) - rom_addr; if ( (unsigned) offset > (unsigned) (rom.size() - pad_size) ) offset = 0; // unmapped return &rom [offset]; }
static int ial_procnet_ifinet6(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list) { const char *myname = "inet_addr_local[procnet_ifinet6]"; FILE *fp; char buf[BUFSIZ]; unsigned plen; VSTRING *addrbuf; struct sockaddr_in6 addr; struct sockaddr_in6 mask; /* * Example: 00000000000000000000000000000001 01 80 10 80 lo * * Fields: address, interface index, prefix length, scope value * (net/ipv6.h), interface flags (linux/rtnetlink.h), device name. * * FIX 200501 The IPv6 patch used fscanf(), which will hang on unexpected * input. Use fgets() + sscanf() instead. */ if ((fp = fopen(_PATH_PROCNET_IFINET6, "r")) != 0) { addrbuf = vstring_alloc(MAI_V6ADDR_BYTES + 1); memset((void *) &addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; #ifdef HAS_SA_LEN addr.sin6_len = sizeof(addr); #endif mask = addr; while (fgets(buf, sizeof(buf), fp) != 0) { /* 200501 hex_decode() is light-weight compared to getaddrinfo(). */ if (hex_decode(addrbuf, buf, MAI_V6ADDR_BYTES * 2) == 0 || sscanf(buf + MAI_V6ADDR_BYTES * 2, " %*x %x", &plen) != 1 || plen > MAI_V6ADDR_BITS) { msg_warn("unexpected data in %s - skipping IPv6 configuration", _PATH_PROCNET_IFINET6); break; } /* vstring_str(addrbuf) has worst-case alignment. */ addr.sin6_addr = *(struct in6_addr *) vstring_str(addrbuf); inet_addr_list_append(addr_list, SOCK_ADDR_PTR(&addr)); memset((void *) &mask.sin6_addr, ~0, sizeof(mask.sin6_addr)); mask_addr((unsigned char *) &mask.sin6_addr, sizeof(mask.sin6_addr), plen); inet_addr_list_append(mask_list, SOCK_ADDR_PTR(&mask)); } vstring_free(addrbuf); fclose(fp); /* FIX 200501 */ } else { msg_warn("can't open %s (%m) - skipping IPv6 configuration", _PATH_PROCNET_IFINET6); } return (0); }
VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why) { const char *myname = "cidr_match_parse"; char *mask_search; char *mask; MAI_HOSTADDR_STR hostaddr; unsigned char *np; unsigned char *mp; /* * Strip [] from [addr/len] or [addr]/len, destroying the pattern. CIDR * maps don't need [] to eliminate syntax ambiguity, but matchlists need * it. While stripping [], figure out where we should start looking for * /mask information. */ if (*pattern == '[') { pattern++; if ((mask_search = split_at(pattern, ']')) == 0) { vstring_sprintf(why ? why : (why = vstring_alloc(20)), "missing ']' character after \"[%s\"", pattern); return (why); } else if (*mask_search != '/') { if (*mask_search != 0) { vstring_sprintf(why ? why : (why = vstring_alloc(20)), "garbage after \"[%s]\"", pattern); return (why); } mask_search = pattern; } } else mask_search = pattern; /* * Parse the pattern into network and mask, destroying the pattern. */ if ((mask = split_at(mask_search, '/')) != 0) { ip->addr_family = CIDR_MATCH_ADDR_FAMILY(pattern); ip->addr_bit_count = CIDR_MATCH_ADDR_BIT_COUNT(ip->addr_family); ip->addr_byte_count = CIDR_MATCH_ADDR_BYTE_COUNT(ip->addr_family); if (!alldig(mask) || (ip->mask_shift = atoi(mask)) > ip->addr_bit_count || inet_pton(ip->addr_family, pattern, ip->net_bytes) != 1) { vstring_sprintf(why ? why : (why = vstring_alloc(20)), "bad net/mask pattern: \"%s/%s\"", pattern, mask); return (why); } if (ip->mask_shift > 0) { /* Allow for bytes > 8. */ memset(ip->mask_bytes, ~0U, ip->addr_byte_count); mask_addr(ip->mask_bytes, ip->addr_byte_count, ip->mask_shift); } else memset(ip->mask_bytes, 0, ip->addr_byte_count); /* * Sanity check: all host address bits must be zero. */ for (np = ip->net_bytes, mp = ip->mask_bytes; np < ip->net_bytes + ip->addr_byte_count; np++, mp++) { if (*np & ~(*mp)) { mask_addr(ip->net_bytes, ip->addr_byte_count, ip->mask_shift); if (inet_ntop(ip->addr_family, ip->net_bytes, hostaddr.buf, sizeof(hostaddr.buf)) == 0) msg_fatal("inet_ntop: %m"); vstring_sprintf(why ? why : (why = vstring_alloc(20)), "non-null host address bits in \"%s/%s\", " "perhaps you should use \"%s/%d\" instead", pattern, mask, hostaddr.buf, ip->mask_shift); return (why); } } } /* * No /mask specified. Treat a bare network address as /allbits. */ else { ip->addr_family = CIDR_MATCH_ADDR_FAMILY(pattern); ip->addr_bit_count = CIDR_MATCH_ADDR_BIT_COUNT(ip->addr_family); ip->addr_byte_count = CIDR_MATCH_ADDR_BYTE_COUNT(ip->addr_family); if (inet_pton(ip->addr_family, pattern, ip->net_bytes) != 1) { vstring_sprintf(why ? why : (why = vstring_alloc(20)), "bad address pattern: \"%s\"", pattern); return (why); } ip->mask_shift = ip->addr_bit_count; /* Allow for bytes > 8. */ memset(ip->mask_bytes, ~0U, ip->addr_byte_count); } /* * Wrap up the result. */ ip->next = 0; return (0); }