appletalk(7) appletalk(7)
NAME
appletalk - general AppleTalk socket interface
DESCRIPTION
This section describes particular special files and the
general nature of the AppleTalk interface.
The 254 special files /dev/appletalk/socket1 through
/dev/appletalk/socket254 provide access to the 254 sockets
that the AppleTalk DDP (DataGram Delivery Protocol) provides
on each node.
The AppleTalk I/O driver itself is accessed by the special
file /dev/appletalk/control, socket 1 is accessed by
/dev/appletalk/socket1, and so on.
The standard system calls read(2) and write(2) are used to
read and write DataGrams to and from sockets.
Opening Sockets
Sockets correspond one to one to Oreo files. To open a
socket, you open a file on the filename of the socket,
for example:
fildes = open("/dev/appletalk/socket1",1);
However, in AppleTalk, there are two kinds of sockets.
Static sockets and dynamic sockets. Static sockets are
opened just as described above. To open a dynamic socket,
you must first ask the AppleTalk I/O driver to give you a
random socket number. Once you have that socket number, you
can use it to create the special file filename for opening
the dynamic socket with.
To open a dynamic socket, the following code can be used:
int control_file;
int socket_file;
int socket_number;
char buffer[64];
control_file = open("/dev/appletalk/control",0);
ioctl(control_file,AT_GET_DYNAMIC_SOCKET,&socket_number);
sprintf(buffer,"/dev/appletalk/socket%d",socket_number);
socket_file = open(buffer,open_mode);
The use of the ioctl(2) system call is explained later in
the document.
Open Errors
[ENETDOWN] The network is down.
Page 1 (last mod. 1/15/87)
appletalk(7) appletalk(7)
[ENOTCONN] Dynamic open attempted on a socket that
was not previously the subject of an
ATGETDYNAMICSOCKET ioctl(2) system
call.
[ENOTDIR] A component of the path prefix is not a
directory.
[ENOENT] OCREAT is not set and the named file does
not exist.
[EACCES] A component of the path prefix denies
search permission.
[EACCES] Oflag permission is denied for the named
file.
[EISDIR] The named file is a directory and oflag is
write or read/write.
[EEXIST] The file is opened with the OCREAT
and OEXCL option and exists already.
[EMFILE] Twenty (20) file descriptors are currently
open.
[ENXIO] The named file is a character special or
block special file, and the device
associated with this special file does not
exist.
[EFAULT] Path points outside the allocated address
space of the process.
[EINTR] A signal was caught during the open system
call.
[ENFILE] The system file table is full.
[EBUSY] An already opened socket is being opened
again exclusively.
[ENOTSOCK] The file specified in the open system call
does not refer to a socket.
ioctl(2) and DataGram control
ioctl
performs a variety of special functions on the AppleTalk I/O
driver. The general format of an ioctl(2) system call is as
follows:
Page 2 (last mod. 1/15/87)
appletalk(7) appletalk(7)
int control_file;
int request;
int arg;
control_file = open("/dev/appletalk/control",0);
ioctl(control_file,request,arg);
fildes is the file descriptor obtained from a creat(2),
open(2), dup(2), fcntl(2), or pipe(2) system call on an
AppleTalk socket.
request is the ioctl request type to the AppleTalk I/O
driver.
ioctl(2) Requests
The following requests are supported. The value for each of
the requests is defined in the appletalk.h header file. For
most of the requests, the file descriptor in the first
argument should be for the AppleTalk control file. Some of
the requests are "special", in the sense that the file
descriptor for those requests will be the file descriptor of
a socket. Those requests determine in which mode the socket
associated with the descriptor will be used, the default
being the DDP (Datagram) mode. They are:
AT_SET_DDP_PROTOCOL
Sets the mode of a specific socket to be DDP. This
socket can now only be used for receiving and sending
datagrams on it.
AT_SET_ATP_TREQ_PROTOCOL
Sets the mode of a specific socket to be ATP Request.
This socket can now only be used for sending ATP
requests and for receiving ATP responses on it.
AT_SET_ATP_TRES_PROTOCOL
Sets the mode of a specific socket to be ATP Response.
This socket can now only be used for receiving ATP
requests and for sending ATP responses on it.
Those modes affect the way in which the user can use the
read and write system calls. See the description of those
calls for the differences.
The following requests are more general i.e. they are
independent of the socket mode:
FIONREAD
See ``Pending DataGrams'' under ``Reading DataGrams''.
AT_GET_CONFIGURATION
Gets the configuration table from the I/O driver. arg
Page 3 (last mod. 1/15/87)
appletalk(7) appletalk(7)
must be a pointer to an atcfg structure, as defined in
appletalk.h.
AT_GET_DYNAMIC_SOCKET
Gets a dynamic socket number. arg must be a pointer to
an int data type.
AT_RTMP_AGE_A_BRIDGE
This call returns no value nor does it exppect a value.
It ages the a bridge node address. If no RTMP packet
has been received from a bridge since this ioctl was
issued last, the bridge address will be set to zero.
AT_SET_CONFIGURATION
Sets the configuration table in the I/O driver. arg
must be a pointer to an atcfg structure, as defined in
appletalk.h. The following fields from the atcfg
structure are copied into appropriate values in the I/O
driver:
at_cfg_initial_node_address
\ at_cfg_rts_attempts
(only if non-zero)
All others field in atcfg are ignored.
AT_SHUTDOWN
Shuts the network down. All sockets become inoperative
immediately. The node address will still be defended
though.
AT_STARTUP
Resets and starts up the net. All buffers, trace table,
are reset. One needs to be superuser to perform this
function.
AT_TESTWRITE
Internal debugging use. Do not use.
AT_TRACEDUMP
Internal debugging use. Do not use.
AT__ Internal debugging use. Do not use.
ioctl Errors
[EALREADY] An attempt was made to start a network
that is already up.
[ENETDOWN] A shutdown was attempted on a network
that was not started.
[ECONNABORTED] Attempted to AT_GET_DYNAMIC_SOCKET on
a non-zero minor number. That is, the
Page 4 (last mod. 1/15/87)
appletalk(7) appletalk(7)
ioctl(2) AT_GET_DYNAMIC_SOCKET
operation was attempted on a file
descriptor that was opened on a socket
rather than /dev/appletalk/control.
[ENOTCONN] No dynamic sockets are available. All
127 are already dynamically assigned.
[EFAULT] An illegal address was given for the
argument, or a non supported request
was specified.
[EAFNOSUPPORT] The initial node address specified
with the AT_SET_CONFIGURATION request
is out of range.
[ENOTSOCK] An illegal socket file descriptor was
specified with the AT_SET_*_PROTOCOL
request.
[ENETRESET] The network has gone down and has been
brought up again, so all previously
accessed sockets are now closed.
[EACCES] The user starting up the network or
resetting its configuration is not
superuser.
[EINVAL] An illegal value was specified for the
number of attempts with the
AT_SET_CONFIGURATION request.
Reading DataGrams
The data read from the socket is always the entire LAP
packet. Packets of types not corresponding to the
socket protocol they are intended for get thrown away
silently, e.g. from a socket with TReq protocol, only
TReq packets can be read. A read(2) system call will
return the length of data read, from 3 bytes (minimum
length of a LAP packet) to 603 bytes (maximum length of
a LAP packet). If the LAP packet length is greater than
the maximum length specified in the read(2) system call,
the bytes not read from the LAP packet will be silently
(i.e., no indication of error) thrown away.
The read will always block until a packet is received
for the socket.
Reading Pending DataGrams
The length of the next (if any) DataGram may be
determined by using an ioctl(2) call as follows:
Page 5 (last mod. 1/15/87)
appletalk(7) appletalk(7)
int status;
int next_datagram_length;
status = ioctl(fildes,FIONREAD,&next_datagram_length);
Where fildes is the file descriptor obtained from a
creat(2), open(2), dup(2), fcntl(2), or pipe(2) system call,
FIONREAD is a constant value defined in the include header
file <sys/ioctl.h>, and iptr is a pointer to an int variable
in which the number of bytes of the next DataGram to be read
will be returned in. If no DataGram exists for the socket, a
value of zero will be placed in iptr .
Read Return Value
Upon sucessful completion a non-negative integer is
returned indicating the number of bytes actually read.
Otherwise, a -1 is returned, and errno is set to
indicate the error.
Read Errors
[EBADF] The file descriptor is not valid or is not
open for reading.
[EFAULT] The buffer address to write is not a valid
logical address for the process
[EINTR] A signal was caught during the read(2)
system call.
[ENOPROTOOPT]
A request was read from the socket, the user
is not responding to it but is trying to
read another request instead.
[ENETDOWN] The network is down.
Writing DataGrams on a DDP socket
The data written to the socket is the entire LAP packet.
At least 3 bytes, (minimum length of a LAP packet), and
no more than 603 bytes (maximum length of a LAP packet),
may be written.
Write Buffer Manipulation
The following fields in the LAP packet and DataGram will
be filled in by the Oreo driver:
Source address with the current node number.
DataGram length with the computed length.
Source socket with the actual socket number.
Page 6 (last mod. 1/15/87)
appletalk(7) appletalk(7)
DDP checksum with checksum of the DataGram (extended DDP
headers only). This will be optional in the next
release, but the additional ioctl(2) system call
definition didn't make it into this release.
Source node with the current node number (extended DDP
headers only).
Source network number with the current network number
(extended DDP headers only).
Write Return Value
Upon successful completion a non-negative integer is
returned indicating the number of bytes written.
Otherwise, a -1 is returned, and errno is set to
indicate the error.
Write Errors
[EMSGSIZE] The length of the packet is too small
(< 3) or too big (> 603).
[EPROTOTYPE] The packet is not a DDP packet (i.e.,
a value of 0x01 or 0x02 is not in the
3rd byte of the LAP header).
[EBADF] The file descriptor is not valid or is
not open for writing.
[EFAULT ] The buffer address to write is not a
valid logical address for the process.
[ERANGE] The length of the data being written
is less than 3 bytes or more than 603
bytes.
[EINTR] A signal was caught during the
write(2) system call.
[EADDRNOTAVAIL] The destination node number is 0.
[ENOTSOCK] The destination socket number is out
of range (<1 or >254).
[EHOSTUNREACH] The request to send was never
acknowledged; the destination node
went down or an invalid destination
address was specified.
Writing Transaction Requests on a TReq socket
The data written to the socket is a structure of the
type atatpreq, as described in <appletalk.h>. All
fields of the structure must be filled in by the user,
Page 7 (last mod. 1/15/87)
appletalk(7) appletalk(7)
except for atatpreqtrespuserbytes,
atatpreqtresplengths, atatpreqtrespeomseqno,
atatpreqtrespbitmap, atatpreqtid and
atatpreqgottrel. The length specified to the write()
call should be sizeof(atatpreq).
Write Return Value
Upon successful completion a non-negative integer is
returned indicating the number of bytes written.
Otherwise, a -1 is returned, and errno is set to
indicate the error. The packets received in response to
the request will be stored in the atatpreq structure.
The user bytes will be stored in the
atatpreqtrespuserbytes field, the data will be
stored at the addresses provided by the user in the
atatpreqtrespdata fields, and the lengths of the
packets will be in the atatpreqtresplengths fields.
The bitmap in the atatpreqtrespbitmap will indicate
which packets were received, and the
atatpreqtrespeomseqno field which packet is the last
one.
Write Errors
[EBADF] The file descriptor is not valid or is
not open for writing.
[EFAULT ] The address of the atatpreq
structure, or one of the addresses
specified in that structure is not a
valid logical address for the process.
[ERANGE] The length of the data to be written
as specified in the atatpreq
structure is out of range (> 578 or
<0).
[EINVAL] The length specified in the write()
call is not sizeof(atatpreq).
[EINTR] A signal was caught during the
write(2) system call.
[EOPNOTSUPP] The request type specified in the
atatpreq structure is not
AT_ATP_CMD_TREQ.
[ENOSP] There is no more internal buffer space
available.
[EHOSTUNREACH] The request to send was never
acknowledged; the destination node
went down or an invalid destination
Page 8 (last mod. 1/15/87)
appletalk(7) appletalk(7)
address was specified.
[ETIMEDOUT] All response packets could not be
obtained within the time interval and
with the number of tries specified by
the user.
[ENETDOWN] The network is down.
Writing Transaction Responses on a TResp socket
The data written to the socket is a structure of the
type atatpreq, as described in <appletalk.h>. All
fields of the structure must be filled in by the user,
except for
atatpreqtrequserbytes,atatpreqtreqdata,
atatpreqtreqlength,
atatpreqretrytimeout,atatpreqmaximumretries and
atatpreqgottrel. The length specified to the write()
call should be sizeof(atatpreq).
Write Return Value
Upon successful completion a non-negative integer is
returned indicating the number of bytes written.
Otherwise, a -1 is returned, and errno is set to
indicate the error. The atatpreqgottrel field will
indicate (for an exactly_once transaction) whether a
TRel packet was received from the requestor or whether a
timeout occurred.
Write Errors
[EBADF] The file descriptor is not valid or is
not open for writing.
[EFAULT ] The address of the atatpreq
structure, or one of the addresses
specified in that structure is not a
valid logical address for the process.
[ERANGE] The length of the data to be written
as specified in the atatpreq
structure is out of range (> 578 or
<0).
[EINVAL] The length specified in the write()
call is not sizeof(atatpreq).
[EINTR] A signal was caught during the
write(2) system call.
[EOPNOTSUPP] The request type specified in the
atatpreq structure is not
ATATPCMDTREQ.
Page 9 (last mod. 1/15/87)
appletalk(7) appletalk(7)
[ENOSP] There is no more internal buffer space
available.
[EHOSTUNREACH] The request to send was never
acknowledged; the destination node
went down or an invalid destination
address was specified.
[ECONNREFUSED] A response is being written without
having read the request first.
[ENETDOWN] The network is down.
EXAMPLE
#include <stdio.h>
#include "appletalk.h"
main()
{
at_dg datagram;
int i;
int fildes;
int length;
datagram.lap.at_lap_dst_addr = 0x82;
datagram.lap.at_lap_type = AT_LAP_TYPE_DDP_S_HDR;
datagram.ddp.at_ddp_datagram_len = AT_DDP_DATA_MAX;
for (i = 0; i < AT_DDP_DATA_MAX; i++)
{
datagram.buf[i] = 0x57;
}
fildes = open("/dev/appletalk/socket5",2);
length = sizeof(at_lap_hdr) + sizeof(at_ddp_hdr) + AT_DDP_DATA_MAX;
write(fildes,&datagram,length);
}
FILES
/dev/appletalk/socket1
/dev/appletalk/socket2
... ...
... ...
/dev/appletalk/socket254
SEE ALSO
creat(2), open(2), dup(2), fcntl(2).
Page 10 (last mod. 1/15/87)