struct / querub

QueRub embeds a ruby interpreter into a libnetfilter_queue C program for inline fuzzing and reversing of network protocols

This URL has Read+Write access

struct (author)
Thu May 14 22:00:14 -0700 2009
commit  a65d41d09b583b42ea4291a58a0a9dd149e37e03
tree    6983cf474db8663432736d1ab3bbb06148fdddc0
parent  ed26301bd8d9da846619e4771a375cbba5136194
querub / cksum.c
100644 97 lines (76 sloc) 2.308 kb
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
#include "querub.h"
 
/* Various checksum routines taken from TCPDUMP and
http://www.bytebot.net/rrjcode/ratelimit-0.1/ */
void IpChecksum(struct ip *ip)
{
  register u_int32_t sum;
 
  ip->ip_sum = 0;
  sum = SumWords((u_int16_t *) ip, ip->ip_hl << 1);
 
  sum = (sum >> 16) + (sum & 0xFFFF);
  sum += (sum >> 16);
  sum = ~sum;
 
  ip->ip_sum = htons(sum);
}
 
int SumWords(u_int16_t *buf, int nwords)
{
  register u_int32_t sum = 0;
 
  while (nwords >= 16)
  {
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    sum += (u_int16_t) ntohs(*buf++);
    nwords -= 16;
  }
  while (nwords--)
    sum += (u_int16_t) ntohs(*buf++);
  return(sum);
}
 
void UdpChecksum(struct ip *ip)
{
  struct udphdr *const udp = (struct udphdr *) ((long *) ip + ip->ip_hl);
  u_int32_t sum;
 
  udp->uh_sum = 0;
 
  sum = SumWords((u_int16_t *) &ip->ip_src, 4);
  sum += (u_int16_t) IPPROTO_UDP;
  sum += (u_int16_t) ntohs(udp->uh_ulen);
 
  sum += SumWords((u_int16_t *) udp, ((u_int16_t) ntohs(udp->uh_ulen)) >> 1);
  if (ntohs(udp->uh_ulen) & 1)
    sum += (u_int16_t) (((u_char *) udp)[ntohs(udp->uh_ulen) - 1] << 8);
 
  sum = (sum >> 16) + (sum & 0xFFFF);
  sum += (sum >> 16);
  sum = ~sum;
 
  udp->uh_sum = htons(sum);
}
 
void TcpChecksum(struct ip *ip)
{
  struct tcphdr *const tcp = (struct tcphdr *) ((long *) ip + ip->ip_hl);
  u_int32_t sum;
  int tcp_len;
 
  tcp->th_sum = 0;
 
  tcp_len = (u_int16_t) ntohs(ip->ip_len) - (ip->ip_hl << 2);
 
  sum = SumWords((u_int16_t *) &ip->ip_src, 4);
  sum += (u_int16_t) IPPROTO_TCP;
  sum += (u_int16_t) tcp_len;
 
  sum += SumWords((u_int16_t *) tcp, tcp_len >> 1);
 
if (tcp_len & 1)
{
sum += (u_int16_t) (((u_char *) tcp)[tcp_len - 1] << 8);
}
 
  sum = (sum >> 16) + (sum & 0xFFFF);
  sum += (sum >> 16);
  sum = ~sum;
 
  tcp->th_sum = htons(sum);
}