/* This function prints the message. */ static int print_message(const int sk, struct msghdr *msg, size_t msg_len) { struct cmsghdr *scmsg; sctp_cmsg_data_t *data; int i; if (!(MSG_NOTIFICATION & msg->msg_flags)) { int index = 0; DEBUG_PRINT(DEBUG_MIN, "Data %zu bytes.", msg_len); DEBUG_PRINT(DEBUG_MAX, " First %zu bytes: ", (msg_len < BODYSIZE)?msg_len:BODYSIZE); /* Make sure that everything is printable and that we * are NUL terminated... */ while ( msg_len > 0 ) { char *text, tmptext[BODYSIZE]; int len; memset(tmptext, 0x0, BODYSIZE); text = msg->msg_iov[index].iov_base; len = msg->msg_iov[index].iov_len; if (msg_len == 1 && text[0] == 0) { DEBUG_PRINT(DEBUG_MIN, "<empty> text[0]=%d", text[0]); break; } if ( len > msg_len ) { /* text[(len = msg_len) - 1] = '\0'; */ text[(len = msg_len)] = '\0'; } if ( (msg_len -= len) > 0 ) { index++; } for (i = 0; i < len - 1; ++i) { if (!isprint(text[i])) text[i] = '.'; } strncpy(tmptext, text, BODYSIZE); tmptext[BODYSIZE-1] = '\0'; DEBUG_PRINT(DEBUG_MAX, "%s", tmptext); } DEBUG_PRINT(DEBUG_MIN, "\n"); fflush(stdout); } else { /* if(we have notification) */ struct sctp_assoc_change *sac; struct sctp_send_failed *ssf; struct sctp_paddr_change *spc; struct sctp_remote_error *sre; union sctp_notification *snp; char addrbuf[INET6_ADDRSTRLEN]; const char *ap; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; int index = 0; snp = (union sctp_notification *)msg->msg_iov[index].iov_base; DEBUG_PRINT(DEBUG_MIN, "Notification:"); switch (snp->sn_header.sn_type) { case SCTP_ASSOC_CHANGE: sac = &snp->sn_assoc_change; DEBUG_PRINT(DEBUG_MIN, " SCTP_ASSOC_CHANGE(%s)\n", sac_state_tbl[sac->sac_state]); DEBUG_PRINT(DEBUG_MAX, "\t\t(assoc_change: state=%hu, " "error=%hu, instr=%hu " "outstr=%hu)\n", sac->sac_state, sac->sac_error, sac->sac_inbound_streams, sac->sac_outbound_streams); break; case SCTP_PEER_ADDR_CHANGE: spc = &snp->sn_paddr_change; DEBUG_PRINT(DEBUG_MIN, " SCTP_PEER_ADDR_CHANGE\n"); if (spc->spc_aaddr.ss_family == AF_INET) { sin = (struct sockaddr_in *) &spc->spc_aaddr; ap = inet_ntop(AF_INET, &sin->sin_addr, addrbuf, INET6_ADDRSTRLEN); } else { sin6 = (struct sockaddr_in6 *) &spc->spc_aaddr; ap = inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, INET6_ADDRSTRLEN); } DEBUG_PRINT(DEBUG_MAX, "\t\t(peer_addr_change: %s " "state=%d, error=%d)\n", ap, spc->spc_state, spc->spc_error); break; case SCTP_SEND_FAILED: ssf = &snp->sn_send_failed; DEBUG_PRINT(DEBUG_MIN, " SCTP_SEND_FAILED\n"); DEBUG_PRINT(DEBUG_MAX, "\t\t(sendfailed: len=%hu " "err=%d)\n", ssf->ssf_length, ssf->ssf_error); break; case SCTP_REMOTE_ERROR: sre = &snp->sn_remote_error; DEBUG_PRINT(DEBUG_MIN, " SCTP_REMOTE_ERROR\n"); DEBUG_PRINT(DEBUG_MAX, "\t\t(remote_error: err=%hu)\n", ntohs(sre->sre_error)); break; case SCTP_SHUTDOWN_EVENT: DEBUG_PRINT(DEBUG_MIN, " SCTP_SHUTDOWN_EVENT\n"); break; default: DEBUG_PRINT(DEBUG_MIN, " Unknown type: %hu\n", snp->sn_header.sn_type); break; } fflush(stdout); return 1; } /* notification received */ for (scmsg = CMSG_FIRSTHDR(msg); scmsg != NULL; scmsg = CMSG_NXTHDR(msg, scmsg)) { data = (sctp_cmsg_data_t *)CMSG_DATA(scmsg); if (debug_level) print_cmsg(scmsg->cmsg_type, data); } fflush(stdout); return 0; } /* print_message() */
void pipehandler(int s) { print_cmsg(CL_COM); exit(CL_COM); }