Browse Source

code formatting and copyright

pull/1/head
Niels Werensteijn 8 years ago
parent
commit
481ba26c0f
  1. 10
      src/ts3init_header.h
  2. 310
      src/ts3init_target.c

10
src/ts3init_header.h

@ -30,12 +30,12 @@ struct ts3_init_checked_header_data @@ -30,12 +30,12 @@ struct ts3_init_checked_header_data
enum
{
COMMAND_GET_COOKIE = 0,
COMMAND_SET_COOKIE,
COMMAND_SET_COOKIE,
COMMAND_GET_PUZZLE,
COMMAND_SET_PUZZLE,
COMMAND_SOLVE_PUZZLE,
COMMAND_RESET_PUZZLE,
COMMAND_MAX
COMMAND_SET_PUZZLE,
COMMAND_SOLVE_PUZZLE,
COMMAND_RESET_PUZZLE,
COMMAND_MAX
};
#endif /* _TS3INIT_HEADER_H */

310
src/ts3init_target.c

@ -5,8 +5,8 @@ @@ -5,8 +5,8 @@
* This is the "target" code
*
* Authors:
* Niels Werensteijn <niels werensteijn [at] teampseak com>, 2016-10-03
*
* Niels Werensteijn <niels werensteijn [at] teamspeak com>, 2016-10-03
* Maximilian Muenchow <maximilian muenchow [at] teamspeak.com>, 2016-10-03
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License; either version 2
* or 3 of the License, as published by the Free Software Foundation.
@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
#include <linux/udp.h>
#include <linux/netfilter/x_tables.h>
#ifdef CONFIG_BRIDGE_NETFILTER
# include <linux/netfilter_bridge.h>
# include <linux/netfilter_bridge.h>
#endif
#include <net/ip.h>
#include <net/ip6_checksum.h>
@ -33,155 +33,156 @@ @@ -33,155 +33,156 @@
bool
send_ipv6(const struct sk_buff *oldskb, const struct xt_action_param *par, u8 command, const void *payload, const size_t payload_size)
{
const struct udphdr *oldudp;
const struct ipv6hdr *oldip;
struct udphdr *newudp, oldudp_buf;
struct ipv6hdr *newip;
struct sk_buff *newskb;
struct flowi6 fl;
struct dst_entry *dst = NULL;
struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
oldip = ipv6_hdr(oldskb);
oldudp = skb_header_pointer(oldskb, par->thoff,
sizeof(*oldudp), &oldudp_buf);
if (oldudp == NULL)
return false;
if (ntohs(oldudp->len) <= sizeof(*oldudp))
return false;
newskb = alloc_skb(LL_MAX_HEADER + sizeof(*newip) +
sizeof(*newudp) + payload_size, GFP_ATOMIC);
if (newskb == NULL)
return false;
skb_reserve(newskb, LL_MAX_HEADER);
newskb->protocol = oldskb->protocol;
skb_reset_network_header(newskb);
newip = (void *)skb_put(newskb, sizeof(*newip));
newip->version = oldip->version;
newip->priority = oldip->priority;
memcpy(newip->flow_lbl, oldip->flow_lbl, sizeof(newip->flow_lbl));
newip->nexthdr = par->target->proto;
newip->saddr = oldip->daddr;
newip->daddr = oldip->saddr;
skb_reset_transport_header(newskb);
newudp = (void *)skb_put(newskb, sizeof(*newudp));
newudp->source = oldudp->dest;
newudp->dest = oldudp->source;
newudp->len = htons(sizeof(*newudp) + payload_size);
memcpy(skb_put(newskb, payload_size), payload, payload_size);
newip->payload_len = htons(newskb->len);
newudp->check = 0;
newudp->check = csum_ipv6_magic(&newip->saddr, &newip->daddr,
ntohs(newudp->len), IPPROTO_UDP,
csum_partial(newudp, ntohs(newudp->len), 0));
memset(&fl, 0, sizeof(fl));
fl.flowi6_proto = newip->nexthdr;
memcpy(&fl.saddr, &newip->saddr, sizeof(fl.saddr));
memcpy(&fl.daddr, &newip->daddr, sizeof(fl.daddr));
fl.fl6_sport = newudp->source;
fl.fl6_dport = newudp->dest;
security_skb_classify_flow((struct sk_buff *)oldskb, flowi6_to_flowi(&fl));
dst = ip6_route_output(net, NULL, &fl);
if (dst == NULL || dst->error != 0) {
dst_release(dst);
goto free_nskb;
}
skb_dst_set(newskb, dst);
newip->hop_limit = ip6_dst_hoplimit(skb_dst(newskb));
newskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" (?) */
if (newskb->len > dst_mtu(skb_dst(newskb)))
goto free_nskb;
nf_ct_attach(newskb, oldskb);
ip6_local_out(par_net(par), newskb->sk, newskb);
return true;
const struct udphdr *oldudp;
const struct ipv6hdr *oldip;
struct udphdr *newudp, oldudp_buf;
struct ipv6hdr *newip;
struct sk_buff *newskb;
struct flowi6 fl;
struct dst_entry *dst = NULL;
struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
oldip = ipv6_hdr(oldskb);
oldudp = skb_header_pointer(oldskb, par->thoff,
sizeof(*oldudp), &oldudp_buf);
if (oldudp == NULL)
return false;
if (ntohs(oldudp->len) <= sizeof(*oldudp))
return false;
newskb = alloc_skb(LL_MAX_HEADER + sizeof(*newip) +
sizeof(*newudp) + payload_size, GFP_ATOMIC);
if (newskb == NULL)
return false;
skb_reserve(newskb, LL_MAX_HEADER);
newskb->protocol = oldskb->protocol;
skb_reset_network_header(newskb);
newip = (void *)skb_put(newskb, sizeof(*newip));
newip->version = oldip->version;
newip->priority = oldip->priority;
memcpy(newip->flow_lbl, oldip->flow_lbl, sizeof(newip->flow_lbl));
newip->nexthdr = par->target->proto;
newip->saddr = oldip->daddr;
newip->daddr = oldip->saddr;
skb_reset_transport_header(newskb);
newudp = (void *)skb_put(newskb, sizeof(*newudp));
newudp->source = oldudp->dest;
newudp->dest = oldudp->source;
newudp->len = htons(sizeof(*newudp) + payload_size);
memcpy(skb_put(newskb, payload_size), payload, payload_size);
newip->payload_len = htons(newskb->len);
newudp->check = 0;
newudp->check = csum_ipv6_magic(&newip->saddr, &newip->daddr,
ntohs(newudp->len), IPPROTO_UDP,
csum_partial(newudp, ntohs(newudp->len), 0));
memset(&fl, 0, sizeof(fl));
fl.flowi6_proto = newip->nexthdr;
memcpy(&fl.saddr, &newip->saddr, sizeof(fl.saddr));
memcpy(&fl.daddr, &newip->daddr, sizeof(fl.daddr));
fl.fl6_sport = newudp->source;
fl.fl6_dport = newudp->dest;
security_skb_classify_flow((struct sk_buff *)oldskb, flowi6_to_flowi(&fl));
dst = ip6_route_output(net, NULL, &fl);
if (dst == NULL || dst->error != 0)
{
dst_release(dst);
goto free_nskb;
}
skb_dst_set(newskb, dst);
newip->hop_limit = ip6_dst_hoplimit(skb_dst(newskb));
newskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" (?) */
if (newskb->len > dst_mtu(skb_dst(newskb)))
goto free_nskb;
nf_ct_attach(newskb, oldskb);
ip6_local_out(par_net(par), newskb->sk, newskb);
return true;
free_nskb:
kfree_skb(newskb);
return false;
kfree_skb(newskb);
return false;
}
bool
send_ipv4(const struct sk_buff *oldskb, const struct xt_action_param *par, u8 command, const void *payload, const size_t payload_size)
{
const struct udphdr *oldudp;
const struct iphdr *oldip;
struct udphdr *newudp, oldudp_buf;
struct iphdr *newip;
struct sk_buff *newskb;
oldip = ip_hdr(oldskb);
oldudp = skb_header_pointer(oldskb, par->thoff,
sizeof(*oldudp), &oldudp_buf);
if (oldudp == NULL)
return false;
if (ntohs(oldudp->len) <= sizeof(*oldudp))
return false;
newskb = alloc_skb(LL_MAX_HEADER + sizeof(*newip) +
sizeof(*newudp) + payload_size, GFP_ATOMIC);
if (newskb == NULL)
return false;
skb_reserve(newskb, LL_MAX_HEADER);
newskb->protocol = oldskb->protocol;
skb_reset_network_header(newskb);
newip = (void *)skb_put(newskb, sizeof(*newip));
newip->version = oldip->version;
newip->ihl = sizeof(*newip) / 4;
newip->tos = oldip->tos;
newip->id = oldip->id;
newip->frag_off = 0;
newip->protocol = oldip->protocol;
newip->check = 0;
newip->saddr = oldip->daddr;
newip->daddr = oldip->saddr;
skb_reset_transport_header(newskb);
newudp = (void *)skb_put(newskb, sizeof(*newudp));
newudp->source = oldudp->dest;
newudp->dest = oldudp->source;
newudp->len = htons(sizeof(*newudp) + payload_size);
memcpy(skb_put(newskb, payload_size), payload, payload_size);
newip->tot_len = htons(newskb->len);
newudp->check = 0;
newudp->check = csum_tcpudp_magic(newip->saddr, newip->daddr,
ntohs(newudp->len), IPPROTO_UDP,
csum_partial(newudp, ntohs(newudp->len), 0));
/* ip_route_me_harder expects the skb's dst to be set */
skb_dst_set(newskb, dst_clone(skb_dst(oldskb)));
if (ip_route_me_harder(par_net(par), newskb, RTN_UNSPEC) != 0)
goto free_nskb;
newip->ttl = ip4_dst_hoplimit(skb_dst(newskb));
newskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" (?) */
if (newskb->len > dst_mtu(skb_dst(newskb)))
goto free_nskb;
nf_ct_attach(newskb, oldskb);
ip_local_out(par_net(par), newskb->sk, newskb);
return true;
const struct udphdr *oldudp;
const struct iphdr *oldip;
struct udphdr *newudp, oldudp_buf;
struct iphdr *newip;
struct sk_buff *newskb;
oldip = ip_hdr(oldskb);
oldudp = skb_header_pointer(oldskb, par->thoff,
sizeof(*oldudp), &oldudp_buf);
if (oldudp == NULL)
return false;
if (ntohs(oldudp->len) <= sizeof(*oldudp))
return false;
newskb = alloc_skb(LL_MAX_HEADER + sizeof(*newip) +
sizeof(*newudp) + payload_size, GFP_ATOMIC);
if (newskb == NULL)
return false;
skb_reserve(newskb, LL_MAX_HEADER);
newskb->protocol = oldskb->protocol;
skb_reset_network_header(newskb);
newip = (void *)skb_put(newskb, sizeof(*newip));
newip->version = oldip->version;
newip->ihl = sizeof(*newip) / 4;
newip->tos = oldip->tos;
newip->id = oldip->id;
newip->frag_off = 0;
newip->protocol = oldip->protocol;
newip->check = 0;
newip->saddr = oldip->daddr;
newip->daddr = oldip->saddr;
skb_reset_transport_header(newskb);
newudp = (void *)skb_put(newskb, sizeof(*newudp));
newudp->source = oldudp->dest;
newudp->dest = oldudp->source;
newudp->len = htons(sizeof(*newudp) + payload_size);
memcpy(skb_put(newskb, payload_size), payload, payload_size);
newip->tot_len = htons(newskb->len);
newudp->check = 0;
newudp->check = csum_tcpudp_magic(newip->saddr, newip->daddr,
ntohs(newudp->len), IPPROTO_UDP,
csum_partial(newudp, ntohs(newudp->len), 0));
/* ip_route_me_harder expects the skb's dst to be set */
skb_dst_set(newskb, dst_clone(skb_dst(oldskb)));
if (ip_route_me_harder(par_net(par), newskb, RTN_UNSPEC) != 0)
goto free_nskb;
newip->ttl = ip4_dst_hoplimit(skb_dst(newskb));
newskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" (?) */
if (newskb->len > dst_mtu(skb_dst(newskb)))
goto free_nskb;
nf_ct_attach(newskb, oldskb);
ip_local_out(par_net(par), newskb->sk, newskb);
return true;
free_nskb:
kfree_skb(newskb);
return false;
kfree_skb(newskb);
return false;
}
static const char reset_package[] = {'T', 'S', '3', 'I', 'N', 'I', 'T', '1', 0x65, 0, 0x88, COMMAND_RESET_PUZZLE, 0 };
@ -189,20 +190,21 @@ static const char reset_package[] = {'T', 'S', '3', 'I', 'N', 'I', 'T', '1', 0x6 @@ -189,20 +190,21 @@ static const char reset_package[] = {'T', 'S', '3', 'I', 'N', 'I', 'T', '1', 0x6
static unsigned int
ts3init_reset_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
switch (par->family)
{
case NFPROTO_IPV4:
send_ipv4(skb, par, COMMAND_RESET_PUZZLE, reset_package, sizeof(reset_package));
break;
case NFPROTO_IPV6:
send_ipv6(skb, par, COMMAND_RESET_PUZZLE, reset_package, sizeof(reset_package));
break;
}
switch (par->family)
{
case NFPROTO_IPV4:
send_ipv4(skb, par, COMMAND_RESET_PUZZLE, reset_package, sizeof(reset_package));
break;
case NFPROTO_IPV6:
send_ipv6(skb, par, COMMAND_RESET_PUZZLE, reset_package, sizeof(reset_package));
break;
}
return NF_DROP;
}
static struct xt_target ts3init_tg_reg[] __read_mostly = {
static struct xt_target ts3init_tg_reg[] __read_mostly =
{
{
.name = "ts3init_reset",
.revision = 0,

Loading…
Cancel
Save