Receiving Data on an ATM Socket Rate-Enforced SVC Server Example Program
This section describes the procedure for receiving data on an ATM socket rate-enforced SVC server example program.
This program must be compiled with the -D_BSD and -lbsd options. For example, use the cc prog.c -o prog -D_BSD -lbsd command.
/*
* ATM Sockets rate enforced SVC Server Example
*
* This program listens for and accepts an SVC and receives data on it.
* It also demostrates AAL negotiation.
*
*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/ndd_var.h>
#include <sys/atmsock.h>
#define BUFF_SIZE 8192
char buff[BUFF_SIZE];
main(argc, argv)
int argc;
char *argv[];
{
int s; // Socket file descriptor
int new_s; // Socket returned by accept
int error; // Function return code
int i;
sockaddr_ndd_atm_t addr; // ATM Socket Address
unsigned long size; // Size of socket argument
aal_parm_t aal_parm; // AAL parameters
blli_t blli[3]; // Broadband Lower Layer Info
traffic_des_t traffic; // Traffic Descriptor
bearer_t bearer; // Broadband Bearer Capability
cause_t cause; // Cause of failure
unsigned char max_pend;
indaccept_ie_t indaccept;
// Create a socket in the AF_NDD domain of type SOCK_CONN_DGRAM
// and NDD_PROT_ATM protocol.
s = socket(AF_NDD, SOCK_CONN_DGRAM, NDD_PROT_ATM);
if (s == -1) {
perror("socket");
exit(-1);
}
addr.sndd_atm_len = sizeof(addr);
addr.sndd_atm_family = AF_NDD;
strcpy( addr.sndd_atm_nddname, "atm0" ); // The name of the ATM device
// which is to be used.
// The bind command associates this socket with a particular
// ATM device, as specified by addr.sndd_atm_nddname.
error = bind( s, (struct sockaddr *)&addr, sizeof(addr) );
if (error) {
perror("bind");
exit(-1);
} /* endif */
// Although up to 3 BLLIs may be specified by the calling side,
// the listening side may only specify one.
bzero(blli, sizeof(blli_t) );
blli[0].length = sizeof(blli_t);
blli[1].length = 0;
blli[2].length = 0;
// If a call arrives that matches these two parameters, it will
// be given to this application.
blli[0].L2_prot = CM_L2_PROT_USER;
blli[0].L2_info = 2;
// Fields that are not used must be set to NOT_SPECIFIED_B (byte)
blli[0].L2_mode = NOT_SPECIFIED_B;
blli[0].L2_win_size = NOT_SPECIFIED_B;
blli[0].L3_prot = NOT_SPECIFIED_B;
blli[0].L3_mode = NOT_SPECIFIED_B;
blli[0].L3_def_pkt_size = NOT_SPECIFIED_B;
blli[0].L3_pkt_win_size = NOT_SPECIFIED_B;
blli[0].L3_info = NOT_SPECIFIED_B;
blli[0].ipi = NOT_SPECIFIED_B;
blli[0].snap_oui[0] = NOT_SPECIFIED_B;
blli[0].snap_oui[1] = NOT_SPECIFIED_B;
blli[0].snap_oui[2] = NOT_SPECIFIED_B;
blli[0].snap_pid[0] = NOT_SPECIFIED_B;
blli[0].snap_pid[1] = NOT_SPECIFIED_B;
error = setsockopt( s, 0, SO_ATM_BLLI, (void *)&blli,
sizeof(blli) );
if (error) {
perror("setsockopt SO_ATM_BLLI");
exit(-1);
} /* endif */
// Query and print out the ATM address of this station. The
// client application will need it.
bzero( &addr, sizeof(addr));
size = sizeof(addr);
error = getsockname( s, (struct sockaddr *)&addr, &size );
if (error) {
printf("getsock error = %d errno = %d\n", error, errno );
exit(-1);
} /* endif */
printf("My ATM address: ");
for (i=0; i<20; i++) {
printf("%X.", addr.sndd_atm_addr.number.addr[i]);
} /* endfor */
printf("\n");
// The listen call enables this socket to receive incoming call
// that match its BLLI.
error = listen( s, 10 );
if (error) {
// Listen will fail if the station is not connected to
// an ATM switch.
perror("listen");
exit(-1);
} /* endif */
size = sizeof(addr);
printf("accepting\n");
// The accept will return a new socket of an incoming call
// for this socket, or sleep until one arrives.
new_s = accept( s, (struct sockaddr *)&addr, &size );
if (new_s == -1) {
printf("accept error = %d errno = %d\n", new_s, errno );
exit(-1);
} /* endif */
// Query the AAL parameters before fully establishing the
// connection. See the ATM UNI 3.0 for a description of
// which parameters may be negotiated.
size = sizeof(aal_parm_t);
error = getsockopt( new_s, 0, SO_ATM_AAL_PARM,
(void *)&aal_parm, &size );
indaccept.ia_aal_parm = aal_parm;
// Change the fwd_max_sdu_size down to 7520.
if (indaccept.ia_aal_parm.aal_info.aal5.fwd_max_sdu_size > 7520 ) {
indaccept.ia_aal_parm.aal_info.aal5.fwd_max_sdu_size = 7520;
} /* endif */
size = sizeof(indaccept_ie_t);
error = setsockopt( new_s, 0, SO_ATM_ACCEPT,
(void *)&indaccept, size );
if (error) {
perror("setsockopt ACCEPT");
exit(-1);
} /* endif */
while (1) {
error = recv( new_s, buff, BUFF_SIZE, 0 );
if (error == -1) {
// If a recv fails, the cause structure may contain useful
// information for determining the reason of the failure.
// The connection might have been closed by the other party,
// or the physical network might have been disconnected.
// See the ATM UNI 3.0 for a description of the cause values.
// If the send failed for some other reason, the errno will
// indicate this.
perror("recv");
size = sizeof(cause_t);
error = getsockopt(new_s, 0, SO_ATM_CAUSE,
(void *)&cause, &size);
if (error) {
perror("SO_ATM_CAUSE");
} else {
printf("cause = %d\n", cause.cause );
} /* endif */
exit(0);
} /* endif */
printf("recv %d bytes\n", error);
}
}