2 HARP Native ATM Sockets API
3 ===========================
5 ATM sockets are an extension to the traditional BSD sockets API to allow
6 direct user-level access to native ATM protocol services. The ATM sockets
7 extensions are implemented via the addition of a new protocol family (PF_ATM)
8 and a new socket address structure (struct sockaddr_atm).
10 The HARP implementation of native ATM sockets capabilities is intended to be
11 conformant with The Open Group specifications (with known differences listed
12 below) as defined in the following document:
14 The Open Group: Networking Services (XNS) Issue 5
16 http://www.rdg.opengroup.org/public/pubs/catalog/c523.htm
18 And in particular, it is based on the following ATM-specific sections in the
21 ATM Transport Protocol Information for Sockets
22 ATM Transport Protocol Information for XTI
25 The ATM sockets API is an implementation based on the definitions and
26 descriptions set forth in the following document:
28 The ATM Forum: Native ATM Services: Semantic Description, Version 1.0
30 http://www.atmforum.com/atmforum/specs/approved.html
33 Using the HARP Implementation
34 -----------------------------
35 This document only provides the HARP-specific information necessary for using
36 the ATM sockets API. Please refer to the XNS document described above for
37 all of the general interface specifications. There is also sample source
38 code for an ATM sockets application included at the end of this document.
40 All user definitions for the HARP ATM sockets implementation are contained
41 in the file /usr/include/netatm/atm.h. This file must be included in the
42 user's C program source file. In this file, all HARP extensions to the base
43 XNS specifications are denoted with a comment string of "XNS_EXT".
46 HARP Extensions to XNS Issue 5
47 ------------------------------
48 o Socket address structure for ATM addresses
50 An ATM socket address structure was not specifically defined by XNS,
51 although the t_atm_sap structure was defined to be used as an ATM protocol
52 address. Thus, HARP has defined an ATM socket address (using address
53 family AF_ATM) as a 'struct sockaddr_atm', which contains 'struct t_atm_sap'
54 as the protocol address. This structure (properly cast) must be used on
55 all ATM socket system calls requiring a 'struct sockaddr' parameter.
57 o Network Interface Selection socket option (T_ATM_NET_INTF)
59 This option is used to specify the name of the network interface to be
60 used to route an outgoing ATM call using a socket connection. This option
61 is only needed when there are multiple ATM network interfaces defined on a
62 system. If this option is not set, then the first network interface on
63 the first physical ATM interface defined will be used.
65 See the sample application below for an example of the use of this option.
67 o LLC Multiplexing socket option (T_ATM_LLC)
69 For LLC encapsulated VCCs (BLLI Layer 2 Protocol == T_ATM_BLLI2_I8802),
70 HARP has implemented an LLC multiplexing facility. In order to use this
71 multiplexing facility, a user must issue a setsockopt() call specifying the
72 T_ATM_LLC option before the connect() or listen() system call is invoked.
74 If using the LLC multiplexor, the user will only receive PDUs which match
75 the LLC header information specified in the socket option. The kernel
76 multiplexing software will strip the LLC header from all inbound PDUs and
77 add the specified LLC header to all outgoing PDUs - the user will never see
80 For listening sockets, the listener will be notified for all incoming LLC
81 calls (which also meet the other incoming call distribution selection
82 criteria), since the LLC header information is only carried in the data
83 PDUs, not in the signalling protocol.
85 The T_ATM_LLC_SHARING flag is used to denote whether this user wishes to
86 share the VCC with other LLC users requesting similar connection attributes
87 to the same destination.
89 o Application Name socket option (T_ATM_APP_NAME)
91 This option is used to associate an identifier string (typically, the
92 application's name) with an open ATM socket. Currently, it is only used
93 for the "Owner" field in the output of the 'atm show vcc' command. If this
94 option is not set, then the "Owner" field will default to "(AAL5)".
96 See the sample application below for an example of the use of this option.
100 The XNS document specifically does not provide support for ATM PVCs.
101 However, due in part to internal HARP requirements (the ILMI daemon), PVC
102 sockets are supported under the HARP implementation.
104 To support PVC sockets, there is a new address format (T_ATM_PVC_ADDR) and
105 address definition (Atm_addr_pvc). Since there is no actual signalling
106 involved in setting up a PVC, a PVC socket connection only defines the
107 local socket-to-pvc connection - the remainder of the virtual circuit through
108 the ATM network to the remote endpoint must be defined independent of the
109 local socket creation. PVC socket connections are only allowed via the
110 connect() system call - listen()/accept() sockets cannot be supported.
111 Also, since there are no circuit parameters signalled, most of the
112 setsockopt() options are silently ignored.
116 HARP has added ATM socket support for the FORE-proprietary SPANS address
117 format (T_ATM_SPANS_ADDR). A SPANS socket can only be established over
118 an ATM physical interface which is using the SPANS signalling manager.
119 There is limited ATM socket option support - the socket options can be set,
120 but most are silently ignored, since they are not applicable to the SPANS
121 protocols. The SPANS socket address support has not been thoroughly tested.
123 o Miscellaneous user convenience typedefs, macros and defines
126 XNS Issue 5 Features Not Supported in HARP
127 ------------------------------------------
130 The socket protocol for reliable data transport (ATM_PROTO_SSCOP) is not
131 supported in this HARP release. There is some initial skeleton code for
132 SSCOP support, but it was not completed.
134 o Multipoint connections
136 The core HARP code does not provide support for multipoint connections, so,
137 obviously, multipoint socket connections are also not supported.
139 The non-supported socket options are:
144 The non-supported socket option values are:
145 o For the T_ATM_BEARER_CAP socket option:
146 o connection_configuration == T_ATM_1_TO_MANY
149 Example ATM Socket Application
150 ------------------------------
151 The following are simple example client and server applications using the ATM
155 * ATM API sample client application
157 * This application will open an ATM socket to a server, send a text string
158 * in a PDU and then read one PDU from the socket and print its contents.
162 #include <sys/param.h>
163 #include <sys/types.h>
164 #include <sys/socket.h>
166 #include <netatm/atm.h>
168 #define MAX_LEN 4096 /* Maximum PDU length */
169 #define MY_ID 11 /* BLLI Layer 2 protocol */
170 #define MY_APPL "Client"
172 Atm_addr_nsap dst_addr = {
174 #error FIX ME: Replace the 2 lines below with your nsap prefix and esi address
175 {0x00,0x05,0x80,0xff,0xdc,0x00,0x00,0x00,0x00,0x02,0xff,0xff},
176 {0x11,0x22,0x33,0x44,0x55,0x66},
180 static char message[] = "A message from the client";
185 struct t_atm_cause cause;
188 optlen = sizeof(cause);
189 if (getsockopt(s, T_ATM_SIGNALING, T_ATM_CAUSE, &cause, &optlen) < 0) {
190 perror("getsockopt(cause)");
194 fprintf(stderr, "Cause: coding=%d loc=%d cause=%d diag=(%d,%d,%d,%d)\n",
195 cause.coding_standard, cause.location, cause.cause_value,
196 cause.diagnostics[0], cause.diagnostics[1],
197 cause.diagnostics[2], cause.diagnostics[3]);
204 struct sockaddr_atm satm;
205 struct t_atm_aal5 aal5;
206 struct t_atm_traffic traffic;
207 struct t_atm_bearer bearer;
208 struct t_atm_qos qos;
209 struct t_atm_net_intf netintf;
210 struct t_atm_app_name appname;
211 char buffer[MAX_LEN+1];
217 s = socket(AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
224 * Set up destination SAP
226 bzero((caddr_t) &satm, sizeof(satm));
227 satm.satm_family = AF_ATM;
228 #if (defined(BSD) && (BSD >= 199103))
229 satm.satm_len = sizeof(satm);
231 /* Destination ATM address */
232 satm.satm_addr.t_atm_sap_addr.SVE_tag_addr = T_ATM_PRESENT;
233 satm.satm_addr.t_atm_sap_addr.SVE_tag_selector = T_ATM_PRESENT;
234 satm.satm_addr.t_atm_sap_addr.address_format = T_ATM_ENDSYS_ADDR;
235 satm.satm_addr.t_atm_sap_addr.address_length = sizeof(Atm_addr_nsap);
236 bcopy((caddr_t)&dst_addr,
237 (caddr_t)satm.satm_addr.t_atm_sap_addr.address,
240 /* BLLI Layer-2 protocol */
241 satm.satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_PRESENT;
242 satm.satm_addr.t_atm_sap_layer2.ID_type = T_ATM_USER_ID;
243 satm.satm_addr.t_atm_sap_layer2.ID.user_defined_ID = MY_ID;
245 /* BLLI Layer-3 protocol */
246 satm.satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
249 satm.satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
252 * Set up connection parameters
254 aal5.forward_max_SDU_size = MAX_LEN;
255 aal5.backward_max_SDU_size = MAX_LEN;
256 aal5.SSCS_type = T_ATM_NULL;
257 optlen = sizeof(aal5);
258 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
260 perror("setsockopt(aal5)");
264 traffic.forward.PCR_high_priority = T_ATM_ABSENT;
265 traffic.forward.PCR_all_traffic = 100000;
266 traffic.forward.SCR_high_priority = T_ATM_ABSENT;
267 traffic.forward.SCR_all_traffic = T_ATM_ABSENT;
268 traffic.forward.MBS_high_priority = T_ATM_ABSENT;
269 traffic.forward.MBS_all_traffic = T_ATM_ABSENT;
270 traffic.forward.tagging = T_NO;
271 traffic.backward.PCR_high_priority = T_ATM_ABSENT;
272 traffic.backward.PCR_all_traffic = 100000;
273 traffic.backward.SCR_high_priority = T_ATM_ABSENT;
274 traffic.backward.SCR_all_traffic = T_ATM_ABSENT;
275 traffic.backward.MBS_high_priority = T_ATM_ABSENT;
276 traffic.backward.MBS_all_traffic = T_ATM_ABSENT;
277 traffic.backward.tagging = T_NO;
278 traffic.best_effort = T_YES;
279 optlen = sizeof(traffic);
280 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_TRAFFIC, (caddr_t)&traffic,
282 perror("setsockopt(traffic)");
286 bearer.bearer_class = T_ATM_CLASS_X;
287 bearer.traffic_type = T_ATM_NULL;
288 bearer.timing_requirements = T_ATM_NULL;
289 bearer.clipping_susceptibility = T_NO;
290 bearer.connection_configuration = T_ATM_1_TO_1;
291 optlen = sizeof(bearer);
292 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_BEARER_CAP, (caddr_t)&bearer,
294 perror("setsockopt(bearer)");
298 qos.coding_standard = T_ATM_NETWORK_CODING;
299 qos.forward.qos_class = T_ATM_QOS_CLASS_0;
300 qos.backward.qos_class = T_ATM_QOS_CLASS_0;
301 optlen = sizeof(qos);
302 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
304 perror("setsockopt(qos)");
308 #ifdef REMOVE_TO_USE_NET_INTF
309 #error FIX ME: Replace the ni0 below with the local atm network interface name
310 strncpy(netintf.net_intf, "ni0", IFNAMSIZ);
311 optlen = sizeof(netintf);
312 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_NET_INTF, (caddr_t)&netintf,
314 perror("setsockopt(net_intf)");
319 strncpy(appname.app_name, MY_APPL, T_ATM_APP_NAME_LEN);
320 optlen = sizeof(appname);
321 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_APP_NAME, (caddr_t)&appname,
323 perror("setsockopt(app_name)");
328 * Now try to connect to destination
330 if (connect(s, (struct sockaddr *) &satm, sizeof(satm)) < 0) {
337 * Exchange message with peer
339 if (write(s, message, sizeof(message)) != sizeof(message)) {
344 if ((n = read(s, buffer, MAX_LEN)) < 0) {
350 printf("received %d bytes: <%s>\n", n, buffer);
366 * ATM API sample server application
368 * This application will loop forever listening for connections on an ATM
369 * socket. When a new connection arrives, it will send a string in a PDU,
370 * read one PDU from the socket and print its contents.
374 #include <sys/param.h>
375 #include <sys/types.h>
376 #include <sys/socket.h>
378 #include <netatm/atm.h>
380 #define MAX_LEN 4096 /* Maximum PDU length */
381 #define MY_ID 11 /* BLLI Layer 2 protocol */
382 #define MY_APPL "Server"
384 static char message[] = "A message from the server";
389 struct t_atm_cause cause;
392 optlen = sizeof(cause);
393 if (getsockopt(s, T_ATM_SIGNALING, T_ATM_CAUSE, &cause, &optlen) < 0) {
394 perror("getsockopt(cause)");
398 fprintf(stderr, "Cause: coding=%d loc=%d cause=%d diag=(%d,%d,%d,%d)\n",
399 cause.coding_standard, cause.location, cause.cause_value,
400 cause.diagnostics[0], cause.diagnostics[1],
401 cause.diagnostics[2], cause.diagnostics[3]);
408 struct sockaddr_atm satm;
409 struct t_atm_aal5 aal5;
410 struct t_atm_traffic traffic;
411 struct t_atm_bearer bearer;
412 struct t_atm_qos qos;
413 struct t_atm_net_intf netintf;
414 struct t_atm_app_name appname;
415 char buffer[MAX_LEN+1];
421 s = socket(AF_ATM, SOCK_SEQPACKET, ATM_PROTO_AAL5);
428 * Set up destination SAP
430 bzero((caddr_t) &satm, sizeof(satm));
431 satm.satm_family = AF_ATM;
432 #if (defined(BSD) && (BSD >= 199103))
433 satm.satm_len = sizeof(satm);
435 /* Destination ATM address */
436 satm.satm_addr.t_atm_sap_addr.SVE_tag_addr = T_ATM_ANY;
437 satm.satm_addr.t_atm_sap_addr.SVE_tag_selector = T_ATM_ANY;
439 /* BLLI Layer-2 protocol */
440 satm.satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_PRESENT;
441 satm.satm_addr.t_atm_sap_layer2.ID_type = T_ATM_USER_ID;
442 satm.satm_addr.t_atm_sap_layer2.ID.user_defined_ID = MY_ID;
444 /* BLLI Layer-3 protocol */
445 satm.satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
448 satm.satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
451 * Set up connection parameters
453 aal5.forward_max_SDU_size = MAX_LEN;
454 aal5.backward_max_SDU_size = MAX_LEN;
455 aal5.SSCS_type = T_ATM_NULL;
456 optlen = sizeof(aal5);
457 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_AAL5, (caddr_t)&aal5,
459 perror("setsockopt(aal5)");
463 traffic.forward.PCR_high_priority = T_ATM_ABSENT;
464 traffic.forward.PCR_all_traffic = 100000;
465 traffic.forward.SCR_high_priority = T_ATM_ABSENT;
466 traffic.forward.SCR_all_traffic = T_ATM_ABSENT;
467 traffic.forward.MBS_high_priority = T_ATM_ABSENT;
468 traffic.forward.MBS_all_traffic = T_ATM_ABSENT;
469 traffic.forward.tagging = T_NO;
470 traffic.backward.PCR_high_priority = T_ATM_ABSENT;
471 traffic.backward.PCR_all_traffic = 100000;
472 traffic.backward.SCR_high_priority = T_ATM_ABSENT;
473 traffic.backward.SCR_all_traffic = T_ATM_ABSENT;
474 traffic.backward.MBS_high_priority = T_ATM_ABSENT;
475 traffic.backward.MBS_all_traffic = T_ATM_ABSENT;
476 traffic.backward.tagging = T_NO;
477 traffic.best_effort = T_YES;
478 optlen = sizeof(traffic);
479 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_TRAFFIC, (caddr_t)&traffic,
481 perror("setsockopt(traffic)");
485 bearer.bearer_class = T_ATM_CLASS_X;
486 bearer.traffic_type = T_ATM_NULL;
487 bearer.timing_requirements = T_ATM_NULL;
488 bearer.clipping_susceptibility = T_NO;
489 bearer.connection_configuration = T_ATM_1_TO_1;
490 optlen = sizeof(bearer);
491 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_BEARER_CAP, (caddr_t)&bearer,
493 perror("setsockopt(bearer)");
497 qos.coding_standard = T_ATM_NETWORK_CODING;
498 qos.forward.qos_class = T_ATM_QOS_CLASS_0;
499 qos.backward.qos_class = T_ATM_QOS_CLASS_0;
500 optlen = sizeof(qos);
501 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_QOS, (caddr_t)&qos,
503 perror("setsockopt(qos)");
507 strncpy(appname.app_name, MY_APPL, T_ATM_APP_NAME_LEN);
508 optlen = sizeof(appname);
509 if (setsockopt(s, T_ATM_SIGNALING, T_ATM_APP_NAME, (caddr_t)&appname,
511 perror("setsockopt(app_name)");
516 * Now try to bind/listen
518 if (bind(s, (struct sockaddr *) &satm, sizeof(satm)) < 0) {
522 if (listen(s, 4) < 0) {
528 struct sockaddr_atm claddr;
531 /* Wait for incoming call */
532 cllen = sizeof(claddr);
533 clsock = accept(s, (struct sockaddr *) &claddr, &cllen);
538 printf("Server: new connection\n");
541 * Exchange message with peer
543 if (write(clsock, message, sizeof(message)) != sizeof(message)) {
548 if ((n = read(clsock, buffer, MAX_LEN)) < 0) {
554 printf("received %d bytes: <%s>\n", n, buffer);
561 if (close(clsock) < 0) {
571 @(#) $FreeBSD: src/share/examples/atm/atm-sockets.txt,v 1.3 1999/08/28 00:19:07 peter Exp $