/* This program reads the monitor output of a TNC-1 with DED proms, and writes the data from or to a particular callsign. The "header" lines are removed and as much as possible duplicate (retransmissions) are removed. The program cannot detect "lost" frames, and if a frame is lost, the next 6 frames will be detected as duplicates and not output. I use this program by leaving my TNC in monitor mode and copy the data to a file. Then, at the end of the day, I use this program to "spy" on my local mailbox server, looking for interesting files and QSTs that they have downloaded, thus saving my having to download then also. Currently, this program only understands the WA8DED monitor format, but any ambitious programmer could modify it to understand TAPR format or any other format. Bill Danielson, N6FQR */ /* #include "ctype.h" */ #include "stdio.h" char from[10], to[10], ctl[12], pid[10]; char lastframe[512], buffer[512], who[10]; char name[128]; int log = 0; int toside = 0; int fromexpected = 0; int toexpected = 0; int fromseq, toseq; int *expected, *seq; FILE *fp; char *lookfor(); main(argc, argv) int argc; char *argv[]; { char *c; /* Make sure program was called with correct number of arguments */ if (argc != 2) usage(); /* Convert argument to upper case...assume C routine "toupper" doesn't check for non-alpha characters (some don't!) */ c = name; while (*argv[1]) { if (isalpha(*argv[1])) *c++ = toupper(*argv[1]); else *c++ = *argv[1]; argv[1]++; } *c = '\0'; printf("------Spying on %s------\n\n", name); who[0] = '\0'; /* Get a line and process it */ while(gets(buffer)) { /* Look for "fm" at the beginning of the line to see if a control message */ if (buffer[0] == 'f' && buffer[1] == 'm' && buffer[2] == ' ') { /* If we have data in "lastframe", now is the time to see if it should be output */ if (log) { /* Strip off the extra newline at the end of the data */ lastframe[strlen(lastframe)-2] = '\0'; /* See if sequence number is the "next expected" one. If so output the frame, if not chuck it (hopefully it is a duplicate!) */ if (toside) { seq = &toseq; expected = &toexpected; } else { seq = &fromseq; expected = &fromexpected; } if (*seq == *expected) { printf("%s", lastframe); *expected = (*expected + 1) % 8; } } log = 0; lastframe[0] = '\0'; /* Scan the buffer. Assumes WA8DED ROMs in a TNC-1 */ /* Look for "fm XXXXXX to XXXXX" */ /* If we find something else, skip this line */ if (sscanf(buffer, "fm %s to %s", from, to) != 2) continue; /* Ok, next skip over the "fm XXXXXX to XXXXX" and look for "ctl" to skip over any repeater fields */ c = buffer + 8 + strlen(from) + strlen(to); c = lookfor(c, "ctl"); /* Next look for "ctl XXX pid XXX". If we find something else, skip this line */ if (sscanf(c, "ctl %s pid %s", ctl, pid) != 2) continue; /* Check if the control field indicates information field. If not, skip this line */ if (ctl[0] != 'I') continue; /* Check if either "to" or "from" callsign matches the callsign we are spying on. If not, skip this line */ if (!strcmp(from, name)) { fromseq = ctl[2] - '0'; /* Get sequence number */ log = 1; /* Flag to copy data to "lastframe" */ toside = 0; /* Match was on "from" callsign */ if (strcmp(to, who)) { /* Same connection as before? */ printf("\n\n------New connection with %s------\n\n", to); strcpy(who, to); /* Save callsign */ toexpected = 0; /* Guess at correct next-expected */ fromexpected = fromseq; /* Current is next-expected */ } } else if (!strcmp(to, name)) { toseq = ctl[2] - '0'; /* Get sequence number */ log = 1; /* Flag to copy data to "lastframe" */ toside = 1; /* Match was on "to" callsign */ if (strcmp(from, who)) { /* Same connection as before? */ printf("\n\n------New connection with %s------\n\n", from); strcpy(who, from); /* Save callsign */ fromexpected = 0; /* Guess at correct next-expected */ toexpected = toseq; /* Current is next expected */ } } } else { /* Not a "fm ..." line. */ /* If copying data, do it, else skip this line */ if (log) { strcat(lastframe, buffer); strcat(lastframe, "\n"); } } } } /* Look through a string "s", looking for the string "what". Returns new pointer into string "s" pointing to the start of the first occurance of string "what" */ char * lookfor(s, what) char *s; char *what; { int len = strlen(what); while (*s) { if (!strncmp(s, what, len)) return(s); else s++; } return(s); } usage() { fprintf(stderr, "usage: tncspy from-host\n"); fprintf(stderr, " reads a monitor file from standard input\n"); fprintf(stderr, " writes to standard output\n"); fprintf(stderr, "\n"); fprintf(stderr, "For example:\n"); fprintf(stderr, " tncspy N6IIU-1 n6iiu.log\n"); exit(1); }