DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C++ (http://www.daniweb.com/forums/forum8.html)
-   -   struct is wrong, I guess... (http://www.daniweb.com/forums/thread135113.html)

JBtje Jul 17th, 2008 8:28 pm
struct is wrong, I guess...
 
Hello,

On a website I found the next source code "sniffer.cpp"

Sniffer.cpp
/*

  OoOoOoOoOoOoOoOoOoO
  o HTTP-Sniffer    o
  O www.1plus.se    O
  oOoOoOoOoOoOoOoOoOo

  INFO: The trick is to use raw packets with SIO_RCVALL

 */

#include <iostream>
#include <fstream>
#include <string>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include "packet_headers.h"

using namespace std;

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

/*
        Init Winsock
        Startup winsock, version 2.
*/

bool fInitWinsock(){
        WSADATA lWsa;

        if ( WSAStartup(MAKEWORD(2,0), &lWsa) != 0 )
                return false;
       
        return true;
}

void LogToFile(const char *log, ... )
{
        va_list va_alist;
        char buff[1024]="";
        va_start (va_alist, log);
        _vsnprintf (buff, sizeof(buff), log, va_alist);
        va_end (va_alist);

        ofstream lOutput;
        lOutput.open("packetlog.txt",ios::app);
        if(lOutput.fail()) return;
        lOutput << buff;
        lOutput.close();
}

/*
        Init Raw Sockets
        !!SIO_RCVALL!!
  */

SOCKET fInitSocket(){
        SOCKET lSock;
        DWORD  lpBuffer[255]; // Should be enough if you dont have like 100 adapters. :P
        DWORD  lSize;
        SOCKET_ADDRESS_LIST *lSaddrlist;

        // RAW SOCKET, PROTOCOL IP
        if( (lSock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET){
      return -1;
    }

        /*
        MSDN:
        The SIO_ADDRESS_LIST_QUERY socket I/O control operation allows a
        WSK application to query the current list of local transport
        addresses for a socket's address family.

    OutputBuffer A pointer to the buffer that receives the current list of local transport addresses
        */
        WSAIoctl(lSock,SIO_ADDRESS_LIST_QUERY,NULL,0,lpBuffer,sizeof(lpBuffer),&lSize,NULL,NULL);
        lSaddrlist = (SOCKET_ADDRESS_LIST*)lpBuffer;

        // Assume its the first.
        // Dont know how many got more then one network adapter in use.
        // TODO: Fix ?
        const sockaddr *lSockAddr=lSaddrlist->Address[0].lpSockaddr;

        /* Bind socket to first address */
    if(bind(lSock,lSockAddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
        printf("bind() error");
        return -1;
    }

        /* Heres where the fun happens ;) */
        unsigned int  optval = 1;
        if(WSAIoctl(lSock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&lSize,NULL,NULL) == SOCKET_ERROR){
                printf("ERROR!\n");
        return -1;
    }

        return lSock;

}

int main(void){
        char lPacket[1024];
        SOCKET lSock;
        IP *lIP;
        TCP *lTCP;

        // Same as packet. :)
        // Pointer never changes, so we can set it at the begging.
        lIP = (IP*)lPacket;

        // Print Banner.
        printf("  OoOoOoOoOoOoOoOoOoO\n");
        printf("  o HTTP-Sniffer    o\n");
        printf("  O www.1plus.se    O\n");
        printf("  oOoOoOoOoOoOoOoOoOo\n\n");

        LogToFile("  OoOoOoOoOoOoOoOoOoO\n");
        LogToFile("  o HTTP-Sniffer    o\n");
        LogToFile("  O www.1plus.se    O\n");
        LogToFile("  oOoOoOoOoOoOoOoOoOo\n\n");
        SYSTEMTIME lol;
        GetSystemTime(&lol);
        LogToFile("  Started at: %i:%i:%i\n\n",lol.wDay,lol.wMonth,lol.wYear);


        // Init Winsock.
        if(!fInitWinsock()) return -1;

        // Init socket to recieve all packets.
        lSock = fInitSocket();

        // Failed to initialize socket
        if(lSock==-1){
                printf("Failed to initialize socket\n");
                return -1;
        }


        // Main loop
        while(1){
                // NOTE: Usually you should check if RECV is 0. but connection is never closed, so no need!
                int lRecv=recv(lSock,lPacket,1024,0);


                // TCP-Packet.
                if(lIP->protocol==6){
                       
                        // Get Ip Header Length.
                        unsigned short lHeaderLength=lIP->ihl*4;

                        // Change TCP-Header pointer to corect address
                        lTCP = (TCP*)(lPacket+lHeaderLength);


                        // Port 80?
                        if(ntohs((unsigned short)lTCP->dest_port)==80){
                                // Get data offset.
                                unsigned short lDataStart=lTCP->data*4;

                                // The data part.
                                char *lData = (char*)(lPacket+lHeaderLength+lDataStart);
                       
                                // End the string :)
                                char *lEndPtr = (char*)(lPacket+lRecv);
                                *lEndPtr='\0';

                                // Dont log SYN/ACK packets
                                if(lTCP->flags == 24){
                                        LogToFile("%s\n",lData);
                                        printf("%s\n",lData);
                                }
                        }
                }
        }

}

But in the rar on the website, the file "packet_headers.h" was NOT included :S so I had to recover it myself.... There I have no experience with C++, I'm shure there the mistake is....

packet_headers.h
#pragma once
#pragma comment(lib, "ws2_32.lib")

#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600    // Change this to the appropriate value to target other versions of Windows.
#endif


typedef struct lIP
{
        unsigned char ihl; // Version and IP Header Length
        unsigned int protocol;
} IP;

typedef struct lTCP
{
        unsigned short flags; //Flags 3 bits and Fragment offset 13 bits
        unsigned short data;
        unsigned long dest_port;
} TCP;

With these files I am capable to make an executable, but it doesn't do what it is supposed to do :S

On line 147 of Sniffer.cpp ther is standing " if(lIP->protocol==6){" This checks if the protocol is TCP, as I need it to be...
Unfortunately, when I print lIP->protocol on the screen it returns 1,2 and 5 but not the needed 6 as it should do when I brows the internet with IE...


Can anyone help me with finding a solution for this lIP->protocol problem, so the correct value is inthere?
The source of "packet_headers.h" Is all "scripted" by me, and not (as far as I know) the original source......
The source of "Sniffer.cpp" is downloaded and should be working perfectly (in combination with "packet_headers.h" ofcourse)


Also I'm working with C++ for 2 days now, so there is a realy big change I made a mistake somewhere!


Thanks in advance,
Jeffrey


All times are GMT -4. The time now is 7:05 am.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC