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:
parent
eae66741ec
commit
957ec5d63a
@ -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)));
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user