guile-netlink/netlink/route/attrs.scm

attrs.scm

1
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2
;;;; 
3
;;;; This library is free software; you can redistribute it and/or
4
;;;; modify it under the terms of the GNU Lesser General Public
5
;;;; License as published by the Free Software Foundation; either
6
;;;; version 3 of the License, or (at your option) any later version.
7
;;;; 
8
;;;; This library is distributed in the hope that it will be useful,
9
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
;;;; Lesser General Public License for more details.
12
;;;; 
13
;;;; You should have received a copy of the GNU Lesser General Public
14
;;;; License along with this library; if not, write to the Free Software
15
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
;;;; 
17
18
(define-module (netlink route attrs)
19
  #:use-module (ice-9 match)
20
  #:use-module (netlink constant)
21
  #:use-module (netlink data)
22
  #:use-module (rnrs bytevectors)
23
  #:use-module (srfi srfi-9)
24
  #:export(make-route-attr
25
           route-attr?
26
           route-attr-kind
27
           route-attr-data
28
           route-attr-size
29
           make-u8-route-attr
30
           make-u16-route-attr
31
           make-u32-route-attr
32
           make-s32-route-attr
33
           make-string-route-attr
34
           make-ethernet-route-attr
35
           make-ipv4-route-attr
36
           make-ipv6-route-attr
37
           make-bv-route-attr
38
           deserialize-route-attr
39
           deserialize-route-attr-data-string
40
           deserialize-route-attr-data-u8
41
           deserialize-route-attr-data-u32
42
           deserialize-route-attr-data-s32
43
           deserialize-route-attr-data-ethernet
44
           deserialize-route-attr-data-ipv4
45
           deserialize-route-attr-data-ipv6
46
           deserialize-route-attr-data-bv
47
           %default-route-link-attr-decoder
48
           %default-route-addr-ipv4-attr-decoder
49
           %default-route-addr-ipv6-attr-decoder))
50
51
(define-data-type route-attr
52
  attr-type-size
53
  (lambda (attr pos bv)
54
    (match attr
55
      (($ route-attr-type type data)
56
       (bytevector-u16-set! bv pos (attr-type-size attr) (native-endianness))
57
       (bytevector-u16-set! bv (+ pos 2) type (native-endianness))
58
       (serialize data (+ pos 4) bv))))
59
  (type route-attr-kind route-attr-type-type)
60
  (data route-attr-data route-attr-type-data))
61
62
(define (attr-type-size attr)
63
  (+ 4 (data-size (route-attr-type-data attr))))
64
65
(define (make-u8-route-attr num)
66
  (make-nl-data
67
    num
68
    (const 1)
69
    (lambda (data pos bv)
70
      (bytevector-u8-set! bv pos data))))
71
72
(define (make-u16-route-attr num)
73
  (make-nl-data
74
    num
75
    (const 2)
76
    (lambda (data pos bv)
77
      (bytevector-u16-set! bv pos data (native-endianness)))))
78
79
(define (make-u32-route-attr num)
80
  (make-nl-data
81
    num
82
    (const 4)
83
    (lambda (data pos bv)
84
      (bytevector-u32-set! bv pos data (native-endianness)))))
85
86
(define (make-s32-route-attr num)
87
  (make-nl-data
88
    num
89
    (const 4)
90
    (lambda (data pos bv)
91
      (bytevector-s32-set! bv pos data (native-endianness)))))
92
93
(define (make-string-route-attr str)
94
  (make-nl-data
95
    str
96
    (lambda (str) (bytevector-length (string->utf8 str)))
97
    (lambda (data pos bv)
98
      (let ((s (string->utf8 data)))
99
        (bytevector-copy! s 0 bv pos (bytevector-length s))))))
