/* ipsctp_debug.c - Debug Routines for IPSCTP */ /* * Copyright (c) 2008 Wind River Systems, Inc. * * The right to copy, distribute or otherwise make use of this software * may be licensed only pursuant to the terms of an applicable Wind River * license agreement. No license to Wind River intellectual property rights * is granted herein. All rights not licensed by Wind River are reserved * by Wind River. */ /* modification history -------------------- 01a,15jul08, . */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #ifndef IPCOM_KERNEL #define IPCOM_KERNEL #endif #include "ipsctp_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include "ipsctp_h.h" #ifdef IPSCTP_DEBUG /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPSCTP_LEN_SHOW_TEMP_BUF (256) #define IPSCTP_SHOW_FMT_TITLE ("%-24s%-16s%-24s%-16s\n") #define ipsctp_print_line() ipcom_debug_printf("%s", "--------------------------------------------------------------------------------\n") #define IPSCTP_SHOW_FMT(prompt1, fm1, var1, prompt2, fm2, var2) \ do \ { \ char tmp_buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; \ char tmp_buf2[IPSCTP_LEN_SHOW_TEMP_BUF]; \ ipsctp_memzero(tmp_buf1, IPSCTP_LEN_SHOW_TEMP_BUF); \ ipsctp_memzero(tmp_buf2, IPSCTP_LEN_SHOW_TEMP_BUF); \ (void)ipcom_sprintf(tmp_buf1, \ (fm1), \ (var1)); \ (void)ipcom_sprintf(tmp_buf2, \ (fm2), \ (var2)); \ ipcom_debug_printf( IPSCTP_SHOW_FMT_TITLE, \ (prompt1), \ tmp_buf1, \ (prompt2), \ tmp_buf2); \ } while(0) /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ IP_PUBLIC Ip_u32 ipsctp_debug_flags = 0; IP_STATIC IP_CONST char *sctp_state_list[] = { "LISTEN", "CLOSED", "COOKIE_WAIT", "COOKIE_ECHOED", "ESTABLISHED", "SHUTDOWN_PENDING", "SHUTDOWN_RECEIVED", "SHUTDOWN_SENT", "SHUTDOWN_ACK_SENT", "UNKNOWN" }; IP_STATIC IP_CONST char *ipsctp_timer_str_list[] = { "", /* IPSCTP_TIMO_NONE */ "INIT", /* IPSCTP_TIMO_T1 */ "SHUTDOWN", /* IPSCTP_TIMO_T2 */ "RETRANSMISSION", /* IPSCTP_TIMO_T3 */ "SHUTDOWN GUARD", /* IPSCTP_TIMO_T5 */ "DELAY ACK", /* IPSCTP_TIMO_DACK */ #ifdef IPSCTP_FAST_RETRANSMITE "FR", /* IPSCTP_TIMO_FR */ #else "NOT SUPPORT", #endif "COOKIE", /* IPSCTP_TIMO_COOKIE */ "HEARTBEAT", /* IPSCTP_TIMO_HB */ "SECRET", /* IPSCTP_TIMO_SECRET */ "LINGER", /* IPSCTP_TIMO_LINGER */ "AUTOCLOSE", /* IPSCTP_TIMO_AUTOCLOSE */ "SENDALL", /* IPSCTP_TIMO_SENDALL */ "UNKNOWN" /* IPSCTP_TIMO_MAX */ }; IP_STATIC IP_CONST char *ipsctp_notification_str_list[] = { "", /* SCTP_NOTIFY_NONE */ "ASSOCIATION UP", /* SCTP_NOTIFY_ASSOC_UP */ "ASSOCIATION DOWN", /* SCTP_NOTIFY_ASSOC_DOWN */ "INTERFACE DOWN", /* SCTP_NOTIFY_INTERFACE_DOWN */ "INTERFACE UP", /* SCTP_NOTIFY_INTERFACE_UP */ "SEND FAIL", /* SCTP_NOTIFY_SEND_FAIL */ "ASSOCIATION ABORT", /* SCTP_NOTIFY_ASSOC_ABORTED */ "ASSOCIATION RESTART", /* SCTP_NOTIFY_ASSOC_RESTART */ "PEER SHUTDOWN", /* SCTP_NOTIFY_PEER_SHUTDOWN */ "INTERFACE CONFIRMED", /* SCTP_NOTIFY_INTERFACE_CONFIRMED */ "REMOTE ERROR", /* SCTP_NOTIFY_REMOTE_ERROR */ "UNKNOWN" /* SCTP_NOTIFY_MAX */ }; IP_PUBLIC int ipsctp_sock_debug = 0; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipsctp_state_to_str *=========================================================================== * Description: Returns a string representation of the state. * Parameters: state - One of the SCTP states. * Returns: A string representation. * */ IP_GLOBAL IP_CONST char * ipsctp_state_to_str(int state) { if (state < IPSCTP_STATE_MAX) return sctp_state_list[state]; else return sctp_state_list[IPSCTP_STATE_MAX]; } /* *=========================================================================== * ipsctp_timer_to_str *=========================================================================== * Description: Returns a string representation of the timer type. * Parameters: state - One of the SCTP timer types. * Returns: A string representation. * */ IP_GLOBAL IP_CONST char * ipsctp_timer_to_str(Ipsctp_timo type) { if (type < IPSCTP_TIMO_MAX) return ipsctp_timer_str_list[type]; else return ipsctp_timer_str_list[IPSCTP_TIMO_MAX]; } /* *=========================================================================== * ipsctp_notification_to_str *=========================================================================== * Description: Returns a string representation of the NOTIFICATION type. * Parameters: state - One of the SCTP NOTIFICATION types. * Returns: A string representation. * */ IP_GLOBAL IP_CONST char * ipsctp_notification_to_str(Ipsctp_notify_type type) { if (type < SCTP_NOTIFY_MAX) return ipsctp_notification_str_list[type]; else return ipsctp_notification_str_list[SCTP_NOTIFY_MAX]; } /* *=========================================================================== * ipsctp_print_hex *=========================================================================== * Description: Print the buffer with hex. * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ /* TODO(td) : length is not the same. */ IP_PUBLIC void ipsctp_print_hex(void *buf, const char *prompt, Ip_u32 len) { #define IPSCTP_PRINT_BUF_LEN (2048) #define IPSCTP_PRINT_LINE (5) #if defined(IPSCTP_DEBUG) char cp[IPSCTP_PRINT_BUF_LEN]; /* TODO(td) : no black */ char *cp_buf = (char *)cp; Ip_u32 *cp_out = (Ip_u32 *)buf; Ip_u32 i = 0; if (0/*ipsctp_debug_flags & IPSCTP_DBG_PKT*/) return; if ((IP_NULL == buf) || (IPSCTP_PRINT_BUF_LEN < (len + ipcom_strlen(prompt)))) return; ipsctp_memzero(cp, IPSCTP_PRINT_BUF_LEN); cp_buf += ipcom_sprintf(cp_buf, "%s++ len = %u ++\n", prompt, len); /* sprintf the output buffer */ for (i = 0; i * 4 < len && cp_buf < cp + IPSCTP_PRINT_BUF_LEN - sizeof(Ip_u32) ; i++) { if ((0 == i % IPSCTP_PRINT_LINE)&&(0 != i)) cp_buf += ipcom_sprintf(cp_buf, "%s", "\n"); cp_buf += ipcom_sprintf(cp_buf, "%08X ", cp_out[i]); } /* output the hex data */ IPSCTP_DBG1(IPSCTP_DBG_PKT, "IPSCTP : %s\n", cp); #endif return; } /* *=========================================================================== * ipsctp_t_show_sock *=========================================================================== * Description: Print the buffer with hex. * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_t_show_sock(Ip_fd sh_fd) { #define IPSCTP_ADDR_LEN (sizeof("255.255.255.255")) #define IPSOCK_T_SHOW_SOCK_TITLE1 ("%-5s%-17s%-9s%-17s%-9s%-18s\n") #define IPSOCK_T_SHOW_SOCK_TITLE2 ("%-5d%-17s%-9d%-17s%-9d%-18s\n") Ipsctp_laddr_entry *laddr = IP_NULL; Ipsctp_transport *tp = IP_NULL; Ipsctp_socket *cur_sock = IP_NULL; Ipsctp_instance *inst = IP_NULL; Ipsctp_tcb *tcb = IP_NULL; Ip_u16 rport = 0; char addr_buf1[IPSCTP_ADDR_LEN]; char addr_buf2[IPSCTP_ADDR_LEN]; Ipsctp_state state = IPSCTP_STATE_MAX; if (IP_NULL == (cur_sock = ipnet->sockets[sh_fd])) { ipcom_printf("Null socket pointer : [%d]\n",sh_fd); return; } inst = (Ipsctp_instance *)cur_sock->sctp_inst; ip_assert(IP_NULL != inst); ipcom_printf(IPSOCK_T_SHOW_SOCK_TITLE1, "Fd", "Local Address", "Port", "Remote Address", "Port", "State"); ipsctp_memzero(addr_buf1, IPSCTP_ADDR_LEN); laddr = (Ipsctp_laddr_entry *)ipcom_list_first(&inst->laddr_list); if (IP_NULL != laddr) ipsctp_addr_ntop(&laddr->laddr, addr_buf1, IPSCTP_ADDR_LEN); else ipcom_memcpy(addr_buf1, "0.0.0.0", sizeof("0.0.0.0")); ipsctp_memzero(addr_buf2, IPSCTP_ADDR_LEN); tcb = (Ipsctp_tcb *)ipcom_list_first(&inst->assoc_list); if (IP_NULL != tcb) { tp = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list); if (IP_NULL != tp) ipsctp_addr_ntop(&tp->paddr, addr_buf2, IPSCTP_ADDR_LEN); else ipcom_memcpy(addr_buf2, "0.0.0.0", sizeof("0.0.0.0")); rport = tcb->rport; state = tcb->state; } else { ipcom_memcpy(addr_buf2, "0.0.0.0", sizeof("0.0.0.0")); rport = 0; state = IPSCTP_STATE_MAX; } ipcom_printf(IPSOCK_T_SHOW_SOCK_TITLE2, sh_fd, addr_buf1, inst->lport, addr_buf2, rport, ipsctp_state_to_str((int)state)); return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_chunk_recv(Ipsctp_chunk_recv *ch) { if (IP_NULL == ch) return; ipsctp_print_line(); ipcom_debug_printf("%s", "+++ Received Chunk information:-------------------------------------------------------\n"); IPSCTP_SHOW_FMT("chunk_start", "%u", ch->chunk.chunk_start, "chunk_end", "%u", ch->chunk.chunk_end); IPSCTP_SHOW_FMT("chunk_type", "%u", ch->chunk.chunk_type, "flag", "%u", ch->chunk.flag); IPSCTP_SHOW_FMT("sndrcv_info.assoc_id", "%u", ch->sndrcv_info.sinfo_assoc_id, "sndrcv_info.flags", "%u", ch->sndrcv_info.sinfo_flags); IPSCTP_SHOW_FMT("sndrcv_info.ssn", "%u", ch->sndrcv_info.sinfo_ssn, "sndrcv_info.stream", "%u", ch->sndrcv_info.sinfo_stream); IPSCTP_SHOW_FMT("sndrcv_info.tsn", "%u", ch->sndrcv_info.sinfo_tsn, "length", "%u", ch->length); /* print the packet data, if needed */ return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_chunk(Ipsctp_chunk *ch) { if (IP_NULL == ch) return; ipsctp_print_line(); ipcom_debug_printf("%s", "+++Chunk information:-------------------------------------------------------\n"); IPSCTP_SHOW_FMT("chunk_start", "%u", ch->chunk_start, "chunk_end", "%u", ch->chunk_end); IPSCTP_SHOW_FMT("chunk_type", "%u", ch->chunk_type, "flag", "%u", ch->flag); /* print the packet data, if needed */ return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_stream_in(Ipsctp_stream_in *si) { Ipsctp_chunk_recv *ch = IP_NULL; if (IP_NULL == si) return; ipsctp_print_line(); ipcom_debug_printf("+++Stream IN(%-10u) information:-------------------------------------------\n", si->stream_number); IPSCTP_SHOW_FMT("last_ssn_delivered", "%u", si->last_ssn_delivered, "last_tsn_delivered", "0X%X", si->last_tsn_delivered); IPSCTP_SHOW_FMT("flag", "%u", si->flag, "flag", "%u", si->flag); for (ch = (Ipsctp_chunk_recv *)ipcom_list_first(&si->queue_chunks); ch; ch = (Ipsctp_chunk_recv *)ipcom_list_next(&ch->chunk.chunk_next)) { if (IP_NULL == ch) continue; ipsctp_show_chunk_recv(ch); } return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_stream_out(Ipsctp_stream_out *so) { Ipsctp_chunk *ch = IP_NULL; if (IP_NULL == so) return; ipsctp_print_line(); ipcom_debug_printf( "+++Stream OUT(%-10u) information:------------------------------------------\n", so->stream_number); IPSCTP_SHOW_FMT("next_ssn_sent", "%u", so->next_ssn_sent, "last_msg_incomplete", "%u", so->last_msg_incomplete); for (ch = (Ipsctp_chunk *)ipcom_list_first(&so->chunk_list); ch; ch = (Ipsctp_chunk *)ipcom_list_next(&ch->chunk_next)) { if (IP_NULL == ch) continue; ipsctp_show_chunk(ch); } return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_transport(Ipsctp_transport *tp) { char buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; char buf2[IPSCTP_LEN_SHOW_TEMP_BUF]; if (IP_NULL == tp) return; ipsctp_print_line(); ipcom_debug_printf("%s", "+++Transport information:-------------------------------------------------------\n"); ipsctp_addr_ntop(&tp->paddr, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipsctp_addr_ntop(&tp->saddr, buf2, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("paddr", "%s", buf1, "saddr", "%s", buf2); IPSCTP_SHOW_FMT("err_cnt", "%u", tp->err_cnt, "err_thresh", "%u", tp->err_thresh); IPSCTP_SHOW_FMT("cwnd", "%u", tp->cwnd, "ssthresh", "%u", tp->ssthresh); IPSCTP_SHOW_FMT("rto", "%u", tp->rto, "srtt", "%u", tp->srtt); IPSCTP_SHOW_FMT("rttvar", "%u", tp->rttvar, "pt_bytes_acked", "%u", tp->pt_bytes_acked); IPSCTP_SHOW_FMT("flight_size", "%u", tp->flight_size, "net_ack", "%u", tp->net_ack); IPSCTP_SHOW_FMT("net_ack2", "%u", tp->net_ack2, "state", "%u", tp->state); IPSCTP_SHOW_FMT("pmtu", "%u", tp->pmtu, "", "", 0); IPSCTP_SHOW_FMT("tos_flowlabel", "%u", tp->tos_flowlabel, "hbinterval", "%u", tp->hbinterval); return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_tcb(Ipsctp_tcb *tcb) { Ipsctp_stream_out *so = IP_NULL; Ipsctp_stream_in *si = IP_NULL; Ipsctp_transport *tp = IP_NULL; Ipsctp_chunk *ch = IP_NULL; int i = 0; char buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; char buf2[IPSCTP_LEN_SHOW_TEMP_BUF]; if (IP_NULL == tcb) return; ipsctp_print_line(); ipcom_debug_printf("%s", "+++TCB information:-------------------------------------------------------------\n"); IPSCTP_SHOW_FMT("INSTANCE", "0X%X", tcb->instance, "SOCK", "0X%X", tcb->sock); IPSCTP_SHOW_FMT("TCB_FLAGS", "0X%X", tcb->tcb_flags, "TCB_PEER_FLAGS", "0X%X", tcb->tcb_peer_flags); IPSCTP_SHOW_FMT("PEER_VTAG", "0X%X", tcb->peer_vtag, "MY_VTAG", "0X%X", tcb->my_vtag); IPSCTP_SHOW_FMT("MY_VTAG_NONCE", "0X%X", tcb->my_vtag_nonce, "PEER_VTAG_NONCE", "0X%X", tcb->peer_vtag_nonce); IPSCTP_SHOW_FMT("MAX_INIT_TIMES", "%d", tcb->max_init_times, "MAX_SEND_TIMES", "%d", tcb->max_send_times); IPSCTP_SHOW_FMT("MAX_TRANSPORT_RETRANS", "%d", tcb->max_transport_retrans, "INITIAL_INIT_RTO_MAX", "%d", tcb->initial_init_rto_max); IPSCTP_SHOW_FMT("INITIAL_RTO", "%d", tcb->initial_rto, "MIN_RTO", "%d", tcb->min_rto); IPSCTP_SHOW_FMT("MAX_RTO", "%d", tcb->max_rto, "", "%s", " "); #ifdef IPCOM_USE_INET6 IPSCTP_SHOW_FMT("IPV6_FLOWLABEL", "%d", tcb->ipv6_flowlabel, "", "%s", " "); #endif #ifdef IPCOM_USE_INET IPSCTP_SHOW_FMT("IPV4_TOS", "%d", tcb->ipv4_tos, "", "%s", " "); #endif IPSCTP_SHOW_FMT("CONTEXT", "%d", tcb->context, "STATE", "%s", ipsctp_state_to_str(tcb->state)); ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); if (IP_NULL != tcb->primary_transport) ipsctp_addr_ntop(&tcb->primary_transport->paddr, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); else ipcom_memcpy(buf1, "null", sizeof("null")); ipsctp_memzero(buf2, IPSCTP_LEN_SHOW_TEMP_BUF); tp = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list); if (IP_NULL != tp) ipsctp_addr_ntop(&tp->paddr, buf2, IPSCTP_LEN_SHOW_TEMP_BUF); else ipcom_memcpy(buf2, "null", sizeof("null")); IPSCTP_SHOW_FMT("PRIMARY", "%s", buf1, "TRANSPORT", "%s", buf2); IPSCTP_SHOW_FMT("last_ctrl_from", "0X%X", tcb->last_ctrl_from, "last_data_from", "0X%X", tcb->last_data_from); IPSCTP_SHOW_FMT("pmtu", "%u", tcb->pmtu, "frag_point", "%u", tcb->frag_point); IPSCTP_SHOW_FMT("rport", "%u", tcb->rport, "", "%s", " "); /* sndrcvinfo */ IPSCTP_SHOW_FMT("SINFO_STREAM", "%u", tcb->def_send.sinfo_stream, "SINFO_SSN", "%u", tcb->def_send.sinfo_ssn); IPSCTP_SHOW_FMT("SINFO_FLAGS", "0X%X", tcb->def_send.sinfo_flags, "SINFO_PR_POLICY", "%u", tcb->def_send.sinfo_pr_policy); IPSCTP_SHOW_FMT("SINFO_PPID", "%u", tcb->def_send.sinfo_ppid, "SINFO_CONTEXT", "%u", tcb->def_send.sinfo_context); IPSCTP_SHOW_FMT("SINFO_PR_VALUE", "%u", tcb->def_send.sinfo_pr_value, "SINFO_TSN", "%u", tcb->def_send.sinfo_tsn); IPSCTP_SHOW_FMT("SINFO_CUMTSN", "%u", tcb->def_send.sinfo_cumtsn, "TP number", "%u", ipsctp_list_size(&tcb->transport_list)); for (tp = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list); tp; tp = (Ipsctp_transport *)ipcom_list_next(&tp->trans_next)) { if (IP_NULL == tp) continue; ipsctp_show_transport(tp); } ipsctp_print_line(); IPSCTP_SHOW_FMT("oa_err_cnt", "%u", tcb->oa_err_cnt, "total_flight", "%u", tcb->total_flight); IPSCTP_SHOW_FMT("sent_queue_retran_cnt", "%u", tcb->sent_queue_retran_cnt, "max_burst", "%u", tcb->max_burst); #ifdef IPSCTP_USE_MULTIBUF IPSCTP_SHOW_FMT("send_chunks_cnt", "%u", tcb->send_chunks_cnt, "send_bytes", "%u", tcb->send_bytes); IPSCTP_SHOW_FMT("recv_chunks_cnt", "%u", tcb->recv_chunks_cnt, "recv_bytes", "%u", tcb->recv_bytes); IPSCTP_SHOW_FMT("cnt_on_in_queue", "%u", tcb->cnt_on_in_queue, "size_on_in_queue", "%u", tcb->size_on_in_queue); #endif IPSCTP_SHOW_FMT("peers_rwnd", "%u", tcb->peers_rwnd, "", "%s", " "); IPSCTP_SHOW_FMT("my_last_reported_rwnd", "%u", tcb->my_last_reported_rwnd, "congestion_..._module", "%u", tcb->congestion_control_module); IPSCTP_SHOW_FMT("recv_tsn_bitmap_size", "%u", tcb->recv_tsn_bitmap_size, "recv_tsn_bitmap_base", "%u", tcb->recv_tsn_bitmap_base); IPSCTP_SHOW_FMT("cumulative_tsn", "0X%X", tcb->cumulative_tsn, "highest_tsn_inside_map", "%u", tcb->highest_tsn_inside_map); IPSCTP_SHOW_FMT("numduptsns", "%u", tcb->numduptsns, "tsn_last_delivered", "%u", tcb->tsn_last_delivered); IPSCTP_SHOW_FMT("init_tsn_number", "0X%X", tcb->init_tsn_number, "tsn_next", "0X%X", tcb->tsn_next); IPSCTP_SHOW_FMT("fast_recovery_tsn", "%u", tcb->fast_recovery_tsn, "sat_t3_recovery_tsn", "%u", tcb->sat_t3_recovery_tsn); IPSCTP_SHOW_FMT("this_sack_highest_gap", "%u", tcb->this_sack_highest_gap, "last_acked_tsn", "0X%X", tcb->last_acked_tsn); IPSCTP_SHOW_FMT("sack_freq", "%u", tcb->sack_freq, "data_pkts_seen", "%u", tcb->data_pkts_seen); IPSCTP_SHOW_FMT("streamincnt", "%u", tcb->streamincnt, "streamoutcnt", "%u", tcb->streamoutcnt); for (i = 0; i < tcb->streamincnt; i++) { si = tcb->streams_in + i; if (IP_NULL == si) continue; ipsctp_show_stream_in(si); } for (i = 0; i < tcb->streamoutcnt; i++) { so = tcb->streams_out + i; if (IP_NULL == so) continue; ipsctp_show_stream_out(so); } for (ch = (Ipsctp_chunk *)ipcom_list_first(&tcb->control_chunk_list); ch; ch = (Ipsctp_chunk *)ipcom_list_next(&ch->chunk_next)) { if (IP_NULL == ch) continue; if (ch == (Ipsctp_chunk *)ipcom_list_first(&tcb->control_chunk_list)) ipsctp_print_line(); ipsctp_show_chunk(ch); } for (ch = (Ipsctp_chunk *)ipcom_list_first(&tcb->transmitted_chunk_list); ch; ch = (Ipsctp_chunk *)ipcom_list_next(&ch->chunk_next)) { if (IP_NULL == ch) continue; if (ch == (Ipsctp_chunk *)ipcom_list_first(&tcb->transmitted_chunk_list)) ipsctp_print_line(); ipsctp_show_chunk(ch); } IPSCTP_SHOW_FMT("max_inbound_streams", "%u", tcb->max_inbound_streams, "pre_open_streams", "%u", tcb->pre_open_streams); IPSCTP_SHOW_FMT("total_sends", "%u", tcb->total_sends, "total_recvs", "%u", tcb->total_recvs); IPSCTP_SHOW_FMT("hb_interval", "%u", tcb->hb_interval, "autoclose_time", "%u", tcb->autoclose_time); IPSCTP_SHOW_FMT("delayed_ack", "%u", tcb->delayed_ack, "cookie_life", "%u", tcb->cookie_life); IPSCTP_SHOW_FMT("stale_cookie_count", "%u", tcb->stale_cookie_count, "", "%s", " "); return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_instance(Ipsctp_instance *inst) { Ipsctp_chunk_recv *chunk_received = IP_NULL; int i = 0; Ipsctp_laddr_entry *laddr = IP_NULL; char buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; ipsctp_print_line(); ipcom_debug_printf( "%s", "+++Instance information:--------------------------------------------------------\n"); IPSCTP_SHOW_FMT("SOCK", "0X%X", inst->sock, "ASSOC_LIST SIZE", "%d", ipsctp_list_size(&inst->assoc_list)); IPSCTP_SHOW_FMT("LPORT", "%d", inst->lport, "INST_FLAGS", "0X%X", inst->inst_flags); /* laddr_list more than 1 */ ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); laddr = (Ipsctp_laddr_entry *)ipcom_list_first(&inst->laddr_list); if (IP_NULL != laddr) ipsctp_addr_ntop(&laddr->laddr, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); else ipcom_memcpy(buf1, "null", sizeof("null")); IPSCTP_SHOW_FMT("LADDR_LIST SIZE", "%u", ipsctp_list_size(&inst->laddr_list), "LOCAL ADDR", "%s", buf1); for (laddr = laddr ? (Ipsctp_laddr_entry *)ipcom_list_next(&laddr->next) : IP_NULL; laddr; laddr = (Ipsctp_laddr_entry *)ipcom_list_next(&laddr->next)) { if (IP_NULL == laddr) break; ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipsctp_addr_ntop(&laddr->laddr, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("", "%s", " ", "LOCAL ADDR", "%s", buf1); } IPSCTP_SHOW_FMT("RECV_LOWAT", "%d", inst->recv_lowat, "SEND_LOWAT", "%d", inst->send_lowat); IPSCTP_SHOW_FMT("LINGER_TIME", "%d", inst->linger_time, "", "%s", " "); IPSCTP_SHOW_FMT("FRAG_POINT", "%d", inst->frag_point, "PD_POINT", "%d", inst->pd_point); IPSCTP_SHOW_FMT("CONTEXT", "%d", inst->context, "FEATURE_FLAGS", "%d", inst->feature_flags); /* Ipsctp_rtoinfo */ IPSCTP_SHOW_FMT("SRTO_MIN", "%d", inst->rtoinfo.srto_min, "SRTO_MAX", "%d", inst->rtoinfo.srto_max); IPSCTP_SHOW_FMT("SRTO_INITIAL", "%d", inst->rtoinfo.srto_initial, "", "%s", " "); /* Ipsctp_paddrparams */ IPSCTP_SHOW_FMT("SPP_HBINTERVAL", "%d", inst->paddrparam.spp_hbinterval, "SPP_PATHMAXRXT", "%d", inst->paddrparam.spp_pathmaxrxt); IPSCTP_SHOW_FMT("SPP_PATHMTU", "%d", inst->paddrparam.spp_pathmtu, "SPP_FLAGS", "0X%X", inst->paddrparam.spp_flags); IPSCTP_SHOW_FMT("SPP_IPV6_FLOWLABEL", "%d", inst->paddrparam.spp_ipv6_flowlabel, "SPP_IPV4_TOS", "%d", inst->paddrparam.spp_ipv4_tos); /* assocparams */ IPSCTP_SHOW_FMT("SASOC_ASOCMAXRXT", "%d", inst->assocparams.sasoc_asocmaxrxt, "SASOC_COOKIE_LIFE", "%d", inst->assocparams.sasoc_cookie_life); /* sndrcvinfo */ IPSCTP_SHOW_FMT("SINFO_STREAM", "%u", inst->sndrcvinfo.sinfo_stream, "SINFO_SSN", "%u", inst->sndrcvinfo.sinfo_ssn); IPSCTP_SHOW_FMT("SINFO_FLAGS", "0X%X", inst->sndrcvinfo.sinfo_flags, "SINFO_PR_POLICY", "%u", inst->sndrcvinfo.sinfo_pr_policy); IPSCTP_SHOW_FMT("SINFO_PPID", "%u", inst->sndrcvinfo.sinfo_ppid, "SINFO_CONTEXT", "%u", inst->sndrcvinfo.sinfo_context); IPSCTP_SHOW_FMT("SINFO_PR_VALUE", "%u", inst->sndrcvinfo.sinfo_pr_value, "SINFO_TSN", "%u", inst->sndrcvinfo.sinfo_tsn); IPSCTP_SHOW_FMT("SINFO_CUMTSN", "%u", inst->sndrcvinfo.sinfo_cumtsn, "", "%s", " "); /* backlog */ IPSCTP_SHOW_FMT("BACKLOG_LEN", "%d", inst->backlog_len, "BACKLOG_USED", "%d", inst->backlog_used); IPSCTP_SHOW_FMT("BACKLOG_PENDING", "0X%X", inst->backlog_pending, "BACKLOG_DONE", "0X%X", inst->backlog_done); i = 0; while ((i < inst->backlog_len) && ((IP_SOCKERR != inst->backlog_pending[i]) || (IP_SOCKERR != inst->backlog_done[i]))) { IPSCTP_SHOW_FMT("pending", "%u", (IP_SOCKERR != inst->backlog_pending[i] ? inst->backlog_pending[i] : 0), "done", "%u", (IP_SOCKERR != inst->backlog_done[i] ? inst->backlog_done[i] : 0)); i++; } #ifndef IPSCTP_USE_MULTIBUF IPSCTP_SHOW_FMT("send_chunks_cnt", "%u", inst->send_chunks_cnt, "recv_chunks_cnt", "%u", inst->recv_chunks_cnt); IPSCTP_SHOW_FMT("cnt_on_in_queue", "%u", inst->cnt_on_in_queue, "size_on_in_queue", "%u", inst->size_on_in_queue); #endif IPSCTP_SHOW_FMT("TCB count", "%u", ipsctp_list_size(&inst->assoc_list), "", "%s", " "); ipcom_debug_printf( "%s", "+++Instance Recv List:-------------------------------------------------------\n"); ipsctp_list_for_each(&inst->recv_list, chunk_received, Ipsctp_chunk_recv) { ipsctp_show_chunk_recv(chunk_received); } return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_sock(Ip_fd sh_fd, int detail) { Ipsctp_socket *cur_sock = IP_NULL; Ipsctp_instance *inst = IP_NULL; Ipsctp_tcb *tcb = IP_NULL; char buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; char buf2[IPSCTP_LEN_SHOW_TEMP_BUF]; if (IP_NULL == (cur_sock = ipnet->sockets[sh_fd])) { ipcom_printf("Null socket pointer : [%d]\n",sh_fd); return; } ipcom_debug_printf("%s", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); if (!detail) { ipsctp_t_show_sock(sh_fd); return; } ipcom_debug_printf("%s", "+++Socket information:----------------------------------------------------------\n"); /* Ipcom_socket */ IPSCTP_SHOW_FMT("FD", "%d", cur_sock->ipcom.fd, "PID", "%d", cur_sock->ipcom.pid); IPSCTP_SHOW_FMT("TYPE", "%d", cur_sock->ipcom.type, "DOMAIN", "%d", cur_sock->ipcom.domain); IPSCTP_SHOW_FMT("COOKIE", "0X%X", cur_sock->ipcom.cookie, "EVENT_CB", "0X%X", cur_sock->ipcom.event_cb); IPSCTP_SHOW_FMT("RCV_BYTES", "%d", cur_sock->ipcom.rcv_bytes, "", "%s", " "); /* ipnet_socket */ IPSCTP_SHOW_FMT("REF_COUNT", "%d", cur_sock->ref_count, "FLAGS", "0X%X", cur_sock->flags); IPSCTP_SHOW_FMT("PROTO", "%d", cur_sock->proto, "VR_INDEX", "%d", cur_sock->vr_index); IPSCTP_SHOW_FMT("MAX_HDRSPACE", "%d", cur_sock->max_hdrspace, "CHK_OFFSET", "%d", cur_sock->chk_offset); IPSCTP_SHOW_FMT("SPORT", "%d", cur_sock->sport, "DPORT", "%d", cur_sock->dport); IPSCTP_SHOW_FMT("UNI_HOP_LIMIT", "%d", cur_sock->uni_hop_limit, "MULTI_HOP_LIMIT", "%d", cur_sock->multi_hop_limit); IPSCTP_SHOW_FMT("PROMISC_COUNT", "%d", cur_sock->promisc_count, "BIND_TO_IFINDEX", "%d", cur_sock->bind_to_ifindex); IPSCTP_SHOW_FMT("SEND_MAX_BYTES", "%d", cur_sock->send_max_bytes, "RECV_MAX_BYTES", "%d", cur_sock->recv_max_bytes); IPSCTP_SHOW_FMT("SND_ROUTE_CACHE_ID", "%d", cur_sock->snd_route_cache_id, "SND_BYTES", "%d", cur_sock->snd_bytes); ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipsctp_addr_ntop((Ipsctp_addr *)cur_sock->snd_to, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("SND_HEAD", "0X%X", cur_sock->snd_head, "SND_TO", "%s", buf1); IPSCTP_SHOW_FMT("RCV_HEAD", "0X%X", cur_sock->rcv_head, "RCV_TAIL", "0X%X", cur_sock->rcv_tail); IPSCTP_SHOW_FMT("SCTP_INST", "0X%X", cur_sock->sctp_inst, "SOCK_END", "0X%X", cur_sock->sock_end); #ifdef IPCOM_USE_INET if (IP_NULL == cur_sock->ip4) goto show_ip6; ipsctp_print_line(); ipcom_debug_printf("%s", "+++IPV4 information:------------------------------------------------------------\n"); /* Ipnet_ip4_socket */ ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); (void)ipcom_inet_ntop(IP_AF_INET, (void *)&cur_sock->ip4->saddr_n, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipsctp_memzero(buf2, IPSCTP_LEN_SHOW_TEMP_BUF); (void)ipcom_inet_ntop(IP_AF_INET, (void *)&cur_sock->ip4->daddr_n, buf2, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("SADDR_N", "%s", buf1, "DADDR_N", "%s", buf2); IPSCTP_SHOW_FMT("MULTICAST_IF", "%u", cur_sock->ip4->multicast_if, "FLAGS", "0X%X", cur_sock->ip4->flags); #if 0 IPSCTP_SHOW_FMT("ROUTER_ALERT", "%d", cur_sock->ip4->router_alert, "DONT_FRAG", "%d", cur_sock->ip4->dont_frag); #endif IPSCTP_SHOW_FMT("TYPE_OF_SERVICE", "%d", cur_sock->ip4->type_of_service, "MULTICAST_ADDR_LIST", "0X%X", cur_sock->ip4->multicast_addr_list); IPSCTP_SHOW_FMT("OPTS", "0X%X", cur_sock->ip4->opts, "ICMP_FILTER", "0X%X", cur_sock->ip4->icmp_filter); show_ip6: #endif #ifdef IPCOM_USE_INET6 if (IP_NULL == cur_sock->ip6) goto show_inst; ipsctp_print_line(); ipcom_debug_printf("%s", "+++IPV6 information:------------------------------------------------------------\n"); /* Ipnet_ip6_socket */ ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); (void)ipcom_inet_ntop(IP_AF_INET6, (void *)&cur_sock->ip6->saddr, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipsctp_memzero(buf2, IPSCTP_LEN_SHOW_TEMP_BUF); (void)ipcom_inet_ntop(IP_AF_INET6, (void *)&cur_sock->ip6->daddr, buf2, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("SADDR_N", "%s", buf1, "DADDR_N", "%s", buf2); IPSCTP_SHOW_FMT("MULTICAST_IF", "%u", cur_sock->ip6->multicast_if, "FLAGS", "0X%X", cur_sock->ip6->flags); IPSCTP_SHOW_FMT("tclass", "%u", cur_sock->ip6->tclass, "prefer_src_flags", "0X%X", cur_sock->ip6->prefer_src_flags); IPSCTP_SHOW_FMT("iscope_id", "%u", cur_sock->ip6->iscope_id, "flowinfo", "%u", cur_sock->ip6->flowinfo); IPSCTP_SHOW_FMT("multicast_addr_list", "0X%X", cur_sock->ip6->multicast_addr_list, "icmp6_filter", "0X%X", cur_sock->ip6->icmp6_filter); show_inst: #endif /* sctp_inst, if TCP just return. */ inst = (Ipsctp_instance *)cur_sock->sctp_inst; if (IP_NULL == inst) return; ipsctp_show_instance(inst); /* TCB information */ ipsctp_list_for_each(&inst->assoc_list, tcb, Ipsctp_tcb) { ipsctp_show_tcb(tcb); } return; } /* *=========================================================================== * ipsctp_show_sock_all *=========================================================================== * Description: Prints all sockets. * Parameters: * Returns: * */ IP_PUBLIC void ipsctp_show_sock_all(int cmd) { Ipsctp_socket *cur_sock = IP_NULL; Ip_u32 i = 0; for (i = 0; i < ipnet_conf_max_sockets; i++) { if (IP_NULL == (cur_sock = ipnet->sockets[i])) continue; if (IP_IPPROTO_SCTP != cur_sock->proto) continue; switch (cmd) { case 0: case 1: ipsctp_show_sock(i, cmd); break; case 2: if ((IP_BIT_ISSET(cur_sock->sctp_inst->inst_flags, IPSCTP_SOCKET_LISTENING)) && (IP_SOCK_SEQPACKET == cur_sock->ipcom.type)) { ipcom_printf("socket : [%u] association count = %u, ref_count = %u"IP_LF, i, ipsctp_list_size(&cur_sock->sctp_inst->assoc_list), cur_sock->ref_count); } else { ipcom_printf("socket : [%u]->ref_count = %u"IP_LF, i, cur_sock->ref_count); } break; default: break; } } return; } /* *=========================================================================== * ipsctp_show_global_cb_tcb_hashtable *=========================================================================== * Description: Prints all TCBs. * Parameters: * Returns: * */ IP_STATIC void ipsctp_show_global_cb_tcb_hashtable(void *cookie, void *unused) { Ipsctp_tcb *tcb = (Ipsctp_tcb *)cookie; (void) unused; if (IP_NULL == tcb) return; ipsctp_show_tcb(tcb); return; } /* *=========================================================================== * ipsctp_show_global_cb_tcb_hashtable *=========================================================================== * Description: Prints all TCBs. * Parameters: * Returns: * */ IP_STATIC void ipsctp_show_global_cb_vtag_timewait(void *cookie, void *unused) { Ipsctp_vtag_timewait *vtag_timewait = (Ipsctp_vtag_timewait *)cookie; (void) unused; IPSCTP_SHOW_FMT("vtag", "0X%X", vtag_timewait->vtag, "timeout", "0X%X", &vtag_timewait->timer); return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_global_hash_port(void) { if (IP_NULL == ipsctp) { return; } ipcom_debug_printf("%s", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); /* tcb_hashtable_port */ if (IP_NULL != ipsctp->tcb_hashtable_port) { IPSCTP_SHOW_FMT("tcb_hashtable_port ELEM", "%u", ipsctp->tcb_hashtable_port->elem, "tcb_hashtable_port SIZE", "%u", ipsctp->tcb_hashtable_port->size); ipsctp_hash_for_each(ipsctp->tcb_hashtable_port, (Ipsctp_hash_foreach_cb_func)ipsctp_show_global_cb_tcb_hashtable, IP_NULL); } return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_global(void) { if (IP_NULL == ipsctp) { return; } ipcom_debug_printf("%s", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); /* tcb_hashtable */ if (IP_NULL != ipsctp->tcb_hashtable) { IPSCTP_SHOW_FMT("tcb_hashtable ELEM", "%u", ipsctp->tcb_hashtable->elem, "tcb_hashtable SIZE", "%u", ipsctp->tcb_hashtable->size); ipsctp_hash_for_each(ipsctp->tcb_hashtable, (Ipsctp_hash_foreach_cb_func)ipsctp_show_global_cb_tcb_hashtable, IP_NULL); } /* tcb_hashtable_port */ if (IP_NULL != ipsctp->tcb_hashtable_port) { IPSCTP_SHOW_FMT("tcb_hashtable_port ELEM", "%u", ipsctp->tcb_hashtable_port->elem, "tcb_hashtable_port SIZE", "%u", ipsctp->tcb_hashtable_port->size); ipsctp_hash_for_each(ipsctp->tcb_hashtable_port, (Ipsctp_hash_foreach_cb_func)ipsctp_show_global_cb_tcb_hashtable, IP_NULL); } /* vtag_timewait */ if (IP_NULL != ipsctp->vtag_timewait) { IPSCTP_SHOW_FMT("vtag_timewait ELEM", "%u", ipsctp->vtag_timewait->elem, "vtag_timewait SIZE", "%u", ipsctp->vtag_timewait->size); ipsctp_print_line(); ipsctp_hash_for_each(ipsctp->vtag_timewait, (Ipsctp_hash_foreach_cb_func)ipsctp_show_global_cb_vtag_timewait, IP_NULL); } return; } #if 0 #ifdef IPCOM_USE_INET /* *=========================================================================== * ipsctp_show_global_cb_tcb_hashtable *=========================================================================== * Description: Prints all TCBs. * Parameters: * Returns: * */ IP_STATIC void ipsctp_show_ipnet_cb_ip4_addrs(void *cookie, void *unused) { Ipnet_ip4_addr_entry *addr = (Ipnet_ip4_addr_entry *)cookie; struct Ipnet_socket_struct *sk = IP_NULL; char tmp_buf1[IPSCTP_LEN_SHOW_TEMP_BUF]; char *buf1 = tmp_buf1; /* ##ugly, but needed## */ (void) unused; if (IP_NULL == addr) return; if (IP_NULL != addr->netif) IPSCTP_SHOW_FMT("--INTERFACE NAME", "%s", addr->netif->ipcom.name, "", "%s", " "); else IPSCTP_SHOW_FMT("--INTERFACE NAME", "%s", "null", "", "%s", " "); ipsctp_memzero(buf1, IPSCTP_LEN_SHOW_TEMP_BUF); ipcom_inet_ntop(IP_AF_INET, (void *)&addr->ipaddr_n, buf1, IPSCTP_LEN_SHOW_TEMP_BUF); IPSCTP_SHOW_FMT("ipaddr_n", "%s", buf1, "ref_count", "%u", addr->ref_count); IPSCTP_SHOW_FMT("flags", "0X%X", addr->flags, "type", "%u", addr->type); if (IP_NULL == (sk = addr->socket_list)) return; if (IP_IPPROTO_SCTP != sk->proto) return; ipsctp_show_sock(sk->ipcom.fd, 0); return; } #endif /* *=========================================================================== * ipsctp_show_global_cb_tcb_hashtable *=========================================================================== * Description: Prints all TCBs. * Parameters: * Returns: * */ IP_STATIC void ipsctp_show_ipnet_cb_netifs(void *cookie, void *unused) { Ipnet_netif *netif = (Ipnet_netif *)cookie; (void) unused; if (IP_NULL == netif) return; IPSCTP_SHOW_FMT("INTERFACE NAME", "%s", netif->ipcom.name, "link_hdr_size", "%u", netif->ipcom.link_hdr_size); return; } /* *=========================================================================== * ipsctp_t_server *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: buf - The buffer thant you wantted to print * prompt - The prompt * len - The buffer length * Returns: None * */ IP_PUBLIC void ipsctp_show_ipnet(void) { if (IP_NULL == ipnet) { return; } ipcom_debug_printf("%s", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); /* bound_sockets */ if ((IP_NULL != ipnet->reachable_sockets) && (IP_NULL != ipnet->socket_ops) && (IP_NULL != ipnet->bound_sockets)) { IPSCTP_SHOW_FMT("reachable_sockets ELEM", "%u", ipnet->reachable_sockets->elem, "socket_ops ELEM", "%u", ipnet->socket_ops->elem); IPSCTP_SHOW_FMT("bound_sockets ELEM", "%u", ipnet->bound_sockets->elem, "largest_socket_size", "%u", ipnet->largest_socket_size); } #ifdef IPCOM_USE_INET /* ip4.addrs */ if (IP_NULL != ipnet->ip4.addrs) { ipsctp_print_line(); IPSCTP_SHOW_FMT("ip4 addrs ELEM", "%s", " ", "", "%u", ipnet->ip4.addrs->elem); ipcom_hash_for_each(ipnet->ip4.addrs, (Ipcom_hash_foreach_cb_func)ipsctp_show_ipnet_cb_ip4_addrs, IP_NULL); ipsctp_print_line(); IPSCTP_SHOW_FMT("ip4 addrs_ignore_if ELEM", "%s", " ", "", "%u", ipnet->ip4.addrs_ignore_if->elem); ipcom_hash_for_each(ipnet->ip4.addrs_ignore_if, (Ipcom_hash_foreach_cb_func)ipsctp_show_ipnet_cb_ip4_addrs, IP_NULL); ipsctp_print_line(); { Ipnet_ip4_addr_entry *g_addr = IP_NULL; g_addr = ipnet->ip4.globals; while (g_addr) { ipsctp_show_ipnet_cb_ip4_addrs((void*)g_addr, IP_NULL); g_addr = g_addr->global_next; } } } #endif #if 1 /* please refer to "ifconfig" */ /* netifs */ if (IP_NULL != ipnet->netifs) { ipsctp_print_line(); IPSCTP_SHOW_FMT("netifs ELEM", "%u", ipnet->netifs->elem, "", "%s", " "); ipcom_hash_for_each(ipnet->netifs, (Ipcom_hash_foreach_cb_func)ipsctp_show_ipnet_cb_netifs, IP_NULL); } #endif return; } #endif /* *=========================================================================== * ipsctp_search_tcb *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: * * Returns: None * */ IP_PUBLIC void ipsctp_search_tcb(Ip_u32 vtag, /* local's verification tag */ IP_CONST char *local_addr, /* The local IPv4 address in network order, IP_NULL for any address */ Ip_u16 local_port, /* port in host order, 0 for any port.*/ IP_CONST char *peer_addr, /* The peer IPv4 address in network order, IP_NULL for any address */ Ip_u16 peer_port, /* port in host order, 0 for any port.*/ Ip_u16 vr /* the using virtual router */ ) { union Ip_in_addr_union local; union Ip_in_addr_union peer; Ipsctp_tcb *tcb; Ipsctp_transport *transport = NULL; Ipsctp_af_ops *af_ops = ipsctp_get_af_ops(IP_AF_INET); ipcom_memset(&local, 0, sizeof(local)); ipcom_memset(&peer, 0, sizeof(peer)); if (local_addr) { #ifdef IPCOM_USE_INET if (ipcom_inet_pton(IP_AF_INET, local_addr, &local.in) != 1) { } else { af_ops = ipsctp_get_af_ops(IP_AF_INET); goto pass_local; } #endif #ifdef IPCOM_USE_INET6 if (ipcom_inet_pton(IP_AF_INET6, local_addr, &local.in6) != 1) { return; } else { af_ops = ipsctp_get_af_ops(IP_AF_INET6); } #endif } pass_local: if (peer_addr) { #ifdef IPCOM_USE_INET if (ipcom_inet_pton(IP_AF_INET, peer_addr, &peer.in) != 1) { } else { goto pass_peer; } #endif #ifdef IPCOM_USE_INET6 if (ipcom_inet_pton(IP_AF_INET6, local_addr, &peer.in6) != 1) return; #endif } pass_peer: tcb = ipsctp_tcb_lookup(vtag, vr, IP_IPPROTO_SCTP, &local, local_port, &peer, peer_port, af_ops, &transport ); if (tcb) { ipsctp_show_tcb(tcb); } return; } /* *=========================================================================== * ipsctp_show_stat_mib *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: * * Returns: None * */ IP_PUBLIC void ipsctp_show_stat_mib(void) { ipsctp_print_line(); ipcom_debug_printf( "%s", "+++SCTP MIB statistics:-------------------------------------------------------"IP_LF); ipcom_debug_printf( "%-26s: %15u; %-26s: %15u;"IP_LF, "sctp_Curr_Estab", IPSCTP_MIB_STATS(sctp_Curr_Estab), "sctp_Active_Estabs", IPSCTP_MIB_STATS(sctp_Active_Estabs)); ipcom_debug_printf( "%-26s: %15u; %-26s: %15u;"IP_LF, "sctp_Passive_Estabs", IPSCTP_MIB_STATS(sctp_Passive_Estabs), "sctp_Active_Estabs", IPSCTP_MIB_STATS(sctp_Active_Estabs)); ipcom_debug_printf( "%-26s: %15u; %-26s: %15u;"IP_LF, "sctp_Aborteds", IPSCTP_MIB_STATS(sctp_Aborteds), "sctp_Shutdowns", IPSCTP_MIB_STATS(sctp_Shutdowns)); ipcom_debug_printf( "%-26s: %15u; %-26s: %15u;"IP_LF, "sctp_OutOfBlues", IPSCTP_MIB_STATS(sctp_OutOfBlues), "sctp_Checksum_Errors", IPSCTP_MIB_STATS(sctp_Checksum_Errors)); ipcom_debug_printf( "%-26s: 0x%05x%08x; %-26s: 0x%05x%08x;"IP_LF, "sctp_Out_Ctrl_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Out_Ctrl_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Out_Ctrl_Chunks)), "sctp_Out_Order_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Out_Order_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Out_Order_Chunks))); ipcom_debug_printf( "%-26s: 0x%8x%8x; %-26s: 0x%8x%8x;"IP_LF, "sctp_Out_Unorder_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Out_Unorder_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Out_Unorder_Chunks)), "sctp_In_Ctrl_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_In_Ctrl_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_In_Ctrl_Chunks))); ipcom_debug_printf( "%-26s: 0x%8x%8x; %-26s: 0x%8x%8x;"IP_LF, "sctp_In_Order_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_In_Order_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_In_Order_Chunks)), "sctp_In_Unorder_Chunks", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_In_Unorder_Chunks)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_In_Unorder_Chunks))); ipcom_debug_printf( "%-26s: 0x%8x%8x; %-26s: 0x%8x%8x;"IP_LF, "sctp_Frag_UsrMsgs", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Frag_UsrMsgs)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Frag_UsrMsgs)), "sctp_Reasm_UsrMsgs", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Reasm_UsrMsgs)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Reasm_UsrMsgs))); ipcom_debug_printf( "%-26s: 0x%8x%8x; %-26s: 0x%8x%8x;"IP_LF, "sctp_Out_SCTP_Packs", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_Out_SCTP_Packs)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_Out_SCTP_Packs)), "sctp_In_SCTP_Packs", IP_U64_GETHI(IPSCTP_MIB_STATS(sctp_In_SCTP_Packs)), IP_U64_GETLO(IPSCTP_MIB_STATS(sctp_In_SCTP_Packs))); ipcom_debug_printf( "%-26s: time = %u, time = %u;"IP_LF, "sctp_Discontinuity_Time", IPSCTP_MIB_STATS(sctp_Discontinuity_Time), IPSCTP_MIB_STATS(sctp_Discontinuity_Time)); ipsctp_print_line(); } /* *=========================================================================== * ipsctp_show_stat_debug *=========================================================================== * Description: * ------------------------------------------------------------------------------------------ * Parameters: * * Returns: None * */ IP_PUBLIC void ipsctp_show_stat_debug(void) { ipsctp_show_stat_mib(); ipsctp_print_line(); ipcom_debug_printf( "%s", "+++SCTP debug statistics:-------------------------------------------------------"IP_LF); ipcom_debug_printf( "sctp_input: %15u; sctp_input_hdr_trunc: %15u;"IP_LF, IPSCTP_STATS(sctp_input), IPSCTP_STATS(sctp_input_hdr_trunc)); ipcom_debug_printf( "sctp_input_tcb_nomatch: %15u; sctp_input_tcb_match: %15u;"IP_LF, IPSCTP_STATS(sctp_input_tcb_nomatch), IPSCTP_STATS(sctp_input_tcb_match)); ipcom_debug_printf( "sctp_input_bad_vtag: %15u; sctp_input_dup_chunks: %15u;"IP_LF, IPSCTP_STATS(sctp_input_bad_vtag), IPSCTP_STATS(sctp_input_dup_chunks)); ipcom_debug_printf( "sctp_tsn_bitmap_expand: %15u; sctp_input_drop_chunks_bitmap: %15u;"IP_LF, IPSCTP_STATS(sctp_tsn_bitmap_expand), IPSCTP_STATS(sctp_input_drop_chunks_bitmap)); ipcom_debug_printf( "sctp_input_drop_chunks_invalid_sid: %15u; sctp_input_drop_chunks_no_buf: %15u;"IP_LF, IPSCTP_STATS(sctp_input_drop_chunks_invalid_sid), IPSCTP_STATS(sctp_input_drop_chunks_no_buf)); ipcom_debug_printf( "sctp_input_chunks_express: %15u; sctp_input_chunks_express_pd: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_express), IPSCTP_STATS(sctp_input_chunks_express_pd)); ipcom_debug_printf( "sctp_input_chunks_queue2buf: %15u; sctp_input_chunks_queue2pd: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_queue2buf), IPSCTP_STATS(sctp_input_chunks_queue2pd)); ipcom_debug_printf( "sctp_input_chunks_pd: %15u; sctp_input_chunks_fragment: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_pd), IPSCTP_STATS(sctp_input_chunks_fragment)); ipcom_debug_printf( "sctp_input_chunks_queued_fragment: %15u; sctp_input_chunks_not_fragment: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_queued_fragment), IPSCTP_STATS(sctp_input_chunks_not_fragment)); ipcom_debug_printf( "sctp_input_chunks_queued_not_fragment: %15u; sctp_input_msgs_reasm_queued: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_queued_not_fragment), IPSCTP_STATS(sctp_input_msgs_reasm_queued)); ipcom_debug_printf( "sctp_input_chunks_buf2user: %15u; sctp_input_chunks_fragment2user: %15u;"IP_LF, IPSCTP_STATS(sctp_input_chunks_buf2user), IPSCTP_STATS(sctp_input_chunks_fragment2user)); ipcom_debug_printf( "sctp_input_msgs_reasm_2user: %15u; sctp_output_window_update: %15u;"IP_LF, IPSCTP_STATS(sctp_input_msgs_reasm_2user), IPSCTP_STATS(sctp_output_window_update)); ipcom_debug_printf( "sctp_read_peeks: %15u; sctp_read_peeks: %15u;"IP_LF, IPSCTP_STATS(sctp_read_peeks), IPSCTP_STATS(sctp_read_peeks)); ipcom_debug_printf( "sctp_output_data: %15u; sctp_output_data_err: %15u;"IP_LF, IPSCTP_STATS(sctp_output_data), IPSCTP_STATS(sctp_output_data_err)); ipcom_debug_printf( "sctp_output_data_chunk: %15u; sctp_output_data_chunk_err: %15u;"IP_LF, IPSCTP_STATS(sctp_output_data_chunk), IPSCTP_STATS(sctp_output_data_chunk_err)); ipcom_debug_printf( "sctp_output_data_chunk_retr: %15u; sctp_output_data_chunk_retr_err: %15u;"IP_LF, IPSCTP_STATS(sctp_output_data_chunk_retr), IPSCTP_STATS(sctp_output_data_chunk_retr_err)); ipcom_debug_printf( "sctp_output_ctrl_chunk: %15u; sctp_output_ctrl_chunk_err: %15u;"IP_LF, IPSCTP_STATS(sctp_output_ctrl_chunk), IPSCTP_STATS(sctp_output_ctrl_chunk_err)); ipcom_debug_printf( "sctp_output_pkt: %15u; sctp_output_pkt_err: %15u;"IP_LF, IPSCTP_STATS(sctp_output_pkt), IPSCTP_STATS(sctp_output_pkt_err)); ipcom_debug_printf( "sctp_output_data_chunk_cwnd: %15u; sctp_output_data_chunk_cwnd_retr: %15u;"IP_LF, IPSCTP_STATS(sctp_output_data_chunk_cwnd), IPSCTP_STATS(sctp_output_data_chunk_cwnd_retr)); ipcom_debug_printf( "sctp_output_data_chunk_nagle: %15u; sctp_output_data_chunk_mult_owner: %15u;"IP_LF, IPSCTP_STATS(sctp_output_data_chunk_nagle), IPSCTP_STATS(sctp_output_data_chunk_mult_owner)); ipsctp_print_line(); } #ifndef IPSCTP_USE_MULTIBUF IP_PUBLIC Ip_u32 ipsctp_show_buffer(Ipsctp_socket *sock) { IPCOM_LOG6(INFO, "ipsctp buffer info: sport = %u, buf_max = %u, buf_len = %u, " "buf_cnt = %u, queue_len = %u, queue_cnt = %u"IP_LF, sock->sport, sock->recv_max_bytes, sock->ipcom.rcv_bytes, sock->sctp_inst->recv_chunks_cnt, sock->sctp_inst->size_on_in_queue, sock->sctp_inst->cnt_on_in_queue); return 0; } #endif #ifdef IPCOM_FORWARDER_NAE const char *sctp_tmr_string[] = { "IPSCTP_TIMO_NONE", /* Placeholder that means: do not add a timer */ "IPSCTP_TIMO_T1" , /* init timer */ "IPSCTP_TIMO_T2" , /* shutdown timer */ "IPSCTP_TIMO_T3" , /* retransmission timer */ "IPSCTP_TIMO_T5" , /* shutdown guard timer */ "IPSCTP_TIMO_DACK" , /* delay ack timer */ #ifdef IPSCTP_FAST_RETRANSMITE "IPSCTP_TIMO_FR" , /* fr timer */ #else "IPSCTP_TIMO_NONE" , /* none */ #endif "IPSCTP_TIMO_COOKIE" , /* cookie timer */ "IPSCTP_TIMO_HB" , /* heartbeat timer */ "IPSCTP_TIMO_SECRET" , /* secret change timer */ "IPSCTP_TIMO_LINGER" , /* linger timer */ "IPSCTP_TIMO_AUTOCLOSE" , /* autoclose timer */ "IPSCTP_TIMO_SENDALL" , /* send all timer */ "IPSCTP_TIMO_MAX" /* invalid value */ } ; void ipsctp_timer_show(Ipsctp_instance *instance) { Ipcom_list *tmr_node; Ipsctp_timer *tmr; Ipsctp_tcb* tcb = (Ipsctp_tcb *)ipcom_list_first(&instance->assoc_list); tmr_node = IPCOM_LIST_FIRST(&instance->timers); ipcom_printf("Active timers: \n"); while (tmr_node != IP_NULL) { tmr = ipcom_list_entry(tmr_node, Ipsctp_timer, list); ipcom_printf("%s : expires %d msec_now %d delta %d\n", sctp_tmr_string[tmr->type],tmr->msec_expires,ipstack->msec_now,tmr->msec_expires-ipstack->msec_now); tmr_node = IPCOM_LIST_NEXT(tmr_node); } } void printPktsx(Ipcom_pkt *pkt) { if (pkt) { #ifdef IP_LW_DEBUG ipcom_printf("\tLength: %d, start: %d, end: %d, Ptr: %p, last loc: %d, nae: %d\n", ipcom_pkt_get_length(pkt), pkt->start, pkt->end, pkt, pkt->lw_trace, pkt->lw_nae); #else ipcom_printf("\tLength: %d, start: %d, end: %d, Ptr: %p\n", ipcom_pkt_get_length(pkt), pkt->start, pkt->end, pkt); #endif printPktsx(pkt->next); } } void printSctpRetransList(Ipsctp_tcb* stcb) { Ipsctp_chunk_send *chunk_send = IP_NULL; /* If something in transmitted queue */ if (0 != stcb->transmitted_chunk_list.size) { /* Get the first chunk */ chunk_send = (Ipsctp_chunk_send *)ipcom_list_first(&stcb->transmitted_chunk_list); /* Lookup eligible retransmit chunk which is in RESEND state */ while (IP_NULL != chunk_send) { /* It is an resent chunk */ if (IPSCTP_CHUNK_FLAG_GET_SEND_STATE(chunk_send->chunk.flag)== IPSCTP_CHUNK_FLAG_SEND_STATE_RESEND) { ipcom_printf("TSN: %u, cumtsm %u\n", chunk_send->sndrcv_info.sinfo_tsn,chunk_send->sndrcv_info.sinfo_cumtsn); printPktsx(chunk_send->chunk.pkt); } chunk_send = (Ipsctp_chunk_send *)ipcom_list_next((Ipcom_list*)chunk_send); } } } void printSctpTransmitedList(Ipsctp_tcb* stcb) { Ipsctp_chunk_send *chunk_send = IP_NULL; /* If something in transmitted queue */ if (0 != stcb->transmitted_chunk_list.size) { /* Get the first chunk */ chunk_send = (Ipsctp_chunk_send *)ipcom_list_first(&stcb->transmitted_chunk_list); /* Lookup eligible retransmit chunk which is in RESEND state */ while (IP_NULL != chunk_send) { ipcom_printf("TSN: %u, cumtsm %u\n", chunk_send->sndrcv_info.sinfo_tsn,chunk_send->sndrcv_info.sinfo_cumtsn); printPktsx(chunk_send->chunk.pkt); chunk_send = (Ipsctp_chunk_send *)ipcom_list_next((Ipcom_list*)chunk_send); } } } int ipsctp_check_packet(Ipsctp_tcb* stcb,Ipsctp_transport* trans) { Ipsctp_chunk_send *chunk_send = IP_NULL; int re = 0; int i = 0; /* If something in transmitted queue */ /* if (0 != stcb->transmitted_chunk_list.size)*/ { /* Get the first chunk */ chunk_send = (Ipsctp_chunk_send *)ipcom_list_first(&stcb->transmitted_chunk_list); /* Lookup eligible retransmit chunk which is in RESEND state */ while (IP_NULL != chunk_send) { if (!i++) ipcom_printf("\ntransmitted_chunk_list.size = %d\n",stcb->transmitted_chunk_list.size); ipcom_printf("TSN: %u, cumtsm %u\n", chunk_send->sndrcv_info.sinfo_tsn,chunk_send->sndrcv_info.sinfo_cumtsn); printPktsx(chunk_send->chunk.pkt); chunk_send = (Ipsctp_chunk_send *)ipcom_list_next((Ipcom_list*)chunk_send); re++; } } return re; } void sctpSockInfo(Ipnet_socket *sock) { Ipsctp_transport *transport; Ipsctp_instance *instance = sock->sctp_inst; Ipsctp_tcb *tcb = (Ipsctp_tcb *)ipcom_list_first(&sock->sctp_inst->assoc_list); ipcom_printf("SCTP socket with descriptor %d\n", sock->ipcom.fd); ipcom_printf("sock->flags: %x\n", sock->flags); ipcom_printf("%d bytes in the send queue\n",ipcom_atomic_get(&sock->snd_bytes)); /* For each transport in this tcb */ for(transport = (Ipsctp_transport *)ipcom_list_first(&tcb->transport_list); IP_NULL != transport; transport = (Ipsctp_transport *)ipcom_list_next(&transport->trans_next)) { int i = 0; /* If nothing was acked on this destination skip it */ if (0 == transport->net_ack) continue; ipcom_printf("transport%d: %d bytes unsent, %d has not been ACK:ed\n",++i, transport->unsent_bytes, transport->flight_size); } ipsctp_timer_show(instance); ipcom_printf("Packets in transmitted queue are:\n"); printSctpTransmitedList(tcb); ipcom_printf("Packets in retrans queue are:\n"); printSctpRetransList(tcb); } int sSockInfo(int fd); int sSockInfo(int fd) { Ipnet_socket *sock; if (fd < 0 || fd >= ipnet_conf_max_sockets) ipcom_printf("File descriptor %d is out of range\n", fd); sock = ipnet->sockets[fd]; if (sock == IP_NULL) ipcom_printf("%d is not a valid socket descriptor\n", fd); switch (sock->proto) { case IP_IPPROTO_SCTP: sctpSockInfo(sock); break; default: break; } return 0; } #endif #endif #ifdef IPNET_DEBUG /* *=========================================================================== * ipsctp_tick_to_string *=========================================================================== * Description: * Parameters: unused - * buf - * buf_len - * Returns: * */ IP_GLOBAL int ipsctp_tick_to_string(void *unused, char *buf, Ip_size_t buf_len) { IPCOM_UNUSED_ARG(unused); return ipcom_snprintf(buf, buf_len, "SCTP tick timer."); } #endif /* IPNET_DEBUG */ #ifdef IPSCTP_DBGSTAT IP_PUBLIC Ip_u32 ipsctp_debug_statistics[IPSCTP_DBGSTAT_MAX]; IP_STATIC IP_CONST char *ipsctp_dbgstat_ctl_str[] = { "BASE", "SYS_SEND_INIT", "RESTART_AND_OPEN", "SEND_INIT_PIPE", "COOKIE_TIMER", "SEND_INIT_ERR", "RECV_INIT", "SEND_INIT_ACK", "RECV_INIT_ACK", "SEND_COOKIE_ECHO", "RECV_COOKIE_ECHO", "SEND_COOKIE_ACK", "RECV_COOKIE_ACK", "MAX" }; /* *=========================================================================== * ipsctp_dbgstat_ctl *=========================================================================== * Description: Prints all sockets. * Parameters: * Returns: * */ IP_PUBLIC void ipsctp_dbgstat_ctl(int cmd) { Ipsctp_socket *cur_sock = IP_NULL; Ip_u32 i = 0; switch (cmd) { case 0: /* show : default */ for (i = 0; i< (Ip_u32)IPSCTP_DBGSTAT_MAX; i++) ipcom_printf("%-20s = %u\n", ipsctp_dbgstat_ctl_str[i], IPSCTP_DBGSTAT_GET(i)); break; case 1: /* clear */ for (i = 0; i< (Ip_u32)IPSCTP_DBGSTAT_MAX; i++) { ipcom_printf("clear %s.\n", ipsctp_dbgstat_ctl_str[i]); IPSCTP_DBGSTAT_INIT(i); } break; case 2: /* association state */ for (i = 0; i < ipnet_conf_max_sockets; i++) { if (IP_NULL == (cur_sock = ipnet->sockets[i])) continue; if (IP_IPPROTO_SCTP != cur_sock->proto) continue; } break; } return; } #endif /* **************************************************************************** * END OF FILE **************************************************************************** */