summaryrefslogtreecommitdiff
path: root/tools/sniffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/sniffer.cpp')
-rw-r--r--tools/sniffer.cpp194
1 files changed, 100 insertions, 94 deletions
diff --git a/tools/sniffer.cpp b/tools/sniffer.cpp
index 52b2eba9bd3..0422f87399e 100644
--- a/tools/sniffer.cpp
+++ b/tools/sniffer.cpp
@@ -157,11 +157,11 @@ map< Connection, map< long long, long long > > mapCursor;
void processMessage( Connection& c , Message& d );
-void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
+void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
const struct sniff_ip* ip = (struct sniff_ip*)(packet + captureHeaderSize);
int size_ip = IP_HL(ip)*4;
- if ( size_ip < 20 ){
+ if ( size_ip < 20 ) {
cerr << "*** Invalid IP header length: " << size_ip << " bytes" << endl;
return;
}
@@ -170,13 +170,13 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
const struct sniff_tcp* tcp = (struct sniff_tcp*)(packet + captureHeaderSize + size_ip);
int size_tcp = TH_OFF(tcp)*4;
- if (size_tcp < 20){
+ if (size_tcp < 20) {
cerr << "*** Invalid TCP header length: " << size_tcp << " bytes" << endl;
return;
}
if ( ! ( serverPorts.count( ntohs( tcp->th_sport ) ) ||
- serverPorts.count( ntohs( tcp->th_dport ) ) ) ){
+ serverPorts.count( ntohs( tcp->th_dport ) ) ) ) {
return;
}
@@ -199,7 +199,8 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
if ( expectedSeq[ c ] != ntohl( tcp->th_seq ) ) {
cerr << "Warning: sequence # mismatch, there may be dropped packets" << endl;
}
- } else {
+ }
+ else {
seen[ c ] = true;
}
@@ -223,7 +224,8 @@ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pa
messageBuilder[ c ]->appendBuf( (void*)payload, size_payload );
return;
}
- } else {
+ }
+ else {
bytesRemainingInMessage[ c ] -= size_payload;
messageBuilder[ c ]->appendBuf( (void*)payload, size_payload );
if ( bytesRemainingInMessage[ c ] < 0 ) {
@@ -264,70 +266,71 @@ public:
}
};
-void processMessage( Connection& c , Message& m ){
+void processMessage( Connection& c , Message& m ) {
AuditingDbMessage d(m);
-
+
if ( m.operation() == mongo::opReply )
out() << " - " << (unsigned)m.header()->responseTo;
out() << endl;
try {
- switch( m.operation() ){
- case mongo::opReply:{
- mongo::QueryResult* r = (mongo::QueryResult*)m.singleData();
- out() << "\treply" << " n:" << r->nReturned << " cursorId: " << r->cursorId << endl;
- if ( r->nReturned ){
- mongo::BSONObj o( r->data() , 0 );
- out() << "\t" << o << endl;
- }
- break;
- }
- case mongo::dbQuery:{
- mongo::QueryMessage q(d);
- out() << "\tquery: " << q.query << " ntoreturn: " << q.ntoreturn << " ntoskip: " << q.ntoskip << endl;
- break;
+ switch( m.operation() ) {
+ case mongo::opReply: {
+ mongo::QueryResult* r = (mongo::QueryResult*)m.singleData();
+ out() << "\treply" << " n:" << r->nReturned << " cursorId: " << r->cursorId << endl;
+ if ( r->nReturned ) {
+ mongo::BSONObj o( r->data() , 0 );
+ out() << "\t" << o << endl;
}
- case mongo::dbUpdate:{
- int flags = d.pullInt();
- BSONObj q = d.nextJsObj( "update" );
- BSONObj o = d.nextJsObj( "update" );
- out() << "\tupdate flags:" << flags << " q:" << q << " o:" << o << endl;
- break;
- }
- case mongo::dbInsert:{
- out() << "\tinsert: " << d.nextJsObj( "insert" ) << endl;
- while ( d.moreJSObjs() ) {
- out() << "\t\t" << d.nextJsObj( "insert" ) << endl;
- }
- break;
- }
- case mongo::dbGetMore:{
- int nToReturn = d.pullInt();
- long long cursorId = d.pullInt64();
- out() << "\tgetMore nToReturn: " << nToReturn << " cursorId: " << cursorId << endl;
- break;
- }
- case mongo::dbDelete:{
- int flags = d.pullInt();
- BSONObj q = d.nextJsObj( "delete" );
- out() << "\tdelete flags: " << flags << " q: " << q << endl;
- break;
- }
- case mongo::dbKillCursors:{
- int *x = (int *) m.singleData()->_data;
- x++; // reserved
- int n = *x;
- out() << "\tkillCursors n: " << n << endl;
- break;
+ break;
+ }
+ case mongo::dbQuery: {
+ mongo::QueryMessage q(d);
+ out() << "\tquery: " << q.query << " ntoreturn: " << q.ntoreturn << " ntoskip: " << q.ntoskip << endl;
+ break;
+ }
+ case mongo::dbUpdate: {
+ int flags = d.pullInt();
+ BSONObj q = d.nextJsObj( "update" );
+ BSONObj o = d.nextJsObj( "update" );
+ out() << "\tupdate flags:" << flags << " q:" << q << " o:" << o << endl;
+ break;
+ }
+ case mongo::dbInsert: {
+ out() << "\tinsert: " << d.nextJsObj( "insert" ) << endl;
+ while ( d.moreJSObjs() ) {
+ out() << "\t\t" << d.nextJsObj( "insert" ) << endl;
}
- default:
- cerr << "*** CANNOT HANDLE TYPE: " << m.operation() << endl;
+ break;
+ }
+ case mongo::dbGetMore: {
+ int nToReturn = d.pullInt();
+ long long cursorId = d.pullInt64();
+ out() << "\tgetMore nToReturn: " << nToReturn << " cursorId: " << cursorId << endl;
+ break;
+ }
+ case mongo::dbDelete: {
+ int flags = d.pullInt();
+ BSONObj q = d.nextJsObj( "delete" );
+ out() << "\tdelete flags: " << flags << " q: " << q << endl;
+ break;
}
- } catch ( ... ) {
+ case mongo::dbKillCursors: {
+ int *x = (int *) m.singleData()->_data;
+ x++; // reserved
+ int n = *x;
+ out() << "\tkillCursors n: " << n << endl;
+ break;
+ }
+ default:
+ cerr << "*** CANNOT HANDLE TYPE: " << m.operation() << endl;
+ }
+ }
+ catch ( ... ) {
cerr << "Error parsing message for operation: " << m.operation() << endl;
}
-
-
+
+
if ( !forwardAddress.empty() ) {
if ( m.operation() != mongo::opReply ) {
boost::shared_ptr<DBClientConnection> conn = forwarder[ c ];
@@ -353,10 +356,12 @@ void processMessage( Connection& c , Message& m ){
}
}
lastCursor[ c ] = 0;
- } else {
+ }
+ else {
conn->port().say( m );
}
- } else {
+ }
+ else {
Connection r = c.reverse();
long long myCursor = lastCursor[ r ];
QueryResult *qr = (QueryResult *) m.singleData();
@@ -375,7 +380,7 @@ void processMessage( Connection& c , Message& m ){
}
}
-void processDiagLog( const char * file ){
+void processDiagLog( const char * file ) {
Connection c;
MemoryMappedFile f;
long length;
@@ -385,45 +390,45 @@ void processDiagLog( const char * file ){
length = (long) L;
assert( root );
assert( length > 0 );
-
+
char * pos = root;
long read = 0;
- while ( read < length ){
+ while ( read < length ) {
Message m(pos,false);
int len = m.header()->len;
DbMessage d(m);
cout << len << " " << d.getns() << endl;
-
+
processMessage( c , m );
read += len;
pos += len;
}
-
+
f.close();
}
void usage() {
cout <<
- "Usage: mongosniff [--help] [--forward host:port] [--source (NET <interface> | (FILE | DIAGLOG) <filename>)] [<port0> <port1> ... ]\n"
- "--forward Forward all parsed request messages to mongod instance at \n"
- " specified host:port\n"
- "--source Source of traffic to sniff, either a network interface or a\n"
- " file containing previously captured packets in pcap format,\n"
- " or a file containing output from mongod's --diaglog option.\n"
- " If no source is specified, mongosniff will attempt to sniff\n"
- " from one of the machine's network interfaces.\n"
- "--objcheck Log hex representation of invalid BSON objects and nothing\n"
- " else. Spurious messages about invalid objects may result\n"
- " when there are dropped tcp packets.\n"
- "<port0>... These parameters are used to filter sniffing. By default, \n"
- " only port 27017 is sniffed.\n"
- "--help Print this help message.\n"
- << endl;
+ "Usage: mongosniff [--help] [--forward host:port] [--source (NET <interface> | (FILE | DIAGLOG) <filename>)] [<port0> <port1> ... ]\n"
+ "--forward Forward all parsed request messages to mongod instance at \n"
+ " specified host:port\n"
+ "--source Source of traffic to sniff, either a network interface or a\n"
+ " file containing previously captured packets in pcap format,\n"
+ " or a file containing output from mongod's --diaglog option.\n"
+ " If no source is specified, mongosniff will attempt to sniff\n"
+ " from one of the machine's network interfaces.\n"
+ "--objcheck Log hex representation of invalid BSON objects and nothing\n"
+ " else. Spurious messages about invalid objects may result\n"
+ " when there are dropped tcp packets.\n"
+ "<port0>... These parameters are used to filter sniffing. By default, \n"
+ " only port 27017 is sniffed.\n"
+ "--help Print this help message.\n"
+ << endl;
}
-int main(int argc, char **argv){
+int main(int argc, char **argv) {
stringstream nullStream;
nullStream.clear(ios::failbit);
@@ -435,7 +440,7 @@ int main(int argc, char **argv){
struct bpf_program fp;
bpf_u_int32 mask;
bpf_u_int32 net;
-
+
bool source = false;
bool replay = false;
bool diaglog = false;
@@ -451,10 +456,10 @@ int main(int argc, char **argv){
if ( arg == string( "--help" ) ) {
usage();
return 0;
- }
+ }
else if ( arg == string( "--forward" ) ) {
forwardAddress = args[ ++i ];
- }
+ }
else if ( arg == string( "--source" ) ) {
uassert( 10266 , "can't use --source twice" , source == false );
uassert( 10267 , "source needs more args" , args.size() > i + 2);
@@ -474,21 +479,22 @@ int main(int argc, char **argv){
serverPorts.insert( atoi( args[ i ] ) );
}
}
- } catch ( ... ) {
+ }
+ catch ( ... ) {
usage();
return -1;
}
if ( !serverPorts.size() )
serverPorts.insert( 27017 );
-
- if ( diaglog ){
+
+ if ( diaglog ) {
processDiagLog( file );
return 0;
}
- else if ( replay ){
+ else if ( replay ) {
handle = pcap_open_offline(file, errbuf);
- if ( ! handle ){
+ if ( ! handle ) {
cerr << "error opening capture file!" << endl;
return -1;
}
@@ -502,18 +508,18 @@ int main(int argc, char **argv){
}
cout << "found device: " << dev << endl;
}
- if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1){
+ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
cerr << "can't get netmask: " << errbuf << endl;
return -1;
}
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
- if ( ! handle ){
+ if ( ! handle ) {
cerr << "error opening device: " << errbuf << endl;
return -1;
}
- }
+ }
- switch ( pcap_datalink( handle ) ){
+ switch ( pcap_datalink( handle ) ) {
case DLT_EN10MB:
captureHeaderSize = 14;
break;