struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int fill)
{
- unsigned int v4; /* in network byte order */
+ struct in_addr v4; /* in network byte order */
struct in6_addr tmp6;
struct in_addr *s;
struct ebmb_node *node;
}
/* The IPv4 sample don't match the IPv4 tree. Convert the IPv4
- * sample address to IPv6 with the mapping method using the ::ffff:
- * prefix, and try to lookup in the IPv6 tree.
+ * sample address to IPv6 and try to lookup in the IPv6 tree.
*/
- memset(&tmp6, 0, 10);
- write_u16(&tmp6.s6_addr[10], htons(0xffff));
- write_u32(&tmp6.s6_addr[12], smp->data.u.ipv4.s_addr);
+ v4tov6(&tmp6, &smp->data.u.ipv4);
node = ebmb_lookup_longest(&expr->pattern_tree_2, &tmp6);
while (node) {
elt = ebmb_entry(node, struct pattern_tree, node);
return &static_pattern;
}
- /* Try to convert 6 to 4 when the start of the ipv6 address match the
- * following forms :
- * - ::ffff:ip:v4 (ipv4 mapped)
- * - ::0000:ip:v4 (old ipv4 mapped)
- * - 2002:ip:v4:: (6to4)
- */
- if ((read_u64(&smp->data.u.ipv6.s6_addr[0]) == 0 &&
- (read_u32(&smp->data.u.ipv6.s6_addr[8]) == 0 ||
- read_u32(&smp->data.u.ipv6.s6_addr[8]) == htonl(0xFFFF))) ||
- read_u16(&smp->data.u.ipv6.s6_addr[0]) == htons(0x2002)) {
- if (read_u32(&smp->data.u.ipv6.s6_addr[0]) == 0)
- v4 = read_u32(&smp->data.u.ipv6.s6_addr[12]);
- else
- v4 = htonl((ntohs(read_u16(&smp->data.u.ipv6.s6_addr[2])) << 16) +
- ntohs(read_u16(&smp->data.u.ipv6.s6_addr[4])));
-
+ /* Try to convert 6 to 4 */
+ if (v6tov4(&v4, &smp->data.u.ipv6)) {
/* Lookup an IPv4 address in the expression's pattern tree using the longest
* match method.
*/
/* The input sample is IPv4, use it as is. */
if (smp->data.type == SMP_T_IPV4) {
- v4 = smp->data.u.ipv4.s_addr;
+ v4.s_addr = smp->data.u.ipv4.s_addr;
}
else if (smp->data.type == SMP_T_IPV6) {
- /* v4 match on a V6 sample. We want to check at least for
- * the following forms :
- * - ::ffff:ip:v4 (ipv4 mapped)
- * - ::0000:ip:v4 (old ipv4 mapped)
- * - 2002:ip:v4:: (6to4)
- */
- if (read_u64(&smp->data.u.ipv6.s6_addr[0]) == 0 &&
- (read_u32(&smp->data.u.ipv6.s6_addr[8]) == 0 ||
- read_u32(&smp->data.u.ipv6.s6_addr[8]) == htonl(0xFFFF))) {
- v4 = read_u32(&smp->data.u.ipv6.s6_addr[12]);
- }
- else if (read_u16(&smp->data.u.ipv6.s6_addr[0]) == htons(0x2002)) {
- v4 = htonl((ntohs(read_u16(&smp->data.u.ipv6.s6_addr[2])) << 16) +
- ntohs(read_u16(&smp->data.u.ipv6.s6_addr[4])));
- }
- else
+ /* v4 match on a V6 sample. Try to convert v6 form to v4 address */
+ if (!v6tov4(&v4, &smp->data.u.ipv6))
continue;
} else {
/* impossible */
}
/* Check if the input sample match the current pattern. */
- if (((v4 ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
+ if (((v4.s_addr ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
return pattern;
}
return NULL;