void networkStatusChangeNotif(unsigned int assocID, short destAddrIndex, unsigned short newState, void* ulpDataPtr) { SCTP_AssociationStatus assocStatus; SCTP_PathStatus pathStatus; unsigned short pathID; if (verbose) { sprintf(tstr, "%-8x: Network status change: path %u is now %s\n", assocID, destAddrIndex, ((newState == SCTP_PATH_OK) ? "ACTIVE" : "INACTIVE")); waddstr(statusWin,tstr); wrefresh(statusWin); } /* if the primary path has become inactive */ if ((newState == SCTP_PATH_UNREACHABLE) && (destAddrIndex == sctp_getPrimary(assocID))) { /* select a new one */ sctp_getAssocStatus(assocID, &assocStatus); for (pathID=0; pathID < assocStatus.numberOfAddresses; pathID++){ sctp_getPathStatus(assocID, pathID, &pathStatus); if (pathStatus.state == SCTP_PATH_OK) break; } /* and use it */ if (pathID < assocStatus.numberOfAddresses) { sctp_setPrimary(assocID, pathID); getDestinationIPaddr((char *)peeraddr); } } }
void restartNotif(unsigned int assocID, void* ulpDataPtr) { SCTP_AssociationStatus assocStatus; if (verbose) { sprintf(tstr, "%-8x: Restart\n", assocID); waddstr(statusWin,tstr); } sctp_getAssocStatus(assocID, &assocStatus); }
/* This function reads the input from the parameters of the SCTP_PathStatus structure and displays the data on a window of ncurses. */ void ncurses_display_AssocStatus(unsigned int assocID) { SCTP_AssociationStatus assocStatus; int i; char tstr[200]; wclear(assocWin); wrefresh(assocWin); sctp_getAssocStatus(assocID,&assocStatus); sprintf(assocInfo," Association ID : %d, Local port : %d, Remote port : %d\n", assocID,assocStatus.sourcePort,assocStatus.destPort); waddstr(assocWin,assocInfo); wrefresh(assocWin); sprintf(assocInfo," Local address(es) is(are) :"); for (i=0; i < noOfLocalAddresses; i++) { sprintf(tstr," %s,", localAddressList[i]); strcat(assocInfo,tstr); } waddstr(assocWin,assocInfo); wrefresh(assocWin); sprintf(assocInfo,"\n No. of Destination address : %d,\t\t Primary destination address : %s\n Number of incoming Streams : %d,\t\t Number of outgoing streams : %d\n Primary Address Index: %d,\t\t\t Current Receiver Window Size : %d\n Outstanding bytes : %-8d,\t\t\t No. of chunks in send queue : %d\n No. of chunks in retransmission queue : %d,\t No. of chunks in reception queue : %d\n Initial Round Trip Timeout : %d (msecs),\t Minimum Round Trip Timeout : %d (msecs)\n Maximum Round Trip Timeout : %d(msecs),\t Cookie Lifetime : %d (msecs)\n Max retransmission per association : %d,\t Max retransmission per path : %d\n Max Initial Retransmission : %d,\t\t Local Receiver Window : %d\n Delay for delay acknowledge : %d (msecs),\t IP Type Of Service : %x\n Current Incoming stream ID : %d,\t\t Current Outgoing stream ID : %d ", assocStatus.numberOfAddresses, assocStatus.primaryDestinationAddress, statusUpdate.noOfInStreams, statusUpdate.noOfOutStreams, assocStatus.primaryAddressIndex, assocStatus.currentReceiverWindowSize, assocStatus.outstandingBytes, assocStatus.noOfChunksInSendQueue, assocStatus.noOfChunksInRetransmissionQueue, assocStatus.noOfChunksInReceptionQueue, assocStatus.rtoInitial, assocStatus.rtoMin, assocStatus.rtoMax, assocStatus.validCookieLife, assocStatus.assocMaxRetransmits, assocStatus.pathMaxRetransmits, assocStatus.maxInitRetransmits, assocStatus.myRwnd, assocStatus.delay, assocStatus.ipTos, statusUpdate.InstreamIDList[currInstreamID], statusUpdate.OutstreamIDList[currOutstreamID] ); waddstr(assocWin,assocInfo); wrefresh(assocWin); wrefresh(textWin); }
int SCTP_getAssocStatus(unsigned int associationID, SCTP_AssociationStatus* status) { int result; if ((result = sctp_getAssocStatus(associationID, status)) != SCTP_SUCCESS) { if (result == SCTP_LIBRARY_NOT_INITIALIZED) { fprintf(stderr, "sctp_getAssocStatus: library not initialized.\n"); } else if (result == SCTP_ASSOC_NOT_FOUND) { fprintf(stderr, "sctp_getAssocStatus: association not found.\n"); } else if (result == SCTP_PARAMETER_PROBLEM) { fprintf(stderr, "sctp_getAssocStatus: parameter problem (NULL pointer ?)\n"); } else { fprintf(stderr, "sctp_getAssocStatus: unknown value (%i) returned.\n", result); } fflush(stderr); } return result; }
void networkStatusChangeNotif(unsigned int assocID, short destAddrIndex, unsigned short newState, void* ulpDataPtr) { SCTP_AssociationStatus assocStatus; SCTP_PathStatus pathStatus; unsigned short pathID; sctp_getPathStatus(assocID, destAddrIndex , &pathStatus); sprintf(statusInfo, " Association ID =%-8x: Network status change: path %u (towards %s) is now %s\n", assocID, destAddrIndex, pathStatus.destinationAddress, pathStateName(newState)); waddstr(statusWin,statusInfo); wrefresh(statusWin); /* if the primary path has become inactive */ if ((newState == SCTP_PATH_UNREACHABLE) && (destAddrIndex == sctp_getPrimary(assocID))) { sctp_getAssocStatus(assocID, &assocStatus); for (pathID=0; pathID < assocStatus.numberOfAddresses; pathID++) { sctp_getPathStatus(assocID, pathID, &pathStatus); if (pathStatus.state == SCTP_PATH_OK) { break; } } /* and use it */ if (pathID < assocStatus.numberOfAddresses) { sctp_setPrimary(assocID, pathID); } } /* Display functions */ ncurses_display_AssocStatus(assocID); displayPathDetails = 0; ncurses_display_PathStatus(assocID); }
void stdinCallback(int fd, short int revents, short int* gotEvents, void* dummy) { /* This function gets triggered by the ncurses library upon *any* keystroke from user (for handling of Ctrl-C, see function finish()) */ int key; static unsigned short outstreamID = 0; SCTP_AssociationStatus assocStatus; /* call ncurses function wgetch() to read in one user keystroke. Did not use the wgetstr() function because it blocks until the user# terminates with a end-of-line (return) key. This prevents the SCTP library from sending out heartbeats, as well as queuing other callbacks waiting for this potentially long function to terminate. */ key = wgetch(textWin); switch (key) { case ERR: sctp_shutdown(associationID); endwin(); break; /* ascii code for return key is 13 */ case 13: case KEY_ENTER: buffer[bufCount++]='\n'; buffer[bufCount++]=0; /* Increment the Stream ID by 1 everytime data is sent, if stream ID = largest stream ID assigned, reset stream ID to 0 */ if (outstreamID == statusUpdate.noOfOutStreams) outstreamID = 0; sctp_send(associationID, outstreamID, (unsigned char *)buffer, strlen(buffer), SCTP_GENERIC_PAYLOAD_PROTOCOL_ID, SCTP_USE_PRIMARY, SCTP_NO_CONTEXT, SCTP_INFINITE_LIFETIME, SCTP_ORDERED_DELIVERY, SCTP_BUNDLING_DISABLED); /* Update the Outstream ID list in Monitor tool structure */ if (statusUpdate.OutstreamIDList[outstreamID] == -1) statusUpdate.OutstreamIDList[outstreamID] = outstreamID; /* Update the current position of OutstreamIDList array */ currOutstreamID = outstreamID; /* update the display */ ncurses_display_AssocStatus(associationID); outstreamID ++; waddch(textWin,'\n'); wrefresh(textWin); bufCount=0; break; case KEY_BACKSPACE: displayPathDetails = 0; ncurses_display_PathStatus(associationID); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* ascii code for key '0' is 48, key '1' is 49 and so fro..... therefore, key - 48 will return the value of the Path ID chosen */ chosenPath = key - 48; displayPathDetails = 1; sctp_getAssocStatus(associationID,&assocStatus); if (chosenPath < assocStatus.numberOfAddresses) ncurses_display_PathStatus(associationID); break; case KEY_RESIZE: endwin(); initializecurses(); wrefresh(statusWin); /* Display Functions*/ ncurses_display_AssocStatus(associationID); ncurses_display_PathStatus(associationID); break; default: if (bufCount<SCTP_MAXIMUM_DATA_LENGTH); { buffer[bufCount++]= key; waddch(textWin, key); wrefresh(textWin); } } }
/* This function reads the input from the parameters of the SCTP_PathStatus structure and displays the data on a window of ncurses. */ void ncurses_display_PathStatus(unsigned int assocID) { SCTP_AssociationStatus assocStatus; SCTP_PathStatus pathStatus; unsigned short pathID; unsigned int Rto[SCTP_MAX_NUM_ADDRESSES], HB_Interval[SCTP_MAX_NUM_ADDRESSES]; unsigned int SRTT[SCTP_MAX_NUM_ADDRESSES],RTTVar[SCTP_MAX_NUM_ADDRESSES]; unsigned int SlowStThres[SCTP_MAX_NUM_ADDRESSES], PartBytesAck[SCTP_MAX_NUM_ADDRESSES]; unsigned int CongestWin[SCTP_MAX_NUM_ADDRESSES],CongestWin2[SCTP_MAX_NUM_ADDRESSES]; unsigned int MTU[SCTP_MAX_NUM_ADDRESSES], OutBytesPerAddr[SCTP_MAX_NUM_ADDRESSES]; short State[SCTP_MAX_NUM_ADDRESSES]; char destaddr[SCTP_MAX_NUM_ADDRESSES][SCTP_MAX_IP_LEN]; unsigned char IPTos[SCTP_MAX_NUM_ADDRESSES]; wclear(pathWin); wrefresh(pathWin); sctp_getAssocStatus(assocID, &assocStatus); for (pathID=0; pathID < assocStatus.numberOfAddresses; pathID++) { sctp_getPathStatus(assocID, pathID, &pathStatus); strcpy((char *)destaddr[pathID], (const char *)pathStatus.destinationAddress); State[pathID] = pathStatus.state; Rto[pathID] = pathStatus.rto; HB_Interval[pathID] = pathStatus.heartbeatIntervall; SRTT[pathID] = pathStatus.srtt; RTTVar[pathID] = pathStatus.rttvar; SlowStThres[pathID] = pathStatus.ssthresh; PartBytesAck[pathID] = pathStatus.partialBytesAcked; CongestWin[pathID] = pathStatus.cwnd; CongestWin2[pathID] = pathStatus.cwnd2; MTU[pathID] = pathStatus.mtu; OutBytesPerAddr[pathID] = pathStatus.outstandingBytesPerAddress; IPTos[pathID] = pathStatus.ipTos; if (displayPathDetails == 0) { /* Check if the current path is the primary path */ if (pathID == sctp_getPrimary(assocID)) { sprintf(pathInfo," Primary Path ID : %d, state of path : %s\n", pathID, pathStateName(State[pathID])); waddstr(pathWin,pathInfo); wrefresh(pathWin); } else { sprintf(pathInfo," Path ID : %d, state of path : %s\n", pathID, pathStateName(State[pathID])); waddstr(pathWin,pathInfo); wrefresh(pathWin); } } else if (displayPathDetails == 1) { mvwaddstr(pathWin,0,0,"[Hit Backspace to return to main menu]\n"); wrefresh(pathWin); if (pathID == chosenPath) { sprintf(pathInfo,"\n Path ID : %d, State of path : %s\t\t Destination address : %s\n Heartbeat Interval : %-8u\t\t Retransmisson time(msecs) : %-8d\n Smooth Round Trip time(msecs) : %-8d\t Round Trip time Variations(msecs) : %-8d\n Slow start threshold : %-8d\t\t Congestion Window Size : %-8d\n Outstanding Bytes per Address : %-8d\t Congestion Window Size 2 : %-8d\n Partial bytes acknowledge : %-8d\t\t IP type of service : %x\n MTU : %d bytes\n\n", pathID, pathStateName(State[pathID]), destaddr[pathID],HB_Interval[pathID],Rto[pathID], SRTT[pathID],RTTVar[pathID],SlowStThres[pathID],CongestWin[pathID], OutBytesPerAddr[pathID], CongestWin2[pathID],PartBytesAck[pathID], IPTos[pathID],MTU[pathID]); waddstr(pathWin,pathInfo); wrefresh(pathWin); } } } wrefresh(textWin); displayPathDetails = 0; }