Changeset 1143


Ignore:
Timestamp:
02/21/07 14:39:26 (6 years ago)
Author:
spa1
Message:

Updated tracereport to include all the work Josef has done

Location:
trunk/tools/tracereport
Files:
4 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/tracereport/Makefile.am

    r1141 r1143  
     1## Process this file with automake to produce Makefile.in 
     2 
     3## Created by Anjuta - will be overwritten 
     4## If you don't want it to overwrite it, 
     5##      Please disable it in the Anjuta project configuration 
     6 
     7man_MANS = tracereport.1 
     8EXTRA_DIST = $(man_MANS) 
     9include ../Makefile.tools 
    110bin_PROGRAMS = tracereport 
    2 man_MANS=tracereport.1 
    311 
    4 include ../Makefile.tools 
    5 tracereport_SOURCES = tracereport.c tracereport.h report.h \ 
    6                         contain.c contain.h \ 
    7                         ttl_report.c tos_report.c port_report.c error_report.c \ 
    8                         flow_report.c dir_report.c protocol_report.c 
     12tracereport_SOURCES = \ 
     13        tracereport.c\ 
     14        contain.c\ 
     15        dir_report.c\ 
     16        error_report.c\ 
     17        flow_report.c\ 
     18        port_report.c\ 
     19        protocol_report.c\ 
     20        tos_report.c\ 
     21        ttl_report.c\ 
     22        tcpopt_report.c\ 
     23        nlp_report.c\ 
     24        ecn_report.c\ 
     25        tcpsegment_report.c\ 
     26        contain.h\ 
     27        report.h\ 
     28        tracereport.h 
    929 
     30tracereport_LDFLAGS =  
     31 
     32tracereport_LDADD = \ 
     33         -ltrace 
     34 
  • trunk/tools/tracereport/dir_report.c

    r1125 r1143  
    55#include "libtrace.h" 
    66#include "tracereport.h" 
    7 #include "report.h" 
    87 
    98static uint64_t dir_bytes[8]; 
     
    1211void dir_per_packet(struct libtrace_packet_t *packet) 
    1312{ 
    14         if (trace_get_direction(packet)==~0U) 
     13        if (trace_get_direction(packet)==-1) 
    1514                return; 
    1615        dir_bytes[trace_get_direction(packet)]+=trace_get_wire_length(packet); 
  • trunk/tools/tracereport/flow_report.c

    r1093 r1143  
    77#include "tracereport.h" 
    88#include "contain.h" 
    9 #include "report.h" 
    109 
    1110static uint64_t flow_count=0; 
  • trunk/tools/tracereport/port_report.c

    r1093 r1143  
    88#include "tracereport.h" 
    99#include "contain.h" 
    10 #include "report.h" 
    1110 
    12 stat_t ports[256][65536]={{{0,0}}}; 
     11stat_t ports[4][256][65536]={{{{0,0}}}}; 
    1312char protn[256]={0}; 
     13static bool suppress[4] = {true,true,true,true}; 
    1414 
    1515void port_per_packet(struct libtrace_packet_t *packet) 
     
    1717        uint8_t proto; 
    1818        int port; 
    19  
     19        int dir = trace_get_direction(packet); 
     20        if(dir < 0 || dir > 1) 
     21                dir = 2; 
    2022        if(trace_get_transport(packet,&proto,NULL)==NULL)  
    2123                return; 
     
    2729                : trace_get_destination_port(packet); 
    2830 
    29         ports[proto][port].bytes+=trace_get_wire_length(packet); 
    30         ports[proto][port].count++; 
     31        ports[dir][proto][port].bytes+=trace_get_wire_length(packet); 
     32        ports[dir][proto][port].count++; 
    3133        protn[proto]=1; 
     34        suppress[dir] = false; 
    3235} 
    3336 
    34 static void port_port(int i,char *prot, int j) 
     37void port_suppress() 
     38{ 
     39        int i; 
     40        printf("%-20s","Direction:"); 
     41        //printf("%20s", " "); 
     42        for(i=0;i<4;i++){ 
     43                if(!suppress[i]){ 
     44                        switch(i){ 
     45                                case 0: 
     46                                        printf("\t%24s", "Outbound   "); 
     47                                        break; 
     48                                case 1: 
     49                                        printf("\t%24s", "Inbound   "); 
     50                                        break; 
     51                                case 2: 
     52                                        printf("\t%24s", "Undefined   "); 
     53                                        break; 
     54                                default: 
     55                                        break; 
     56                        } 
     57                } 
     58        } 
     59        printf("\n"); 
     60        printf("%-20s","Port"); 
     61        for(i=0;i<4;i++){ 
     62                if(!suppress[i]){ 
     63                        printf("\t%12s\t%12s", "bytes","packets"); 
     64                } 
     65        } 
     66        printf("\n"); 
     67} 
     68 
     69void port_port(int i,char *prot, int j) 
    3570{ 
    3671        struct servent *ent = getservbyport(htons(j),prot); 
    37         if(ent) 
    38                 printf("%20s:\t%12" PRIu64 "\t%12" PRIu64 "\n", 
    39                                 ent->s_name, 
    40                                 ports[i][j].bytes, 
    41                                 ports[i][j].count 
     72        int k; 
     73         
     74        if(ent){ 
     75                printf("%20s:",ent->s_name); 
     76                for(k=0;k<4;k++){ 
     77                        if (ports[k][i][j].count==0){ 
     78                                if(!suppress[k]) 
     79                                        printf("\t%24s"," "); 
     80                                continue; 
     81                        } 
     82                        printf("\t%12" PRIu64 "\t%12" PRIu64, 
     83                                ports[k][i][j].bytes, 
     84                                ports[k][i][j].count 
    4285                      ); 
    43         else 
    44                 printf("%20i:\t%12" PRIu64 "\t%12" PRIu64 "\n", 
    45                                 j, 
    46                                 ports[i][j].bytes, 
    47                                 ports[i][j].count 
     86                } 
     87        } 
     88        else{ 
     89                printf("%20i:",j); 
     90                for(k=0;k<4;k++){ 
     91                        if (ports[k][i][j].count==0){ 
     92                                if(!suppress[k]) 
     93                                        printf("\t%24s"," "); 
     94                                continue; 
     95                        } 
     96                        printf("\t%12" PRIu64 "\t%12" PRIu64, 
     97                                ports[k][i][j].bytes, 
     98                                ports[k][i][j].count 
    4899                      ); 
     100                } 
     101        } 
     102        printf("\n"); 
    49103} 
    50104 
    51 static void port_protocol(int i) 
     105void port_protocol(int i) 
    52106{ 
    53         int j; 
     107        int j,k; 
    54108        struct protoent *ent = getprotobynumber(i); 
    55109        printf("Protocol: %i %s%s%s\n",i, 
    56110                        ent?"(":"",ent?ent->p_name:"",ent?")":""); 
    57111        for(j=0;j<65536;++j) { 
    58                 if (ports[i][j].count) { 
    59                         port_port(i,ent?ent->p_name:"",j); 
     112                for(k=0;k<4;k++){ 
     113                        if (ports[k][i][j].count) { 
     114                                port_port(i,ent?ent->p_name:"",j); 
     115                                break; 
     116                        } 
    60117                } 
    61118        } 
     
    66123        int i; 
    67124        printf("# Port breakdown:\n"); 
    68         printf("%-20s \t%12s\t%12s\n","Port","Bytes","Packets"); 
     125        port_suppress(); 
    69126        setservent(1); 
    70127        setprotoent(1); 
     
    76133        endprotoent(); 
    77134        endservent(); 
     135         
     136        int total, j,k; 
     137        for(i=0;i<4;i++){ 
     138                total = 0; 
     139                for(j=0;j<256;j++) 
     140                        for(k=0;k<65536;k++) 
     141                                total += ports[i][j][k].count; 
     142                //printf("%s: %i\n", "Total", total); 
     143        } 
    78144} 
  • trunk/tools/tracereport/protocol_report.c

    r811 r1143  
    77#include "report.h" 
    88 
    9 static stat_t prot_stat[256] = { {0,0} } ; 
     9static stat_t prot_stat[4][256] = {{{0,0}}} ; 
     10static bool suppress[4] = {true,true,true,true}; 
    1011 
    1112void protocol_per_packet(struct libtrace_packet_t *packet) 
    1213{ 
    1314        uint8_t proto; 
     15        int dir = trace_get_direction(packet); 
     16        if(dir < 0 || dir > 1) 
     17                dir = 2; 
    1418        if (trace_get_transport(packet,&proto,NULL)==NULL) 
    1519                return; 
    1620                 
    17         prot_stat[proto].count++; 
    18         prot_stat[proto].bytes+=trace_get_wire_length(packet); 
     21        prot_stat[dir][proto].count++; 
     22        prot_stat[dir][proto].bytes+=trace_get_wire_length(packet); 
     23        suppress[dir] = false; 
     24} 
     25 
     26void protocol_suppress() 
     27{ 
     28        int i; 
     29        printf("%-20s","Direction:"); 
     30        //printf("%20s", " "); 
     31        for(i=0;i<4;i++){ 
     32                if(!suppress[i]){ 
     33                        switch(i){ 
     34                                case 0: 
     35                                        printf("\t%24s", "Outbound   "); 
     36                                        break; 
     37                                case 1: 
     38                                        printf("\t%24s", "Inbound   "); 
     39                                        break; 
     40                                case 2: 
     41                                        printf("\t%24s", "Undefined   "); 
     42                                        break; 
     43                                default: 
     44                                        break; 
     45                        } 
     46                } 
     47        } 
     48        printf("\n"); 
     49        printf("%-20s","Protocol"); 
     50        for(i=0;i<4;i++){ 
     51                if(!suppress[i]){ 
     52                        printf("\t%12s\t%12s", "bytes","packets"); 
     53                } 
     54        } 
     55        printf("\n"); 
    1956} 
    2057 
    2158void protocol_report(void) 
    2259{ 
    23         int i; 
     60        int i,j; 
    2461        printf("# Protocol breakdown:\n"); 
    25         printf("%-20s \t%12s\t%12s\n","Protocol","bytes","packets"); 
     62        protocol_suppress(); 
    2663        setprotoent(1); 
    2764        for(i=0;i<256;++i) { 
    2865                struct protoent *prot; 
    29                 if (prot_stat[i].count==0) 
     66                if (prot_stat[0][i].count==0 &&  
     67                        prot_stat[1][i].count==0 && prot_stat[2][i].count==0) 
    3068                        continue; 
    3169                prot = getprotobynumber(i); 
    3270                if (prot) { 
    33                 printf("%20s:\t%12" PRIu64 "\t%12" PRIu64 "\n", 
    34                                 prot->p_name, 
    35                                 prot_stat[i].bytes, 
    36                                 prot_stat[i].count); 
     71                        printf("%20s",prot->p_name); 
     72                        for(j=0;j<4;j++){ 
     73                                if (prot_stat[j][i].count==0){ 
     74                                        if(!suppress[j]) 
     75                                                printf("\t%24s"," "); 
     76                                        continue; 
     77                                } 
     78                                printf("\t%12" PRIu64 "\t%12" PRIu64, 
     79                                                prot_stat[j][i].bytes, 
     80                                                prot_stat[j][i].count); 
     81                        } 
    3782                } 
    3883                else { 
    39                 printf("%20i:\t%12" PRIu64 "\t%12" PRIu64 "\n", 
    40                                 i, 
    41                                 prot_stat[i].bytes, 
    42                                 prot_stat[i].count); 
    43  
     84                        printf("%20i:",i); 
     85                        for(j=0;j<4;j++){ 
     86                                if (prot_stat[j][i].count==0){ 
     87                                        if(!suppress[j]) 
     88                                                printf("\t%24s"," "); 
     89                                        continue; 
     90                                } 
     91                                printf("\t%12" PRIu64 "\t%12" PRIu64, 
     92                                                prot_stat[j][i].bytes, 
     93                                                prot_stat[j][i].count); 
     94                        } 
    4495                } 
     96                printf("\n"); 
    4597        } 
    4698        setprotoent(0); 
     99         
     100        int total; 
     101        for(i=0;i<4;i++){ 
     102                total = 0; 
     103                for(j=0;j<256;j++) 
     104                        total += prot_stat[i][j].count; 
     105                //printf("%s: %i\n", "Total", total); 
     106        } 
    47107} 
  • trunk/tools/tracereport/report.h

    r810 r1143  
    99void tos_per_packet(struct libtrace_packet_t *packet); 
    1010void ttl_per_packet(struct libtrace_packet_t *packet); 
     11void tcpopt_per_packet(struct libtrace_packet_t *packet); 
     12void nlp_per_packet(struct libtrace_packet_t *packet); 
     13void ecn_per_packet(struct libtrace_packet_t *packet); 
     14void tcpseg_per_packet(struct libtrace_packet_t *packet); 
    1115 
    1216void dir_report(void); 
     
    1721void tos_report(void); 
    1822void ttl_report(void); 
     23void tcpopt_report(void); 
     24void nlp_report(void); 
     25void ecn_report(void); 
     26void tcpseg_report(void); 
    1927 
    2028#endif 
  • trunk/tools/tracereport/tos_report.c

    r1093 r1143  
    55#include "libtrace.h" 
    66#include "tracereport.h" 
    7 #include "report.h" 
    87 
    9 static stat_t tos_stat[256] = { {0,0} } ; 
     8static stat_t tos_stat[4][256] = {{{0,0}}} ; 
     9static bool suppress[4] = {true,true,true,true}; 
    1010 
    1111void tos_per_packet(struct libtrace_packet_t *packet) 
    1212{ 
    1313        struct libtrace_ip *ip = trace_get_ip(packet); 
     14         
    1415        if (!ip) 
    1516                return; 
     17        int dir = trace_get_direction(packet); 
     18        if(dir < 0 || dir > 1) 
     19                dir = 2; 
     20        tos_stat[dir][ip->ip_tos].count++; 
     21        tos_stat[dir][ip->ip_tos].bytes+=trace_get_wire_length(packet); 
     22        suppress[dir] = false; 
     23} 
    1624 
    17         tos_stat[ip->ip_tos].count++; 
    18         tos_stat[ip->ip_tos].bytes+=trace_get_wire_length(packet); 
     25void tos_suppress() 
     26{ 
     27        int i; 
     28        printf("%-20s","Direction:"); 
     29        //printf("%20s", " "); 
     30        for(i=0;i<4;i++){ 
     31                if(!suppress[i]){ 
     32                        switch(i){ 
     33                                case 0: 
     34                                        printf("\t%24s", "Outbound   "); 
     35                                        break; 
     36                                case 1: 
     37                                        printf("\t%24s", "Inbound   "); 
     38                                        break; 
     39                                case 2: 
     40                                        printf("\t%24s", "Undefined   "); 
     41                                        break; 
     42                                default: 
     43                                        break; 
     44                        } 
     45                } 
     46        } 
     47        printf("\n"); 
     48        printf("%-20s","ToS"); 
     49        for(i=0;i<4;i++){ 
     50                if(!suppress[i]){ 
     51                        printf("\t%12s\t%12s", "bytes","packets"); 
     52                } 
     53        } 
     54        printf("\n"); 
    1955} 
    2056 
    2157void tos_report(void) 
    2258{ 
    23         int i; 
     59        int i,j; 
    2460        printf("# TOS breakdown:\n"); 
    25         printf("%-20s \t%12s\t%12s\n","ToS","bytes","packets"); 
     61        tos_suppress(); 
    2662        for(i=0;i<256;++i) { 
    27                 if (tos_stat[i].count==0) 
     63                if (tos_stat[0][i].count==0 &&  
     64                        tos_stat[1][i].count==0 && tos_stat[2][i].count==0) 
    2865                        continue; 
    29                 printf("%16s0x%02x:\t%12" PRIu64 ":\t%12" PRIu64 "\n", 
    30                                 " ", 
    31                                 i, 
    32                                 tos_stat[i].bytes, 
    33                                 tos_stat[i].count); 
     66                printf("%20i:",i); 
     67                for(j=0;j<4;j++){ 
     68                        if (tos_stat[j][i].count==0){ 
     69                                if(!suppress[j]) 
     70                                        printf("\t%24s"," "); 
     71                                continue; 
     72                        } 
     73                        printf("\t%12" PRIu64 "\t%12" PRIu64, 
     74                                tos_stat[j][i].bytes, 
     75                                tos_stat[j][i].count); 
     76                } 
     77                printf("\n"); 
     78        } 
     79         
     80        int total; 
     81        for(i=0;i<4;i++){ 
     82                total = 0; 
     83                for(j=0;j<256;j++) 
     84                        total += tos_stat[i][j].count; 
     85                //printf("%s: %i\n", "Total", total); 
    3486        } 
    3587} 
  • trunk/tools/tracereport/tracereport.c

    r1131 r1143  
    22 * This file is part of libtrace 
    33 * 
    4  * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand. 
     4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand. 
    55 * Authors: Daniel Lawson  
    66 *          Perry Lorier  
     7 *                      Josef Vodanovich 
    78 *           
    89 * All rights reserved. 
     
    5051#include <getopt.h> 
    5152#include <inttypes.h> 
    52 #include "lt_inttypes.h" 
     53//#include "lt_inttypes.h" 
    5354 
    5455#include "libtrace.h" 
     
    5960 
    6061/* Process a trace, counting packets that match filter(s) */ 
    61 static void run_trace(char *uri, libtrace_filter_t *filter, int count)  
     62void run_trace(char *uri, libtrace_filter_t *filter, int count)  
    6263{ 
    6364        struct libtrace_packet_t *packet = trace_create_packet(); 
    6465 
    6566        fprintf(stderr,"%s:\n",uri); 
    66  
    67         trace = trace_create(uri); 
     67        trace = trace_create(uri); 
     68         
    6869        if (trace_is_err(trace)) { 
    6970                trace_perror(trace,"trace_create"); 
     
    8081        } 
    8182 
    82         for (;;) { 
     83        for (;;) { 
    8384                int psize; 
    8485                if (count--<1) 
    8586                        break; 
    86                 if ((psize = trace_read_packet(trace, packet)) <1) { 
    87                         break; 
    88                 } 
    89  
     87                if ((psize = trace_read_packet(trace, packet)) <1) { 
     88                        break; 
     89                } 
    9090                error_per_packet(packet); 
    9191                port_per_packet(packet); 
     
    9494                ttl_per_packet(packet); 
    9595                flow_per_packet(packet); 
     96                tcpopt_per_packet(packet); 
     97                nlp_per_packet(packet); 
    9698                dir_per_packet(packet); 
    97  
    98         } 
    99  
    100         trace_destroy(trace); 
     99                //ecn_per_packet(packet); 
     100                //tcpseg_per_packet(packet); 
     101        } 
     102        trace_destroy(trace); 
    101103} 
    102104 
    103 static void usage(char *argv0) 
     105void usage(char *argv0) 
    104106{ 
    105107        fprintf(stderr,"Usage:\n" 
    106108        "%s flags traceuri [traceuri...]\n" 
    107         "-f --filter            Apply BPF filter. Can be specified multiple times\n" 
     109        "-f --filter=bpf        Apply BPF filter. Can be specified multiple times\n" 
    108110        "-H --libtrace-help     Print libtrace runtime documentation\n" 
    109111        ,argv0); 
     
    113115int main(int argc, char *argv[]) { 
    114116 
    115         libtrace_filter_t *filter = NULL; 
     117        int i; 
    116118 
    117         if (argc<2) 
    118                 usage(argv[0]); 
     119        /*char *filterstring="host 130.197.127.210"; */ 
    119120 
    120         while(1) { 
    121                 int option_index; 
    122                 struct option long_options[] = { 
    123                                 { "filter",             1, 0, 'f' }, 
    124                                 { "libtrace-help",      0, 0, 'H' }, 
    125                                 {NULL,                  0, 0, 0   }, 
    126                         }; 
    127                 int c = getopt_long(argc, argv, "f:H", 
    128                                 long_options, &option_index); 
    129                 if (c == -1) 
    130                         break; 
    131                 switch(c) { 
    132                         case 'f': 
    133                                 if (filter != NULL) { 
    134                                         fprintf(stderr,"You can only have one filter\n"); 
    135                                         usage(argv[0]); 
    136                                 } 
    137                                 filter=trace_create_filter(optarg); 
    138                                 break; 
    139                         case 'H': 
    140                                 trace_help(); 
    141                                 exit(1); 
    142                                 break; 
    143                         default: 
    144                                 printf("Unknown option: %c\n", c); 
    145                                 usage(argv[0]); 
    146                 } 
    147         } 
     121        libtrace_filter_t *filter = NULL;/*trace_bpf_setfilter(filterstring); */ 
    148122 
    149         while(optind < argc) { 
    150                 run_trace(argv[optind++],filter,(1<<30)); 
     123        for(i=1;i<argc;++i) { 
     124                run_trace(argv[i],filter,(1<<30)); 
    151125        } 
    152126 
     
    157131        port_report(); 
    158132        ttl_report(); 
     133        tcpopt_report(); 
     134        nlp_report(); 
    159135        dir_report(); 
    160  
    161         return 0; 
     136        //ecn_report(); 
     137        //tcpseg_report(); 
     138    return 0; 
    162139} 
  • trunk/tools/tracereport/ttl_report.c

    r1093 r1143  
    55#include "libtrace.h" 
    66#include "tracereport.h" 
    7 #include "report.h" 
    87 
    9 static stat_t ttl_stat[256] = { {0,0} } ; 
     8static stat_t ttl_stat[4][256] = {{{0,0}}} ; 
     9static bool suppress[4] = {true,true,true,true}; 
    1010 
    1111void ttl_per_packet(struct libtrace_packet_t *packet) 
     
    1414        if (!ip) 
    1515                return; 
     16        int dir = trace_get_direction(packet); 
     17        if(dir < 0 || dir > 1) 
     18                dir = 2; 
     19        ttl_stat[dir][ip->ip_ttl].count++; 
     20        ttl_stat[dir][ip->ip_ttl].bytes+=trace_get_wire_length(packet); 
     21        suppress[dir] = false; 
     22} 
    1623 
    17         ttl_stat[ip->ip_ttl].count++; 
    18         ttl_stat[ip->ip_ttl].bytes+=trace_get_wire_length(packet); 
     24void ttl_suppress() 
     25{ 
     26        int i; 
     27        printf("%-20s","Direction:"); 
     28        //printf("%20s", " "); 
     29        for(i=0;i<4;i++){ 
     30                if(!suppress[i]){ 
     31                        switch(i){ 
     32                                case 0: 
     33                                        printf("\t%24s", "Outbound   "); 
     34                                        break; 
     35                                case 1: 
     36                                        printf("\t%24s", "Inbound   "); 
     37                                        break; 
     38                                case 2: 
     39                                        printf("\t%24s", "Undefined   "); 
     40                                        break; 
     41                                default: 
     42                                        break; 
     43                        } 
     44                } 
     45        } 
     46        printf("\n"); 
     47        printf("%-20s","TTL"); 
     48        for(i=0;i<4;i++){ 
     49                if(!suppress[i]){ 
     50                        printf("\t%12s\t%12s", "bytes","packets"); 
     51                } 
     52        } 
     53        printf("\n"); 
    1954} 
    2055 
    2156void ttl_report(void) 
    2257{ 
    23         int i; 
     58        int i,j; 
    2459        printf("# TTL breakdown:\n"); 
    25         printf("%-20s \t%12s\t%12s\n","TTL","bytes","packets"); 
     60        ttl_suppress(); 
    2661        for(i=0;i<256;++i) { 
    27                 if (ttl_stat[i].count==0) 
     62                if (ttl_stat[0][i].count==0 &&  
     63                        ttl_stat[1][i].count==0 && ttl_stat[2][i].count==0) 
    2864                        continue; 
    29                 printf("%20i:\t%12" PRIu64 ":\t%12" PRIu64 "\n", 
    30                                 i, 
    31                                 ttl_stat[i].bytes, 
    32                                 ttl_stat[i].count); 
     65                printf("%20i:",i); 
     66                for(j=0;j<4;j++){ 
     67                        if (ttl_stat[j][i].count==0){ 
     68                                if(!suppress[j]) 
     69                                        printf("\t%24s"," "); 
     70                                continue; 
     71                        } 
     72                        printf("\t%12" PRIu64 "\t%12" PRIu64, 
     73                                ttl_stat[j][i].bytes, 
     74                                ttl_stat[j][i].count); 
     75                } 
     76                printf("\n"); 
     77        } 
     78         
     79        int total; 
     80        for(i=0;i<4;i++){ 
     81                total = 0; 
     82                for(j=0;j<256;j++) 
     83                        total += ttl_stat[i][j].count; 
     84                //printf("%s: %i\n", "Total", total); 
    3385        } 
    3486} 
Note: See TracChangeset for help on using the changeset viewer.