sctp_darn.c   sctp_darn.c 
skipping to change at line 145 skipping to change at line 145
INTER_RCV, INTER_RCV,
INTER_SNDBUF, INTER_SNDBUF,
INTER_RCVBUF, INTER_RCVBUF,
INTER_BINDX_ADD, INTER_BINDX_ADD,
INTER_BINDX_REM, INTER_BINDX_REM,
INTER_SET_PRIM, INTER_SET_PRIM,
INTER_SET_PEER_PRIM, INTER_SET_PEER_PRIM,
INTER_SHUTDOWN, INTER_SHUTDOWN,
INTER_ABORT, INTER_ABORT,
INTER_NODELAY, INTER_NODELAY,
INTER_MAXSEG INTER_MAXSEG,
INTER_HEARTBEAT,
INTER_GET_STATS
}; };
enum shutdown_type { enum shutdown_type {
SHUTDOWN_ABORT = 0, SHUTDOWN_ABORT = 0,
SHUTDOWN_SHUTDOWN SHUTDOWN_SHUTDOWN
}; };
struct inter_entry { struct inter_entry {
char *cmd; char *cmd;
int cmd_num; int cmd_num;
skipping to change at line 171 skipping to change at line 173
{"sndbuf", INTER_SNDBUF}, {"sndbuf", INTER_SNDBUF},
{"rcvbuf", INTER_RCVBUF}, {"rcvbuf", INTER_RCVBUF},
{"bindx-add", INTER_BINDX_ADD}, {"bindx-add", INTER_BINDX_ADD},
{"bindx-rem", INTER_BINDX_REM}, {"bindx-rem", INTER_BINDX_REM},
{"primary", INTER_SET_PRIM}, {"primary", INTER_SET_PRIM},
{"peer_primary", INTER_SET_PEER_PRIM}, {"peer_primary", INTER_SET_PEER_PRIM},
{"shutdown", INTER_SHUTDOWN}, {"shutdown", INTER_SHUTDOWN},
{"abort", INTER_ABORT}, {"abort", INTER_ABORT},
{"nodelay", INTER_NODELAY}, {"nodelay", INTER_NODELAY},
{"maxseg", INTER_MAXSEG}, {"maxseg", INTER_MAXSEG},
{"heartbeat", INTER_HEARTBEAT},
{"stats", INTER_GET_STATS},
{NULL, -1}, {NULL, -1},
}; };
#define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */ #define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */
int poll_sks[POLL_SK_MAX]; /* The array for using select(). */ int poll_sks[POLL_SK_MAX]; /* The array for using select(). */
struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */ struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */
#define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */ #define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */
struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs, struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs,
int *ret_count) ; int *ret_count) ;
int build_endpoint(char *argv0, int portnum); int build_endpoint(char *argv0, int portnum);
static int parse_inter_commands(char *, char *, int); static int parse_inter_commands(char *, char *, int);
static void snd_func(char *); static void snd_func(char *);
static void sndbuf_func(char *, int, int, int); static void sndbuf_func(char *, int, int, int);
static void rcvbuf_func(char *, int, int, int); static void rcvbuf_func(char *, int, int, int);
static struct sockaddr *get_bindx_addr(char *, int *); static struct sockaddr *get_bindx_addr(char *, int *);
static int bindx_func(char *, int, struct sockaddr *, int, int, int); static int bindx_func(char *, int, struct sockaddr *, int, int, int);
static int connectx_func(char *, int, struct sockaddr *, int); static int connectx_func(char *, int, struct sockaddr *, int);
static void primary_func(char *, int, char *, int); static void primary_func(char *, int, char *, int);
static void peer_primary_func(char *, int, char *, int); static void peer_primary_func(char *, int, char *, int);
static void spp_hb_demand_func(char *, int, char *, int);
static int nodelay_func(char *, int, int val, int set); static int nodelay_func(char *, int, int val, int set);
static int maxseg_func(char *, int, int val, int set); static int maxseg_func(char *, int, int val, int set);
static int shutdown_func(char *argv0, int *skp, int shutdown_type); static int shutdown_func(char *argv0, int *skp, int shutdown_type);
static int get_assocstats_func(int, sctp_assoc_t);
static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id); static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id);
static char * gen_message(int); static char * gen_message(int);
static sctp_assoc_t test_recv_assoc_change(int); static sctp_assoc_t test_recv_assoc_change(int);
static sctp_assoc_t test_verify_assoc_change(struct msghdr *); static sctp_assoc_t test_verify_assoc_change(struct msghdr *);
void print_addr_buf(void * laddrs, int n_laddrs); void print_addr_buf(void * laddrs, int n_laddrs);
int print_sockaddr(struct sockaddr *sa_addr); int print_sockaddr(struct sockaddr *sa_addr);
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
int sk = -1; int sk = -1;
skipping to change at line 1509 skipping to change at line 1515
printf("rcv=<int> - Do a recvmsg."); printf("rcv=<int> - Do a recvmsg.");
printf("The length is ignored for now.\n"); printf("The length is ignored for now.\n");
printf("bindx-add=<addr> - Add a local address"); printf("bindx-add=<addr> - Add a local address");
printf(" with bindx. \n"); printf(" with bindx. \n");
printf("bindx-rem=<addr> - Remove a local address"); printf("bindx-rem=<addr> - Remove a local address");
printf(" with bindx. \n"); printf(" with bindx. \n");
printf("rcvbuf=<int> - Get/Set receive buffer size\n"); printf("rcvbuf=<int> - Get/Set receive buffer size\n");
printf("sndbuf=<int> - Get/Set send buffer size.\n"); printf("sndbuf=<int> - Get/Set send buffer size.\n");
printf("primary=<addr> - Get/Set association's primary\n") ; printf("primary=<addr> - Get/Set association's primary\n") ;
printf("peer_primary=addr- Set association's peer_primary\n" ); printf("peer_primary=addr- Set association's peer_primary\n" );
printf("heartbeat=<addr> - Request a user initiated heartbea t\n");
printf("maxseg=<int> - Get/Set Maximum fragment size.\n" ); printf("maxseg=<int> - Get/Set Maximum fragment size.\n" );
printf("nodelay=<0|1> - Get/Set NODELAY option.\n"); printf("nodelay=<0|1> - Get/Set NODELAY option.\n");
printf("shutdown - Shutdown the association.\n"); printf("shutdown - Shutdown the association.\n");
printf("abort - Abort the association.\n"); printf("abort - Abort the association.\n");
printf("stats - Print GET_ASSOC_STATS (if availab le in kernel).\n");
printf("? - Help. Display this message.\n"); printf("? - Help. Display this message.\n");
return -1; return -1;
} }
for (i = 0; i < REALLY_BIG; i++) { for (i = 0; i < REALLY_BIG; i++) {
if (('=' == *p) || if (('=' == *p) ||
('?' == *p) || ('?' == *p) ||
('\n' == *p)) { ('\n' == *p)) {
if ('=' == *p) { if ('=' == *p) {
set = 1; set = 1;
skipping to change at line 1589 skipping to change at line 1597
bindx_func(argv0, inter_sk, tmp_addrs, len, bindx_func(argv0, inter_sk, tmp_addrs, len,
SCTP_BINDX_REM_ADDR, local_port); SCTP_BINDX_REM_ADDR, local_port);
free(tmp_addrs); free(tmp_addrs);
break; break;
case INTER_SET_PRIM: case INTER_SET_PRIM:
primary_func(argv0, inter_sk, p, set); primary_func(argv0, inter_sk, p, set);
break; break;
case INTER_SET_PEER_PRIM: case INTER_SET_PEER_PRIM:
peer_primary_func(argv0, inter_sk, p, set); peer_primary_func(argv0, inter_sk, p, set);
break; break;
case INTER_HEARTBEAT:
spp_hb_demand_func(argv0, inter_sk, p, set);
break;
case INTER_SHUTDOWN: case INTER_SHUTDOWN:
shutdown_func(argv0, &inter_sk, SHUTDOWN_SHU TDOWN); shutdown_func(argv0, &inter_sk, SHUTDOWN_SHU TDOWN);
break; break;
case INTER_ABORT: case INTER_ABORT:
shutdown_func(argv0, &inter_sk, SHUTDOWN_ABO RT); shutdown_func(argv0, &inter_sk, SHUTDOWN_ABO RT);
break; break;
case INTER_NODELAY: case INTER_NODELAY:
if (set) { if (set) {
if (*p < '0' || *p > '9') { if (*p < '0' || *p > '9') {
goto err_input; goto err_input;
skipping to change at line 1613 skipping to change at line 1624
break; break;
case INTER_MAXSEG: case INTER_MAXSEG:
if (set) { if (set) {
if (*p < '0' || *p > '9') { if (*p < '0' || *p > '9') {
goto err_input; goto err_input;
} }
} }
val = (set) ? atoi(p) : 0; val = (set) ? atoi(p) : 0;
maxseg_func(argv0, inter_sk, val, set); maxseg_func(argv0, inter_sk, val, set);
break; break;
case INTER_GET_STATS:
get_assocstats_func(inter_sk, associd);
break;
default: default:
goto err_input; goto err_input;
break; break;
} }
return i; return i;
} }
i++; i++;
} }
skipping to change at line 1976 skipping to change at line 1990
goto err; goto err;
return; return;
err: err:
if (!errno) if (!errno)
errno = EINVAL; errno = EINVAL;
fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0, fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0,
(set)?"setting":"getting", strerror(errno)); (set)?"setting":"getting", strerror(errno));
} }
static void
spp_hb_demand_func(char *argv0, int sk, char *cp, int set)
{
struct sctp_paddrparams params;
struct sockaddr_in *in_addr;
struct sockaddr_in6 *in6_addr;
int ret;
char *p = cp;
memset(&params, 0, sizeof(struct sctp_paddrparams));
params.spp_assoc_id = associd;
params.spp_flags = SPP_HB_DEMAND;
if (set) {
/* Set the buffer for address parsing. */
while ('\n' != *p)
p++;
*p = '\0';
if (strchr(cp, '.')) {
in_addr = (struct sockaddr_in *)&params.spp_address;
in_addr->sin_port = htons(remote_port);
in_addr->sin_family = AF_INET;
ret = inet_pton(AF_INET, cp, &in_addr->sin_addr);
if (ret <= 0)
goto err;
} else if (strchr(cp, ':')) {
in6_addr = (struct sockaddr_in6 *)&params.spp_addres
s;
in6_addr->sin6_port = htons(remote_port);
in6_addr->sin6_family = AF_INET6;
ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr);
if (ret <= 0)
goto err;
} else
goto err;
}
ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&params, sizeof(struct sctp_paddrparams));
if (ret < 0)
goto err;
return;
err:
if (!errno)
errno = EINVAL;
fprintf(stderr, "%s: error %s peer_addr_params: %s.\n", argv0,
(set)?"setting":"getting", strerror(errno));
}
static int static int
nodelay_func(char *argv0, int sk, int val, int set) nodelay_func(char *argv0, int sk, int val, int set)
{ {
socklen_t optlen; socklen_t optlen;
int error; int error;
if (set) { if (set) {
error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY, error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY,
(char *)&val, sizeof(val)); (char *)&val, sizeof(val));
} else { } else {
skipping to change at line 2160 skipping to change at line 2224
new_connection = 1; new_connection = 1;
} else { } else {
printf("%s failed\n", sd_type); printf("%s failed\n", sd_type);
exit(1); exit(1);
} }
return 0; return 0;
} }
static int static int
get_assocstats_func(int sk, sctp_assoc_t assoc_id)
{
int error = 0;
struct sctp_assoc_stats stats;
socklen_t len;
if (assoc_id == 0) {
printf("No association present yet\n");
return -1;
}
memset(&stats, 0, sizeof(struct sctp_assoc_stats));
stats.sas_assoc_id = assoc_id;
len = sizeof(struct sctp_assoc_stats);
error = getsockopt(sk, SOL_SCTP, SCTP_GET_ASSOC_STATS,
(char *)&stats, &len);
if (error != 0) {
printf("get_assoc_stats() failed %s\n", strerror(errno));
return error;
}
printf("Retransmitted Chunks: %llu\n", stats.sas_rtxchu
nks);
printf("Gap Acknowledgements Received: %llu\n", stats.sas_gapcnt
);
printf("TSN received > next expected: %llu\n", stats.sas_outofs
eqtsns);
printf("SACKs sent: %llu\n", stats.sas_osacks
);
printf("SACKs received: %llu\n", stats.sas_isacks
);
printf("Control chunks sent : %llu\n", stats.sas_octrlc
hunks);
printf("Control chunks received : %llu\n", stats.sas_ictrlc
hunks);
printf("Ordered data chunks sent: %llu\n", stats.sas_oodchu
nks);
printf("Ordered data chunks received: %llu\n", stats.sas_iodchu
nks);
printf("Unordered data chunks sent: %llu\n", stats.sas_ouodch
unks);
printf("Unordered data chunks received: %llu\n", stats.sas_iuodch
unks);
printf("Dups received (ordered+unordered): %llu\n", stats.sas_idupch
unks);
printf("Packets sent: %llu\n", stats.sas_opacke
ts);
printf("Packets received: %llu\n", stats.sas_ipacke
ts);
printf("Maximum Observed RTO this period: %llu - Transport: ", stats
.sas_maxrto);
print_sockaddr((struct sockaddr *)&stats.sas_obs_rto_ipaddr);
printf("\n");
return 0;
}
static int
test_sk_for_assoc(int sk, sctp_assoc_t assoc_id) test_sk_for_assoc(int sk, sctp_assoc_t assoc_id)
{ {
int error = 0; int error = 0;
struct sctp_status status; struct sctp_status status;
socklen_t status_len; socklen_t status_len;
memset(&status, 0, sizeof(status)); memset(&status, 0, sizeof(status));
if (assoc_id) if (assoc_id)
status.sstat_assoc_id = assoc_id; status.sstat_assoc_id = assoc_id;
status_len = sizeof(struct sctp_status); status_len = sizeof(struct sctp_status);
 End of changes. 10 change blocks. 
1 lines changed or deleted 124 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/