Go Library for Creating RPSL Objects
rpsl
is a library for creating and serializing Routing Policy Specification Language (RPSL) objects, which are used by Internet Routing Registry (IRR) databases for route origin validation.
This library tends to lean towards compatibility with ARIN's IRR spec, but should be compatible with any RPSL-compliant IRR provider.
Note
While the import
, export
, default
(and mp-
versions) are provided, they are not validated.
If there is interest, this library could also house a RPSL-compliant policy builder, but does not currently.
- RFC 2622: Routing Policy Specification Language (RPSL)
- RFC 4012: Routing Policy Specification Language next generation (RPSLng)
go get -d go.mdl.wtf/rpsl
route := &rpsl.Route{
Route: "192.0.2.0/24",
Origin: 65000,
Description: "test",
AdminPOC: "TEST-ADMIN",
TechPOC: "TEST-TECH",
MntBy: "MNT-TEST",
}
formatted, _ := rpsl.MarshalBinary(&route)
fmt.Println(string(formatted))
/*
route: 192.0.2.0/24
origin: AS65000
descr: test
admin-c: TEST-ADMIN
tech-c: TEST-TECH
mnt-by: MNT-TEST
*/
route := &rpsl.Route6{
Route6: "2001:db8::/32",
Origin: 65000,
Description: "test",
AdminPOC: "TEST-ADMIN",
TechPOC: "TEST-TECH",
MntBy: "MNT-TEST",
}
formatted, _ := rpsl.MarshalBinary(&route)
fmt.Println(string(formatted))
/*
route6: 2001:db8::/32
origin: AS65000
descr: test
admin-c: TEST-ADMIN
tech-c: TEST-TECH
mnt-by: MNT-TEST
*/
route_set := &rpsl.RouteSet{
RouteSet: "RS-ACME",
Members: rpsl.RSMembers(netip.MustParsePrefix("192.0.2.0/24"), "RS-ACME"), // with mixed types
Members: []string{"192.0.2.0/24", "RS-ACME"}, // or just a string slice
}
formatted, _ := rpsl.MarshalBinary(&route_set)
fmt.Println(string(formatted))
/*
route-set: RS-ACME
members: 192.0.2.0/24,RS-CORP
*/
aut_num := &rpsl.AutNum{
AutNum: rpsl.ASN(65000),
ASName: "AS-65000",
MemberOf: rpsl.AutNumMembers( // with mixed types
rpsl.ASN(65001), // rpsl.ASN type
65002, // uint32
"AS-ACME", // as-set as string
),
MemberOf: []string{"65001", "AS65002", "AS-ACME"}, // or just a string slice
}
formatted, _ := rpsl.MarshalBinary(&aut_num)
fmt.Println(string(formatted))
/*
aut-num: AS65000
as-name: AS-65000
member-of: AS65001, AS65002, AS-ACME
*/
as_set := &rpsl.ASSet{
ASSet: "AS-ACME",
Members: rpsl.ASSetMembers( // with mixed types
rpsl.ASN(65000), // rpsl.ASN type
65001, // uint32
"AS-CORP", // AS-Set name
),
Members: []string{"65000", "AS65001", "AS-CORP"}, // or just a string slice
}
formatted, _ := rpsl.MarshalBinary(&as_set)
fmt.Println(string(formatted))
/*
as-set: AS-ACME
members: AS65000
members: AS65001
members: AS-CORP
*/
// ↑ AS-Sets list members as separate lines, this is handled appropriately.
rpsl
can also decode an RPSL blob:
b := []byte(`
route: 192.0.2.0/24
origin: AS65000
some-unknown-attribute: ur a n3rd
`)
var route rpsl.Route
_ := rpsl.UnmarshalBinary(b, &route)
fmt.Println(route.Route)
// 192.0.2.0/24
fmt.Println(route.Origin.String())
// AS65000
fmt.Println(route.Extra["some-unknown-attribute"]) // ← unknown attributes are placed into a map[string]string accessible via .Extra
// ur a n3rd