syscalls: Add bindings for SIOCGIFNETMASK and SIOCSIFNETMASK.
* guix/build/syscalls.scm (SIOCGIFNETMASK, SIOCSIFNETMASK): New variables. (set-network-interface-netmask, network-interface-netmask): New procedures. * tests/syscalls.scm ("network-interface-netmask lo") ("set-network-interface-netmask"): New tests.
This commit is contained in:
parent
9d9d0c9c98
commit
67e5f3b71d
|
@ -87,10 +87,12 @@
|
||||||
all-network-interface-names
|
all-network-interface-names
|
||||||
network-interface-names
|
network-interface-names
|
||||||
network-interface-flags
|
network-interface-flags
|
||||||
|
network-interface-netmask
|
||||||
loopback-network-interface?
|
loopback-network-interface?
|
||||||
network-interface-address
|
network-interface-address
|
||||||
set-network-interface-flags
|
set-network-interface-flags
|
||||||
set-network-interface-address
|
set-network-interface-address
|
||||||
|
set-network-interface-netmask
|
||||||
set-network-interface-up
|
set-network-interface-up
|
||||||
configure-network-interface
|
configure-network-interface
|
||||||
|
|
||||||
|
@ -764,6 +766,14 @@ exception if it's already taken."
|
||||||
(if (string-contains %host-type "linux")
|
(if (string-contains %host-type "linux")
|
||||||
#x8916 ;GNU/Linux
|
#x8916 ;GNU/Linux
|
||||||
-1)) ;FIXME: GNU/Hurd?
|
-1)) ;FIXME: GNU/Hurd?
|
||||||
|
(define SIOCGIFNETMASK
|
||||||
|
(if (string-contains %host-type "linux")
|
||||||
|
#x891b ;GNU/Linux
|
||||||
|
-1)) ;FIXME: GNU/Hurd?
|
||||||
|
(define SIOCSIFNETMASK
|
||||||
|
(if (string-contains %host-type "linux")
|
||||||
|
#x891c ;GNU/Linux
|
||||||
|
-1)) ;FIXME: GNU/Hurd?
|
||||||
|
|
||||||
;; Flags and constants from <net/if.h>.
|
;; Flags and constants from <net/if.h>.
|
||||||
|
|
||||||
|
@ -970,6 +980,22 @@ interface NAME."
|
||||||
(list name (strerror err))
|
(list name (strerror err))
|
||||||
(list err))))))
|
(list err))))))
|
||||||
|
|
||||||
|
(define (set-network-interface-netmask socket name sockaddr)
|
||||||
|
"Set the network mask of interface NAME to SOCKADDR."
|
||||||
|
(let ((req (make-bytevector ifreq-struct-size)))
|
||||||
|
(bytevector-copy! (string->utf8 name) 0 req 0
|
||||||
|
(min (string-length name) (- IF_NAMESIZE 1)))
|
||||||
|
;; Set the 'ifr_addr' field.
|
||||||
|
(write-socket-address! sockaddr req IF_NAMESIZE)
|
||||||
|
(let-values (((ret err)
|
||||||
|
(%ioctl (fileno socket) SIOCSIFNETMASK
|
||||||
|
(bytevector->pointer req))))
|
||||||
|
(unless (zero? ret)
|
||||||
|
(throw 'system-error "set-network-interface-netmask"
|
||||||
|
"set-network-interface-netmask on ~A: ~A"
|
||||||
|
(list name (strerror err))
|
||||||
|
(list err))))))
|
||||||
|
|
||||||
(define (network-interface-address socket name)
|
(define (network-interface-address socket name)
|
||||||
"Return the address of network interface NAME. The result is an object of
|
"Return the address of network interface NAME. The result is an object of
|
||||||
the same type as that returned by 'make-socket-address'."
|
the same type as that returned by 'make-socket-address'."
|
||||||
|
@ -986,6 +1012,22 @@ the same type as that returned by 'make-socket-address'."
|
||||||
(list name (strerror err))
|
(list name (strerror err))
|
||||||
(list err))))))
|
(list err))))))
|
||||||
|
|
||||||
|
(define (network-interface-netmask socket name)
|
||||||
|
"Return the netmask of network interface NAME. The result is an object of
|
||||||
|
the same type as that returned by 'make-socket-address'."
|
||||||
|
(let ((req (make-bytevector ifreq-struct-size)))
|
||||||
|
(bytevector-copy! (string->utf8 name) 0 req 0
|
||||||
|
(min (string-length name) (- IF_NAMESIZE 1)))
|
||||||
|
(let-values (((ret err)
|
||||||
|
(%ioctl (fileno socket) SIOCGIFNETMASK
|
||||||
|
(bytevector->pointer req))))
|
||||||
|
(if (zero? ret)
|
||||||
|
(read-socket-address req IF_NAMESIZE)
|
||||||
|
(throw 'system-error "network-interface-netmask"
|
||||||
|
"network-interface-netmask on ~A: ~A"
|
||||||
|
(list name (strerror err))
|
||||||
|
(list err))))))
|
||||||
|
|
||||||
(define (configure-network-interface name sockaddr flags)
|
(define (configure-network-interface name sockaddr flags)
|
||||||
"Configure network interface NAME to use SOCKADDR, an address as returned by
|
"Configure network interface NAME to use SOCKADDR, an address as returned by
|
||||||
'make-socket-address', and FLAGS, a bitwise-or of IFF_* constants."
|
'make-socket-address', and FLAGS, a bitwise-or of IFF_* constants."
|
||||||
|
|
|
@ -326,6 +326,27 @@
|
||||||
;; We get EPERM with Linux 3.18ish and EACCES with 2.6.32.
|
;; We get EPERM with Linux 3.18ish and EACCES with 2.6.32.
|
||||||
(memv (system-error-errno args) (list EPERM EACCES))))))
|
(memv (system-error-errno args) (list EPERM EACCES))))))
|
||||||
|
|
||||||
|
(test-equal "network-interface-netmask lo"
|
||||||
|
(make-socket-address AF_INET (inet-pton AF_INET "255.0.0.0") 0)
|
||||||
|
(let* ((sock (socket AF_INET SOCK_STREAM 0))
|
||||||
|
(addr (network-interface-netmask sock "lo")))
|
||||||
|
(close-port sock)
|
||||||
|
addr))
|
||||||
|
|
||||||
|
(test-skip (if (zero? (getuid)) 1 0))
|
||||||
|
(test-assert "set-network-interface-netmask"
|
||||||
|
(let ((sock (socket AF_INET SOCK_STREAM 0)))
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
(set-network-interface-netmask sock "nonexistent"
|
||||||
|
(make-socket-address
|
||||||
|
AF_INET
|
||||||
|
(inet-pton AF_INET "255.0.0.0")
|
||||||
|
0)))
|
||||||
|
(lambda args
|
||||||
|
(close-port sock)
|
||||||
|
(memv (system-error-errno args) (list EPERM EACCES))))))
|
||||||
|
|
||||||
(test-equal "network-interfaces returns one or more interfaces"
|
(test-equal "network-interfaces returns one or more interfaces"
|
||||||
'(#t #t #t)
|
'(#t #t #t)
|
||||||
(match (network-interfaces)
|
(match (network-interfaces)
|
||||||
|
|
Loading…
Reference in New Issue