Volevo creare uno scanner di porte che utilizza la tecnica half open, ovvero che, per verificare se una porta su un dato host è aperta, non compie tutti i passaggi del 3way handshaking del TCP (come avverrebbe utilizzando una connect) ma soltanto i primi 2:

A -> SYN -> B
A <- SYN+ACK <- B

Per farlo sto utilizzando le raw socket ma sono uno scarsone e quindi ho dei problemi.
La mia struct che rappresenta il pacchetto da inviare è così formata:

codice:
struct packet
{
	struct ip iph;
	struct tcphdr tcph;
	char c[200];
} tcp_p;
Inizializzo l'indirizzo dell'host a cui inviare il pacchetto in questa maniera:
codice:
	struct sockaddr_in server_addr;
        struct hostent *host;
        
        host = gethostbyname(argv[1]);
	server_addr.sin_port = htons((u_short) atoi(argv[2]));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
Il socket lo creo di tipo RAW e indico al sistema operativo che voglio compilare manualmente l'header ip:
codice:
	if((sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
	{
		perror("socket(): ");
		exit(-1);
	}
	
	if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(int)) == -1)
	{
		perror("setsockopt(): ");
		exit(-1);
	}
E la struct tcp_p la riempio così:
codice:
	/* riempimento della struct tcp_p (parte IP)*/
	
	tcp_p.iph.ip_hl = 5;
	tcp_p.iph.ip_v = 4;
	tcp_p.iph.ip_tos = 0;
	tcp_p.iph.ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr));
	tcp_p.iph.ip_id = htons(242);
	tcp_p.iph.ip_off = htons(IP_DF);
	tcp_p.iph.ip_ttl = 255;
	tcp_p.iph.ip_p = IPPROTO_TCP;
	tcp_p.iph.ip_sum = 0;
	tcp_p.iph.ip_src.s_addr = mio_addr.sin_addr.s_addr;
	tcp_p.iph.ip_dst.s_addr = server_addr.sin_addr.s_addr;
	
	/* riempimento della struct tcp_p (parte TCP) */
	
	tcp_p.tcph.source = mio_addr.sin_port;
	tcp_p.tcph.dest = server_addr.sin_port;
	tcp_p.tcph.seq = htonl(0x12345678);
	tcp_p.tcph.ack_seq = 0;
	tcp_p.tcph.doff = 0;
	tcp_p.tcph.syn = 1;
	tcp_p.tcph.ack = 0;
	tcp_p.tcph.fin = 0;
	tcp_p.tcph.window = htons(1024);
	tcp_p.tcph.check = 0;
	tcp_p.tcph.urg_ptr = 0;
Infine invio il pacchetto utilizzando la sendto (dal momento che da quel che ho capito send e recv non vanno bene con socket di tipo raw):
codice:
	if(sendto(sd, &tcp_p, sizeof(tcp_p), 0, (struct sockaddr *) & server_addr, sizeof(server_addr)) == -1)
	{
		perror("sendto");
		exit(-1);
	}
Peccato che non funzioni! Infatti se provo in seguito all'inzio a mettermi in ascolto sul socket con una recvfrom o con una read sul socket non ricevo nulla... e anche attivando uno sniffer mi rendo conto che non mi arriva nessun pacchetto... quindi presumo che:

1. Sbaglio qualcosa nell'invio e quindi l'host non riceve nessun pacchetto con flag SYN attivo
2. Non ho capito niente del meccaniscmo dell'half open o delle raw sockets

Aiutatemi XD