5 Network Protocol¶
The SANE interface has been designed to facilitate network access to image acquisition devices. In particular, most SANE implementations are expected to support a network backend (net client) and a corresponding network daemon (net server) that allows accessing image acquisition devices through a network connection. Network access is useful in several situations:
To provide controlled access to resources that are inaccessible to a regular user. For example, a user may want to access a device on a host where she has no account on. With the network protocol, it is possible to allow certain users to access scanners without giving them full access to the system.
Controlling access through the network daemon can be useful even in the local case: for example, certain backends may require root privileges to access a device. Rather than installing each frontend as setuid-root, a system administrator could instead install the SANE network daemon as setuid-root. This enables regular users to access the privileged device through the SANE daemon (which, presumably, supports a more fine-grained access control mechanism than the simple setuid approach). This has the added benefit that the system administrator only needs to trust the SANE daemon, not each and every frontend that may need access to the privileged device.
Network access provides a sense of ubiquity of the available image acquisition devices. For example, in a local area network environment, this allows a user to log onto any machine and have convenient access to any resource available to any machine on the network (subject to permission constraints).
For devices that do not require physical access when used (e.g., video cameras), network access allows a user to control and use these devices without being in physical proximity. Indeed, if such devices are connected to the Internet, access from any place in the world is possible.
The network protocol described in this chapter has been design with the following goals in mind:
Image transmission should be efficient (have low encoding overhead).
Accessing option descriptors on the client side must be efficient (since this is a very common operation).
Other operations, such as setting or inquiring the value of an option are less performance critical since they typically require explicit user action.
The network protocol should be simple and easy to implement on any host architecture and any programming language.
The SANE protocol can be run across any transport protocol that provides reliable data delivery. While SANE does not specify a specific transport protocol, it is expected that TCP/IP will be among the most commonly used protocols.
5.1 Data Type Encoding¶
5.1.1 Primitive Data Types¶
The four primitive types of the SANE standard are encoded as follows:
SANE_Byte
A byte is encoded as an 8 bit value. Since the transport protocol is assumed to be byte-orientd, the bit order is irrelevant.
SANE_Word
A word is encoded as 4 bytes (32 bits). The bytes are ordered from most-significant to least-significant byte (big-endian byte-order).
SANE_Char
A character is currently encoded as an 8-bit ISO LATIN-1 value. An extension to support wider character sets (16 or 32 bits) is planned for the future, but not supported at this point.
SANE_String
A string pointer is encoded as a
SANE_Char
array. The trailing NUL byte is considered part of the array and aNULL
pointer is encoded as a zero-length array.
SANE_Handle
A handle is encoded like a word. The network backend needs to take care of converting these integer values to the opaque pointer values that are presented to the user of the network backend. Similarly, the SANE daemon needs to take care of converting the opaque pointer values it receives from its backends into 32-bit integers suitable for use for network encoding.
- enumeration types
Enumeration types are encoded like words.
5.1.2 Type Constructors¶
Closely following the type constructors of the C language, the SANE network protocol supports the following four constructors:
- pointer
A pointer is encoded by a word that indicates whether the pointer is a NULL-pointer which is then followed by the value that the pointer points to (in the case of a non-NULL pointer; in the case of a NULL pointer, no bytes are encoded for the pointer value).
- array
An array is encoded by a word that indicates the length of the array followed by the values of the elements in the array. The length may be zero in which case no bytes are encoded for the element values.
- structure
A structure is encoded by simply encoding the structure members in the order in which they appear in the corresponding C type declaration.
- union
A union must always be accompanied by a tag value that indicates which of the union members is the currently the active one. For this reason, the union itself is encoded simply by encoding the value of the currently active member.
Note that for type constructors, the pointer, element, or member values themselves may have a constructed type. Thus, the above rules should be applied recursively until a sequence of primitive types has been found.
Also SANE had no need for encoding of circular structures. This greatly simplifies the network protocol.
5.2 Remote Procedure Call Requests¶
The SANE network protocol is a client/server-style remote procedure call (RPC) protocol. This means that all activity is initiated by the client side (the network backend)—a server is restricted to answering requests sent by the client.
The data transferred from the client to the server is comprised of the
RPC code (as a SANE_WORD
), followed by arguments defined in
the request column below. The format of the server’s answer is
given in the reply column.
5.2.1 SANE_NET_INIT
¶
RPC Code: 0
This RPC establishes a connection to a particular SANE network daemon. It must be the first call in a SANE network session. The parameter and reply arguments for this call are shown in the table below:
request |
reply |
---|---|
|
|
|
|
The version_code
argument in the request is the SANE
version-code of the network backend that is contacting the network
daemon (see Section 4.1). The
“build-revision” in the version code is used to hold the network
protocol version. The SANE network daemon receiving such a request must
make sure that the network protocol version corresponds to a supported
version since otherwise the encoding of the network stream may be
incompatible (even though the SANE interface itself may be compatible).
The user_name
argument is the name of the user on
whose behalf this call is being performed. If the network backend cannot
determine a user-name, it passes a NULL
pointer for
this argument. No trust should be placed in the authenticity of this
user-name. The intent of this string is to provide more convenience to
the user. E.g., it could be used as the default-user name in subsequent
authentication calls.
In the reply, status
indicates the completion
status. If the value is anything other than
SANE_STATUS_SUCCESS
, the remainder of the reply has
undefined values. 1 The version_code
argument
returns the SANE version-code that the network daemon supports. See the
comments in the previous paragraph on the meaning of the build-revision
in this version code.
5.2.2 SANE_NET_GET_DEVICES
¶
RPC Code: 1
This RPC is used to obtain the list of devices accessible by the SANE daemon.
request |
reply |
---|---|
|
|
|
There are no arguments in the request for this call.
In the reply, status
indicates the completion
status. If the value is anything other than
SANE_STATUS_SUCCESS
, the remainder of the reply has
undefined values. The device_list
argument is a
pointer to a NULL
-terminated array of
SANE_Device
pointers.
5.2.3 SANE_NET_OPEN
¶
RPC Code: 2
This RPC is used to open a connection to a remote SANE device.
request |
reply |
---|---|
|
|
|
|
|
The device_name
argument specifies the name of the
device to open.
In the reply, status
indicates the completion
status. If the value is anything other than
SANE_STATUS_SUCCESS
, the remainder of the reply has
undefined values. The handle
argument specifies the
device handle that uniquely identifies the connection. The
resource
argument is used to request authentication.
If it has a non-NULL
value, the network backend
should authenticate the specified resource and then retry this operation
(see Section 5.2.10 for details on how to
authorize a resource).
5.2.4 SANE_NET_CLOSE
¶
RPC Code: 3
This RPC is used to close a connection to a remote SANE device.
request |
reply |
---|---|
|
|
The handle
argument identifies the connection that
should be closed.
In the reply, the dummy
argument is unused. Its
purpose is to ensure proper synchronization (without it, a net client
would not be able to determine when the RPC has completed).
5.2.5 SANE_NET_GET_OPTION_DESCRIPTORS
¶
RPC Code: 4
This RPC is used to obtain all the option descriptors for a remote SANE device.
request |
reply |
---|---|
|
|
The handle
argument identifies the remote device
whose option descriptors should be obtained.
In the reply, the odesc
argument is used to return
the array of option descriptors. The option descriptor array has the
following structure:
struct Option_Descriptor_Array { SANE_Word num_options; SANE_Option_Descriptor **desc; };
5.2.6 SANE_NET_CONTROL_OPTION
¶
RPC Code: 5
This RPC is used to control (inquire, set, or set to automatic) a specific option of a remote SANE device.
request |
reply |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
The handle
argument identifies the remote device
whose option should be controlled. Argument option
is the number (index) of the option that should be controlled. Argument
action
specifies what action should be taken (get,
set, or set automatic). Argument value_type
specifies the type of the option value (must be one of
SANE_TYPE_BOOL
, SANE_TYPE_INT
,
SANE_TYPE_FIXED
,
SANE_TYPE_STRING
,
SANE_TYPE_BUTTON
). Argument
value_size
specifies the size of the option value in
number of bytes (see Section sec:valuesize
for the
precise meaning of this value). Finally, argument
value
is a pointer to the option value. It must be a
writeable area that is at least value_size
bytes
large. (Note that this area must be writable even if the action is to
set the option value. This is because the backend may not be able to set
the exact option value, in which case the option value is used to return
the next best value that the backend has chosen.)
In the reply, argument resource
is set to the name
of the resource that must be authorized before this call can be retried.
If this value is non-NULL
, all other arguments have
undefined values (see Section 5.2.10 for
details on how to authorize a resource). Argument
status
indicates the completion status. If the value
is anything other than SANE_STATUS_SUCCESS
, the
remainder of the reply has undefined values. The
info
argument returns the information on how well
the backend was able to satisfy the request. For details, see the
description of the corresponding argument in
Section 4.3.7. Arguments
value_type
and value_size
have
the same values as the arguments by the same name in corresponding
request. The values are repeated here to ensure that both the request
and the reply are self-contained (i.e., they can be encoded and decoded
independently). Argument value
is holds the value of
the option that has become effective as a result of this RPC.
5.2.7 SANE_NET_GET_PARAMETERS
¶
RPC Code: 6
This RPC is used to obtain the scan parameters of a remote SANE device.
request |
reply |
---|---|
|
|
|
The handle
argument identifies the connection to the
remote device whose scan parameters should be returned.
In the reply, status
indicates the completion
status. If the value is anything other than
SANE_STATUS_SUCCESS
, the remainder of the reply
has undefined values. The argument params
is used to
return the scan parameters.
5.2.8 SANE_NET_START
¶
RPC Code: 7
This RPC is used to start image acquisition (scanning).
request |
reply |
---|---|
|
|
|
|
|
|
|
The handle
argument identifies the connection to the
remote device from which the image should be acquired.
In the reply, argument resource
is set to the name
of the resource that must be authorized before this call can be retried.
If this value is non-NULL
, all other arguments have
undefined values (see Section 5.2.10 for
details on how to authorize a resource). Argument,
status
indicates the completion status. If the value
is anything other than SANE_STATUS_SUCCESS
, the
remainder of the reply has undefined values. The argument
port
returns the port number from which the image
data will be available. To read the image data, a network client must
connect to the remote host at the indicated port number. Through this
port, the image data is transmitted as a sequence of data records. Each
record starts with the data length in bytes. The data length is
transmitted as a sequence of four bytes. These bytes should be
interpreted as an unsigned integer in big-endian format. The four length
bytes are followed by the number of data bytes indicated by the length.
Except for byte-order, the data is in the same format as defined for
sane_read()
. Since some records may contain no data
at all, a length value of zero is perfectly valid. The special length
value of 0xffffffff
is used to indicate the end of
the data stream. That is, after receiving a record length of
0xffffffff
, the network client should close the data
connection and stop reading data.
Argument byte_order
specifies the byte-order of the
image data. A value of 0x1234 indicates little-endian format, a value of
0x4321 indicates big-endian format. All other values are presently
undefined and reserved for future enhancements of this protocol. The
intent is that a network server sends data in its own byte-order and the
client is responsible for adjusting the byte-order, if necessary. This
approach causes no unnecessary overheads in the case where the server
and client byte-order match and puts the extra burden on the client side
when there is a byte-order mismatch. Putting the burden on the
client-side improves the scalability properties of this protocol.
5.2.9 SANE_NET_CANCEL
¶
RPC Code: 8
This RPC is used to cancel the current operation of a remote SANE device.
request |
reply |
---|---|
|
|
The handle
argument identifies the connection whose
operation should be cancelled.
In the reply, the dummy
argument is unused. Its
purpose is to ensure proper synchronization (without it, a net client
would not be able to determine when the RPC has completed).
5.2.10 SANE_NET_AUTHORIZE
¶
RPC Code: 9
This RPC is used to pass authorization data from the net client to the net server.
request |
reply |
---|---|
|
|
|
|
|
The resource
argument specifies the name of the
resource to be authorized. This argument should be set to the string
returned in the resource
argument of the RPC reply
that required this authorization call. The username
and password
are the name of the user that is
accessing the resource and the password for the specified resource/user
pair.
Since the password is not encrypted during network transmission, it is recommended to use the following extension:
If the server adds the string $MD5$
to the resource-name followed
by a random string not longer then 128 bytes, the client may answer
with the MD5 digest of the concatenation of the password and the
random string. To differentiate between the MD5 digest and a strange
password the client prepends the MD5 digest with the string $MD5$
.
In the reply, dummy
is completely unused. Note that
there is no direct failure indication. This is unnecessary since a net
client will retry the RPC that resulted in the authorization request
until that call succeeds (or until the request is cancelled). The RPC
that resulted in the authorization request continues after the reply
from the client and may fail with SANE_STATUS_ACCESS_DENIED
.
5.2.11 SANE_NET_EXIT
¶
RPC Code: 10
This RPC is used to disconnect a net client from a net server. There are
no request or reply arguments in this call. As a result of this call,
the connection between the client and the server that was established by
the SANE_NET_INIT
call will be closed.
- 1
The username and password should be encrypted before network transmission but currently they are always in plain text.