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 periodicRefreshFunction(unsigned int timerID, void *parameter1, void *parameter2) { /* Display the primary path details by default when data arrive */ displayPathDetails = 1; chosenPath = sctp_getPrimary(associationID); ncurses_display_PathStatus(associationID); sctp_startTimer(deltaT/1000, (deltaT%1000)*1000, periodicRefreshFunction, NULL, NULL); }
short SCTP_getPrimary(unsigned int associationID) { int result; if ((result = sctp_getPrimary(associationID)) < 0) { fprintf(stderr, "sctp_setPrimary: error value (%i) returned.\n", result); fflush(stderr); } return result; }
void getDestinationIPaddr(char paddr[SCTP_MAX_IP_LEN]) /*This routine copies the IP address of the primary path into an array paddr */ { SCTP_PathStatus pathStatus; int i, pathID; pathID = sctp_getPrimary(associationID); sctp_getPathStatus(associationID, pathID, &pathStatus); strcpy((char *)paddr, (const char *)pathStatus.destinationAddress); /* refreshes the ncurses window with the new IP address */ mvwaddstr(peerWinStatus, 0, 0, paddr); for (i=strlen(paddr);i<COLS-3;i++) mvwaddch(peerWinStatus,0,i,'-'); wrefresh(peerWinStatus); wrefresh(statusWin); }
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 dataArriveNotif(unsigned int assocID, unsigned short streamID, unsigned int len, unsigned short streamSN,unsigned int TSN, unsigned int protoID, unsigned int unordered, void* ulpDataPtr) { char chunk[SCTP_MAXIMUM_DATA_LENGTH + 1]; unsigned int length; int i; unsigned int InstreamID_position = 0; unsigned int tsn; unsigned short ssn; sprintf(statusInfo, " Association ID =%-8x: Data arrived (%u bytes on stream %u, %s)\n", assocID, len, streamID, (unordered==SCTP_ORDERED_DELIVERY)?"ordered":"unordered"); waddstr(statusWin,statusInfo); wrefresh(statusWin); /* read it */ length = SCTP_MAXIMUM_DATA_LENGTH; sctp_receive(assocID, streamID, (unsigned char *)chunk, &length, &ssn, &tsn, SCTP_MSG_DEFAULT); chunk[length]=0; /* and display it */ sprintf(receivedInfo, " Data received : %s", chunk); waddstr(receivedWin,receivedInfo); wrefresh(receivedWin); /* Stores the stream Id into the structure statusUpdate each time a data arrives */ for (i=0; i <statusUpdate.noOfInStreams; i++) { if (statusUpdate.InstreamIDList[i] == -1) { statusUpdate.InstreamIDList[i] = streamID; InstreamID_position = i; } else if (statusUpdate.InstreamIDList[i] != -1 && statusUpdate.InstreamIDList[i] != streamID) { statusUpdate.InstreamIDList[i] = streamID; InstreamID_position = i; } else if (statusUpdate.InstreamIDList[i] == streamID) { InstreamID_position = i; } } /* Update the current position of the InstreamIDList array */ currInstreamID = InstreamID_position; /* Display the Association details */ ncurses_display_AssocStatus(assocID); if (!periodicRefresh) { /* Display the primary path details by default when data arrive */ displayPathDetails = 1; chosenPath = sctp_getPrimary(assocID); ncurses_display_PathStatus(assocID); } }
/* 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; }