#pragma module ACC_DUMP "ACC_DUMP-1-A" /* ** File name: ACC_DUMP ** Product: TCPware for VMS ** Version: V5.5 ** Edit level: 3 ** ** Copyright (c) 2000, 2001 by ** Process Software ** Framingham, Massachusetts ** ** This software is furnished under a license for use on a ** single computer system and may be copied only with the ** inclusion of the above copyright notice. This software, or ** any other copies thereof, may not be provided or otherwise ** made available to any other person except for use on such ** system and to one who agrees to these license terms. Title ** to and ownership of the software shall at all times remain ** in Process Software's name. ** ** The information in this document is subject to change ** without notice and should not be construed as a commitment ** by Process Software. Process Software assumes no ** responsibility for any errors that may appear in this ** document. ** ** Abstract: ** This program dumps the accounting file that can be written ** by the ACC_LISTENER progrm ** ** ** ** Author: Richard Whalen ** Date: September, 2000 ** ** 16-Feb-2001 RVW Edit 2 ** Update for changes in format in SMTP records. ** ** 12-Mar-2001 RVW Edit 3 ** Add checks for long enough records (especially SMTP) ** ** 2-MAR-2002 RRL Some redesign. ** */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include #include #include #include #include "accounting.h" #define INIT_SDESC(dsc, len, ptr) {(dsc).dsc$b_dtype = DSC$K_DTYPE_T;\ (dsc).dsc$b_class = DSC$K_CLASS_S; (dsc).dsc$w_length = (short) (len);\ (dsc).dsc$a_pointer = (ptr);} #define MAX_ACCNTNG_MSG 4096 char accounting_record [MAX_ACCNTNG_MSG]; struct FAB Fab; struct RAB Rab; /* ** ** CLI$ Declaration stuff ** */ extern void *ACC_DUMP; $DESCRIPTOR(p_inpfile, "INPUTFILE"); $DESCRIPTOR(q_since, "SINCE"); $DESCRIPTOR(q_before, "BEFORE"); static void dump_ftp_record(struct FTPaccounting_data *entry, int RecordSize) { if (RecordSize < sizeof(struct FTPaccounting_data)) { printf("undersized FTP record\n"); return; } if (entry->header.type == 'C') printf("FTP Client "); else if (entry->header.type == 'S') printf("FTP Server "); else printf("FTP Unknown "); printf("reported from %s ", inet_ntoa(entry->header.reporterIP)); printf("from a session with %s, \n", inet_ntoa(entry->partnerIP)); format_time(entry->start_time); printf("Starting at %s ", msgbuf); format_time(entry->end_time); printf(" Ending at %s\n", msgbuf); entry->user[12] = 0; printf(" User %s\n", entry->user); printf(" %d files sent, %d KBytes sent, %d files received, %d KBytes received\n\n", entry->filessent, entry->datasent, entry->filesrecv, entry->datarecv); } static void dump_smtp_record(struct SMTPaccounting_data *entry, int RecordSize) { if (RecordSize < sizeof(struct SMTPaccounting_data)) { printf("undersized SMTP record\n"); return; } if (entry->header.type == 'N') printf("SMTP Network delivery "); else if (entry->header.type == 'L') printf("SMTP Local delivery "); else if (entry->header.type == 'F') printf("SMTP Forwarded message "); else if (entry->header.type == 'R') printf("SMTP Returned message "); else if (entry->header.type == 'D') printf("SMTP Delivery Receipt sent "); else if (entry->header.type == 'Q') printf("SMTP message requeued "); else if (entry->header.type == 'J') printf("SMTP message rejected "); else printf("SMTP Unknown "); format_time(entry->date); printf("reported from %s on %s ", inet_ntoa(entry->header.reporterIP), msgbuf); if (RecordSize < (sizeof(struct SMTPaccounting_data) + entry->from_str_size + 1)) { printf("\nrecord too short to contain valid user info\n\n"); return; } printf("%s sent %d bytes\n", entry->from_to_str, entry->msg_size); if (RecordSize < (sizeof(struct SMTPaccounting_data) + entry->from_str_size + entry->to_str_size + 2)) { printf("to information missing\n"); return; } printf("to %s ", &entry->from_to_str[entry->from_str_size + 1]); if (RecordSize < (sizeof(struct SMTPaccounting_data) + entry->from_str_size + entry->to_str_size + entry->partner_str_size + 3)) { printf(" Via information not present\n"); return; } printf("via %s\n\n", &entry->from_to_str[entry->from_str_size + 1 + entry->to_str_size + 1]); } int main (void) { int status,since[2],before[2],sz,smtp,ftp,records; char buf[4096]; struct dsc$descriptor junk; struct accountingPDU *entry = (struct accountingPDU *)&buf; /* ** Open an accounting file */ INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&p_inpfile,&junk,&sz))) ) return status; junk.dsc$w_length = sz; fab = cc$rms_fab; fab.fab$b_fac = FAB$M_GET; fab.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT; fab.fab$l_fna = junk.dsc$a_pointer; fab.fab$b_fns = junk.dsc$w_length; fab.fab$v_nil = fab.fab$v_nlk = 1; if ( !(1 & (status = sys$open (&dbsrcfab))) ) return status; rab = cc$rms_rab; rab.rab$l_fab = &fab; if ( !(1 & (status = sys$connect (&dbsrcrab))) ) return status; rab.rab$l_ubf = buf; rab.rab$w_usz = sizeof(buf); /* ** Is there a /SINCE option ? */ if ( CLI$_PRESENT == (status = cli$present (&q_since))) ) { INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&q_since,&junk,&sz))) ) return status; junk.dsc$w_length = sz; if ( !(1 & (status = lib$convert_date_string(&junk,&since,0,0,0,0))) ) return status; } else { since [ 0 ] = since [ 1 ] = 0; } /* ** Is there a /BEFORE option ? */ if ( CLI$_PRESENT == (status = cli$present (&q_before))) ) { INIT_SDESC(junk,sizeof(buf),buf); if ( !(1 & (status = cli$get_value(&q_before,&junk,&sz))) ) return status; junk.dsc$w_length = sz; if ( !(1 & (status = lib$convert_date_string(&junk,&before,0,0,0,0))) ) return status; } else { before [ 0 ] = before [ 1 ] = -1; } /* ** Get record selection criterias */ if ( CLI$_PRESENT == cli$present (&q_type) ) { INIT_SDESC(junk,sizeof(buf),buf); while (CLI$_ABSENT != (status = cli$get_value(&q_accept_id,&junk,&sz)) ) { if ( junk.dsc$a_pointer == 'F' ) ftp |= 1; if ( junk.dsc$a_pointer == 'S' ) smtp |= 1; } } else { smtp = ftp = 1; } /* ** Start reading and processing recods */ for (records = 0;1 & (status = sys$get(&rab));records++) { if ( rab.rab$w_rsz < sizeof(struct accountingPDU) ) { printf("undersized record\n"); continue; } if (entry->port == 21) dump_ftp_record((struct FTPaccounting_data *)entry, Rab.rab$w_rsz); else if (entry->port == 25) dump_smtp_record((struct SMTPaccounting_data *)entry, Rab.rab$w_rsz); } }