1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

fixed tcp data offset and checksum

(This used to be ctdb commit 2df23e0d3df52b746e9aee8d194ad1da16b62657)
This commit is contained in:
Andrew Tridgell 2007-05-27 16:56:12 +10:00
parent eae66741ec
commit 957ec5d63a
3 changed files with 49 additions and 12 deletions

View File

@ -71,7 +71,7 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *
(unsigned)ntohs(tcp->daddr.sin_port),
inet_ntoa(tcp->saddr.sin_addr),
(unsigned)ntohs(tcp->saddr.sin_port)));
ret = ctdb_sys_send_ack(&tcp->daddr, &tcp->saddr);
ret = ctdb_sys_send_ack(&tcp->saddr, &tcp->daddr);
if (ret != 0) {
DEBUG(0,(__location__ " Failed to send tcp tickle ack for %s\n",
inet_ntoa(tcp->saddr.sin_addr)));

View File

@ -127,20 +127,42 @@ int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface)
return 0;
}
/*
simple IP checksum - assumes data is multiple of 2 bytes long
uint16 checksum for n bytes
*/
static uint16_t ip_checksum(uint16_t *data, size_t n)
static uint32_t uint16_checksum(uint16_t *data, size_t n)
{
uint16_t sum=0;
while (n--) {
sum += ntohs(*data);
uint32_t sum=0;
while (n>=2) {
sum += (uint32_t)ntohs(*data);
data++;
n -= 2;
}
if (sum == 0) {
if (n == 1) {
sum += (uint32_t)ntohs(*(uint8_t *)data);
}
return sum;
}
/*
simple TCP checksum - assumes data is multiple of 2 bytes long
*/
static uint16_t tcp_checksum(uint16_t *data, size_t n, struct iphdr *ip)
{
uint32_t sum = uint16_checksum(data, n);
uint16_t sum2;
sum += uint16_checksum((uint16_t *)&ip->saddr, sizeof(ip->saddr));
sum += uint16_checksum((uint16_t *)&ip->daddr, sizeof(ip->daddr));
sum += ip->protocol + n;
sum = (sum & 0xFFFF) + (sum >> 16);
sum = (sum & 0xFFFF) + (sum >> 16);
sum2 = htons(sum);
sum2 = ~sum2;
if (sum2 == 0) {
return 0xFFFF;
}
return htons(sum);
return sum2;
}
/*
@ -185,20 +207,21 @@ int ctdb_sys_send_ack(const struct sockaddr_in *dest,
ZERO_STRUCT(pkt);
pkt.ip.version = 4;
pkt.ip.ihl = sizeof(pkt.ip)/4;
pkt.ip.tot_len = sizeof(pkt);
pkt.ip.tot_len = htons(sizeof(pkt));
pkt.ip.ttl = 255;
pkt.ip.protocol = IPPROTO_TCP;
pkt.ip.saddr = src->sin_addr.s_addr;
pkt.ip.daddr = dest->sin_addr.s_addr;
pkt.ip.check = ip_checksum((uint16_t *)&pkt.ip, sizeof(pkt.ip)/2);
pkt.ip.check = 0;
pkt.tcp.source = src->sin_port;
pkt.tcp.dest = dest->sin_port;
pkt.tcp.ack = 1;
pkt.tcp.check = 0;
pkt.tcp.doff = sizeof(pkt.tcp)/4;
pkt.tcp.check = tcp_checksum((uint16_t *)&pkt.tcp, sizeof(pkt.tcp), &pkt.ip);
ret = sendto(s, &pkt, sizeof(pkt), 0, dest, sizeof(*dest));
if (ret != 0) {
if (ret != sizeof(pkt)) {
DEBUG(0,(__location__ " failed sendto (%s)\n", strerror(errno)));
}
close(s);

View File

@ -1139,6 +1139,20 @@ int main(int argc, const char *argv[])
{ "thaw", control_thaw },
};
{
struct sockaddr_in saddr, daddr;
inet_aton("192.168.115.128", &daddr.sin_addr);
inet_aton("192.168.115.1", &saddr.sin_addr);
daddr.sin_port = htons(1234);
saddr.sin_port = htons(445);
daddr.sin_family = AF_INET;
saddr.sin_family = AF_INET;
ctdb_sys_send_ack(&daddr, &saddr);
exit(0);
}
pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
while ((opt = poptGetNextOpt(pc)) != -1) {