Raw socket "bogus tcp header length"
Bonjour,
Voila j'ai voulu coder un petit programme qui envoie un paquet tcp/ip , quand je sniffe l envoie du paquet je peux voir sa dans l entete tcp :
Citation:
Header length : bogus, must be at least 20
Et je ne vois pas d'ou cela pourrais venire , voila le code , si vous pourriez me donner une piste ... .
Code:
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <errno.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>
typedef struct iphdr_s {
unsigned int ihl:4;
unsigned int version:4;
unsigned char tos;
unsigned short int tot_len;
unsigned short int id;
unsigned short int offset;
unsigned char ttl;
unsigned char protocol;
unsigned short int checksum;
unsigned int src;
unsigned int dst;
} iphdr_t;
typedef struct tcphdr_s {
unsigned short psrc;
unsigned short pdst;
unsigned int seq;
unsigned int ack;
unsigned char doffset;
unsigned char flags;
unsigned short win;
unsigned short checksum;
unsigned short urgp;
} tcphdr_t;
typedef struct fakehdr_s {
unsigned long saddr;
unsigned long daddr;
char useless;
unsigned char protocol;
unsigned short length;
} fakehdr_t;
unsigned short in_cksum(unsigned short * addr,int len);
int main(int argc, char *argv[]) {
iphdr_t *iphdr = NULL;
tcphdr_t *tcphdr = NULL;
fakehdr_t *fakehdr = NULL;
char *pkt_send = NULL;
char *pkt_recv = NULL;
int res;
int sock;
struct sockaddr_in to;
pkt_send = (char *) malloc(sizeof(iphdr_t) + sizeof(tcphdr_t));
if ( pkt_send == NULL ) {
fprintf(stderr, "malloc on pkt_send failed\n");
return -1;
}
fakehdr = (fakehdr_t *) malloc(sizeof(fakehdr_t));
if ( fakehdr == NULL ) {
fprintf(stderr, "malloc on fakehdr failed\n");
return -1;
}
iphdr = (iphdr_t *) pkt_send;
tcphdr = (tcphdr_t *) (pkt_send + sizeof(iphdr_t));
iphdr->ihl = 5;
iphdr->version = 4;
iphdr->tos = 0;
iphdr->tot_len = (sizeof(iphdr_t) + sizeof(tcphdr_t));
iphdr->id = 0;
iphdr->ttl = 255;
iphdr->protocol = IPPROTO_TCP;
iphdr->checksum = 0;
iphdr->src = inet_addr("192.168.1.100");
iphdr->dst = inet_addr("192.168.1.1");
iphdr->checksum = in_cksum((unsigned short *)iphdr, sizeof(iphdr_t));
tcphdr->psrc = htons(5000);
tcphdr->pdst = htons(80);
tcphdr->seq = 7;
tcphdr->ack = 0;
tcphdr->doffset = 5;
tcphdr->flags = 0x02;
tcphdr->win = 550;
tcphdr->checksum = 0;
tcphdr->urgp = 0;
fakehdr->saddr = inet_addr("192.168.1.100");
fakehdr->daddr = inet_addr("192.168.1.1");
fakehdr->useless = htons(0);
fakehdr->protocol = IPPROTO_TCP;
fakehdr->length = sizeof(tcphdr_t);
tcphdr->checksum = in_cksum((unsigned short *)fakehdr, sizeof(tcphdr_t)+sizeof(fakehdr_t));
sock = socket(AF_INET,SOCK_RAW, IPPROTO_TCP);
if ( sock == -1 ) {
fprintf(stderr, "function socket() failed\n");
free(fakehdr);
free(pkt_send);
fakehdr = NULL;
pkt_send = NULL;
return -1;
}
to.sin_family = AF_INET;
to.sin_port = htons(80);
to.sin_addr.s_addr = inet_addr("192.168.1.1");
if ( setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (void *)&res, (socklen_t) sizeof(int)) == 1 ) {
fprintf(stderr, "setsockopt() failed\n");
free(fakehdr);
free(pkt_send);
fakehdr = NULL;
pkt_send = NULL;
return -1;
}
if ( sendto(sock, pkt_send, iphdr->tot_len, 0, (struct sockaddr *)&to, sizeof(to)) == -1 ) {
fprintf(stderr, "sendto() failed\n");
free(fakehdr);
free(pkt_send);
fakehdr = NULL;
pkt_send = NULL;
return -1;
}
free(fakehdr);
free(pkt_send);
fakehdr = NULL;
pkt_send = NULL;
return 0;
}
unsigned short
in_cksum(unsigned short * addr,int len)
{
/* pas de moi */
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;
} |