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); } }