Add route address types

Julien LepillerSat Oct 10 22:19:49+0200 2020

e97af1d

Add route address types

Makefile.am

77
  netlink/message.scm \
88
  netlink/standard.scm \
99
  netlink/deserialize.scm \
10+
  netlink/route/addr.scm \
1011
  netlink/route/attrs.scm \
1112
  netlink/route/link.scm
1213

doc/guile-netlink.texi

379379
@item @code{ethernet}
380380
An ethernet address.  Its value is a string that represents that address,
381381
for instnace @code{"01:23:45:67:89:ab"}
382+
@item @code{ipv4}
383+
An IPv4 address.  Its value is a string that represents that address,
384+
for instnace @code{"192.0.2.152"}
385+
@item @code{ipv6}
386+
An IPv6 address.  Its value is a string that represents that address,
387+
for instnace @code{"2001:db8::0123:4567:89ab:cdef"}
382388
@item @code{bv}
383389
A bytevector.  This is used by default when the type is not supported.
384390
@end table

413419
@end table
414420
@end deffn
415421
422+
@node Address Messages
423+
@subsection Address Messages
424+
425+
The @code{(netlink route addr)} package defines the following data type:
426+
427+
@deffn {Datatype} addr-message
428+
This datatype represents an address message with its routing attributes.  This
429+
type of message is expected when using the @var{RTM_*ADDR} message types.
430+
431+
@table @asis
432+
@item @code{family}
433+
The network family, either @code{AF_INET} for IPv4 addresses, or @code{AF_INET6}
434+
for IPv6 addresses.
435+
436+
@item @code{prefix-len}
437+
The prefix length, i.e.@: the length of the prefix mask, in bits, if defined
438+
for the address family.
439+
440+
@item @code{flags}
441+
Address flags.  This can be a flag word of @code{IFA_F_SECONDARY} for secondary
442+
address (old alias interface), @code{IFA_F_PERMANENT} for a permanent
443+
address set by the user and other undocumented flags.
444+
445+
@item @code{scope}
446+
The address scope.
447+
448+
@item @code{index}
449+
The index of the device this address is for.
450+
451+
@item @code{attrs}
452+
A list of attributes.  This field must contain a list of @code{nl-data}
453+
structures, not a structure by itself.
454+
@end table
455+
@end deffn
456+
416457
@bye

netlink/constant.scm

9191
  (RTM_NEWLINK 16)
9292
  RTM_DELLINK
9393
  RTM_GETLINK
94-
  RTM_SETLINK)
94+
  RTM_SETLINK
95+
96+
  (RTM_NEWADDR 20)
97+
  RTM_DELADDR
98+
  RTM_GETADDR)
9599
96100
(define-public NLM_F_REQUEST #x01)
97101
(define-public NLM_F_MULTI #x02)

netlink/deserialize.scm

1717
1818
(define-module (netlink deserialize)
1919
  #:use-module (netlink constant)
20+
  #:use-module ((netlink route addr) #:prefix route:)
2021
  #:use-module ((netlink route attrs) #:prefix route:)
2122
  #:use-module ((netlink route link) #:prefix route:)
2223
  #:use-module (netlink standard)

3637
      (,RTM_NEWLINK . ,route:deserialize-link-message)
3738
      (,RTM_DELLINK . ,route:deserialize-link-message)
3839
      (,RTM_GETLINK . ,route:deserialize-link-message)
39-
      (,RTM_SETLINK . ,route:deserialize-link-message))
40+
      (,RTM_SETLINK . ,route:deserialize-link-message)
41+
      (,RTM_NEWADDR . ,route:deserialize-addr-message)
42+
      (,RTM_DELADDR . ,route:deserialize-addr-message)
43+
      (,RTM_GETADDR . ,route:deserialize-addr-message))
4044
    (link-attr ,(route:deserialize-route-attr 'link-attr)
41-
               ,@route:%default-route-link-attr-decoder)))
45+
               ,@route:%default-route-link-attr-decoder)
