Move ipfw_send_pkt() from ip_fw_dynamic.c into ip_fw2.c.
It is not specific for dynamic states function and called also from generic code. Obtained from: Yandex LLC MFC after: 1 week Sponsored by: Yandex LLC
This commit is contained in:
parent
288bf455bb
commit
30df59d581
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326116
@ -468,6 +468,155 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
|
||||
#endif /* __FreeBSD__ */
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a TCP packet, containing either a RST or a keepalive.
|
||||
* When flags & TH_RST, we are sending a RST packet, because of a
|
||||
* "reset" action matched the packet.
|
||||
* Otherwise we are sending a keepalive, and flags & TH_
|
||||
* The 'replyto' mbuf is the mbuf being replied to, if any, and is required
|
||||
* so that MAC can label the reply appropriately.
|
||||
*/
|
||||
struct mbuf *
|
||||
ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
|
||||
u_int32_t ack, int flags)
|
||||
{
|
||||
struct mbuf *m = NULL; /* stupid compiler */
|
||||
struct ip *h = NULL; /* stupid compiler */
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *h6 = NULL;
|
||||
#endif
|
||||
struct tcphdr *th = NULL;
|
||||
int len, dir;
|
||||
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return (NULL);
|
||||
|
||||
M_SETFIB(m, id->fib);
|
||||
#ifdef MAC
|
||||
if (replyto != NULL)
|
||||
mac_netinet_firewall_reply(replyto, m);
|
||||
else
|
||||
mac_netinet_firewall_send(m);
|
||||
#else
|
||||
(void)replyto; /* don't warn about unused arg */
|
||||
#endif
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
len = sizeof(struct ip) + sizeof(struct tcphdr);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* XXX: log me?!? */
|
||||
FREE_PKT(m);
|
||||
return (NULL);
|
||||
}
|
||||
dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
|
||||
|
||||
m->m_data += max_linkhdr;
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
bzero(m->m_data, len);
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
h = mtod(m, struct ip *);
|
||||
|
||||
/* prepare for checksum */
|
||||
h->ip_p = IPPROTO_TCP;
|
||||
h->ip_len = htons(sizeof(struct tcphdr));
|
||||
if (dir) {
|
||||
h->ip_src.s_addr = htonl(id->src_ip);
|
||||
h->ip_dst.s_addr = htonl(id->dst_ip);
|
||||
} else {
|
||||
h->ip_src.s_addr = htonl(id->dst_ip);
|
||||
h->ip_dst.s_addr = htonl(id->src_ip);
|
||||
}
|
||||
|
||||
th = (struct tcphdr *)(h + 1);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
h6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/* prepare for checksum */
|
||||
h6->ip6_nxt = IPPROTO_TCP;
|
||||
h6->ip6_plen = htons(sizeof(struct tcphdr));
|
||||
if (dir) {
|
||||
h6->ip6_src = id->src_ip6;
|
||||
h6->ip6_dst = id->dst_ip6;
|
||||
} else {
|
||||
h6->ip6_src = id->dst_ip6;
|
||||
h6->ip6_dst = id->src_ip6;
|
||||
}
|
||||
|
||||
th = (struct tcphdr *)(h6 + 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir) {
|
||||
th->th_sport = htons(id->src_port);
|
||||
th->th_dport = htons(id->dst_port);
|
||||
} else {
|
||||
th->th_sport = htons(id->dst_port);
|
||||
th->th_dport = htons(id->src_port);
|
||||
}
|
||||
th->th_off = sizeof(struct tcphdr) >> 2;
|
||||
|
||||
if (flags & TH_RST) {
|
||||
if (flags & TH_ACK) {
|
||||
th->th_seq = htonl(ack);
|
||||
th->th_flags = TH_RST;
|
||||
} else {
|
||||
if (flags & TH_SYN)
|
||||
seq++;
|
||||
th->th_ack = htonl(seq);
|
||||
th->th_flags = TH_RST | TH_ACK;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Keepalive - use caller provided sequence numbers
|
||||
*/
|
||||
th->th_seq = htonl(seq);
|
||||
th->th_ack = htonl(ack);
|
||||
th->th_flags = TH_ACK;
|
||||
}
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
th->th_sum = in_cksum(m, len);
|
||||
|
||||
/* finish the ip header */
|
||||
h->ip_v = 4;
|
||||
h->ip_hl = sizeof(*h) >> 2;
|
||||
h->ip_tos = IPTOS_LOWDELAY;
|
||||
h->ip_off = htons(0);
|
||||
h->ip_len = htons(len);
|
||||
h->ip_ttl = V_ip_defttl;
|
||||
h->ip_sum = 0;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
|
||||
sizeof(struct tcphdr));
|
||||
|
||||
/* finish the ip6 header */
|
||||
h6->ip6_vfc |= IPV6_VERSION;
|
||||
h6->ip6_hlim = IPV6_DEFHLIM;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (m);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
/*
|
||||
* ipv6 specific rules here...
|
||||
|
@ -1019,155 +1019,6 @@ ipfw_install_state(struct ip_fw_chain *chain, struct ip_fw *rule,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a TCP packet, containing either a RST or a keepalive.
|
||||
* When flags & TH_RST, we are sending a RST packet, because of a
|
||||
* "reset" action matched the packet.
|
||||
* Otherwise we are sending a keepalive, and flags & TH_
|
||||
* The 'replyto' mbuf is the mbuf being replied to, if any, and is required
|
||||
* so that MAC can label the reply appropriately.
|
||||
*/
|
||||
struct mbuf *
|
||||
ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
|
||||
u_int32_t ack, int flags)
|
||||
{
|
||||
struct mbuf *m = NULL; /* stupid compiler */
|
||||
int len, dir;
|
||||
struct ip *h = NULL; /* stupid compiler */
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *h6 = NULL;
|
||||
#endif
|
||||
struct tcphdr *th = NULL;
|
||||
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return (NULL);
|
||||
|
||||
M_SETFIB(m, id->fib);
|
||||
#ifdef MAC
|
||||
if (replyto != NULL)
|
||||
mac_netinet_firewall_reply(replyto, m);
|
||||
else
|
||||
mac_netinet_firewall_send(m);
|
||||
#else
|
||||
(void)replyto; /* don't warn about unused arg */
|
||||
#endif
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
len = sizeof(struct ip) + sizeof(struct tcphdr);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* XXX: log me?!? */
|
||||
FREE_PKT(m);
|
||||
return (NULL);
|
||||
}
|
||||
dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
|
||||
|
||||
m->m_data += max_linkhdr;
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
bzero(m->m_data, len);
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
h = mtod(m, struct ip *);
|
||||
|
||||
/* prepare for checksum */
|
||||
h->ip_p = IPPROTO_TCP;
|
||||
h->ip_len = htons(sizeof(struct tcphdr));
|
||||
if (dir) {
|
||||
h->ip_src.s_addr = htonl(id->src_ip);
|
||||
h->ip_dst.s_addr = htonl(id->dst_ip);
|
||||
} else {
|
||||
h->ip_src.s_addr = htonl(id->dst_ip);
|
||||
h->ip_dst.s_addr = htonl(id->src_ip);
|
||||
}
|
||||
|
||||
th = (struct tcphdr *)(h + 1);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
h6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/* prepare for checksum */
|
||||
h6->ip6_nxt = IPPROTO_TCP;
|
||||
h6->ip6_plen = htons(sizeof(struct tcphdr));
|
||||
if (dir) {
|
||||
h6->ip6_src = id->src_ip6;
|
||||
h6->ip6_dst = id->dst_ip6;
|
||||
} else {
|
||||
h6->ip6_src = id->dst_ip6;
|
||||
h6->ip6_dst = id->src_ip6;
|
||||
}
|
||||
|
||||
th = (struct tcphdr *)(h6 + 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dir) {
|
||||
th->th_sport = htons(id->src_port);
|
||||
th->th_dport = htons(id->dst_port);
|
||||
} else {
|
||||
th->th_sport = htons(id->dst_port);
|
||||
th->th_dport = htons(id->src_port);
|
||||
}
|
||||
th->th_off = sizeof(struct tcphdr) >> 2;
|
||||
|
||||
if (flags & TH_RST) {
|
||||
if (flags & TH_ACK) {
|
||||
th->th_seq = htonl(ack);
|
||||
th->th_flags = TH_RST;
|
||||
} else {
|
||||
if (flags & TH_SYN)
|
||||
seq++;
|
||||
th->th_ack = htonl(seq);
|
||||
th->th_flags = TH_RST | TH_ACK;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Keepalive - use caller provided sequence numbers
|
||||
*/
|
||||
th->th_seq = htonl(seq);
|
||||
th->th_ack = htonl(ack);
|
||||
th->th_flags = TH_ACK;
|
||||
}
|
||||
|
||||
switch (id->addr_type) {
|
||||
case 4:
|
||||
th->th_sum = in_cksum(m, len);
|
||||
|
||||
/* finish the ip header */
|
||||
h->ip_v = 4;
|
||||
h->ip_hl = sizeof(*h) >> 2;
|
||||
h->ip_tos = IPTOS_LOWDELAY;
|
||||
h->ip_off = htons(0);
|
||||
h->ip_len = htons(len);
|
||||
h->ip_ttl = V_ip_defttl;
|
||||
h->ip_sum = 0;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case 6:
|
||||
th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
|
||||
sizeof(struct tcphdr));
|
||||
|
||||
/* finish the ip6 header */
|
||||
h6->ip6_vfc |= IPV6_VERSION;
|
||||
h6->ip6_hlim = IPV6_DEFHLIM;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue keepalive packets for given dynamic rule
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user