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 Client Example * * This program opens a opens a rate enforced (not best effort) SVC * and sends data on it. * */ #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 100000 char buff[BUFF_SIZE]; main(argc, argv) int argc; char *argv[]; { int s; // Socket file descriptor 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 int o[20]; // Temporary variable for ATM // address cause_t cause; // Cause of failure unsigned char max_pend; // Maximum outstanding transmits // 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 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) { // An error from bind would indicate the perror("bind"); // requested ATM device is not available. exit(-1); // Check smitty devices. } /* endif */ // Set the AAL parameters. // See the ATM UNI 3.0 for valid combinations. // For a rate enforced connection the adapter will segment // according to the fwd_max_sdu_size field. This means that // although the client sends 100000 bytes at once, the server // will receive them in packets the size of fwd_max_sdu_size. bzero( aal_parm, sizeof(aal_parm_t) ); aal_parm.length = sizeof(aal_5_t); aal_parm.aal_type = CM_AAL_5; aal_parm.aal_info.aal5.fwd_max_sdu_size = 7708; aal_parm.aal_info.aal5.bak_max_sdu_size = 7520; aal_parm.aal_info.aal5.mode = CM_MESSAGE_MODE; aal_parm.aal_info.aal5.sscs_type = CM_NULL_SSCS; error = setsockopt( s, 0, SO_ATM_AAL_PARM, (void *)&aal_parm, sizeof(aal_parm_t) ); if (error) { perror("setsockopt SO_AAL_PARM"); exit(-1); } /* endif */ // Up to three BLLI may be specified in the setup message. // If a BLLI contains valid information, its length must be // set to sizeof(blli_t). Otherwise set its length to 0. // In this example the application specifies two BLLIs. // After the connection has been established, the application // can use getsockopt to see which BLLI was accepted by the // called station. bzero(blli, sizeof(blli_t) ); blli[0].length = sizeof(blli_t); blli[1].length = sizeof(blli_t); blli[2].length = 0; blli[0].L2_prot = CM_L2_PROT_USER; blli[0].L2_info = 1; // 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; // Up to three blli may be specified in the setup message. // The caller must query the blli with getsockopt to see which // blli the other side accepted. blli[1].L2_prot = CM_L2_PROT_USER; blli[1].L2_info = 2; // Fields that are not used must be set to NOT_SPECIFIED_B (byte) blli[1].L2_mode = NOT_SPECIFIED_B; blli[1].L2_win_size = NOT_SPECIFIED_B; blli[1].L3_prot = NOT_SPECIFIED_B; blli[1].L3_mode = NOT_SPECIFIED_B; blli[1].L3_def_pkt_size = NOT_SPECIFIED_B; blli[1].L3_pkt_win_size = NOT_SPECIFIED_B; blli[1].L3_info = NOT_SPECIFIED_B; blli[1].ipi = NOT_SPECIFIED_B; blli[1].snap_oui[0] = NOT_SPECIFIED_B; blli[1].snap_oui[1] = NOT_SPECIFIED_B; blli[1].snap_oui[2] = NOT_SPECIFIED_B; blli[1].snap_pid[0] = NOT_SPECIFIED_B; blli[1].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 */ // See ATM UNI 3.0 Appendix xx for details of valid combinations // Here we specify a rate enforced 1 Mbps connection. traffic.best_effort = FALSE; // Specifies Rate enforcement traffic.fwd_peakrate_lp = 1000; // Kbps traffic.bak_peakrate_lp = 1000; // Kbps traffic.tagging_bak = FALSE; traffic.tagging_fwd = FALSE; // Fields that are not used must be set to NOT_SPECIFIED_L (long) traffic.fwd_peakrate_hp = NOT_SPECIFIED_L; traffic.bak_peakrate_hp = NOT_SPECIFIED_L; traffic.fwd_sus_rate_hp = NOT_SPECIFIED_L; traffic.bak_sus_rate_hp = NOT_SPECIFIED_L; traffic.fwd_sus_rate_lp = NOT_SPECIFIED_L; traffic.bak_sus_rate_lp = NOT_SPECIFIED_L; traffic.fwd_bur_size_hp = NOT_SPECIFIED_L; traffic.bak_bur_size_hp = NOT_SPECIFIED_L; traffic.fwd_bur_size_lp = NOT_SPECIFIED_L; traffic.bak_bur_size_lp = NOT_SPECIFIED_L; error = setsockopt( s, 0, SO_ATM_TRAFFIC_DES, (void *)&traffic, sizeof(traffic_des_t) ); if (error) { perror("set traffic"); exit(-1); } /* endif */ // Set the Broadband Bearer Capability // See the UNI 3.0 for valid combinations bearer.bearer_class = CM_CLASS_C; bearer.traffic_type = NOT_SPECIFIED_B; bearer.timing = NOT_SPECIFIED_B; bearer.clipping = CM_NOT_SUSCEPTIBLE; bearer.connection_cfg = CM_CON_CFG_PTP; error = setsockopt( s, 0, SO_ATM_BEARER, (void *)&bearer, sizeof(bearer_t) ); if (error) { perror("set bearer"); exit(-1); } /* endif */ printf("Input ATM address to be called:\n"); i = scanf("%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x", &o[0], &o[1], &o[2], &o[3], &o[4], &o[5], &o[6], &o[7], &o[8], &o[9], &o[10], &o[11], &o[12], &o[13], &o[14], &o[15], &o[16], &o[17], &o[18], &o[19] ); if (i != 20) { printf("invalid atm address\n"); exit(-1); } for (i=0; i<20; i++) { addr.sndd_atm_addr.number.addr[i] = o[i]; } /* endfor */ addr.sndd_atm_addr.length = ATM_ADDR_LEN; addr.sndd_atm_addr.type = CM_INTL_ADDR_TYPE; addr.sndd_atm_addr.plan_id = CM_NSAP; addr.sndd_atm_addr.pres_ind = NOT_SPECIFIED_B; addr.sndd_atm_addr.screening = NOT_SPECIFIED_B; addr.sndd_atm_vc_type = CONN_SVC; error = connect( s, (struct sockaddr *)&addr, sizeof(addr) ); if (error) { perror("connect"); // If a connect fails, the cause structure may contain useful // information for determining the reason of the failure. // See the ATM UNI 3.0 for a description of the cause values. size = sizeof(cause_t); error = getsockopt(s, 0, SO_ATM_CAUSE, (void *)&cause, &size); if (error) { perror("SO_ATM_CAUSE"); } else { printf("cause = %d\n", cause.cause ); } /* endif */ exit(-1); } /* endif */ // The caller can now check to see which BLLI was accepted by // the called station. size = sizeof(blli_t); error = getsockopt(s, 0, SO_ATM_BLLI, (void *)&blli, &size); if (error) { perror("get blli"); exit(0); } /* endif */ printf("The call was accepted by L2_info %d\n", blli[0].L2_info ); size = sizeof(aal_parm_t); error = getsockopt(s, 0, SO_ATM_AAL_PARM, (void *)&aal_parm, &size); // If any of these negotiated parameters is unacceptable to // the caller, he should disconnect the call by closing the socket. printf("fwd %d\n", aal_parm.aal_info.aal5.fwd_max_sdu_size ); printf("bak %d\n", aal_parm.aal_info.aal5.bak_max_sdu_size ); // Specifies how many outstanding transmits are allowed before // the adapter device driver will return an error. The error // informs the application that it must wait before trying to // transmit again. max_pend = 2; error = setsockopt( s, 0, SO_ATM_MAX_PEND, (void *)&max_pend, 1 ); if (error) { perror("set MAX_PENDING"); exit(-1); } /* endif */ while (1) { error = send( s, buff, BUFF_SIZE, 0 ); if (error == -1) { if (errno == ENOSPC) { // The application has reached the maximum outstanding // transmits. It must wait before trying again. perror("send"); sleep(1); } else { perror("send"); size = sizeof(cause_t); error = getsockopt(s, 0, SO_ATM_CAUSE, (void *)&cause, &size); if (error) { perror("SO_ATM_CAUSE"); } else { printf("cause = %d\n", cause.cause ); } exit(-1); } /* endif */ } else { printf("sent %d\n", error ); } } }