46+
    (ipv4-attr ,(route:deserialize-route-attr 'ipv4-attr)
47+
               ,@route:%default-route-ipv4-attr-decoder)
48+
    (ipv6-attr ,(route:deserialize-route-attr 'ipv6-attr)
49+
               ,@route:%default-route-ipv6-attr-decoder)))

netlink/route/addr.scm unknown status 1

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 addr)
19+
  #:use-module (ice-9 match)
20+
  #:use-module (netlink data)
21+
  #:use-module (netlink route attrs)
22+
  #:use-module (srfi srfi-9)
23+
  #:use-module (rnrs bytevectors)
24+
  #:export (make-addr-message
25+
            addr-message?
26+
            addr-message-family
27+
            addr-message-prefix-len
28+
            addr-message-flags
29+
            addr-message-scope
30+
            addr-message-index
31+
            addr-message-attrs
32+
            deserialize-addr-message))
33+
34+
(define (align pos to)
35+
  (+ pos -1 (- to (modulo (- pos 1) to))))
36+
37+
(define-data-type addr-message
38+
  (lambda (msg)
39+
    (+ 8 (apply + (map (lambda (d) (align (data-size d) 4)) attrs))))
40+
  (lambda (msg pos bv)
41+
    (match msg
42+
      (($ addr-message-type family prefix-len flags scope index attrs)
43+
       (bytevector-u8-set! bv pos family)
44+
       (bytevector-u8-set! bv (+ pos 1) prefix-len)
45+
       (bytevector-u8-set! bv (+ pos 2) flags)
46+
       (bytevector-u8-set! bv (+ pos 3) scope)
47+
       (bytevector-u32-set! bv (+ pos 4) index (native-endianness))
48+
       (let loop ((attrs attrs) (pos (+ pos 8)))
49+
         (match attrs
50+
           ((attr attrs ...)
51+
            (serialize attr pos bv)
52+
            (loop attrs (+ pos (align (data-size attr) 4))))
53+
           (() #t))))))
54+
  (family addr-message-family addr-message-type-family)
55+
  (prefix-len addr-message-prefix-len addr-message-type-prefix-len)
56+
  (flags addr-message-flags addr-message-type-flags)
57+
  (scope addr-message-scope addr-message-type-scope)
58+
  (index addr-message-index addr-message-type-index)
59+
  (attrs addr-message-attrs addr-message-type-attrs))
60+
61+
(define (deserialize-addr-message decoder bv pos)
62+
  (let ((family (bytevector-u8-ref bv pos)))
63+
    (make-addr-message
64+
      family
65+
      (bytevector-u8-ref bv (+ pos 1))
66+
      (bytevector-u8-ref bv (+ pos 2))
67+
      (bytevector-u8-ref bv (+ pos 3))
68+
      (bytevector-u32-ref bv (+ pos 4) (native-endianness))
69+
      (let ((len (bytevector-length bv)))
70+
        (let loop ((pos (+ pos 8)) (attrs '()))
71+
          (if (>= pos len)
72+
              attrs
73+
              (let ((attr (deserialize (cond
74+
                                         ((equal? family AF_INET) 'ipv4-attr)
75+
                                         ((equal? family AF_INET6) 'ipv6-attr)
76+
                                         (else (throw 'unknown-family family)))
77+
                                       decoder bv pos)))
78+
                (loop (+ pos (align (data-size attr) 4))
79+
                      (cons attr attrs)))))))))

netlink/route/attrs.scm

3232
           make-s32-route-attr
3333
           make-string-route-attr
3434
           make-ethernet-route-attr
35+
           make-ipv4-route-attr
36+
           make-ipv6-route-attr
3537
           make-bv-route-attr
3638
           deserialize-route-attr
3739
           deserialize-route-attr-data-string

3941
           deserialize-route-attr-data-u32
4042
           deserialize-route-attr-data-s32
4143
           deserialize-route-attr-data-ethernet
44+
           deserialize-route-attr-data-ipv4
45+
           deserialize-route-attr-data-ipv6
4246
           deserialize-route-attr-data-bv
4347
           default-route-attr-decoder
44-
           %default-route-link-attr-decoder))
48+
           %default-route-link-attr-decoder
49+
           %default-route-ipv4-attr-decoder
50+
           %default-route-ipv6-attr-decoder))
4551
4652
(define-data-type route-attr
4753
  attr-type-size

104110
      (let ((a (ethernet->bv data)))
105111
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
106112
113+
(define (ipv4->bv addr)
114+
  (u8-list->bytevector (map (lambda (n) (string->number n))
115+
                            (string-split addr #\.))))
116+
(define (make-ipv4-route-attr addr)
117+
  (make-nl-data
118+
    addr
119+
    (lambda (addr) (bytevector-length (ipv4->bv addr)))
120+
    (lambda (data pos bv)
121+
      (let ((a (ipv4->bv data)))
122+
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
123+
124+
;16 bytes
125+
(define (ipv6->bv addr)
126+
  (let loop ((num (inet-pton AF_INET6 addr)) (lst '()))
127+
    (match lst
128+
      ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
129+
       (u8-list->bytevector (reverse lst)))
130+
      (_
131+
       (loop (quotient num 256) (cons (modulo num 256) lst))))))
132+
(define (make-ipv6-route-attr addr)
133+
  (make-nl-data
134+
    addr
135+
    (lambda (addr) (bytevector-length (ipv6->bv addr)))
136+
    (lambda (data pos bv)
137+
      (let ((a (ipv6->bv data)))
138+
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
139+
107140
(define (make-bv-route-attr bv)
108141
  (make-nl-data
109142
    bv

123156
        (deserialize decoder data-bv 0)))))
124157
125158
(define (deserialize-route-attr-data-string decoder bv pos)
126-
  (make-string-route-attr (utf8->string bv)))
159+
  (make-string-route-attr
160+
    (or (false-if-exception (utf8->string bv))
161+
        (make-string (bytevector-length bv) #\a))))
127162
128163
(define (deserialize-route-attr-data-u32 decoder bv pos)
129164
  (make-u32-route-attr (bytevector-u32-ref bv pos (native-endianness))))

143178
                      (bytevector->u8-list bv))
144179
                 ":")))
145180
146-
(define %default-route-link-attr-decoder
147-
  (default-route-attr-decoder deserialize-route-attr-data-ethernet))
181+
(define (deserialize-route-attr-data-ipv4 decoder bv pos)
182+
  (make-ipv4-route-attr
183+
    (string-join (map (lambda (n) (number->string n))
184+
                      (bytevector->u8-list bv))
185+
                 ".")))
186+
187+
(define (deserialize-route-attr-data-ipv6 decoder bv pos)
188+
  (define (ipv6->number addr)
189+
    (let loop ((addr (bytevector->u8-list addr)) (num 0))
190+
      (match addr
191+
        (() num)
192+
        ((byte addr ...)
193+
         (loop addr (+ (* 256 num) byte))))))
194+
  (make-ipv6-route-attr
195+
    (inet-ntop AF_INET6 (ipv6->number bv))))
148196
149197
(define (default-route-attr-decoder deserialize-addr)
150198
  `((,IFLA_IFNAME . ,deserialize-route-attr-data-string)

179227
    (,IFLA_BROADCAST . ,deserialize-addr)
180228
    (,IFLA_PERM_ADDRESS . ,deserialize-addr)
181229
    (default . ,deserialize-route-attr-data-bv)))
230+
231+
(define %default-route-link-attr-decoder
232+
  (default-route-attr-decoder deserialize-route-attr-data-ethernet))
233+
234+
(define %default-route-ipv4-attr-decoder
235+
  (default-route-attr-decoder deserialize-route-attr-data-ipv4))
236+
237+
(define %default-route-ipv6-attr-decoder
238+
  (default-route-attr-decoder deserialize-route-attr-data-ipv6))