The Samba-Bugzilla – Attachment 5560 Details for
Bug 7295
winbindd doesn't reconnect to it's own domain in the parent
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
A standalone tickleack command
tickleack.c (text/x-csrc), 8.66 KB, created by
Stefan Metzmacher
on 2010-03-29 13:39:55 UTC
(
hide
)
Description:
A standalone tickleack command
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2010-03-29 13:39:55 UTC
Size:
8.66 KB
patch
obsolete
>/* > Copyright (C) Ronnie Sahlberg 2007 > Copyright (C) Andrew Tridgell 2007 > Copyright (C) Stefan Metzmacher 2010 > > This program is free software; you can redistribute it and/or modify > it under the terms of the GNU General Public License as published by > the Free Software Foundation; either version 3 of the License, or > (at your option) any later version. > > This program is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General Public License for more details. > > You should have received a copy of the GNU General Public License > along with this program; if not, see <http://www.gnu.org/licenses/>. >*/ > >/* > * this is largely copied from the ctdb sources... > * compile it with: > * > * gcc -g -o tickleack tickleack.c -Wall -Wfatal-errors > */ > >#include <stdio.h> >#include <stdlib.h> >#include <stdint.h> >#include <stdbool.h> >#include <string.h> >#include <errno.h> > >#include <sys/socket.h> >#include <sys/un.h> >#include <netinet/in.h> >#include <arpa/inet.h> >#include <netdb.h> >#include <netinet/tcp.h> >#include <netinet/in_systm.h> >#include <netinet/ip.h> >#include <net/if.h> >#include <unistd.h> >#include <sys/ioctl.h> >#include <ifaddrs.h> > >#include <netinet/if_ether.h> >#include <netinet/ip6.h> >#include <netinet/icmp6.h> >#include <net/if_arp.h> >#include <netpacket/packet.h> > >/* > uint16 checksum for n bytes > */ >static uint32_t uint16_checksum(uint16_t *data, size_t n) >{ > uint32_t sum=0; > while (n>=2) { > sum += (uint32_t)ntohs(*data); > data++; > n -= 2; > } > if (n == 1) { > sum += (uint32_t)ntohs(*(uint8_t *)data); > } > return sum; >} > >/* > calculate the tcp checksum for tcp over ipv6 >*/ >static uint16_t tcp_checksum6(uint16_t *data, size_t n, struct ip6_hdr *ip6) >{ > uint32_t phdr[2]; > uint32_t sum = 0; > uint16_t sum2; > > sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_src, 16); > sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_dst, 16); > > phdr[0] = htonl(n); > phdr[1] = htonl(ip6->ip6_nxt); > sum += uint16_checksum((uint16_t *)phdr, 8); > > sum += uint16_checksum(data, n); > > sum = (sum & 0xFFFF) + (sum >> 16); > sum = (sum & 0xFFFF) + (sum >> 16); > sum2 = htons(sum); > sum2 = ~sum2; > if (sum2 == 0) { > return 0xFFFF; > } > return sum2; >} > >/* > 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 *)(void *)&ip->saddr, > sizeof(ip->saddr)); > sum += uint16_checksum((uint16_t *)(void *)&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 sum2; >} > >union generic_sockaddr { > struct sockaddr sa; > struct sockaddr_in sin; > struct sockaddr_in6 sin6; > struct sockaddr_storage ss; >}; > >/* > Send tcp segment from the specified IP/port to the specified > destination IP/port. > > This is used to trigger the receiving host into sending its own ACK, > which should trigger early detection of TCP reset by the client > after IP takeover > > This can also be used to send RST segments (if rst is true) and also > if correct seq and ack numbers are provided. > */ >static int sys_send_tcp(const union generic_sockaddr *src, > const union generic_sockaddr *dst, > uint32_t seq, uint32_t ack, int rst) >{ > int s; > int ret; > uint32_t one = 1; > union generic_sockaddr tmpdst; > struct { > struct iphdr ip; > struct tcphdr tcp; > } ip4pkt; > struct { > struct ip6_hdr ip6; > struct tcphdr tcp; > } ip6pkt; > > switch (src->sa.sa_family) { > case AF_INET: > memset(&ip4pkt, 0, sizeof(ip4pkt)); > ip4pkt.ip.version = 4; > ip4pkt.ip.ihl = sizeof(ip4pkt.ip)/4; > ip4pkt.ip.tot_len = htons(sizeof(ip4pkt)); > ip4pkt.ip.ttl = 255; > ip4pkt.ip.protocol = IPPROTO_TCP; > ip4pkt.ip.saddr = src->sin.sin_addr.s_addr; > ip4pkt.ip.daddr = dst->sin.sin_addr.s_addr; > ip4pkt.ip.check = 0; > > ip4pkt.tcp.source = src->sin.sin_port; > ip4pkt.tcp.dest = dst->sin.sin_port; > ip4pkt.tcp.seq = seq; > ip4pkt.tcp.ack_seq = ack; > ip4pkt.tcp.ack = 1; > if (rst) { > ip4pkt.tcp.rst = 1; > } > ip4pkt.tcp.doff = sizeof(ip4pkt.tcp)/4; > /* this makes it easier to spot in a sniffer */ > ip4pkt.tcp.window = htons(1234); > ip4pkt.tcp.check = tcp_checksum((uint16_t *)&ip4pkt.tcp, sizeof(ip4pkt.tcp), &ip4pkt.ip); > > /* open a raw socket to send this segment from */ > s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW)); > if (s == -1) { > printf("failed to open raw socket (%s)\n", > strerror(errno)); > return -1; > } > > ret = setsockopt(s, SOL_IP, IP_HDRINCL, &one, sizeof(one)); > if (ret != 0) { > printf("failed to setup IP headers (%s)\n", > strerror(errno)); > close(s); > return -1; > } > > ret = sendto(s, &ip4pkt, sizeof(ip4pkt), 0, &dst->sa, sizeof(dst->sin)); > close(s); > if (ret != sizeof(ip4pkt)) { > printf("failed sendto (%s)\n", strerror(errno)); > return -1; > } > break; > case AF_INET6: > memset(&ip6pkt, 0, sizeof(ip6pkt)); > ip6pkt.ip6.ip6_vfc = 0x60; > ip6pkt.ip6.ip6_plen = htons(20); > ip6pkt.ip6.ip6_nxt = IPPROTO_TCP; > ip6pkt.ip6.ip6_hlim = 64; > ip6pkt.ip6.ip6_src = src->sin6.sin6_addr; > ip6pkt.ip6.ip6_dst = dst->sin6.sin6_addr; > > ip6pkt.tcp.source = src->sin6.sin6_port; > ip6pkt.tcp.dest = dst->sin6.sin6_port; > ip6pkt.tcp.seq = seq; > ip6pkt.tcp.ack_seq = ack; > ip6pkt.tcp.ack = 1; > if (rst) { > ip6pkt.tcp.rst = 1; > } > ip6pkt.tcp.doff = sizeof(ip6pkt.tcp)/4; > /* this makes it easier to spot in a sniffer */ > ip6pkt.tcp.window = htons(1234); > ip6pkt.tcp.check = tcp_checksum6((uint16_t *)&ip6pkt.tcp, sizeof(ip6pkt.tcp), &ip6pkt.ip6); > > s = socket(PF_INET6, SOCK_RAW, IPPROTO_RAW); > if (s == -1) { > printf("Failed to open sending socket\n"); > return -1; > > } > /* sendto() dont like if the port is set and the socket is > in raw mode. > */ > tmpdst = *dst; > tmpdst.sin6.sin6_port = 0; > ret = sendto(s, &ip6pkt, sizeof(ip6pkt), 0, &tmpdst.sa, sizeof(tmpdst.sin6)); > close(s); > > if (ret != sizeof(ip6pkt)) { > printf("failed sendto (%s)\n", strerror(errno)); > return -1; > } > break; > > default: > printf("not an ipv4/v6 address\n"); > return -1; > } > > return 0; >} > >static bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin) >{ > sin->sin_family = AF_INET; > sin->sin_port = htons(port); > > if (inet_pton(AF_INET, s, &sin->sin_addr) != 1) { > printf("inet_pton failed to translate %s into sin_addr\n", s); > return false; > } > > return true; >} > >static bool parse_ipv6(const char *s, const char *ifaces, unsigned port, struct sockaddr_in6 *sin6) >{ > sin6->sin6_family = AF_INET6; > sin6->sin6_port = htons(port); > sin6->sin6_flowinfo = 0; > sin6->sin6_scope_id = 0; > > if (inet_pton(AF_INET6, s, &sin6->sin6_addr) != 1) { > printf("inet_pton failed to translate %s into sin6_addr\n", s); > return false; > } > > if (ifaces && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { > if (strchr(ifaces, ',')) { > printf("Link local address %s " > "is specified for multiple ifaces %s\n", > s, ifaces); > return false; > } > sin6->sin6_scope_id = if_nametoindex(ifaces); > } > > return true; >} > >/* > parse an ip > */ >static bool parse_ip(const char *addr, const char *ifaces, unsigned port, union generic_sockaddr *saddr) >{ > char *p; > bool ret; > > /* now is this a ipv4 or ipv6 address ?*/ > p = index(addr, ':'); > if (p == NULL) { > ret = parse_ipv4(addr, port, &saddr->sin); > } else { > ret = parse_ipv6(addr, ifaces, port, &saddr->sin6); > } > > return ret; >} > >/* > parse a ip:port pair > */ >static bool parse_ip_port(const char *addr, union generic_sockaddr *saddr) >{ > char *s, *p; > unsigned port; > char *endp = NULL; > bool ret; > > s = strdup(addr); > if (s == NULL) { > printf("Failed strdup(%s)\n", addr); > return false; > } > > p = rindex(s, ':'); > if (p == NULL) { > printf("This addr: %s does not contain a port number\n", s); > return false; > } > > port = strtoul(p+1, &endp, 10); > if (endp == NULL || *endp != 0) { > printf("Trailing garbage after the port in %s\n", s); > return false; > } > *p = 0; > > > /* now is this a ipv4 or ipv6 address ?*/ > ret = parse_ip(s, NULL, port, saddr); > > return ret; >} > >int main(int argc, const char *argv[]) >{ > int ret; > union generic_sockaddr src, dst; > > if (argc < 3) { > printf("tickleack <srcip>:<srcport> <dstip>:<dstport>\n"); > return -1; > } > > if (!parse_ip_port(argv[1], &src)) { > printf("Bad IP:port '%s'\n", argv[1]); > return -1; > } > > if (!parse_ip_port(argv[2], &dst)) { > printf("Bad IP:port '%s'\n", argv[2]); > return -1; > } > > ret = sys_send_tcp(&src, &dst, 0, 0, 0); > if (ret==0) { > return 0; > } > printf("Error while sending tickle ack\n"); > > return -1; >} >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 7295
:
5543
|
5559
| 5560 |
5561
|
5562
|
5598
|
5607