There have been some changes made to the libBGPStream and PyBGPStream APIs. Below are some instructions for upgrading your code to work with BGPStream V2.
There have been several changes made to the C API, but all changes will result in compiler errors, so it should be safe to use the compiler to direct you to code that needs changing. You should use the BGPReader code as a reference for using the new API, and please contact bgpstream-info@caida.org if you need further assistance.
We have added a prototype high-level Python module,
pybgpstream
that should be used instead of
the low-level _pybgpstream
module.
Below is a short working example using this API. See the
bundled
sample template
for more information. We are still developing documentation
for this module, so for now, the best reference is
the code.
Please create an issue (or PR!) on
GitHub
if you have any suggestions for improving this interface.
import pybgpstream
stream = pybgpstream.BGPStream(
from_time="2017-07-07 00:00:00", until_time="2017-07-07 00:10:00 UTC",
collectors=["route-views.sg", "route-views.eqix"],
record_type="updates",
filter="peer 11666 and prefix more 210.180.0.0/16"
)
for elem in stream:
# record fields can be accessed directly from elem
# e.g. elem.time
# or via elem.record
# e.g. elem.record.time
print(elem)
If you wish to continue using the _pybgpstream
module, the API has changed slightly:
1. Change the import line from:
from _pybgpstream import BGPStream, BGPRecord, BGPElem
to:
import _pybgpstream
2. Change the line that creates an instance of BGPStream from something like:
stream = BGPStream()
to:
stream = _pybgpstream.BGPStream()
3. Delete the line that creates the BGPRecord instance:
rec = BGPRecord()
4. The "get_next_record" API has been changed to be the same as the "get_next_elem" API, so you will go from nested loops like this:
while(stream.get_next_record(rec)):
elem = rec.get_next_elem()
while(elem):
# do something with the elem
elem = rec.get_next_elem()
to this:
rec = stream.get_next_record()
while(rec):
elem = rec.get_next_elem()
while(elem):
# do something with the elem
elem = rec.get_next_elem()
rec = stream.get_next_record()
To accommodate new fields in the underlying record and elem structures (e.g., those specific to BMP data like "router"), the record and elem ASCII formats have changed:
V1 Record Format (old)
<dump-type>|<dump-pos>|<project>|<collector>|<status>|<dump-time>
V2 Record Format (new)
<type>|<dump-pos>|<rec-ts-sec>.<rec-ts-usec>| \
<project>|<collector>|<router>|<router-ip>|<status>|<dump-time>
V1 Elem Format (old)
<dump-type>|<elem-type>|<record-ts>| \
<project>|<collector>|<peer-ASN>|<peer-IP>| \
<prefix>|<next-hop-IP>|<AS-path>|<origin-AS>| \
<communities>|<old-state>|<new-state>
V2 Elem Format (new)
<rec-type>|<elem-type>|<rec-ts-sec>.<rec-ts-usec>| \
<project>|<collector>|<router>|<router-ip>|<peer-ASN>|<peer-IP>| \
<prefix>|<next-hop-IP>|<AS-path>|<origin-AS>| \
<communities>|<old-state>|<new-state>
Note that timestamps are now represented with sub-second
precision. E.g. 1499385779
is now represented as
1499385779.000000