100
101
(define (ethernet->bv addr)
102
  (u8-list->bytevector (map (lambda (n) (string->number n 16))
103
                            (string-split addr #\:))))
104
(define (make-ethernet-route-attr addr)
105
  (make-nl-data
106
    addr
107
    (lambda (addr) (bytevector-length (ethernet->bv addr)))
108
    (lambda (data pos bv)
109
      (let ((a (ethernet->bv data)))
110
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
111
112
(define (ipv4->bv addr)
113
  (u8-list->bytevector (map (lambda (n) (string->number n))
114
                            (string-split addr #\.))))
115
(define (make-ipv4-route-attr addr)
116
  (make-nl-data
117
    addr
118
    (lambda (addr) (bytevector-length (ipv4->bv addr)))
119
    (lambda (data pos bv)
120
      (let ((a (ipv4->bv data)))
121
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
122
123
;16 bytes
124
(define (ipv6->bv addr)
125
  (let loop ((num (inet-pton AF_INET6 addr)) (lst '()))
126
    (match lst
127
      ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
128
       (u8-list->bytevector (reverse lst)))
129
      (_
130
       (loop (quotient num 256) (cons (modulo num 256) lst))))))
131
(define (make-ipv6-route-attr addr)
132
  (make-nl-data
133
    addr
134
    (lambda (addr) (bytevector-length (ipv6->bv addr)))
135
    (lambda (data pos bv)
136
      (let ((a (ipv6->bv data)))
137
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
138
139
(define (make-bv-route-attr bv)
140
  (make-nl-data
141
    bv
142
    (lambda (bv) (bytevector-length bv))
143
    (lambda (data pos bv)
144
      (bytevector-copy! data 0 bv pos (bytevector-length data)))))
145
146
(define (deserialize-route-attr message-type)
147
  (lambda (decoder bv pos)
148
    (let* ((len (bytevector-u16-ref bv pos (native-endianness)))
149
           (type (bytevector-u16-ref bv (+ pos 2) (native-endianness)))
150
           (deserialize (get-next-deserialize decoder message-type type))
151
           (data-bv (make-bytevector (- len 4))))
152
      (bytevector-copy! bv (+ pos 4) data-bv 0 (- len 4))
153
      (make-route-attr
154
        type
155
        (deserialize decoder data-bv 0)))))
156
157
(define (deserialize-route-attr-data-string decoder bv pos)
158
  (make-string-route-attr
159
    (or (false-if-exception (utf8->string bv))
160
        (make-string (bytevector-length bv) #\a))))
161
162
(define (deserialize-route-attr-data-u32 decoder bv pos)
163
  (make-u32-route-attr (bytevector-u32-ref bv pos (native-endianness))))
164
165
(define (deserialize-route-attr-data-s32 decoder bv pos)
166
  (make-s32-route-attr (bytevector-s32-ref bv pos (native-endianness))))
167
168
(define (deserialize-route-attr-data-u8 decoder bv pos)
169
  (make-u8-route-attr (bytevector-u8-ref bv pos)))
170
171
(define (deserialize-route-attr-data-bv decoder bv pos)
172
  (make-bv-route-attr bv))
173
174
(define (deserialize-route-attr-data-ethernet decoder bv pos)
175
  (make-ethernet-route-attr
176
    (string-join (map (lambda (n) (number->string n 16))
177
                      (bytevector->u8-list bv))
178
                 ":")))
179
180
(define (deserialize-route-attr-data-ipv4 decoder bv pos)
181
  (make-ipv4-route-attr
182
    (string-join (map (lambda (n) (number->string n))
183
                      (bytevector->u8-list bv))
184
                 ".")))
185
186
(define (deserialize-route-attr-data-ipv6 decoder bv pos)
187
  (define (ipv6->number addr)
188
    (let loop ((addr (bytevector->u8-list addr)) (num 0))
189
      (match addr
190
        (() num)
191
        ((byte addr ...)
192
         (loop addr (+ (* 256 num) byte))))))
193
  (make-ipv6-route-attr
194
    (inet-ntop AF_INET6 (ipv6->number bv))))
195
196
(define %default-route-link-attr-decoder
197
  `((,IFLA_ADDRESS . ,deserialize-route-attr-data-ethernet)
198
    (,IFLA_BROADCAST . ,deserialize-route-attr-data-ethernet)
199
    (,IFLA_IFNAME . ,deserialize-route-attr-data-string)
200
    (,IFLA_MTU . ,deserialize-route-attr-data-u32)
201
    (,IFLA_LINK . ,deserialize-route-attr-data-u32)
202
    (,IFLA_QDISC . ,deserialize-route-attr-data-string)
203
    ;; TODO: struct rtnl_link_stats
204
    ;(,IFLA_STATS . ,deserialize-route-attr-data-stats)
205
    (default . ,deserialize-route-attr-data-bv)))
206
207
(define (default-route-addr-attr-decoder address-decoder)
208
  `((,IFA_ADDRESS . ,address-decoder)
209
    (,IFA_LOCAL . ,address-decoder)
210
    (,IFA_LABEL . ,deserialize-route-attr-data-string)
211
    (,IFA_BROADCAST . ,address-decoder)
212
    (,IFA_ANYCAST . ,address-decoder)
213
    ;; TODO: struct ifa_cacheinfo
214
    ;(,IFA_CACHEINFO . ,deserialize-route-attr-data-cache-info)
215
    (default . ,deserialize-route-attr-data-bv)))
216
217
(define %default-route-addr-ipv4-attr-decoder
218
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv4))
219
220
(define %default-route-addr-ipv6-attr-decoder
221
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv6))
222