Make sure that OPEN-STREAM-P works on stream sockets.
[iolib.git] / src / sockets / iface.lisp
blobd8771f8bbd26a7bf5dbbaaeb4dd7c302afd0d1a1
1 ;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; --- Network interface lookup.
4 ;;;
6 (in-package :iolib.sockets)
8 (defun make-interface (name index)
9 "Constructor for INTERFACE objects."
10 (cons name index))
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)
28 `(foreign-slot-value
29 (mem-aref ifptr 'if-nameindex ,index)
30 'if-nameindex ,slot)))
31 (unwind-protect
32 (progn
33 (setf ifptr (%if-nameindex))
34 (loop :for i :from 0
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)
42 (handler-case
43 (%if-indextoname index buffer)
44 (isys:enxio ()
45 (signal-unknown-interface-error index))
46 (:no-error (name)
47 (make-interface name index)))))
49 (defun get-interface-by-name (name)
50 (handler-case
51 (%if-nametoindex name)
52 (isys:enxio ()
53 (signal-unknown-interface-error name))
54 (:no-error (index)
55 (make-interface (copy-seq name) index))))
57 (defun interface-name (interface)
58 "Return the name of an network interface."
59 (car interface))
61 (defun interface-index (interface)
62 "Return the OS index of a network interface."
63 (cdr 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)))
70 (typecase interface
71 (unsigned-byte (get-interface-by-index parsed))
72 (string (get-interface-by-name parsed)))))