Forum: PC Hard- und Software raw socket - tcp checksum


von Buns T. (buns)


Lesenswert?

Hallo,

Ich habe den folgenden Code geschrieben. Mein tcp checksum ist nicht 
korrekt, obwohl ip checksum richtig ist. Ich kann den Fehler gerade 
nicht finden. ich bedanke mich für euere Hilfe
1
#include....
2
#define MSG_LENGTH 1024
3
4
5
struct hdr{
6
struct iphdr ip;
7
struct tcphdr tcp;
8
char Data[MSG_LENGTH];
9
10
};
11
12
int main(){
13
  
14
  struct hdr paket;
15
  
16
  struct pseudohdr Pseudo;
17
 
18
  struct sockaddr_in addr;
19
 
20
  int rawsock;
21
 
22
  const int on=1;
23
 
24
  int se;
25
  
26
  /**
27
   *create a raw socket
28
   *
29
   *transport protokol: TCP Protokol
30
   */
31
  rawsock = create_socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
32
  printf("create a Raw Socket\n");
33
  /**
34
   *set a socket option 
35
   */
36
  if(setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){
37
    perror("setsockopt()");
38
    exit(1);
39
  }
40
  /**
41
   *initialize paket
42
   */
43
  memset(&paket, 0, sizeof(struct hdr));
44
  /**
45
   *create IP Header
46
   */
47
  ....
48
49
  paket.ip.check = compute_checksum((uint16*)&paket.ip, sizeof(struct iphdr));///checksum
50
  /**
51
   *create TCP Header
52
  
53
   */
54
 ....
55
56
  /**
57
   *create Pseudo Header for computing TCP checksum
58
   *(quelle rfc 793)
59
   */
60
  Pseudo.saddr = paket.ip.saddr;
61
  Pseudo.daddr = paket.ip.daddr;
62
  Pseudo.reserved = 0;
63
  Pseudo.protocol = paket.ip.protocol;
64
  Pseudo.tcp_seg_len = htons(sizeof(struct tcphdr));
65
  bcopy((char*)&paket.tcp, (char*)&Pseudo.tcp, sizeof(struct tcphdr));
66
 
67
  
68
  printf("give your Data:\t");
69
  fgets(paket.Data, MSG_LENGTH, stdin);
70
71
  bcopy((char*)&paket.Data, (char*)&Pseudo.buf, MSG_LENGTH);
72
73
74
  paket.tcp.check = compute_checksum((uint16*)&Pseudo, MSG_LENGTH +
75
             sizeof(struct tcphdr) + sizeof(struct pseudohdr));
76
77
  /**
78
   *now the paket is sent
79
   */
80
81
    se = sendto(rawsock, &paket, sizeof(struct hdr), 0, 
82
    (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
83
   
84
  printf("the paket is sent\n");
85
  printf("Sent %d byte paket to %s\n",paket.ip.tot_len, DES_IP);
86
  
87
88
  close_socket(rawsock);
89
90
  return 0;
91
}
92
/**
93
 *hier ist checksum
94
 */
95
uint16
96
compute_checksum(uint16 *ptr,
97
     int byte){
98
  register int sum=0;
99
  u_short odd_byte=0;
100
  /**
101
   *we add sequential 16 bit words to a 32 bit accumulator(sum)
102
   *
103
   *and at the end, fold back all the carry bit from the top 16 bits
104
   *into the lower 16 bits
105
   */
106
  while(byte >1){
107
    sum += *ptr++;
108
    byte -=2;
109
  }
110
  /**
111
   *mod up and add byte, if necessary
112
   */
113
  if(byte ==1){
114
    *((u_char*)&odd_byte) = *(u_char*)ptr;
115
    sum += odd_byte;
116
  }
117
  /**
118
   *add back carry outs from top 16 bits to low 16 bits
119
   */
120
  sum = (sum >> 16) + (sum & 0xffff);///add hight to low
121
  sum += (sum >>16);///add carry
122
  odd_byte =~sum;
123
  return (odd_byte);
124
}

MFG

Buns

von NoL (Gast)


Lesenswert?

Hi,

es ist aus deinem Quelltext nicht ganz ersichtlich, aber achtest du 
darauf das sich der Speicherbereich des tcphdr und deiner Daten nicht 
überschreiben? Bzw das zu Pseudo.tcp und Pseudo.buf vorher reservierst 
und diese bereiche auch direkt aneinander grenzen? Ich sitze auch gerade 
an dem Problem. Bei mir lags daran das die Speicherbereiche nciht direkt 
nebeneinander waren. Dein Algorithmus sieht gut aus.

MfG NoL

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.