Sto tentando disperatamente di programmare le raw socket sotto win ecco cosa ho fatto:
codice:
#include <stdio.h>
#include <winsock2.h>
#define PKT_LEN 8192 //lunghezza pacchetto
#define IP_HDR_LEN sizeof(IP_HDR)
#define TCP_HDR_LEN sizeof(TCP_HDR)
int err;
int control;
typedef struct IP_HDR
{
unsigned int version; //Version and IP Header Length
unsigned int ihl;
unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short frag_off; //Flags 3 bits and Fragment offset 13 bits
unsigned char ttl;
unsigned char protocol;
unsigned short check;//checksum
unsigned long saddr;//indirizzo ip mittente
unsigned long daddr;//indirizzo ip destinatario
//unsigned long Options_and_Padding;
} IP_HDR;
typedef struct TCP_HDR
{
unsigned short source; //porta sorgente da cui è partito il pacchetto TCP
unsigned short dest; //porta a cui è destinato il pacchetto
unsigned long seq; //numero di sequenza utilizzato per il servizio di trasporto affidabile dei dati che implementa il TCP
unsigned long ack_seq; //numero di riscontro usato anch'esso nel servizio di trasporto affidabile dei dati
unsigned short res1:4; //4 bit non utilizzati
unsigned short doff:4; //lunghezza dell' header TCP in parole di 32 bit, se non vengono inserite opzioni la lunghezza dell' intestazione è di 20 byte, quindi il valore da inserire è 5
unsigned short fin:1; //flag che viene utilizzato per chiudere una connessione
unsigned short syn:1; //flag che serve per stabilire una connessione
unsigned short rst:1; //flag che serve per resettare una connessione
unsigned short psh:1; //flag che specifica che i dati presenti nel pacchetto sono da passare immediatamente al programma
unsigned short ack:1; //flag che serve per stabilire una connessione
unsigned short urg:1; //flag che notifica la presenza di dati urgenti (non molto utilizzato)
unsigned short res2:2; //2 bit non utilizzati
unsigned short window; //finestra di ricezione che specifica quanti pacchetti possono essere ricevuti insieme (questo campo assume molta importanza nella "TCP reset vulnerability")
unsigned short check; //checksum per controllare la correttezza dei dati
unsigned short urg_ptr; //puntatore ai dati urgenti che il flag "urg" ha notificato
} TCP_HDR;
/* ceksum */
unsigned short csum(unsigned short *buf, int nwords){ //funzione di checksum del pacchetto IP
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return ~sum;
}
/* start winsock */
void StartWinsock()
{
WSADATA data;
WORD p = MAKEWORD(2,0);
/* controllo che il socket venga inizializzato */
if ((err = WSAStartup (p,&data)) != 0)
{
printf("\n\t (warning)- Cannot initialize winsock \n");
system("pause");
}
}
int main(){
SOCKET sd;
char buffer[PKT_LEN];
struct IP_HDR *ip = (struct IP_HDR*) buffer;
struct TCP_HDR *tcp = (struct TCP_HDR *) (buffer + IP_HDR_LEN);
struct sockaddr_in sin;
unsigned int one = 1;
memset(buffer, 0, PKT_LEN);
StartWinsock();
sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (sd < 0){
perror("\n\t(warning)Errore socket()");
system("pause");
}
sin.sin_family = AF_INET;
sin.sin_port = htons(21); //porta a cui connettersi (in questo caso 21) modificare per altra porta
sin.sin_addr.s_addr = inet_addr("127.0.0.1"); //indirizzo IP destinazione (in questo 127.0.0.1) modificare per altro IP
ip->ihl = 5; //riempio la struttura IP
ip->version = 4;
ip->tos = 16;
ip->tot_len = IP_HDR_LEN + TCP_HDR_LEN;
ip->id = htons(52407);
ip->frag_off = 0;
ip->ttl = 64;
ip->protocol = 6;
ip->check = 0; //per ora setto a 0 poi calcolerò quando conoscerò la dimensione del pacchetto TCP
ip->saddr = inet_addr("127.0.0.1"); //indirizzo IP destinazione (in questo 127.0.0.1) modificare per altro IP
ip->daddr = inet_addr("127.0.0.1"); //indirizzo IP destinazione (in questo 127.0.0.1) modificare per altro IP
//riempio la struttura TCP
tcp->source = htons(2485); //porta sorgente (in questo caso 2485) modificare per altra porta
tcp->dest = htons(21); //porta a cui connettersi (in questo caso 21) modificare per altra porta
tcp->seq = htonl(1);
tcp->ack_seq = 0;
tcp->doff = 5;
tcp->syn = 1;
tcp->ack = 0;
tcp->window = htons(32767);
tcp->check = 0; //questo valore verrà inserito dal sistema operativo
tcp->urg_ptr = 0;
ip->check = csum((unsigned short *) buffer, IP_HDR_LEN + TCP_HDR_LEN); //utilizzo funzione csum per calcolare il checksum
if (setsockopt(sd, IPPROTO_IP, 2, (char *)&one, sizeof(one)) < 0) //informo il sistema operativo che l'header del paccheto IP è già presente all'interno del datagram
perror("Errore setsockopt()");
if (control = sendto(sd, buffer, ip->tot_len, MSG_OOB, (struct sockaddr *) &sin, sizeof(sin)) == SOCKET_ERROR)
{
control = WSAGetLastError();
printf("sendoto() failed, WSAGetLastError: %d\n", control);
}
closesocket(sd);
err = WSACleanup();
system("pause");
return 0;
}
La compilazione è ok solo che mi da errore durante l' esecuzione della funzione sendto, ho catturato l' errore grazie a WSAGetLastError: WSAGetLastError: 10045
che corrisponde a:
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
se cambio il valore di MSG_OOB in MSG_DONTROUTE, mi da questo errore:
WSAGetLastError: 10022
Che corrisponde a:
WSAEINVAL An unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
Se qualcuno mi puo'aiutare.....