/* Mlisten -- Kevin Almeroth */ /* Release Code 0401970683 */ /* The Parse_SDR_Packet proc is based on code written by: */ /* Mark Handley (M.Handley@cs.ucl.ac.uk) */ #include #include #include #include #include #include #include #include #include #ifdef GUI #include #include #endif #ifdef SOLARIS #define bcopy(s,d,l) (memmove((void *)d,(void *)s,(size_t)l)) #define bzero(s,l) (memset((void *)s,0,(size_t)l)) #define bcmp(s1,s2,l) (memcmp((void *)s1,(void *)s2,(size_t)l)) #endif #ifdef GUI extern char tcl_tk[]; extern char TCL_Startup[]; Tcl_Interp *interp; Tk_Window tkMainWin; #endif #define SD_MULTICAST_IP "224.2.127.255" #define SD_UDP_PORT 9876 #define SDR_MULTICAST_IP "224.2.127.254" #define SDR_UDP_PORT 9875 #define MAX_ACTIVE_SESSIONS 256 #define FILE_NAME_SIZE 80 #define NAME_LENGTH 200 #define ADDRESS_LENGTH 60 #define TIME_LENGTH 12 #define HEADER_DISPLAY_INTERVAL 40 #define TCL_DATA_DISPLAY_INCREMENT 125 #define TCL_CONTROL_DISPLAY_INCREMENT 25 #define MEMBER_TIMEOUT 180 #define SESSION_TIMEOUT 30 /* x times MEMBER_TIMEOUT */ #define TRANSMITTER_TYPE 84 #define RECEIVER_TYPE 82 #define SESSION_TYPE 77 struct sd_header { u_long unknown1; u_long src; u_short unknown2; char name[1]; }; struct sdr_header { u_long unknown1; u_long src; char name[1]; }; typedef struct { char full_address[ADDRESS_LENGTH]; int lifetime; struct tm *first_heard; long listener_packets; long data_packets; void *next_record; } member_record; typedef struct { char session_name[NAME_LENGTH]; char full_address[ADDRESS_LENGTH]; char media_type[NAME_LENGTH]; int display_member; int record_number; int data_socket; int control_socket; int lifetime; int total_num_transmit; int total_num_receive; int num_transmit; int num_receive; int ttl; long control_bandwidth; long total_control_packets; long data_bandwidth; long total_data_packets; struct tm *first_heard; struct tm *last_activity_time; member_record *transmitter_head; member_record *receiver_head; void *next_record; } session_record; int MASTER_TTL = 256; int COLLECT_AUDIO_DATA = 1; int COLLECT_VIDEO_DATA = 1; int COLLECT_WB_DATA = 1; int COLLECT_TEXT_DATA = 1; int COLLECT_DATA = 1; int COLLECT_CONTROL = 1; int COLLECT_PRIVATE = 1; session_record *socket_lookup[MAX_ACTIVE_SESSIONS+1]; int sd_socket,sdr_socket; int new_ttl; char new_session_name[NAME_LENGTH]; char new_media_type[NAME_LENGTH]; char new_full_address[ADDRESS_LENGTH]; char new_port_name[ADDRESS_LENGTH]; int new_port_number; int GLOBAL_RECORD_NUMBER = 0; time_t *current_time; time_t *future_time; int current_seconds; int packet_type; int SOCKET_LOOP; int MAX_OPEN_SOCKET = 0; session_record *SESSION_HEAD = NULL; fd_set active_socket_list; char display_time[TIME_LENGTH]; char display_date[TIME_LENGTH]; struct sockaddr_in senders_address; struct sockaddr_in *cast_pointer; int TOTAL_ACTIVE_SESSIONS = 0; int TOTAL_ACTIVE_TRANSMIT = 0; int TOTAL_ACTIVE_RECEIVE = 0; long TOTAL_PACKETS_RECEIVED = 0; int NEW_ACTIVE_SESSIONS = 0; int ENDED_ACTIVE_SESSIONS = 0; int NEW_ACTIVE_TRANSMIT = 0; int ENDED_ACTIVE_TRANSMIT = 0; int NEW_ACTIVE_RECEIVE = 0; int ENDED_ACTIVE_RECEIVE = 0; float SDR_RATE = 0.0; float CONTROL_RATE = 0.0; float DATA_RATE = 0.0; char File_Name[FILE_NAME_SIZE]; char File_To_Open[FILE_NAME_SIZE]; FILE *stat_file; FILE *done_file; FILE *active_file; char tcl_buf[100]; int dummy_length; float pkt_length; struct timeval timeout_val; fd_set ready_socket_list; int ready_sockets; int header_count = HEADER_DISPLAY_INTERVAL; int Session_Check = SESSION_TIMEOUT; int VERBOSE = 0; int STATUS = 1; int ALARM_ON = 0; char *message_buf; #ifdef GUI /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Process_Tcl() { int loop; session_record *scan_ptr = SESSION_HEAD; while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); while (scan_ptr != NULL) { if (scan_ptr->display_member > 0) { member_record *member_ptr = scan_ptr->receiver_head; sprintf(tcl_buf, "destroy .id$%d",scan_ptr->record_number); Tcl_VarEval(interp, tcl_buf, NULL); strftime(display_date, TIME_LENGTH, "%D", scan_ptr->first_heard); strftime(display_time, TIME_LENGTH, "%T", scan_ptr->first_heard); sprintf(tcl_buf, "dialog %d \"%s\" \"%s\" \"%s\" \"%s\"", scan_ptr->record_number,scan_ptr->session_name, display_date,display_time,scan_ptr->full_address); Tcl_VarEval(interp, tcl_buf, NULL); while(member_ptr != NULL) { strftime(display_date, TIME_LENGTH, "%D", member_ptr->first_heard); strftime(display_time, TIME_LENGTH, "%T", member_ptr->first_heard); sprintf(tcl_buf, "add_line %d \"%21s%13s%13s%11d%11d\n\"", scan_ptr->record_number, member_ptr->full_address, display_date, display_time, member_ptr->lifetime, (member_ptr->listener_packets + member_ptr->data_packets)); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); member_ptr = member_ptr->next_record; } scan_ptr->display_member = 0; } scan_ptr = scan_ptr->next_record; } while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ #endif /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Process_IO() { if (FD_ISSET(sdr_socket,&ready_socket_list) != 0) { TOTAL_PACKETS_RECEIVED++; Parse_SDR_Packet(); ready_sockets--; } for(SOCKET_LOOP=(sdr_socket+1); SOCKET_LOOP<=MAX_OPEN_SOCKET; SOCKET_LOOP++) { if (ready_sockets == 0) return; if (FD_ISSET(SOCKET_LOOP,&ready_socket_list) != 0) { session_record *temp_ptr = socket_lookup[SOCKET_LOOP]; dummy_length = sizeof(senders_address); pkt_length = (float)recvfrom(SOCKET_LOOP,message_buf,2048,0, (struct sockaddr*)&senders_address,&dummy_length); TOTAL_PACKETS_RECEIVED++; Parse_Member_Packet(temp_ptr); ready_sockets--; if (temp_ptr->data_socket == SOCKET_LOOP) DATA_RATE += pkt_length; else CONTROL_RATE += pkt_length; } } } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ int Open_Socket(ip_address,udp_port) char ip_address[ADDRESS_LENGTH]; int udp_port; { int sockfd; int on = 1; struct ip_mreq mreq; struct sockaddr_in sin; /* Max open sockets appears to be 63 */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return(-1); } if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, (char *)&on,sizeof(on)) < 0) { return(-1); } bzero((char *) &sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(ip_address); sin.sin_port = htons(udp_port); if (bind(sockfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { sin.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { close(sockfd); return(-1); } } mreq.imr_multiaddr.s_addr = inet_addr(ip_address); mreq.imr_interface.s_addr = INADDR_ANY; if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) == -1) { close(sockfd); return(-1); } /* if (setsockopt(sockfd, IPPROTO_IP, SO_KEEPALIVE,(char*)1,1) == -1) { close(sockfd); return(-1); } */ return(sockfd); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ session_record *Add_Session_Record() { session_record *new_ptr; char ip_address[ADDRESS_LENGTH]; new_ptr = (session_record*)malloc(sizeof(session_record)); new_ptr->lifetime = 0; new_ptr->data_bandwidth = 0; new_ptr->total_data_packets = 0; new_ptr->control_bandwidth = 0; new_ptr->total_control_packets = 0; new_ptr->data_socket = 0; new_ptr->control_socket = 0; new_ptr->total_num_transmit = 0; new_ptr->num_transmit = 0; new_ptr->total_num_receive = 0; new_ptr->num_receive = 0; new_ptr->transmitter_head = NULL; new_ptr->receiver_head = NULL; strcpy(new_ptr->session_name,new_session_name); strcpy(new_ptr->full_address,new_full_address); strcpy(new_ptr->media_type,new_media_type); new_ptr->ttl = new_ttl; bzero((char*)ip_address,ADDRESS_LENGTH); strncpy(ip_address,new_ptr->full_address, strspn(new_ptr->full_address,"0123456789.")); if (COLLECT_CONTROL == 1) { new_ptr->control_socket = Open_Socket(ip_address,(new_port_number+1)); if (new_ptr->control_socket < 0) { free(new_ptr); return(NULL); } } if (COLLECT_DATA == 1) { new_ptr->data_socket = Open_Socket(ip_address,new_port_number); if (new_ptr->data_socket < 0) { close(new_ptr->control_socket); free(new_ptr); return(NULL); } FD_SET(new_ptr->data_socket,&active_socket_list); socket_lookup[new_ptr->data_socket] = new_ptr; } if (COLLECT_CONTROL == 1) { FD_SET(new_ptr->control_socket,&active_socket_list); socket_lookup[new_ptr->control_socket] = new_ptr; } if (new_ptr->control_socket > MAX_OPEN_SOCKET) MAX_OPEN_SOCKET = new_ptr->control_socket; if (new_ptr->data_socket > MAX_OPEN_SOCKET) MAX_OPEN_SOCKET = new_ptr->data_socket; new_ptr->first_heard = (struct tm*)malloc(sizeof(struct tm)); new_ptr->last_activity_time = (struct tm*)malloc(sizeof(struct tm)); bcopy(localtime(current_time),new_ptr->first_heard,sizeof(struct tm)); bcopy(localtime(current_time),new_ptr->last_activity_time,sizeof(struct tm)); GLOBAL_RECORD_NUMBER++; TOTAL_ACTIVE_SESSIONS++; NEW_ACTIVE_SESSIONS++; new_ptr->record_number = GLOBAL_RECORD_NUMBER; new_ptr->display_member = 0; #ifdef GUI sprintf(tcl_buf, "global ack_display(%d)",GLOBAL_RECORD_NUMBER); Tcl_LinkVar(interp,tcl_buf,(char*)&new_ptr->display_member,TCL_LINK_INT); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "ack_display(%d)",GLOBAL_RECORD_NUMBER); Tcl_LinkVar(interp,tcl_buf,(char*)&new_ptr->display_member,TCL_LINK_INT); Process_Tcl(); #endif new_ptr->next_record = SESSION_HEAD; SESSION_HEAD = new_ptr; return(new_ptr); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ session_record *Check_For_Existing_Session() { session_record *scan_ptr = SESSION_HEAD; while (scan_ptr != NULL) { if (strcmp(scan_ptr->full_address,new_full_address) == 0) { bcopy(localtime(current_time), scan_ptr->last_activity_time,sizeof(struct tm)); scan_ptr->lifetime = mktime(localtime(current_time)) - mktime(scan_ptr->first_heard); return(scan_ptr); } scan_ptr = scan_ptr->next_record; } return(NULL); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Create_Mlisten_Entry() { if (strrchr(new_full_address,0x3a) != NULL) *(strrchr(new_full_address,0x3a)) = '\0'; strcat(new_full_address,":"); strcat(new_full_address,new_port_name); if (strcmp(new_media_type,"other") == 0) return; if ((strcmp(new_media_type,"audio") == 0) && (COLLECT_AUDIO_DATA == 0)) return; if ((strcmp(new_media_type,"video") == 0) && (COLLECT_VIDEO_DATA == 0)) return; if ((strcmp(new_media_type,"wb") == 0) && (COLLECT_WB_DATA == 0)) return; if ((strcmp(new_media_type,"text") == 0) && (COLLECT_TEXT_DATA == 0)) return; if (VERBOSE) { printf("Session: %s\n",new_session_name); printf("Media Type: %s\n",new_media_type); printf("Addr: %s\n",new_full_address); } Process_Session_Packet(); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Parse_SDR_Packet() { int length,need_to_process; char pak_buf[8192]; struct sdr_header *bp; char *data, *version, *cur, *end, *other, *session, *chan, *media; char *value; time(current_time); length = recv(sdr_socket, (char *) pak_buf, sizeof(pak_buf), 0); SDR_RATE += (float)length; strcpy(new_media_type,"none"); *new_full_address = '\0'; *new_port_name = '\0'; need_to_process = 0; bp = (struct sdr_header *) pak_buf; data = bp->name; if (strncmp(data, "v=", 2)!=0) { if (length == 0) return(-1); } else { version=data+2; if (strncmp(version, "0\n", 2)!=0) { return(-1); } length-=2; } if ((end=strchr(version, 0x0a)) == NULL) { return(-1); } *end++ = '\0'; length -= end - pak_buf; while (length > 0) { cur = end; switch (*cur) { case 's': /* session name */ session = end+2; if ((end=strchr(session, 0x0a)) == NULL) return; *end++ = '\0'; length -= end-cur; if (strlen(session) >= NAME_LENGTH) { length = 0; /* Find a way to stop processing the session */ break; } strcpy(new_session_name,session); if (COLLECT_PRIVATE == 0) { if (strstr(new_session_name,"rivate") != NULL) { if (STATUS) { fprintf(stat_file,"Did not add private session: \"%s\"!\n", new_session_name); strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-stats"); fclose(stat_file); stat_file = fopen(File_To_Open,"a"); } return; } } break; case 'c': /* print channel */ chan = end+2; if ((end=strchr(chan, 0x0a)) == NULL) return; *end++ = '\0'; length -= end-cur; sscanf(chan, "%*s %*s %s",new_full_address); /* printf("before: %s length: %d\n",new_full_address,strlen(new_full_address)); */ if (strchr(new_full_address,0x2F) == NULL) break; value = strchr(new_full_address,0x2F); value++; new_ttl = atoi(value); if (new_ttl > MASTER_TTL) { /* printf("Not recording session: ttl of %d threshold of %d\n", new_ttl, MASTER_TTL); */ return; } *(strchr(new_full_address,0x2F)) = '\0'; /* printf("after: %s length: %d\n",new_full_address,strlen(new_full_address)); */ if ((strcmp(new_media_type,"audio") == 0) || (strcmp(new_media_type,"video") == 0) || (strcmp(new_media_type,"wb") == 0) || (strcmp(new_media_type,"text") == 0)) { need_to_process = 0; Create_Mlisten_Entry(); } break; case 'm': if (need_to_process == 1) { need_to_process = 0; Create_Mlisten_Entry(); } media = end+2; if ((end=strchr(media, 0x0a)) == NULL) return; *end++ = '\0'; length -= end-cur; sscanf(media, "%*s %s %*s %*s",new_port_name); new_port_number = atoi(new_port_name); if (strstr(media,"audio") != NULL) { need_to_process = 1; strcpy(new_media_type,"audio"); if (strstr(media,"RTP") != NULL) { if ((new_port_number % 2) == 1) new_port_number--; } } else if (strstr(media,"video") != NULL) { need_to_process = 1; strcpy(new_media_type,"video"); } else if (strstr(media,"whiteboard") != NULL) { need_to_process = 1; strcpy(new_media_type,"wb"); } else if (strstr(media,"text") != NULL) { need_to_process = 1; strcpy(new_media_type,"text"); } else { strcpy(new_media_type,"other"); } break; default: /* other */ other = end+2; if ((end=strchr(other, 0x0a)) == NULL) return; *end++ = '\0'; length -= end-cur; break; } } if (need_to_process == 1) Create_Mlisten_Entry(); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Process_Session_Packet() { session_record *session_scanner; session_scanner = Check_For_Existing_Session(SESSION_HEAD); if (session_scanner == NULL) { session_scanner = Add_Session_Record(); if (session_scanner == NULL) { if (STATUS) { fprintf(stat_file,"Ran out of sockets: Cannot add session \"%s\" with address %s!\n", new_session_name,new_full_address); strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-stats"); fclose(stat_file); stat_file = fopen(File_To_Open,"a"); } return; } #ifdef GUI sprintf(tcl_buf, "set name %d",GLOBAL_RECORD_NUMBER); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set description(%d) \"%s\" ", GLOBAL_RECORD_NUMBER,new_session_name); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set type(%d) \"%s\" ", GLOBAL_RECORD_NUMBER,new_media_type); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set receivers(%d) 0",GLOBAL_RECORD_NUMBER); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set r_bandwidth(%d) 0.0",GLOBAL_RECORD_NUMBER); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set transmitters(%d) 0",GLOBAL_RECORD_NUMBER); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set t_bandwidth(%d) 0.0",GLOBAL_RECORD_NUMBER); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); Process_Tcl(); #endif } session_scanner->control_bandwidth += pkt_length; session_scanner->total_control_packets++; #ifdef GUI if ((session_scanner->total_control_packets % TCL_CONTROL_DISPLAY_INCREMENT) == 0) { sprintf(tcl_buf, "set control(%d) %d", session_scanner->record_number, session_scanner->total_control_packets); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); } #endif } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ member_record *Add_Member_Record(HEAD_POINTER,session_pointer) member_record *HEAD_POINTER; session_record *session_pointer; { member_record *new_ptr; new_ptr = (member_record*)malloc(sizeof(member_record)); new_ptr->first_heard = (struct tm*)malloc(sizeof(struct tm)); bcopy(localtime(current_time),new_ptr->first_heard,sizeof(struct tm)); new_ptr->lifetime = 0; new_ptr->listener_packets = 0; new_ptr->data_packets = 0; strcpy(new_ptr->full_address,new_full_address); if (packet_type == TRANSMITTER_TYPE) { session_pointer->num_transmit++; session_pointer->total_num_transmit++; #ifdef GUI sprintf(tcl_buf, "set transmitters(%d) %d", session_pointer->record_number, session_pointer->num_transmit); Tcl_VarEval(interp, tcl_buf, NULL); /* sprintf(tcl_buf, "set transmit_total(%d) %d", session_pointer->record_number, session_pointer->total_num_transmit); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); */ #endif new_ptr->next_record = session_pointer->transmitter_head; session_pointer->transmitter_head = new_ptr; TOTAL_ACTIVE_TRANSMIT++; NEW_ACTIVE_TRANSMIT++; } else { session_pointer->num_receive++; session_pointer->total_num_receive++; #ifdef GUI strftime(display_time, TIME_LENGTH, "%T",localtime(current_time)); sprintf(tcl_buf, "set current_time(-1) \"Current Time: %s\"", display_time); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set receivers(%d) %d", session_pointer->record_number, session_pointer->num_receive); Tcl_VarEval(interp, tcl_buf, NULL); /* sprintf(tcl_buf, "set receiver_total(%d) %d", session_pointer->record_number, session_pointer->total_num_receive); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); */ #endif new_ptr->next_record = session_pointer->receiver_head; session_pointer->receiver_head = new_ptr; TOTAL_ACTIVE_RECEIVE++; NEW_ACTIVE_RECEIVE++; } return(new_ptr); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ member_record *Process_Member_Packet(HEAD_POINTER) member_record *HEAD_POINTER; { member_record *scan_ptr = HEAD_POINTER; while (scan_ptr != NULL) { if (strcmp(scan_ptr->full_address,new_full_address) == 0) { scan_ptr->lifetime = mktime(localtime(current_time)) - mktime(scan_ptr->first_heard); return(scan_ptr); } scan_ptr = scan_ptr->next_record; } return(NULL); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Parse_Member_Packet(session_ptr) session_record *session_ptr; { member_record *HEAD_POINTER; member_record *record_scanner; time(current_time); bcopy(&senders_address,cast_pointer,sizeof(struct sockaddr_in)); strcpy(new_full_address,(char*)inet_ntoa(cast_pointer->sin_addr)); strcat(new_full_address,":"); sprintf(new_port_name,"%d",ntohs(cast_pointer->sin_port)); strcat(new_full_address,new_port_name); bcopy(localtime(current_time),session_ptr->last_activity_time,sizeof(struct tm)); session_ptr->lifetime = mktime(localtime(current_time)) - mktime(session_ptr->first_heard); if (session_ptr->data_socket == SOCKET_LOOP) { packet_type = TRANSMITTER_TYPE; HEAD_POINTER = session_ptr->transmitter_head; } else { packet_type = RECEIVER_TYPE; HEAD_POINTER = session_ptr->receiver_head; } record_scanner = Process_Member_Packet(HEAD_POINTER); if (record_scanner == NULL) { record_scanner = Add_Member_Record(HEAD_POINTER,session_ptr); } if (session_ptr->data_socket == SOCKET_LOOP) { record_scanner->data_packets++; session_ptr->data_bandwidth += pkt_length; session_ptr->total_data_packets++; if (VERBOSE) { strftime(display_date, TIME_LENGTH, "%D",record_scanner->first_heard); strftime(display_time, TIME_LENGTH, "%T",record_scanner->first_heard); printf("%c%22s%22s%9s%9s%7d%9d\n",packet_type, session_ptr->full_address, record_scanner->full_address, display_date, display_time, record_scanner->lifetime, record_scanner->data_packets); } } else { record_scanner->listener_packets++; session_ptr->control_bandwidth += pkt_length; session_ptr->total_control_packets++; #ifdef GUI if ((session_ptr->total_control_packets % TCL_CONTROL_DISPLAY_INCREMENT) == 0) { sprintf(tcl_buf, "set control(%d) %d", session_ptr->record_number, session_ptr->total_control_packets); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); } #endif } } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Check_For_Session_Departures() { session_record *session_scan1 = SESSION_HEAD; session_record *session_scan2 = SESSION_HEAD; int time_since; time(current_time); while (session_scan2 != NULL) { time_since = mktime(localtime(current_time))- mktime(session_scan2->last_activity_time); if (time_since > (SESSION_TIMEOUT*MEMBER_TIMEOUT)) { TOTAL_ACTIVE_SESSIONS--; ENDED_ACTIVE_SESSIONS++; /* Write record */ Write_Session_Record(session_scan2); #ifdef GUI sprintf(tcl_buf, "destroy .sessions.%d",session_scan2->record_number); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); #endif /* Check for any leftover records */ if (STATUS) { if (session_scan2->transmitter_head != NULL) { fprintf(stat_file,"Still transmitter(s) for %s.\n", session_scan2->session_name); } if (session_scan2->receiver_head != NULL) { fprintf(stat_file,"Still receiver(s) for %s.\n", session_scan2->session_name); } strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-stats"); fclose(stat_file); stat_file = fopen(File_To_Open,"a"); } /* Close sockets and clean up */ if (COLLECT_DATA == 1) { FD_CLR(session_scan2->data_socket,&active_socket_list); socket_lookup[session_scan2->data_socket] = NULL; close(session_scan2->data_socket); } if (COLLECT_CONTROL == 1) { FD_CLR(session_scan2->control_socket,&active_socket_list); socket_lookup[session_scan2->control_socket] = NULL; close(session_scan2->control_socket); } free(session_scan2->first_heard); free(session_scan2->last_activity_time); if (session_scan2 == SESSION_HEAD) { SESSION_HEAD = session_scan2->next_record; session_scan1 = session_scan2->next_record; free(session_scan2); session_scan2 = session_scan1; } else { session_scan1->next_record = session_scan2->next_record; free(session_scan2); session_scan2 = session_scan1->next_record; } } else { session_scan1 = session_scan2; session_scan2 = session_scan2->next_record; } } } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Check_For_Member_Departures() { session_record *session_scan = SESSION_HEAD; member_record *member_scan1; member_record *member_scan2; int time_since; time(current_time); current_seconds = mktime(localtime(current_time)); while (session_scan != NULL) { /* Check transmitter list */ member_scan1 = session_scan->transmitter_head; member_scan2 = session_scan->transmitter_head; packet_type = TRANSMITTER_TYPE; while (member_scan2 != NULL) { time_since = current_seconds - member_scan2->lifetime - mktime(member_scan2->first_heard); if (time_since > MEMBER_TIMEOUT) { TOTAL_ACTIVE_TRANSMIT--; ENDED_ACTIVE_TRANSMIT++; session_scan->num_transmit--; #ifdef GUI sprintf(tcl_buf, "set transmitters(%d) %d", session_scan->record_number,session_scan->num_transmit); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); #endif /* Write Record */ Write_Member_Record(session_scan,member_scan2); if (member_scan2 == session_scan->transmitter_head) { session_scan->transmitter_head = member_scan2->next_record; member_scan1 = member_scan2->next_record; free(member_scan2); member_scan2 = member_scan1; } else { member_scan1->next_record = member_scan2->next_record; free(member_scan2); member_scan2 = member_scan1->next_record; } } else { member_scan1 = member_scan2; member_scan2 = member_scan2->next_record; } } member_scan1 = session_scan->receiver_head; member_scan2 = session_scan->receiver_head; packet_type = RECEIVER_TYPE; while (member_scan2 != NULL) { time_since = current_seconds - member_scan2->lifetime - mktime(member_scan2->first_heard); if (time_since > MEMBER_TIMEOUT) { TOTAL_ACTIVE_RECEIVE--; ENDED_ACTIVE_RECEIVE++; session_scan->num_receive--; #ifdef GUI strftime(display_time, TIME_LENGTH, "%T",localtime(current_time)); sprintf(tcl_buf, "set current_time(-1) \"Current Time: %s\"", display_time); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); sprintf(tcl_buf, "set receivers(%d) %d", session_scan->record_number,session_scan->num_receive); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); #endif /* Write Record */ Write_Member_Record(session_scan,member_scan2); if (member_scan2 == session_scan->receiver_head) { session_scan->receiver_head = member_scan2->next_record; member_scan1 = member_scan2->next_record; free(member_scan2); member_scan2 = member_scan1; } else { member_scan1->next_record = member_scan2->next_record; free(member_scan2); member_scan2 = member_scan1->next_record; } } else { member_scan1 = member_scan2; member_scan2 = member_scan2->next_record; } } session_scan = session_scan->next_record; } if (STATUS) { session_record *sess_scan_ptr = SESSION_HEAD; if (header_count >= HEADER_DISPLAY_INTERVAL) { header_count = 0; fprintf(stat_file,"\n"); fprintf(stat_file," DATE TIME SESSIONS SENDERS "); fprintf(stat_file,"RECEIVERS PACKETS TRANSMIT RATE(Kb/s)\n"); fprintf(stat_file," New Tot New Tot "); fprintf(stat_file,"New Tot (10^6) Sdr Ctrl Data\n"); } header_count++; strftime(display_date, TIME_LENGTH, "%D",localtime(current_time)); strftime(display_time, TIME_LENGTH, "%T",localtime(current_time)); fprintf(stat_file,"%8s%9s%5d%5d%5d%4d%5d%6d%9.2f%7.1f%7.1f%8.1f\n", display_date,display_time, NEW_ACTIVE_SESSIONS,TOTAL_ACTIVE_SESSIONS, NEW_ACTIVE_TRANSMIT,TOTAL_ACTIVE_TRANSMIT, NEW_ACTIVE_RECEIVE,TOTAL_ACTIVE_RECEIVE, ((float)TOTAL_PACKETS_RECEIVED / (float)1000000), (SDR_RATE / 128.0 / (float)MEMBER_TIMEOUT), (CONTROL_RATE / 128.0 / (float)MEMBER_TIMEOUT), (DATA_RATE / 128.0 / (float)MEMBER_TIMEOUT)); #ifdef GUI while(sess_scan_ptr != NULL) { /* 128 is from (8 bits per byte) / (1024 bits per kilobit) */ sprintf(tcl_buf, "set r_bandwidth(%d) %2.2f", sess_scan_ptr->record_number, ((sess_scan_ptr->control_bandwidth) / 128.0 / (float)MEMBER_TIMEOUT)); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); sess_scan_ptr->control_bandwidth = 0; sprintf(tcl_buf, "set t_bandwidth(%d) %2.2f", sess_scan_ptr->record_number, ((sess_scan_ptr->data_bandwidth) / 128.0 / (float)MEMBER_TIMEOUT)); Tcl_VarEval(interp, tcl_buf, NULL); Process_Tcl(); sess_scan_ptr->data_bandwidth = 0; sess_scan_ptr = sess_scan_ptr->next_record; } #endif strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-stats"); fclose(stat_file); stat_file = fopen(File_To_Open,"a"); } NEW_ACTIVE_SESSIONS = 0; ENDED_ACTIVE_SESSIONS = 0; NEW_ACTIVE_TRANSMIT = 0; ENDED_ACTIVE_TRANSMIT = 0; NEW_ACTIVE_RECEIVE = 0; ENDED_ACTIVE_RECEIVE = 0; SDR_RATE = 0.0; CONTROL_RATE = 0.0; DATA_RATE = 0.0; Write_Active_Member_Records(); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ void handler(signum) int signum; { ALARM_ON = 1; } void Turn_On_Alarm() { ALARM_ON = 1; } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ main(argc,argv) int argc; char *argv[]; { char *display; int code; int loop; if (argc > 0) { for(loop=1; loop 1)) { strcpy(File_Name,argv[argc-1]); } else { printf("Data file not specified: "); printf("Using /tmp/mlisten\n"); strcpy(File_Name,"/tmp/mlisten"); printf("You could have used mlisten like this...\n"); printf("Usage: mlisten [-t xxx] [-nostats] [-verbose] [-noaudio] "); printf("[-novideo] [-nowb] [-notext] "); printf("[-nodata] [-nocontrol] [-noprivate] filename\n"); } current_time = (time_t*)malloc(sizeof(time_t)); future_time = (time_t*)malloc(sizeof(time_t)); cast_pointer = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); message_buf = (char*)malloc(2048); timeout_val.tv_sec = 1; timeout_val.tv_usec = 0; FD_ZERO(&active_socket_list); strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-done"); done_file = fopen(File_To_Open,"a"); strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-active"); active_file = fopen(File_To_Open,"w"); if (STATUS) { strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-stats"); stat_file = fopen(File_To_Open,"a"); } sdr_socket = Open_Socket(SDR_MULTICAST_IP,SDR_UDP_PORT); if (sdr_socket == -1) { printf("Could not bind to sdr socket.\n"); exit(-1); } FD_SET(sdr_socket,&active_socket_list); if (sdr_socket > MAX_OPEN_SOCKET) MAX_OPEN_SOCKET = sdr_socket; #ifdef GUI interp = Tcl_CreateInterp(); tkMainWin = Tk_CreateMainWindow(interp, display, "mlisten", "Mlisten"); code = Tcl_VarEval(interp, tcl_tk,NULL); code = Tcl_VarEval(interp, TCL_Startup,NULL); if (code != TCL_OK) { printf("Cannot get Tcl/Tk started.\n"); exit(-1); } Tk_CreateTimerHandler(1,(Tk_TimerProc*)Turn_On_Alarm,NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); #else signal(SIGALRM, handler); alarm(1); #endif while(1) { #ifdef GUI Process_Tcl(); #endif time(current_time); bcopy(&active_socket_list,&ready_socket_list,sizeof(struct fd_set)); if (ready_sockets = select(FD_SETSIZE,&ready_socket_list,0,0,&timeout_val) > 0) Process_IO(); if (ALARM_ON) { ALARM_ON = 0; Check_For_Member_Departures(); #ifdef GUI time(future_time); *future_time += MEMBER_TIMEOUT; strftime(display_time, TIME_LENGTH, "%T",localtime(future_time)); sprintf(tcl_buf, "set member_check(-1) \"Next Member Check: %s\"", display_time); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); strftime(display_time, TIME_LENGTH, "%T",localtime(current_time)); sprintf(tcl_buf, "set current_time(-1) \"Current Time: %s\"", display_time); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); #endif Session_Check++; if (Session_Check >= SESSION_TIMEOUT) { Check_For_Session_Departures(); Session_Check = 0; #ifdef GUI /* Set New Session Check Time */ time(future_time); *future_time += SESSION_TIMEOUT * MEMBER_TIMEOUT; strftime(display_time, TIME_LENGTH, "%T",localtime(future_time)); sprintf(tcl_buf, "set session_check(-1) \"Next Session Check: %s\"", display_time); Tcl_VarEval(interp, tcl_buf, NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); #endif } #ifdef GUI Tk_CreateTimerHandler((1000 * MEMBER_TIMEOUT), (Tk_TimerProc*)Turn_On_Alarm,NULL); while((Tk_DoOneEvent(TK_DONT_WAIT)) != 0); #else /* signal(SIGALRM, Turn_On_Alarm); */ signal(SIGALRM, handler); alarm(MEMBER_TIMEOUT); #endif } } } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Write_Session_Record(session_scan) session_record *session_scan; { char tmp_string[25]; strftime(display_date,TIME_LENGTH,"%D",session_scan->first_heard); strftime(display_time,TIME_LENGTH,"%T",session_scan->first_heard); packet_type = SESSION_TYPE; session_scan->session_name[29] = 0; fprintf(done_file,"%c %s %s %s %s %s\n",packet_type, session_scan->full_address, display_date, display_time, session_scan->media_type, session_scan->session_name); strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-done"); fclose(done_file); done_file = fopen(File_To_Open,"a"); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Write_Active_Member_Records() { session_record *session_scan = SESSION_HEAD; member_record *member_scan; char tmp[100]; strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-active"); fclose(active_file); active_file = fopen(File_To_Open,"w"); while (session_scan != NULL) { /* Write Session Record */ strftime(display_date,TIME_LENGTH,"%D",session_scan->first_heard); strftime(display_time,TIME_LENGTH,"%T",session_scan->first_heard); packet_type = SESSION_TYPE; strcpy(tmp,session_scan->session_name); tmp[29] = 0; fprintf(active_file,"\n%c %s %d %s %s %s %s\n",packet_type, session_scan->full_address, session_scan->ttl, display_date, display_time, session_scan->media_type, tmp); packet_type = TRANSMITTER_TYPE; member_scan = session_scan->transmitter_head; while (member_scan != NULL) { strftime(display_date,TIME_LENGTH,"%D",member_scan->first_heard); strftime(display_time,TIME_LENGTH,"%T",member_scan->first_heard); fprintf(active_file,"%c %s %s %s %s %d %d\n", packet_type, session_scan->full_address, member_scan->full_address, display_date, display_time, member_scan->lifetime, member_scan->data_packets); member_scan = member_scan->next_record; } packet_type = RECEIVER_TYPE; member_scan = session_scan->receiver_head; while (member_scan != NULL) { strftime(display_date,TIME_LENGTH,"%D",member_scan->first_heard); strftime(display_time,TIME_LENGTH,"%T",member_scan->first_heard); fprintf(active_file,"%c %s %s %s %s %d %d\n", packet_type, session_scan->full_address, member_scan->full_address, display_date, display_time, member_scan->lifetime, member_scan->listener_packets); member_scan = member_scan->next_record; } session_scan = session_scan->next_record; } strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-active"); /* fclose(active_file); sprintf(tmp,"cp %s /net/ht3/kevin/WWW/mbone/stats-file.txt",File_To_Open); system(tmp); active_file = fopen(File_To_Open,"a"); */ } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */ Write_Member_Record(session_scan,member_scan) session_record *session_scan; member_record *member_scan; { strftime(display_date,TIME_LENGTH,"%D",member_scan->first_heard); strftime(display_time,TIME_LENGTH,"%T",member_scan->first_heard); if (member_scan->lifetime == 0) member_scan->lifetime = 1; if (packet_type == TRANSMITTER_TYPE) { fprintf(done_file,"%c %s %s %s %s %d %d\n", packet_type, session_scan->full_address, member_scan->full_address, display_date, display_time, member_scan->lifetime, member_scan->data_packets); } else { fprintf(done_file,"%c %s %s %s %s %d %d\n", packet_type, session_scan->full_address, member_scan->full_address, display_date, display_time, member_scan->lifetime, member_scan->listener_packets); } strcpy(File_To_Open,File_Name); strcat(File_To_Open,"-done"); fclose(done_file); done_file = fopen(File_To_Open,"a"); } /* \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ */