blob: 96e031de2b85c6686b93231dcb3c2527df21fa81 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
;; Copyright 2009, NORDUnet A/S.
;;
;; This file is part of Eduroam-stats.
;;
;; Eduroam-stats is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 2 of the License, or
;; (at your option) any later version.
;;
;; Eduroam-stats is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Eduroam-stats. If not, see <http://www.gnu.org/licenses/>.
(in-package :bgp-logger)
(defun xml-top-elem-from-octets (xml-octets)
(dom:document-element
(cxml:parse xml-octets (cxml-dom:make-dom-builder))))
(defun new-entries (top-elem)
"Return BGP-MESSAGE's, one per prefix mentioned in TOP-ELEM.
TOP-ELEM is an XML document element."
;; We assume that top-elem is "BGP_MESSAGE".
;(print (describe top-elem))
(let ((updates (dom:get-elements-by-tag-name top-elem "UPDATE"))
(new-elements nil))
(when (> (length updates) 0)
(let ((update (aref updates 0)))
(when (string= (dom:tag-name (dom:parent-node update)) "ASCII_MSG")
(let ((templ (make-instance 'bgp-message))
(new-prefs nil)
(octet-msgs (dom:get-elements-by-tag-name top-elem "OCTET_MSG"))
(prefixes (dom:get-elements-by-tag-name top-elem "PREFIX"))
(time (aref (dom:get-elements-by-tag-name top-elem "TIME") 0)))
;; Populate new-prefs.
(when (> (length prefixes) 0)
(setf new-prefs
(concatenate
'list
new-elements
(map 'list
(lambda (p)
(list (dom:data (aref (dom:child-nodes p) 0))
(dom:get-attribute p "label")))
prefixes))))
;; TIMESTAMP and PRECISION_TIME --> template.
(let ((ts (aref (dom:get-elements-by-tag-name time "TIMESTAMP") 0))
(pt (aref (dom:get-elements-by-tag-name time "PRECISION_TIME") 0)))
(setf (timestamp templ)
(dom:data (aref (dom:child-nodes ts) 0)))
(setf (precision-time templ)
(dom:data (aref (dom:child-nodes pt) 0))))
;; AS-PATH --> template. Note that we want AS_PATH->AS
;; only, to avoid getting COMMUNITY->AS.
(setf (path templ)
(let ((as-paths (dom:get-elements-by-tag-name update
"AS_PATH")))
(if (= 0 (length as-paths))
"{}"
(let ((str "{"))
(map nil (lambda (node)
(let ((as (dom:data (aref (dom:child-nodes node) 0))))
(setf str (concatenate 'string
str
(format nil "~A," as)))))
(dom:child-nodes (aref as-paths 0)))
(concatenate 'string
(subseq str 0 (- (length str) 1))
"}")))))
;; NEXT_HOP --> template.
(setf (nexthop templ)
(let ((nexthops (dom:get-elements-by-tag-name
update "NEXT_HOP")))
(if (= 0 (length nexthops))
"0.0.0.0"
(dom:data (aref (dom:child-nodes (aref nexthops 0)) 0)))))
;; OCTETS --> template.
(when (> (length octet-msgs) 0)
(let* ((oct (aref (dom:get-elements-by-tag-name
(aref octet-msgs 0) "OCTETS") 0))
(txt (aref (dom:child-nodes oct) 0)))
(setf (bgp-octets templ) (dom:data txt))))
;; Create new elements from new-prefs and the template.
;(format t "templ: ~A~%" (describe templ))
;(format t "new-prefs: ~A~%" new-prefs)
(dolist (p new-prefs)
(push (new-bgp-message templ p) new-elements))))))
new-elements))
(defun new-entry-klacks (xml-doc)
"Return a fresh BGP-MESSAGE built from XML-DOC (array of unsigned bytes)."
(let ((s (cxml:make-source xml-doc))
(e (make-instance 'bgp-message))
(cur-name nil))
(do ((key (klacks:peek s) (klacks:peek s)))
((null key) e)
(case key
(:start-element (setf cur-name (klacks:current-qname s)))
(:end-element (setf cur-name nil))
(:characters (let ((txt (klacks:current-characters s)))
(unless (or (string= cur-name "OCTET_MSG"))
(setf (slot-value e (intern cur-name)) txt)))))
(klacks:consume s))))
(defun marker (mark)
(format t mark)
(force-output))
(defun start-bgpstore (host port)
(with-connection *db-spec*
(let ((reader (new-reader host port))
(count 0))
(marker (format nil "~A: bgpstore started "
(iso-date (get-universal-time) t)))
(do ((e (next-xml-blurb reader "BGP_MESSAGE")
(next-xml-blurb reader "BGP_MESSAGE")))
((null e))
(dolist (obj (new-entries (xml-top-elem-from-octets e)))
(insert-dao obj)
(incf count)
(if (= 0 (mod count 10000))
(marker (format nil "~%~A: ~A "
(iso-date (get-universal-time) t)
count))
(if (= 0 (mod count 1000))
(marker "*")
(if (= 0 (mod count 100))
(marker "."))))))
(close-reader))))
(defun stop-bgpstore ())
;;;;
|