/************************************************** Author: Jeff Pierce, wd4nmq Version 0.5 Beta REVISIONS: 0.5 Beta : 12/25/02 fixed a bug that allows logon's to latest server code 0.3 Beta : as suggested by Ken Adkisson, WB4FAY I made location a define also. WARNING: YOU MUST PUT YOUR PASSWORD, CALLSIGN AND LOCATION IN THE #define'S BELOW!!! This is test program to access the Amateur Radio iLink servers written by Graeme, M0CSH. THIS IS NOT A FULL BLOWN ILINK CLIENT PROGRAM!!!! It is program intended only to test out the accessing of the iLink servers via a sytem other than a Windows OS on the TCP 5200 port. This program was developed after using network sniffing tools to determine how the iLink client or sysop apps: 1. Logged on 2. Logged off 3. Got other station's information, including IP address 4. Informed server when it is and isn't busy. This program can do all of the above. Now on to discovering what is going on between connecting stations on UPD ports 5198 and 5199. iLink must be made to run on OS's other than Windows, especially the sysop version. Windows is way to un-stable to run ANY unattended app. Especially one that controls a radio. Many sysops are already reporting Windows crashes. And quite a number leaving the radio keyed!!! So, until Graeme, m0csh sees fit to release the protocols for other developements, my work will continue. Again, this code is rough. I can see areas of improvement, especially in error catching and recovery and not hard coding some station data. But, this is only a program for testing out the The underlying iLink protocols: The Answer Is Out There! ******************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include /********************* WARNING: YOU MUST PUT YOUR PASSWORD, CALLSIGN AND LOCATION HERE LEAVING THE "'s INTACT *********************/ #define PASSWORD "PASSWORD" #define CALLSIGN "CALLSIGN" // Put some lower case letters in location #define LOCATION "Location" #define MAXCALL 15 #define MAXDATA 45 #define MAXID 7 #define MAXIP 20 struct stationData { char call[MAXCALL]; char data[MAXDATA]; char id[MAXID]; char ip[MAXIP]; }; struct entry { struct stationData *station; struct entry *next; }; struct entry *addEntryList(struct entry *, struct stationData *); struct entry *flushEntryList(struct entry *); int printList(struct entry *); int z; char *srvr_addr = NULL; // struct sockaddr_in adr_srvr;/* AF_INET */ // int len_inet; /* length */ // int s; /* Socket */ struct servent *sp; /* Service entry */ char dtbuf[128]; /* Date/Time info */ struct hostent *hp; struct stationData *station; struct entry *linkHead, *repeaterHead, *confHead, *stationHead; struct entry *messageHead; /* * This function reports the error and * exits back to the shell : */ static void bail(const char *on_what) { fputs(strerror(errno),stderr); fputs(": ",stderr); fputs(on_what,stderr); fputc('\n',stderr); exit(1); } /* * This function is involked when a ctrl-C is * entered from the keyboard to do clean up. * Free all allocated memory, etc. */ void ctrlC(int sig){ printf("\nReceived a crtl-C, shutting down.\n"); flushEntryList(linkHead); flushEntryList(repeaterHead); flushEntryList(confHead); flushEntryList(stationHead); flushEntryList(messageHead); exit(1); } /* * Now the main program loop */ int main(int argc,char **argv) { int quit = 0; char command[10]; (void) signal(SIGINT, ctrlC); station = NULL; linkHead = NULL; repeaterHead = NULL; confHead = NULL; stationHead = NULL; /* * Use a server address from the command * line, if one has been provided. * Otherwise, this program will default * to using the arbitrary address * 127.0.0.1 : */ if ( argc >= 2 ) { /* Addr on cmdline: */ srvr_addr = argv[1]; hp = gethostbyname(srvr_addr); if(hp){ srvr_addr = inet_ntoa(*(struct in_addr *)hp->h_addr_list[0]); printf("IP address for %s is %s..\n", argv[1], inet_ntoa(*(struct in_addr *)hp->h_addr_list[0])); printf("IP address for %s is %s..\n", argv[1], srvr_addr); } } else { /* Use default address: */ srvr_addr = "127.0.0.1"; } printf(" Entry size = %d.\n", sizeof(struct entry)); while(!quit){ printf("\n1 : Log on to server, also go to ON from BUSY\n"); printf("2 : Log off of server\n"); printf("3 : Get Calls\n"); printf("4 : Make busy\n"); printf("5 : Print stations\n"); printf("6 : Print link stations\n"); printf("7 : Print repeater stations\n"); printf("8 : Print conference servers\n"); printf("9 : Print messages\n"); printf("Q : Quit\n"); printf("Enter command: "); gets(command); if(toupper(command[0]) == 'Q') quit = 1; else { switch(atoi(command)){ case 1 : sendLogon(); break; case 2 : sendLogoff(); break; case 3 : getCalls(); break; case 4 : makeBusy(); break; case 5 : printList(stationHead); break; case 6 : printList(linkHead); break; case 7 : printList(repeaterHead); break; case 8 : printList(confHead); break; case 9 : printList(messageHead); break; } } } flushEntryList(stationHead); flushEntryList(linkHead); flushEntryList(repeaterHead); flushEntryList(confHead); return 0; } /************************************/ int sendLogon(void){ struct tm *tm_ptr; time_t theTime; char logTime[6]; unsigned char sendBuf[50], recvBuf[50]; int i, s, z, result; /* Now send the 'l' command */ s = openSocket(srvr_addr); printf("Socket = %d.\n", s); printf("Send the 'l' command.\n"); memset(sendBuf, 0x6c, 1); result = write(s, sendBuf, 1); printf("Wrote %d bytes.\n", result); /* Get the local time */ (void) time(&theTime); tm_ptr = localtime(&theTime); strftime(logTime, 6, "%H:%M", tm_ptr); strcpy(sendBuf, CALLSIGN); strcat(sendBuf,"\254\254"); strcat(sendBuf, PASSWORD); strcat(sendBuf, "\015ONLINE3.38("); strcat(sendBuf, logTime); strcat(sendBuf, ")\015"); strcat(sendBuf,LOCATION); strcat(sendBuf,"\015"); for(i=0;icall, MAXCALL, rx); station->call[strlen(station->call)-1] = 0x00; fgets(station->data, MAXDATA, rx); station->data[strlen(station->data)-1] = 0x00; fgets(station->id, MAXID, rx); station->id[strlen(station->id)-1] = 0x00; fgets(station->ip, MAXIP, rx); station->ip[strlen(station->ip)-1] = 0x00; printf("%-9s%-39s%6s %s\n", station->call, station->data, station->id, station->ip); if(strstr(station->call, "-L")) linkHead = addEntryList(linkHead, station); else if(strstr(station->call, "-R")) repeaterHead = addEntryList(repeaterHead, station); else if(strstr(station->call, "*")) confHead = addEntryList(confHead, station); else if(strlen(station->call) == 1) messageHead = addEntryList(messageHead, station); else stationHead = addEntryList(stationHead, station); // if(i % 10 == 0) // getchar(); } printf("There are %d stations online.\n", numRecs); fclose(tx); fclose(rx); } /******** Flush entry list *************/ struct entry *flushEntryList(struct entry *list){ struct entry *temp; int counter; if(list == NULL) return(0); counter = 0; do{ counter++; temp = list->next; if(list->station != NULL) free(list->station); free(list); list = temp; }while(list != NULL); return(NULL); } /******* Add to entry list ***********/ struct entry *addEntryList(struct entry *list, struct stationData *station){ struct entry *next, *previous, *temp; if(list == NULL){ list = malloc(sizeof (struct entry)); if(list != NULL){ list->station = station; list->next = NULL; } return list; } previous = list; while(previous->next != NULL) previous = previous->next; temp= malloc(sizeof (struct entry)); if(temp == NULL){ perror(" Add entry malloc "); flushEntryList(list); return(NULL); } temp->station = station; temp->next = NULL; previous->next = temp; return(list); } /********* Print the list of pointers *****/ struct entry printPointers(struct entry *list){ struct entry *temp; temp = list; do{ printf("Pointer = %p.\n", temp); temp = temp->next; }while(temp != NULL); } /*********** Print stations list **********/ int printList(struct entry *list){ int counter; counter = 0; while(list != NULL){ printf("%-9s%-39s%6s %s\n", (list->station)->call, (list->station)->data, (list->station)->id, (list->station)->ip); list = list->next; counter++; if(counter % 10 == 0){ printf("Hit return to continue."); getchar(); } } return(counter); }