/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 2000-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* dss ip type library
*
* Glenn Fowler
* AT&T Research
*/
#include <dsslib.h>
#include <bgp.h>
#include <ire.h>
#include <itl.h>
#include <fv.h>
#include <pt.h>
#include <ptv.h>
/* XXX: some compilers choke on static foo bar[]; */
#if _typ_int64_t
#else
static int
{
Cxnumber_t a;
unsigned long u;
u = p / 64;
a = u;
a *= 64;
return (int)(p - a) & 0x3f;
}
#endif
static ssize_t
addrv4_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
char* s;
ssize_t n;
n = strlen(s);
if ((n + 1) > size)
return n + 1;
return n;
}
static ssize_t
addrv4_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
{
return -1;
}
return e - (char*)buf;
}
static ssize_t
addrv6_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
char* s;
unsigned char* pp;
ssize_t n;
int i;
{
n = strlen(s);
if ((n + 1) > size)
return n + 1;
}
else if (s[0] == 'C' && s[1] == 0)
{
n = 80;
if (size < n)
return n;
s = buf;
for (i = 0; i < IP6BITS; i++)
{
if (i)
*s++ = ',';
}
*s = 0;
}
else
n = -1;
return n;
}
static ssize_t
addrv6_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned char* ap;
{
return -1;
}
if (!vm)
{
return -1;
}
return e - (char*)buf;
}
static ssize_t
addr_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
return -1;
}
static ssize_t
addr_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned char* ap;
{
return e - (char*)buf;
}
{
if (!vm)
{
return -1;
}
return e - (char*)buf;
}
return -1;
}
static ssize_t
as16path_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
}
static ssize_t
as16path_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static ssize_t
as32_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
unsigned long as;
int n;
if (n >= size)
return n + 1;
return n;
}
static ssize_t
as32_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned long as;
if (*e == '.')
{
as <<= 16;
}
if (*e)
{
return -1;
}
return e - (char*)buf;
}
static ssize_t
as32path_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
}
static ssize_t
as32path_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static ssize_t
aspath_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
return -1;
}
static ssize_t
aspath_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
register const char* b = buf;
register const char* e = b + size;
while (b < e && !isdigit(*b))
b++;
while (b < e && isdigit(*b))
b++;
if (b < e && *b == '.')
{
}
}
typedef struct Path_match_s
{
} Path_match_t;
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
{
return 0;
}
return pm;
}
static int
{
{
{
return -2;
}
}
{
return -2;
}
}
static int
{
return 0;
}
static ssize_t
cluster_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
}
static ssize_t
cluster_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
}
static ssize_t
community_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
formats[0] = 0;
}
static ssize_t
community_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
}
static ssize_t
extended_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
formats[0] = 0;
}
static ssize_t
extended_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
}
static ssize_t
labels_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
formats[0] = 0;
}
static ssize_t
labels_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
}
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
}
static ssize_t
prefixv4_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
char* s;
ssize_t n;
else
n = strlen(s);
if ((n + 1) > size)
return n + 1;
return n;
}
static ssize_t
prefixv4_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned char bits;
{
return -1;
}
return e - (char*)buf;
}
static ssize_t
prefixv6_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
char* s;
unsigned char* pp;
ssize_t n;
int i;
{
n = strlen(s);
if ((n + 1) > size)
return n + 1;
}
else if (s[0] == 'C' && s[1] == 0)
{
n = 84;
if (size < n)
return n;
s = buf;
for (i = 0; i <= IP6BITS; i++)
{
if (i)
*s++ = ',';
}
*s = 0;
}
else
n = -1;
return n;
}
static ssize_t
prefixv6_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned char* pp;
{
return -1;
}
if (!vm)
{
return -1;
}
return e - (char*)buf;
}
static ssize_t
prefix_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
{
return -1;
}
static ssize_t
prefix_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
{
char* e;
unsigned char* pp;
unsigned char bits;
{
return e - (char*)buf;
}
if (!strtoip6(buf, &e, prefixv6, prefixv6 + IP6BITS) && (e >= ((char*)buf + size) || !*e || isspace(*e)))
{
if (!vm)
{
return -1;
}
return e - (char*)buf;
}
return -1;
}
static int
{
}
static int
{
}
{
"as16path-re",
"Matches on this type treat a string pattern as an ire(3) 16 bit integer list regular expression. Each number in the list is a distinct token. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. For example, '[!1 100]' matches all lists that contain neither 1 nor 100, and '^[!1 100]-701$' matches all lists that don't start with 1 or 100 and end with 701.",
CXH,
};
{
"as32path-re",
"Matches on this type treat a string pattern as an ire(3) 32 bit integer list regular expression. Each number in the list is a distinct token. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. For example, '[!1 100]' matches all lists that contain neither 1 nor 100, and '^[!1 100]-701$' matches all lists that don't start with 1 or 100 and end with 701.",
CXH,
};
{
"aspath-re",
0,
CXH,
};
{
"cluster-re",
"Matches on this type treat a string pattern as an ire(3) integer list regular expression. Each number in the list is a distinct token. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. For example, '[!1 100]' matches all lists that contain neither 1 nor 100, and '^[!1 100]-701$' matches all lists that don't start with 1 or 100 and end with 701.",
CXH,
};
{
"community-re",
"Matches on this type treat a string pattern as an ire(3) integer list regular expression. Each number in the list is a distinct token. Pairs are separated by :. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. If a : tuple separator is omitted then :.* is assumed. For example, '[!1 100]' matches all lists that contain neither 1 nor 100 as the first pair element, and '^[!1: :100]-701:999$' matches all lists that don't start with 1 as the first pair element or 100 as the second pair element and end with 701:999.",
CXH,
};
{
"extended-re",
"Matches on this type treat a string pattern as an ire(3) integer list regular expression for tuples with 8 integer elements in the range 0..255. Each number in the list is a distinct token. Elements are separated by :. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. If a : tuple separator is omitted then :.* is assumed. For example, '[!1 100]' matches all lists that contain neither 1 nor 100 as the first tuple element, and '^[!1: :100]-:201:199$' matches all lists that don't start with 1 as the first tuple element or 100 as the last tuple element and end with :201:199.",
CXH,
};
{
"labels-re",
"Matches on this type treat a string pattern as an ire(3) integer list regular expression. Each number in the list is a distinct token. Pairs are separated by :. ^ $ * + . {n,m} [N1 .. Nn] are supported, and - is equivalent to .*. Adjacent numbers may be separated by space, comma, / or _; multiple adjacent separators are ignored in the match. If a : tuple separator is omitted then :.* is assumed. For example, '[!1 100]' matches all lists that contain neither 1 nor 100 as the first pair element, and '^[!1: :100]-701:999$' matches all lists that don't start with 1 as the first pair element or 100 as the second pair element and end with 701:999.",
CXH,
};
static Pt_t*
{
char* s;
char* t;
unsigned char bits;
return 0;
if (!str)
{
{
return 0;
}
}
{
{
{
return 0;
}
s = t;
}
}
{
{
{
return 0;
}
}
}
return pt;
}
typedef struct Matchdisc_s
{
int prefix;
} Matchdisc_t;
static Ptv_t*
{
char* s;
char* t;
unsigned char* pp;
return 0;
if (!str)
{
if (!ptvinsert(ptv, ptvmin(ptv->size, ptv->r[0], pp, pp[IP6BITS]), ptvmax(ptv->size, ptv->r[1], pp, pp[IP6BITS])))
{
return 0;
}
}
{
{
if (!ptvinsert(ptv, ptvmin(ptv->size, ptv->r[0], prefix, prefix[IP6BITS]), ptvmax(ptv->size, ptv->r[1], prefix, prefix[IP6BITS])))
{
return 0;
}
s = t;
}
}
{
{
if (!ptvinsert(ptv, ptvmin(ptv->size, ptv->r[0], rp->prefixv6, rp->prefixv6[IP6BITS]), ptvmax(ptv->size, ptv->r[1], rp->prefixv6, rp->prefixv6[IP6BITS])))
{
return 0;
}
}
}
return ptv;
}
typedef struct Prefix_match_s
{
int prefix;
int str;
static void*
{
if (!cxisstring(pat))
{
(*disc->errorf)(NiL, disc, 2, "%s: match requires %s pattern", sub->name, cx->state->type_string->name, sub->name);
return 0;
}
{
return 0;
}
return pm;
}
static int
{
{
{
return -2;
}
}
{
return -1;
}
return ptmatch(pm->pt, type->externalf == prefixv4_external ? PREFIX_ADDR(val->number) : (Ptaddr_t)val->number) != 0;
}
static int
{
return 0;
}
{
"prefix-v4-match",
"Matches on this type treat a string pattern as an ipv4 prefix table and test whether the subject is matched by the table. If the first character of the pattern is \b<\b then the remainder of the string is the path name of a file containing a prefix table. If the pattern is a \bipv4prefix_t\b then matches test if the subject is matched by the prefix.",
CXH,
};
{
"prefix-v6-match",
"Matches on this type treat a string pattern as an ipv6 prefix table and test whether the subject is matched by the table. If the first character of the pattern is \b<\b then the remainder of the string is the path name of a file containing a prefix table. If the pattern is an \bipv6prefix_t\b then matches test if the subject is matched by the prefix.",
CXH,
};
{
"prefix-match",
0,
CXH,
};
static int
op_match_ip4_NP(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
{
int ab;
int bb;
r->value.number = (PTMIN(aa,ab) >= PTMIN(ba,bb) && PTMAX(aa,ab) <= PTMAX(ba,bb)) == (pc->op == CX_MATCH);
return 0;
}
static int
op_match_ip6_NP(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
{
unsigned char* ap;
unsigned char* bp;
else
r->value.number = (fvcmp(16, ptvmin(16, r0, ap, ap[IP6BITS]), ptvmin(16, r1, bp, bp[IP6BITS])) >= 0 && fvcmp(16, ptvmax(16, r0, ap, ap[IP6BITS]), ptvmax(16, r1, bp, bp[IP6BITS])) <= 0) == (pc->op == CX_MATCH);
return 0;
}
{
{0}
};
/*
* NOTE: the *_T macros above index into this table
*/
{
{ "as16_t", "An unsigned 16 bit autonomous system number.", CXH, (Cxtype_t*)"number", 0, 0, 0, 0, 0, 2, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 2, 5 }, 0 },
{ "as32_t", "A 32 bit autonomous system number.", CXH, (Cxtype_t*)"number", 0, as32_external, as32_internal, 0, 0, 4, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 4, 11 }, 0 },
{ "as_t", 0, CXH, (Cxtype_t*)"number", 0, 0, 0, 0, 0, 0, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 2, 5 }, 0, 0, &as_generic[0] },
{ "as16path_t", "A sequence of as16_t 16 bit autonomous system numbers.", CXH, (Cxtype_t*)"buffer", 0, as16path_external, as16path_internal, 0, 0, 0, 2, { "The format details string is the format character (\b1\b or \b.\b: dotted 1-byte, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: unsigned decimal (default)), followed by the separator string.", "u," }, &match_as16path },
{ "as32path_t", "A sequence of as32_t 32 bit autonomous system numbers.", CXH, (Cxtype_t*)"buffer", 0, as32path_external, as32path_internal, 0, 0, 0, 4, { "The format details string is the format character (\b1\b or \b.\b: dotted 1-byte, \b2\b: dotted 2-byte, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: unsigned decimal (default)), followed by the separator string.", "u," }, &match_as32path },
{ "aspath_t", 0, CXH, (Cxtype_t*)"buffer", 0, aspath_external, aspath_internal, 0, 0, 0, 0, { 0 }, &match_aspath, 0, &aspath_generic[0] },
{ "cluster_t", "A sequence of unsigned 32 bit integer cluster ids.", CXH, (Cxtype_t*)"buffer", 0, cluster_external, cluster_internal, 0, 0, 0, 4, { "The format details string is the format character (\b.\b: dotted quad, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: default unsigned decimal), followed by the separator string.", ".," }, &match_cluster },
{ "community_t", "A sequence of unsigned 16 bit integer pairs.", CXH, (Cxtype_t*)"buffer", 0, community_external, community_internal, 0, 0, 0, 2, { "The format details string is the format character (\b.\b: dotted quad, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: default unsigned decimal), followed by the separator string.", "u," }, &match_community },
{ "extended_t", "A sequence of unsigned 64 bit integer tuples.", CXH, (Cxtype_t*)"buffer", 0, extended_external, extended_internal, 0, 0, 0, 8, { "The format details string is the format character (\b.\b: dotted elements, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: default unsigned decimal), followed by the separator string.", "u," }, &match_extended },
{ "ipv4addr_t", "A dotted quad ipv4 address.", CXH, (Cxtype_t*)"number", 0, addrv4_external, addrv4_internal, 0, 0, 4, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 4, 16 }, &match_prefixv4 },
{ "ipv6addr_t", "An RFC 2373 ipv6 address. The details string \"C\" lists the prefix as 16 0x%02x comma-separated values.", CXH, (Cxtype_t*)"buffer", 0, addrv6_external, addrv6_internal, 0, 0, 16, 0, { 0 }, &match_prefixv6 },
{ "ipaddr_t", 0, CXH, (Cxtype_t*)"number", 0, addr_external, addr_internal, 0, 0, 0, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 4, 16 }, &match_prefix, 0, &addr_generic[0] },
{ "ipv4prefix_t", "/length appended to an ipv4addr_t prefix.", CXH, (Cxtype_t*)"number", 0, prefixv4_external, prefixv4_internal, 0, 0, 5, 0, { "The format details string is a \bprintf\b(3) format specification for the integer arguments \aaddress,bits\a; e.g., \b%2$u|%1$08x\b prints the decimal bits followed by the hexadecimal prefix address.", 0, CX_UNSIGNED|CX_INTEGER, 8, 19 }, &match_prefixv4 },
{ "ipv6prefix_t", "/length appended to an ipv6addr_t prefix. The details string \"C\" lists the prefix as 17 0x%02x comma-separated values, the first 16 being the address, and the 17th being the number of prefix bits.", CXH, (Cxtype_t*)"buffer", 0, prefixv6_external, prefixv6_internal, 0, 0, 17, 0, { 0 }, &match_prefixv6 },
{ "ipprefix_t", 0, CXH, (Cxtype_t*)"number", 0, prefix_external, prefix_internal, 0, 0, 0, 0, { 0 }, &match_prefix, 0, &prefix_generic[0] },
{ "labels_t", "A sequence of unsigned 32 bit integer pairs.", CXH, (Cxtype_t*)"buffer", 0, labels_external, labels_internal, 0, 0, 0, 8, { "The format details string is the format character (\b.\b: dotted quad, \bd\b: signed decimal, \bo\b: octal, \bx\b: hexadecimal, \bu\b: default unsigned decimal), followed by the separator string.", "u," }, &match_labels },
{0}
};
{
"ip_t",
"IP type support"
"[-?\n@(#)$Id: dss ip type library (AT&T Research) 2008-08-18 $\n]"
CXH,
0,
0,
&types[0],
&callouts[0],
};