1 ;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*-
3 ;;; --- Network interface lookup.
6 (in-package :iolib.sockets
)
8 (defun make-interface (name index
)
9 "Constructor for INTERFACE objects."
12 (define-condition unknown-interface
(isys:enxio
)
13 ((datum :initarg
:datum
:initform nil
:reader unknown-interface-datum
))
14 (:report
(lambda (condition stream
)
15 (format stream
"Unknown interface: ~A"
16 (unknown-interface-datum condition
))))
17 (:documentation
"Condition raised when a network interface is not found."))
18 (setf (documentation 'unknown-interface-datum
'function
)
19 "Return the datum that caused the signalling of an UNKNOWN-INTERFACE condition.")
21 (defun signal-unknown-interface-error (syscall datum
)
22 (error 'unknown-interface
:syscall syscall
:datum datum
))
24 (defun list-network-interfaces ()
25 "Returns a list of network interfaces currently available."
26 (let ((ifptr (null-pointer)))
29 (setf ifptr
(%if-nameindex
))
30 (loop :for p
:= ifptr
:then
(inc-pointer p
(isys:sizeof
'(:struct if-nameindex
)))
31 :for name
:= (foreign-slot-value p
'(:struct if-nameindex
) 'name
)
32 :for index
:= (foreign-slot-value p
'(:struct if-nameindex
) 'index
)
33 :while
(plusp index
) :collect
(make-interface name index
)))
34 (unless (null-pointer-p ifptr
) (%if-freenameindex ifptr
)))))
36 (defun get-interface-by-index (index)
37 (with-foreign-object (buffer :uint8 ifnamesize
)
39 (%if-indextoname index buffer
)
41 (signal-unknown-interface-error "if_indextoname" index
))
43 (make-interface name index
)))))
45 (defun get-interface-by-name (name)
47 (%if-nametoindex name
)
49 (signal-unknown-interface-error "if_nametoindex" name
))
51 (make-interface (copy-seq name
) index
))))
53 (defun interface-name (interface)
54 "Return the name of an network interface."
57 (defun interface-index (interface)
58 "Return the OS index of a network interface."
61 (defun lookup-interface (interface)
62 "Lookup an interface by name or index. UNKNOWN-INTERFACE is
63 signalled if an interface is not found."
64 (check-type interface
(or unsigned-byte string symbol
) "non-negative integer, a string or a symbol")
65 (let ((parsed (ensure-string-or-unsigned-byte interface
:errorp t
)))
67 (unsigned-byte (get-interface-by-index parsed
))
68 (string (get-interface-by-name parsed
)))))