本文整理汇总了C++中CTINFO2DIR函数的典型用法代码示例。如果您正苦于以下问题:C++ CTINFO2DIR函数的具体用法?C++ CTINFO2DIR怎么用?C++ CTINFO2DIR使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CTINFO2DIR函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: nf_nat_local_fn
static unsigned int
nf_nat_local_fn(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
const struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
unsigned int ret;
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT;
ret = nf_nat_fn(hooknum, skb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN &&
(ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.dst.u3.ip !=
ct->tuplehash[!dir].tuple.src.u3.ip) {
if (ip_route_me_harder(skb, RTN_UNSPEC))
ret = NF_DROP;
}
#ifdef CONFIG_XFRM
else if (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
ct->tuplehash[dir].tuple.dst.u.all !=
ct->tuplehash[!dir].tuple.src.u.all)
if (ip_xfrm_me_harder(skb))
ret = NF_DROP;
#endif
}
return ret;
}
示例2: nf_nat_ipv6_local_fn
static unsigned int
nf_nat_ipv6_local_fn(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
const struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
unsigned int ret;
/* root is playing with raw sockets. */
if (skb->len < sizeof(struct ipv6hdr))
return NF_ACCEPT;
ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN &&
(ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
&ct->tuplehash[!dir].tuple.src.u3)) {
if (ip6_route_me_harder(skb))
ret = NF_DROP;
}
#ifdef CONFIG_XFRM
else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
ct->tuplehash[dir].tuple.dst.u.all !=
ct->tuplehash[!dir].tuple.src.u.all)
if (nf_xfrm_me_harder(skb, AF_INET6))
ret = NF_DROP;
#endif
}
return ret;
}
示例3: tcp_packet
/* Returns verdict for packet, or -1 for invalid. */
static int tcp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
u_int8_t pf,
unsigned int hooknum)
{
struct net *net = nf_ct_net(ct);
struct nf_conntrack_tuple *tuple;
#if defined(CONFIG_MV_ETH_NFP_CT_LEARN)
struct nf_conntrack_tuple *tupleInverseDir;
#endif
enum tcp_conntrack new_state, old_state;
enum ip_conntrack_dir dir;
const struct tcphdr *th;
struct tcphdr _tcph;
unsigned long timeout;
unsigned int index;
th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
BUG_ON(th == NULL);
spin_lock_bh(&ct->lock);
old_state = ct->proto.tcp.state;
dir = CTINFO2DIR(ctinfo);
index = get_conntrack_index(th);
new_state = tcp_conntracks[dir][index][old_state];
tuple = &ct->tuplehash[dir].tuple;
#if defined(CONFIG_MV_ETH_NFP_CT_LEARN)
tupleInverseDir = &ct->tuplehash[!dir].tuple;
#endif
switch (new_state) {
case TCP_CONNTRACK_SYN_SENT:
if (old_state < TCP_CONNTRACK_TIME_WAIT)
break;
/* RFC 1122: "When a connection is closed actively,
* it MUST linger in TIME-WAIT state for a time 2xMSL
* (Maximum Segment Lifetime). However, it MAY accept
* a new SYN from the remote TCP to reopen the connection
* directly from TIME-WAIT state, if..."
* We ignore the conditions because we are in the
* TIME-WAIT state anyway.
*
* Handle aborted connections: we and the server
* think there is an existing connection but the client
* aborts it and starts a new one.
*/
if (((ct->proto.tcp.seen[dir].flags
| ct->proto.tcp.seen[!dir].flags)
& IP_CT_TCP_FLAG_CLOSE_INIT)
|| (ct->proto.tcp.last_dir == dir
&& ct->proto.tcp.last_index == TCP_RST_SET)) {
/* Attempt to reopen a closed/aborted connection.
* Delete this connection and look up again. */
spin_unlock_bh(&ct->lock);
/* Only repeat if we can actually remove the timer.
* Destruction may already be in progress in process
* context and we must give it a chance to terminate.
*/
if (nf_ct_kill(ct))
return -NF_REPEAT;
return NF_DROP;
}
/* Fall through */
case TCP_CONNTRACK_IGNORE:
/* Ignored packets:
*
* Our connection entry may be out of sync, so ignore
* packets which may signal the real connection between
* the client and the server.
*
* a) SYN in ORIGINAL
* b) SYN/ACK in REPLY
* c) ACK in reply direction after initial SYN in original.
*
* If the ignored packet is invalid, the receiver will send
* a RST we'll catch below.
*/
if (index == TCP_SYNACK_SET
&& ct->proto.tcp.last_index == TCP_SYN_SET
&& ct->proto.tcp.last_dir != dir
&& ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
/* b) This SYN/ACK acknowledges a SYN that we earlier
* ignored as invalid. This means that the client and
* the server are both in sync, while the firewall is
* not. We kill this session and block the SYN/ACK so
* that the client cannot but retransmit its SYN and
* thus initiate a clean new session.
*/
spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: killing out of sync session ");
nf_ct_kill(ct);
return NF_DROP;
}
ct->proto.tcp.last_index = index;
ct->proto.tcp.last_dir = dir;
//.........这里部分代码省略.........
示例4: quake3_help
static int quake3_help(struct sk_buff **pskb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo)
{
struct udphdr _udph, *uh;
struct ip_conntrack_expect *exp;
void *data, *qb_ptr;
int dir = CTINFO2DIR(ctinfo);
int i, dataoff;
int ret = NF_ACCEPT;
/* Until there's been traffic both ways, don't look in packets. note:
* it's UDP ! */
if (ctinfo != IP_CT_ESTABLISHED
&& ctinfo != IP_CT_IS_REPLY) {
DEBUGP("ip_conntrack_quake3: not ok ! Conntrackinfo = %u\n",
ctinfo);
return NF_ACCEPT;
} else {
DEBUGP("ip_conntrack_quake3: it's ok ! Conntrackinfo = %u\n",
ctinfo);
}
/* Valid UDP header? */
uh = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
sizeof(_udph), &_udph);
if (!uh)
return NF_ACCEPT;
/* Any data? */
dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
if (dataoff >= (*pskb)->len)
return NF_ACCEPT;
spin_lock_bh(&quake3_buffer_lock);
qb_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, quake3_buffer);
BUG_ON(qb_ptr == NULL);
data = qb_ptr;
if (strnicmp(data + 4, quake3s_conntrack.pattern,
quake3s_conntrack.plen) == 0) {
for(i=23; /* 4 bytes filler, 18 bytes "getserversResponse",
1 byte "\" */
i+6 < ntohs(uh->len);
i+=7) {
u_int32_t *ip = data+i;
u_int16_t *port = data+i+4;
#if 0
DEBUGP("ip_conntrack_quake3: adding server at offset "
"%u/%u %u.%u.%u.%u:%u\n", i, ntohs(uh->len),
NIPQUAD(*ip), ntohs(*port));
#endif
exp = ip_conntrack_expect_alloc(ct);
if (!exp) {
ret = NF_DROP;
goto out;
}
memset(exp, 0, sizeof(*exp));
exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
exp->tuple.dst.ip = *ip;
exp->tuple.dst.u.udp.port = *port;
exp->tuple.dst.protonum = IPPROTO_UDP;
exp->mask.src.ip = 0xffffffff;
exp->mask.dst.ip = 0xffffffff;
exp->mask.dst.u.udp.port = 0xffff;
exp->mask.dst.protonum = 0xff;
if (ip_nat_quake3_hook)
ret = ip_nat_quake3_hook(exp);
else if (ip_conntrack_expect_related(exp) != 0) {
ip_conntrack_expect_put(exp);
ret = NF_DROP;
}
goto out;
}
}
out:
spin_unlock_bh(&quake3_buffer_lock);
return ret;
}
示例5: ip_nat_fn
static unsigned int
ip_nat_fn(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
struct ip_nat_info *info;
/* maniptype == SRC for postrouting. */
enum ip_nat_manip_type maniptype = HOOK2MANIP(hooknum);
/* We never see fragments: conntrack defrags on pre-routing
and local-out, and ip_nat_out protects post-routing. */
IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
& htons(IP_MF|IP_OFFSET)));
(*pskb)->nfcache |= NFC_UNKNOWN;
/* If we had a hardware checksum before, it's now invalid */
if ((*pskb)->ip_summed == CHECKSUM_HW)
(*pskb)->ip_summed = CHECKSUM_NONE;
ct = ip_conntrack_get(*pskb, &ctinfo);
/* Can't track? It's not due to stress, or conntrack would
have dropped it. Hence it's the user's responsibilty to
packet filter it out, or implement conntrack/NAT for that
protocol. 8) --RR */
if (!ct) {
/* Exception: ICMP redirect to new connection (not in
hash table yet). We must not let this through, in
case we're doing NAT to the same network. */
struct iphdr *iph = (*pskb)->nh.iph;
struct icmphdr *hdr = (struct icmphdr *)
((u_int32_t *)iph + iph->ihl);
if (iph->protocol == IPPROTO_ICMP
&& hdr->type == ICMP_REDIRECT)
return NF_DROP;
return NF_ACCEPT;
}
switch (ctinfo) {
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
return icmp_reply_translation(*pskb, ct, hooknum,
CTINFO2DIR(ctinfo));
}
/* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
case IP_CT_NEW:
#ifdef CONFIG_IP_NF_NAT_LOCAL
/* LOCAL_IN hook doesn't have a chain and thus doesn't care
* about new packets -HW */
if (hooknum == NF_IP_LOCAL_IN)
return NF_ACCEPT;
#endif
info = &ct->nat.info;
WRITE_LOCK(&ip_nat_lock);
/* Seen it before? This can happen for loopback, retrans,
or local packets.. */
if (!(info->initialized & (1 << maniptype))) {
int in_hashes = info->initialized;
unsigned int ret;
if (ct->master
&& master_ct(ct)->nat.info.helper
&& master_ct(ct)->nat.info.helper->expect) {
ret = call_expect(master_ct(ct), pskb,
hooknum, ct, info);
} else {
ret = ip_nat_rule_find(pskb, hooknum, in, out,
ct, info);
}
if (ret != NF_ACCEPT) {
WRITE_UNLOCK(&ip_nat_lock);
return ret;
}
if (in_hashes) {
IP_NF_ASSERT(info->bysource.conntrack);
replace_in_hashes(ct, info);
} else {
place_in_hashes(ct, info);
}
} else
DEBUGP("Already setup manip %s for ct %p\n",
maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
ct);
WRITE_UNLOCK(&ip_nat_lock);
break;
default:
/* ESTABLISHED */
IP_NF_ASSERT(ctinfo == IP_CT_ESTABLISHED
|| ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
info = &ct->nat.info;
}
//.........这里部分代码省略.........
示例6: help
static int help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
unsigned int dataoff;
const struct iphdr *iph;
const struct tcphdr *th;
struct tcphdr _tcph;
const char *data_limit;
char *data, *ib_ptr;
int dir = CTINFO2DIR(ctinfo);
struct nf_conntrack_expect *exp;
struct nf_conntrack_tuple *tuple;
__be32 dcc_ip;
u_int16_t dcc_port;
__be16 port;
int i, ret = NF_ACCEPT;
char *addr_beg_p, *addr_end_p;
typeof(nf_nat_irc_hook) nf_nat_irc;
/* If packet is coming from IRC server */
if (dir == IP_CT_DIR_REPLY)
return NF_ACCEPT;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
/* Not a full tcp header? */
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = protoff + th->doff*4;
if (dataoff >= skb->len)
return NF_ACCEPT;
spin_lock_bh(&irc_buffer_lock);
ib_ptr = skb_header_pointer(skb, dataoff, skb->len - dataoff,
irc_buffer);
BUG_ON(ib_ptr == NULL);
data = ib_ptr;
data_limit = ib_ptr + skb->len - dataoff;
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
while (data < data_limit - (19 + MINMATCHLEN)) {
if (memcmp(data, "\1DCC ", 5)) {
data++;
continue;
}
data += 5;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
iph = ip_hdr(skb);
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
&iph->saddr, ntohs(th->source),
&iph->daddr, ntohs(th->dest));
for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
/* no match */
continue;
}
data += strlen(dccprotos[i]);
pr_debug("DCC %s detected\n", dccprotos[i]);
/* we have at least
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
* data left (== 14/13 bytes) */
if (parse_dcc(data, data_limit, &dcc_ip,
&dcc_port, &addr_beg_p, &addr_end_p)) {
pr_debug("unable to parse dcc command\n");
continue;
}
pr_debug("DCC bound ip/port: %pI4:%u\n",
&dcc_ip, dcc_port);
/* dcc_ip can be the internal OR external (NAT'ed) IP */
tuple = &ct->tuplehash[dir].tuple;
if (tuple->src.u3.ip != dcc_ip &&
tuple->dst.u3.ip != dcc_ip) {
net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n",
&tuple->src.u3.ip,
&dcc_ip, dcc_port);
continue;
}
exp = nf_ct_expect_alloc(ct);
if (exp == NULL) {
nf_ct_helper_log(skb, ct,
"cannot alloc expectation");
ret = NF_DROP;
goto out;
}
tuple = &ct->tuplehash[!dir].tuple;
port = htons(dcc_port);
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
//.........这里部分代码省略.........
示例7: ip_nat_sip
static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned int coff, matchoff, matchlen;
enum sip_header_types hdr;
union nf_inet_addr addr;
__be16 port;
int request, in_header;
/* Basic rules: requests and responses. */
if (strnicmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) {
if (ct_sip_parse_request(ct, *dptr, *datalen,
&matchoff, &matchlen,
&addr, &port) > 0 &&
!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
request = 1;
} else
request = 0;
if (nf_ct_protonum(ct) == IPPROTO_TCP)
hdr = SIP_HDR_VIA_TCP;
else
hdr = SIP_HDR_VIA_UDP;
/* Translate topmost Via header and parameters */
if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
hdr, NULL, &matchoff, &matchlen,
&addr, &port) > 0) {
unsigned int matchend, poff, plen, buflen, n;
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
/* We're only interested in headers related to this
* connection */
if (request) {
if (addr.ip != ct->tuplehash[dir].tuple.src.u3.ip ||
port != ct->tuplehash[dir].tuple.src.u.udp.port)
goto next;
} else {
if (addr.ip != ct->tuplehash[dir].tuple.dst.u3.ip ||
port != ct->tuplehash[dir].tuple.dst.u.udp.port)
goto next;
}
if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
&addr, port))
return NF_DROP;
matchend = matchoff + matchlen;
/* The maddr= parameter (RFC 2361) specifies where to send
* the reply. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"maddr=", &poff, &plen,
&addr) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
buflen = sprintf(buffer, "%pI4",
&ct->tuplehash[!dir].tuple.dst.u3.ip);
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}
/* The received= parameter (RFC 2361) contains the address
* from which the server received the request. */
if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
"received=", &poff, &plen,
&addr) > 0 &&
addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
buflen = sprintf(buffer, "%pI4",
&ct->tuplehash[!dir].tuple.src.u3.ip);
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}
/* The rport= parameter (RFC 3581) contains the port number
* from which the server received the request. */
if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen,
"rport=", &poff, &plen,
&n) > 0 &&
htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port &&
htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
__be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
buflen = sprintf(buffer, "%u", ntohs(p));
if (!mangle_packet(skb, dataoff, dptr, datalen,
poff, plen, buffer, buflen))
return NF_DROP;
}
}
next:
/* Translate Contact headers */
coff = 0;
//.........这里部分代码省略.........
示例8: help
static int help(struct sk_buff **pskb,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{
unsigned int dataoff;
struct tcphdr _tcph, *th;
char *data, *data_limit, *ib_ptr;
int dir = CTINFO2DIR(ctinfo);
struct ip_conntrack_expect *exp;
u32 seq;
u_int32_t dcc_ip;
u_int16_t dcc_port;
int i, ret = NF_ACCEPT;
char *addr_beg_p, *addr_end_p;
DEBUGP("entered\n");
/* If packet is coming from IRC server */
if (dir == IP_CT_DIR_REPLY)
return NF_ACCEPT;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED
&& ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
DEBUGP("Conntrackinfo = %u\n", ctinfo);
return NF_ACCEPT;
}
/* Not a full tcp header? */
th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = (*pskb)->nh.iph->ihl*4 + th->doff*4;
if (dataoff >= (*pskb)->len)
return NF_ACCEPT;
spin_lock_bh(&irc_buffer_lock);
ib_ptr = skb_header_pointer(*pskb, dataoff,
(*pskb)->len - dataoff, irc_buffer);
BUG_ON(ib_ptr == NULL);
data = ib_ptr;
data_limit = ib_ptr + (*pskb)->len - dataoff;
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
while (data < (data_limit - (19 + MINMATCHLEN))) {
if (memcmp(data, "\1DCC ", 5)) {
data++;
continue;
}
data += 5;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
NIPQUAD(iph->saddr), ntohs(th->source),
NIPQUAD(iph->daddr), ntohs(th->dest));
for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
/* no match */
continue;
}
DEBUGP("DCC %s detected\n", dccprotos[i]);
data += strlen(dccprotos[i]);
/* we have at least
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
* data left (== 14/13 bytes) */
if (parse_dcc((char *)data, data_limit, &dcc_ip,
&dcc_port, &addr_beg_p, &addr_end_p)) {
/* unable to parse */
DEBUGP("unable to parse dcc command\n");
continue;
}
DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
HIPQUAD(dcc_ip), dcc_port);
/* dcc_ip can be the internal OR external (NAT'ed) IP
* Tiago Sousa <[email protected]> */
if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)
&& ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != htonl(dcc_ip)) {
if (net_ratelimit())
printk(KERN_WARNING
"Forged DCC command from "
"%u.%u.%u.%u: %u.%u.%u.%u:%u\n",
NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
HIPQUAD(dcc_ip), dcc_port);
continue;
}
exp = ip_conntrack_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
//.........这里部分代码省略.........
示例9: ip_nat_sip
static unsigned int ip_nat_sip(struct sk_buff **pskb,
enum ip_conntrack_info ctinfo,
struct ip_conntrack *ct,
const char **dptr)
{
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
unsigned int bufflen, dataoff;
u_int32_t ip;
u_int16_t port;
dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
ip = ct->tuplehash[!dir].tuple.dst.ip;
port = ct->tuplehash[!dir].tuple.dst.u.udp.port;
bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port));
/* short packet ? */
if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1))
return 0;
/* Basic rules: requests and responses. */
if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) {
const char *aux;
if ((ctinfo) < IP_CT_IS_REPLY) {
mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen,
&ct_sip_hdrs[POS_CONTACT]);
return 1;
}
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
return 0;
/* This search should ignore case, but later.. */
aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
(*pskb)->len - dataoff);
if (!aux)
return 0;
if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff)))
return 1;
return mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen,
&ct_sip_hdrs[POS_CONTACT]);
}
if ((ctinfo) < IP_CT_IS_REPLY) {
if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
(*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
return 0;
/* Mangle Contact if exists only. - watch udp_nat_mangle()! */
mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
return 1;
}
/* This mangle requests headers. */
return mangle_sip_packet(pskb, ctinfo, ct, dptr,
ct_sip_lnlen(*dptr,
*dptr + (*pskb)->len - dataoff),
buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
}
示例10: ip_nat_sdp_media
static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff,
unsigned int medialen,
union nf_inet_addr *rtp_addr)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
u_int16_t port;
if (ct->tuplehash[dir].tuple.src.u3.ip ==
ct->tuplehash[!dir].tuple.dst.u3.ip)
rtp_addr->ip = rtp_exp->tuple.dst.u3.ip;
else
rtp_addr->ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
rtp_exp->saved_ip = rtp_exp->tuple.dst.u3.ip;
rtp_exp->tuple.dst.u3.ip = rtp_addr->ip;
rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
rtp_exp->dir = !dir;
rtp_exp->expectfn = ip_nat_sip_expected;
rtcp_exp->saved_ip = rtcp_exp->tuple.dst.u3.ip;
rtcp_exp->tuple.dst.u3.ip = rtp_addr->ip;
rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
rtcp_exp->dir = !dir;
rtcp_exp->expectfn = ip_nat_sip_expected;
for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
port != 0; port += 2) {
int ret;
rtp_exp->tuple.dst.u.udp.port = htons(port);
ret = nf_ct_expect_related(rtp_exp);
if (ret == -EBUSY)
continue;
else if (ret < 0) {
port = 0;
break;
}
rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
ret = nf_ct_expect_related(rtcp_exp);
if (ret == 0)
break;
else if (ret == -EBUSY) {
nf_ct_unexpect_related(rtp_exp);
continue;
} else if (ret < 0) {
nf_ct_unexpect_related(rtp_exp);
port = 0;
break;
}
}
if (port == 0)
goto err1;
if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
!ip_nat_sdp_port(skb, dataoff, dptr, datalen,
mediaoff, medialen, port))
goto err2;
return NF_ACCEPT;
err2:
nf_ct_unexpect_related(rtp_exp);
nf_ct_unexpect_related(rtcp_exp);
err1:
return NF_DROP;
}
示例11: ip_nat_sip_expect
static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff,
const char **dptr, unsigned int *datalen,
struct nf_conntrack_expect *exp,
unsigned int matchoff,
unsigned int matchlen)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
__be32 newip;
u_int16_t port;
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
unsigned buflen;
if (ct->tuplehash[dir].tuple.src.u3.ip == ct->tuplehash[!dir].tuple.dst.u3.ip)
newip = exp->tuple.dst.u3.ip;
else
newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
if (exp->tuple.dst.u.udp.port ==
ct->tuplehash[dir].tuple.src.u.udp.port)
port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
else
port = ntohs(exp->tuple.dst.u.udp.port);
exp->saved_ip = exp->tuple.dst.u3.ip;
exp->tuple.dst.u3.ip = newip;
exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
exp->dir = !dir;
exp->expectfn = ip_nat_sip_expected;
for (; port != 0; port++) {
int ret;
exp->tuple.dst.u.udp.port = htons(port);
ret = nf_ct_expect_related(exp);
if (ret == 0)
break;
else if (ret != -EBUSY) {
port = 0;
break;
}
}
if (port == 0)
return NF_DROP;
if (exp->tuple.dst.u3.ip != exp->saved_ip ||
exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
buflen = sprintf(buffer, "%pI4:%u", &newip, port);
if (!mangle_packet(skb, dataoff, dptr, datalen,
matchoff, matchlen, buffer, buflen))
goto err;
}
return NF_ACCEPT;
err:
nf_ct_unexpect_related(exp);
return NF_DROP;
}
示例12: help
static unsigned int help(struct ip_conntrack *ct,
struct ip_conntrack_expect *exp,
struct ip_nat_info *info,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
struct sk_buff **pskb)
{
struct iphdr *iph = (*pskb)->nh.iph;
struct tcphdr *tcph = (void *)iph + iph->ihl*4;
unsigned int datalen;
int dir;
int score;
struct ip_ct_sc_expect *exp_sc_info = &exp->help.exp_sc_info;
/* Only mangle things once: original direction in POST_ROUTING
and reply direction on PRE_ROUTING. */
dir = CTINFO2DIR(ctinfo);
DEBUGP("nat_sc: help()\n");
#if 0
if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_REPLY)
|| (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_ORIGINAL))) {
#if 1
DEBUGP("nat_sc: Not touching dir %s at hook %s\n",
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
: hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
: hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
#endif
return NF_ACCEPT;
}
#endif
datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
score = 0;
LOCK_BH(&ip_sc_lock);
if (exp_sc_info->len) {
/* If it's in the right range... */
score += between(exp_sc_info->seq, ntohl(tcph->seq),
ntohl(tcph->seq) + datalen);
score += between(exp_sc_info->seq + exp_sc_info->len,
ntohl(tcph->seq),
ntohl(tcph->seq) + datalen);
if (score == 1) {
/* Half a match? This means a partial retransmisison.
It's a cracker being funky. */
if (net_ratelimit()) {
printk("SC_NAT: partial packet %u/%u in %u/%u\n",
exp_sc_info->seq, exp_sc_info->len,
ntohl(tcph->seq),
ntohl(tcph->seq) + datalen);
}
UNLOCK_BH(&ip_sc_lock);
return NF_DROP;
} else if (score == 2) {
if (!sc_data_fixup(exp_sc_info, ct, datalen, pskb, ctinfo)) {
UNLOCK_BH(&ip_sc_lock);
return NF_DROP;
}
/* skb may have been reallocated */
iph = (*pskb)->nh.iph;
tcph = (void *)iph + iph->ihl*4;
}
}
UNLOCK_BH(&ip_sc_lock);
DEBUGP("nat_sc: ip_nat_seq_adjust()\n");
ip_nat_seq_adjust(*pskb, ct, ctinfo);
return NF_ACCEPT;
}
示例13: help
static int help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
unsigned int dataoff, datalen;
const struct tcphdr *th;
struct tcphdr _tcph;
void *sb_ptr;
int ret = NF_ACCEPT;
int dir = CTINFO2DIR(ctinfo);
struct nf_ct_sane_master *ct_sane_info;
struct nf_conntrack_expect *exp;
struct nf_conntrack_tuple *tuple;
struct sane_request *req;
struct sane_reply_net_start *reply;
ct_sane_info = &nfct_help(ct)->help.ct_sane_info;
/* Until there's been traffic both ways, don't look in packets. */
if (ctinfo != IP_CT_ESTABLISHED &&
ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY)
return NF_ACCEPT;
/* Not a full tcp header? */
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = protoff + th->doff * 4;
if (dataoff >= skb->len)
return NF_ACCEPT;
datalen = skb->len - dataoff;
spin_lock_bh(&nf_sane_lock);
sb_ptr = skb_header_pointer(skb, dataoff, datalen, sane_buffer);
BUG_ON(sb_ptr == NULL);
if (dir == IP_CT_DIR_ORIGINAL) {
if (datalen != sizeof(struct sane_request))
goto out;
req = sb_ptr;
if (req->RPC_code != htonl(SANE_NET_START)) {
/* Not an interesting command */
ct_sane_info->state = SANE_STATE_NORMAL;
goto out;
}
/* We're interested in the next reply */
ct_sane_info->state = SANE_STATE_START_REQUESTED;
goto out;
}
/* Is it a reply to an uninteresting command? */
if (ct_sane_info->state != SANE_STATE_START_REQUESTED)
goto out;
/* It's a reply to SANE_NET_START. */
ct_sane_info->state = SANE_STATE_NORMAL;
if (datalen < sizeof(struct sane_reply_net_start)) {
pr_debug("nf_ct_sane: NET_START reply too short\n");
goto out;
}
reply = sb_ptr;
if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
/* saned refused the command */
pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
ntohl(reply->status));
goto out;
}
/* Invalid saned reply? Ignore it. */
if (reply->zero != 0)
goto out;
exp = nf_ct_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
&tuple->src.u3, &tuple->dst.u3,
IPPROTO_TCP, NULL, &reply->port);
pr_debug("nf_ct_sane: expect: ");
nf_ct_dump_tuple(&exp->tuple);
/* Can't expect this? Best to drop packet now. */
if (nf_ct_expect_related(exp) != 0)
ret = NF_DROP;
nf_ct_expect_put(exp);
out:
//.........这里部分代码省略.........
示例14: help
static int help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
unsigned int dataoff;
const struct iphdr *iph;
const struct tcphdr *th;
struct tcphdr _tcph;
const char *data_limit;
char *data, *ib_ptr;
int dir = CTINFO2DIR(ctinfo);
struct nf_conntrack_expect *exp;
struct nf_conntrack_tuple *tuple;
__be32 dcc_ip;
u_int16_t dcc_port;
__be16 port;
int i, ret = NF_ACCEPT;
char *addr_beg_p, *addr_end_p;
typeof(nf_nat_irc_hook) nf_nat_irc;
if (dir == IP_CT_DIR_REPLY)
return NF_ACCEPT;
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
return NF_ACCEPT;
th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
dataoff = protoff + th->doff*4;
if (dataoff >= skb->len)
return NF_ACCEPT;
spin_lock_bh(&irc_buffer_lock);
ib_ptr = skb_header_pointer(skb, dataoff, skb->len - dataoff,
irc_buffer);
BUG_ON(ib_ptr == NULL);
data = ib_ptr;
data_limit = ib_ptr + skb->len - dataoff;
while (data < data_limit - (19 + MINMATCHLEN)) {
if (memcmp(data, "\1DCC ", 5)) {
data++;
continue;
}
data += 5;
iph = ip_hdr(skb);
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
&iph->saddr, ntohs(th->source),
&iph->daddr, ntohs(th->dest));
for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
continue;
}
data += strlen(dccprotos[i]);
pr_debug("DCC %s detected\n", dccprotos[i]);
if (parse_dcc(data, data_limit, &dcc_ip,
&dcc_port, &addr_beg_p, &addr_end_p)) {
pr_debug("unable to parse dcc command\n");
continue;
}
pr_debug("DCC bound ip/port: %pI4:%u\n",
&dcc_ip, dcc_port);
tuple = &ct->tuplehash[dir].tuple;
if (tuple->src.u3.ip != dcc_ip &&
tuple->dst.u3.ip != dcc_ip) {
if (net_ratelimit())
printk(KERN_WARNING
"Forged DCC command from %pI4: %pI4:%u\n",
&tuple->src.u3.ip,
&dcc_ip, dcc_port);
continue;
}
exp = nf_ct_expect_alloc(ct);
if (exp == NULL) {
ret = NF_DROP;
goto out;
}
tuple = &ct->tuplehash[!dir].tuple;
port = htons(dcc_port);
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
tuple->src.l3num,
NULL, &tuple->dst.u3,
IPPROTO_TCP, NULL, &port);
nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
//.........这里部分代码省略.........
示例15: tcp_packet
static int tcp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
u_int8_t pf,
unsigned int hooknum,
unsigned int *timeouts)
{
struct net *net = nf_ct_net(ct);
struct nf_conntrack_tuple *tuple;
enum tcp_conntrack new_state, old_state;
enum ip_conntrack_dir dir;
const struct tcphdr *th;
struct tcphdr _tcph;
unsigned long timeout;
unsigned int index;
th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
BUG_ON(th == NULL);
spin_lock_bh(&ct->lock);
old_state = ct->proto.tcp.state;
dir = CTINFO2DIR(ctinfo);
index = get_conntrack_index(th);
new_state = tcp_conntracks[dir][index][old_state];
tuple = &ct->tuplehash[dir].tuple;
switch (new_state) {
case TCP_CONNTRACK_SYN_SENT:
if (old_state < TCP_CONNTRACK_TIME_WAIT)
break;
if (((ct->proto.tcp.seen[dir].flags
| ct->proto.tcp.seen[!dir].flags)
& IP_CT_TCP_FLAG_CLOSE_INIT)
|| (ct->proto.tcp.last_dir == dir
&& ct->proto.tcp.last_index == TCP_RST_SET)) {
spin_unlock_bh(&ct->lock);
if (nf_ct_kill(ct))
return -NF_REPEAT;
return NF_DROP;
}
case TCP_CONNTRACK_IGNORE:
if (index == TCP_SYNACK_SET
&& ct->proto.tcp.last_index == TCP_SYN_SET
&& ct->proto.tcp.last_dir != dir
&& ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
old_state = TCP_CONNTRACK_SYN_SENT;
new_state = TCP_CONNTRACK_SYN_RECV;
ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_end =
ct->proto.tcp.last_end;
ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxend =
ct->proto.tcp.last_end;
ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxwin =
ct->proto.tcp.last_win == 0 ?
1 : ct->proto.tcp.last_win;
ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
ct->proto.tcp.last_wscale;
ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
ct->proto.tcp.last_flags;
memset(&ct->proto.tcp.seen[dir], 0,
sizeof(struct ip_ct_tcp_state));
break;
}
ct->proto.tcp.last_index = index;
ct->proto.tcp.last_dir = dir;
ct->proto.tcp.last_seq = ntohl(th->seq);
ct->proto.tcp.last_end =
segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
ct->proto.tcp.last_win = ntohs(th->window);
if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
struct ip_ct_tcp_state seen = {};
ct->proto.tcp.last_flags =
ct->proto.tcp.last_wscale = 0;
tcp_options(skb, dataoff, th, &seen);
if (seen.flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
ct->proto.tcp.last_flags |=
IP_CT_TCP_FLAG_WINDOW_SCALE;
ct->proto.tcp.last_wscale = seen.td_scale;
}
if (seen.flags & IP_CT_TCP_FLAG_SACK_PERM) {
ct->proto.tcp.last_flags |=
IP_CT_TCP_FLAG_SACK_PERM;
}
}
spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: invalid packet ignored ");
return NF_ACCEPT;
case TCP_CONNTRACK_MAX:
pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
dir, get_conntrack_index(th), old_state);
spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
//.........这里部分代码省略.........