1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include "ipheader.h"
#define PORT 25
typedef int socklent_t;
unsigned short csum(unsigned short *buffer, int nwords)
{
unsigned long sum;
for(sum = 0; nwords > 0; nwords--)
sum += *buffer++;
sum = (sum >> 16) + (sum & 0Xffff);
sum += (sum >> 16);
return ~sum;
}
int main(void)
{
WSADATA WSAData;
int error= WSAStartup(MAKEWORD(2,2), &WSAData);
if(!error)
{
SOCKET sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if(sock == INVALID_SOCKET)
printf("socket() failed \n");
else
{
char datagram[4096];
IPHEAD *iph = (IPHEAD *)datagram;
TCPHEAD *tcph = (TCPHEAD *)datagram + sizeof(IPHEAD);
SOCKADDR_IN sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(datagram, 0, 4096);
/** Remplissage du header ip **/
iph->ip_hl = 5; /* ip header Len */
iph->ip_v = 4; /* ip version (v4) */
iph->ip_tos = 0; /* ip_ type of service */
iph->ip_len = sizeof(IPHEAD) + sizeof(TCPHEAD); /* taille totale du header (ip + tcp) */
iph->ip_id = htonl(54321); /* ID sequence pour réassembler les datagrams (pou 1 datagrms L'ID pas important) */
iph->ip_off = 0; /* Pour réasembler les fragments, le 1er fragments tjrs == 0 */
iph->ip_ttl = 255; /* ttl = time to live, nombre de router traverser avant abandon (255 val max) */
iph->ip_p = 6; /* protocole utilisé dans la couche transport (6 == tcp) **/
iph->ip_sum = 0; /* checksum, mit a 0 avant l'apel de la fonction csum() */
iph->ip_src = inet_addr("1.2.3.4"); /*Addr source.RQ : SYN requete peut etre aveugle (blindly spoofed) */
iph->ip_dst = sin.sin_addr.s_addr; /* ADDR de destination */
printf("iph->ip_len == %d\n", iph->ip_len);
/** Remplissage du header tcp **/
tcph->th_sport = htons(1234); /*Port source (abitraire) */
tcph->th_dport = htons(PORT); /* destination port */
tcph->th_seq = rand(); /* dans u paquet SYN la sequence est au hzard */
tcph->th_ack = 0; /* N°du ack, les paquet suivant continne le N° précédent.Le 1er paquet est tjrs 0 */
tcph->th_x2 = 0; /* Unused, contien des 0 binaire */
tcph->th_off = 0; /* Longeur de l'entête tcp */
tcph->th_flags = TH_SYN; /* Signifie que le client veut initier une connection avec le port de destination */
tcph->th_win = htonl(65535); /* (65535 == max) quantité de bytes envoyer avant que les données soit accépter (ack), et avant envoies d'autres données */
tcph->th_sum = 0; /* si on met a 0 le kernel remplit avec le cheksum correct durant la transmission */
tcph->th_urp = 0; /* si paquet est urgent */
iph->ip_sum = csum((unsigned short*)datagram, iph->ip_len >> 1);
/** verificatioon de l'option IP_HDRINCL (ip_headerinclude), afin d'etre sur que le kernel
connait le header inclus ds les donnée.ET n'ajoute pas le sien **/
/** apparement façon pas tres élégante **/
{
int one = 1;
const int *val = &one;
if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) == SOCKET_ERROR)
printf("Warning can't set IP_HDRINCL option\n\n");
}
/** send data */
while(1)
{
if(sendto ( sock,
datagram,
iph->ip_len,
0,
(SOCKADDR*)&sin,
sizeof(sin)) < 0)
{
printf("error : %d", WSAGetLastError());
exit(1);
}
else
printf("WONGA !!! ");
}
}
closesocket(sock);
}
WSACleanup();
return 0;
} |
Partager