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 (datum)
22 (error 'unknown-interface
:datum datum
))
24 (defun list-network-interfaces ()
25 "Returns a list of network interfaces currently available."
26 (let ((ifptr (null-pointer)))
27 (macrolet ((%if-slot-value
(slot index
)
29 (mem-aref ifptr
'if-nameindex
,index
)
30 'if-nameindex
,slot
)))
33 (setf ifptr
(%if-nameindex
))
35 :for name
:= (%if-slot-value
'name i
)
36 :for index
:= (%if-slot-value
'index i
)
37 :while
(plusp index
) :collect
(make-interface name index
)))
38 (unless (null-pointer-p ifptr
) (%if-freenameindex ifptr
))))))
40 (defun get-interface-by-index (index)
41 (with-foreign-object (buffer :uint8 ifnamesize
)
43 (%if-indextoname index buffer
)
45 (signal-unknown-interface-error index
))
47 (make-interface name index
)))))
49 (defun get-interface-by-name (name)
51 (%if-nametoindex name
)
53 (signal-unknown-interface-error name
))
55 (make-interface (copy-seq name
) index
))))
57 (defun interface-name (interface)
58 "Return the name of an network interface."
61 (defun interface-index (interface)
62 "Return the OS index of a network interface."
65 (defun lookup-interface (interface)
66 "Lookup an interface by name or index. UNKNOWN-INTERFACE is
67 signalled if an interface is not found."
68 (check-type interface
(or unsigned-byte string symbol
) "non-negative integer, a string or a symbol")
69 (let ((parsed (ensure-string-or-unsigned-byte interface
:errorp t
)))
71 (unsigned-byte (get-interface-by-index parsed
))
72 (string (get-interface-by-name parsed
)))))