Newsgroup: it.comp.lang.c++
Titolo: Aiuto. Port Scanner!

Ciao a tutti [spero di non essere OT]
Ho un problema! Non riesco a far funzionare un port scanner (sotto win). Mi
compila e non mi dà
nessun errore in runtime (problema: i pacchetti non partono).
Riporto i listati dei due file: scanner.cpp e mystruct.h. (spero che la
spaziatura non venga rovinata eccessivamente)
Grazie.
scanner.cpp
#include <winsock.h>
#include <iostream.h>
#include <string>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include "mystructs.h"
// Prototipi funzioni
unsigned short chk(unsigned short *addr, int len);
void main(void)
{
    struct iphdr      *ip_head;    // Intestazione IP
    struct tcphdr     *tcp_head;   // Intestazione TCP
    struct setiphdr    ipclone;    // Per il calcolo del checksum del TCP
    struct sockaddr_in msg;        // Struttura usata da sendto()
    struct hostent    *local_info; // Per avere info su questo pc
    int s         = -1;            // Socket (inizializzazione pessimistica)
    int porta     = 7;             // Porta di inizio scansione
    int porte_tot = 120;           // Porta di fine scansione
    int i         = 0;             // Semplice contatore
    char ip_addr[15];              // Indirizzo IP di destinazione
    char this_ip_tmp[20];     // Indirizzo IP di questo computer
    char optval;                   // Opzioni socket
    char *pacchetto, *buffer;      // Pacchetto da inviare e
                                   //   buffer di ricezione dati
    char *local_ip;                // Struttura info da gethostbyname
 // Inizializzazione fondamentale sotto windows
 WSADATA wsaData;
    if(WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
    {
  cout << "Problemi con la libreria winsock.dll. Il programma verra\'
terminato.";
        getch();
  exit(0);
 }
    cout << "           --> Port scanner <--" << endl << endl;
    cout << "\nDammi l'indirizzo IP da sottoporre a scanner:" << endl;
    scanf("%s", ip_addr);
    // Calcolo IP locale
    gethostname(this_ip_tmp, 20);
    char *this_ip = this_ip_tmp;
    local_info = gethostbyname(this_ip);
    local_ip = local_info->h_addr_list[0];
    cout << "\nIP di questo computer: " << inet_ntoa(*((struct in_addr
*)local_ip));
    s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
    if(s == -1)
    {
        cout << "Impossibile inizializzare il socket, il programma verra\'
terminato.";
        getch();
        exit(0);
    }
    setsockopt(s, IPPROTO_IP, true, &optval, sizeof(int));
    // Allocazione memoria
    ip_head   = (struct iphdr *)  malloc(sizeof(struct iphdr));
    tcp_head  = (struct tcphdr *) malloc(sizeof(struct tcphdr));
    pacchetto = (char *) malloc(sizeof(struct iphdr) + sizeof(struct
tcphdr));
    buffer    = (char *) malloc(sizeof(struct iphdr) + sizeof(struct
tcphdr));
    if(ip_head == NULL || tcp_head == NULL || pacchetto == NULL || buffer ==
NULL)
    {
        cout << "Impossibile allocare memoria. Il programma verrra\'
terminato!";
        getch();
        exit(0);
    }
 // Memoria = NULL
    memset(tcp_head, '\0', sizeof(tcphdr));
    memset(ip_head, '\0', sizeof(iphdr));
    ip_head   = (struct iphdr *)pacchetto;
    tcp_head  = (struct tcphdr *)(pacchetto + sizeof(struct iphdr));
    // Informazioni intestazioni IP/TCP + IPclone
    ip_head->ihl      = 5;
 ip_head->version  = 4;
 ip_head->tos      = 0;
 ip_head->tot_len  = sizeof(struct iphdr) + sizeof(struct tcphdr);
 ip_head->id       = 1000;                     //htons(getuid());
    ip_head->ttl      = 255;
 ip_head->protocol = IPPROTO_TCP;
 ip_head->saddr    = inet_addr(local_ip);
 ip_head->daddr    = inet_addr(ip_addr);
    ipclone.saddr    = inet_addr(local_ip);
 ipclone.daddr    = inet_addr(ip_addr);
 ipclone.useless  = htons(0);
 ipclone.protocol = IPPROTO_TCP;
 ipclone.length   = sizeof(struct tcphdr);
    tcp_head->src_port = htons(10000);
    tcp_head->des_port = htons(porta);
    tcp_head->seq_num  = htonl(31337);
    tcp_head->ack_num  = htonl(0);
    tcp_head->d_offset = 5;
    tcp_head->fin      = 0;
    tcp_head->syn      = 1;
    tcp_head->rst      = 0;
    tcp_head->psh      = 0;
    tcp_head->ack      = 0;
    tcp_head->urg      = 0;
    tcp_head->window   = htons(4000);
    tcp_head->urg_ptr  = htons(0);
    // Valori di checksum
    tcp_head->check = chk((unsigned short *)&ipclone, sizeof(struct tcphdr)
+ sizeof(struct setiphdr));
    ip_head->check  = chk((unsigned short *)ip_head, sizeof(struct iphdr));
    msg.sin_family      = AF_INET;
    msg.sin_port        = htons(porta);
    msg.sin_addr.s_addr = inet_addr(ip_addr);
    // Queste due istruzioni sono state inserire per test sul funzionamento
    // (controllano solo la porta 7 (ECHO)
    sendto(s, pacchetto, ip_head->tot_len , 0, (struct sockaddr *)&msg,
sizeof(struct sockaddr));
    recv(s, buffer, sizeof(struct iphdr) + sizeof(struct tcphdr), 0);
/*
    for(i = porta; i < porte_tot; i++)
    {
        tcp_head->des_port = htons(i);
        tcp_head->check    = chk((unsigned short *)&ipclone, sizeof(struct
tcphdr) + sizeof(struct setiphdr));
        msg.sin_port       = htons(i);
        // Si potrebbe creare un thread per il pacchetto ed un delay tra un
pacchetto e l'altro
        sendto(s, pacchetto, ip_head->tot_len , 0, (struct sockaddr *)&msg,
sizeof(struct sockaddr));
        recv(s, buffer, sizeof(struct iphdr) + sizeof(struct tcphdr), 0);
        buffer += (sizeof(struct iphdr)+sizeof(struct udphdr));
     cout << endl << "Risposta dalla porta " << i << ":" << endl << buffer
<< endl << endl;
    }
*/
 closesocket(s);
    getch();
}
// Calcolo del checksum per verifica integrità del pacchetto
inline unsigned short chk(unsigned short *addr, int len)
{
    register int sum    = 0;
 u_short answer      = 0;
 register u_short *w = addr;
 register int nleft  = len;
    while(nleft > 1)
    {
     sum   += *w++;
  nleft -= 2;
    }
    if(nleft == 1)
    {
     *(u_char *) (&answer) = *(u_char *) w;
  sum += answer;
    }
 sum    =  (sum >> 16) + (sum & 0xffff);
 sum    += (sum >> 16);
 answer =  ~sum;
 return (answer);
}
/****  FINE  ****/
mystruct.h
// Header IP
struct iphdr
{
    #if __BYTE_ORDER == __LITTLE_ENDIAN
     unsigned int ihl:     4;
     unsigned int version: 4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
     unsigned int version: 4;
     unsigned int ihl:     4;
 #endif
     unsigned int tos:       8;
     unsigned int tot_len:  16;
     unsigned int id:       16;
     unsigned int frag_off: 16;
     unsigned int ttl:       8;
     unsigned int protocol:  8;
     unsigned int check:    16;
     unsigned int saddr:    32;
     unsigned int daddr:    32;
};
// Header TCP
struct tcphdr
{
    unsigned short int src_port:  16;
    unsigned short int des_port:  16;
    unsigned int seq_num:         32;
    unsigned int ack_num:         32;
   unsigned short int  res1:4,
                    d_offset:4,
           fin:1,
           syn:1,
           rst:1,
           psh:1,
           ack:1,
           urg:1,
           res2:2;
  unsigned short int window;
  unsigned short int check;
  unsigned short int urg_ptr;
};
// Necessario per il calcolo del Checksum del TCP (IP header)
struct setiphdr
{
    unsigned long  saddr;
    unsigned long  daddr;
    char           useless;
    unsigned char  protocol;
    unsigned short length;
};
// Header UDP
struct udphdr
{
    unsigned short int src_port;
    unsigned short int des_port;
    unsigned short int tot_len;
    unsigned short int check;
};
// Header ICMP
struct icmphdr
{
    unsigned int type: 8;
 unsigned int code: 8;
 unsigned int checksum: 16;
    union
    {
        struct
        {
         unsigned int id:       16;
         unsigned int sequence: 16;
        }echo;
     unsigned int gateway: 32;
        struct
        {
         unsigned int unused: 16;
         unsigned int mtu:      16;
        }frag;
    }un;
};

spaziatura non venga rovinata eccessivamente)
La cosa non mi sembra molto standard comunque non ti posso aiutare...
Mi sembra che (dando una rapida occhiata al codice) ci siano delle
"cose in +". Ad ogni modo io ne ho scritto uno in Python e non supera
le 30 righe :)
--
Rhymes (rhy...@NOSPAMmyself.com)
http://www26.brinkster.com/rhymes
" avevo Halo, poi č arrivata la mia fidanzata ;-) "

 ha scritto nel messaggio
news:ea9glus4aqvse48vu...@4ax.com...


Mi puoi inviare il listato?
Se aspetti un paio di giorni lo metto online sul mio sito. versione
con e senza thread
