Add tcp_log_addrs() function to generate and standardized TCP log line
for use thoughout the tcp subsystem. It is IPv4 and IPv6 aware creates a line in the following format: "TCP: [1.2.3.4]:50332 to [1.2.3.4]:80 tcpflags <RST>" A "\n" is not included at the end. The caller is supposed to add further information after the standard tcp log header. The function returns a NUL terminated string which the caller has to free(s, M_TCPLOG) after use. All memory allocation is done with M_NOWAIT and the return value may be NULL in memory shortage situations. Either struct in_conninfo || (struct tcphdr && (struct ip || struct ip6_hdr) have to be supplied. Due to ip[6].h header inclusion limitations and ordering issues the struct ip and struct ip6_hdr parameters have to be casted and passed as void * pointers. tcp_log_addrs(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr, void *ip6hdr) Usage example: struct ip *ip; char *tcplog; if (tcplog = tcp_log_addrs(NULL, th, (void *)ip, NULL)) { log(LOG_DEBUG, "%s; %s: Connection attempt to closed port\n", tcplog, __func__); free(s, M_TCPLOG); }
This commit is contained in:
parent
0ba5d2eedb
commit
df541e5fc1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169683
@ -69,6 +69,7 @@ struct tcphdr {
|
||||
#define TH_ECE 0x40
|
||||
#define TH_CWR 0x80
|
||||
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR)
|
||||
#define PRINT_TH_FLAGS "\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE"
|
||||
|
||||
u_short th_win; /* window */
|
||||
u_short th_sum; /* checksum */
|
||||
|
@ -240,7 +240,6 @@ tcp_input(struct mbuf *m, int off0)
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *ip6 = NULL;
|
||||
int isipv6;
|
||||
char ip6buf[INET6_ADDRSTRLEN];
|
||||
#else
|
||||
const int isipv6 = 0;
|
||||
#endif
|
||||
@ -481,30 +480,17 @@ tcp_input(struct mbuf *m, int off0)
|
||||
*/
|
||||
if ((tcp_log_in_vain == 1 && (thflags & TH_SYN)) ||
|
||||
tcp_log_in_vain == 2) {
|
||||
#ifndef INET6
|
||||
char dbuf[4*sizeof "123"], sbuf[4*sizeof "123"];
|
||||
char *s;
|
||||
#ifdef INET6
|
||||
s = tcp_log_addrs(NULL, th, (void *)ip, (void *)ip6);
|
||||
#else
|
||||
char dbuf[INET6_ADDRSTRLEN+2], sbuf[INET6_ADDRSTRLEN+2];
|
||||
if (isipv6) {
|
||||
strcpy(dbuf, "[");
|
||||
strcat(dbuf,
|
||||
ip6_sprintf(ip6buf, &ip6->ip6_dst));
|
||||
strcat(dbuf, "]");
|
||||
strcpy(sbuf, "[");
|
||||
strcat(sbuf,
|
||||
ip6_sprintf(ip6buf, &ip6->ip6_src));
|
||||
strcat(sbuf, "]");
|
||||
} else
|
||||
s = tcp_log_addrs(NULL, th, (void *)ip, NULL);
|
||||
#endif /* INET6 */
|
||||
{
|
||||
strcpy(dbuf, inet_ntoa(ip->ip_dst));
|
||||
strcpy(sbuf, inet_ntoa(ip->ip_src));
|
||||
if (s != NULL) {
|
||||
log(LOG_INFO, "%s; %s: Connection attempt "
|
||||
"to closed port\n", s, __func__);
|
||||
free(s, M_TCPLOG);
|
||||
}
|
||||
log(LOG_INFO,
|
||||
"Connection attempt to TCP %s:%d "
|
||||
"from %s:%d flags:0x%02x\n",
|
||||
dbuf, ntohs(th->th_dport), sbuf,
|
||||
ntohs(th->th_sport), thflags);
|
||||
}
|
||||
/*
|
||||
* When blackholing do not respond with a RST but
|
||||
|
@ -222,6 +222,7 @@ struct tcpcb_mem {
|
||||
};
|
||||
|
||||
static uma_zone_t tcpcb_zone;
|
||||
MALLOC_DEFINE(M_TCPLOG, "tcplog", "TCP address and flags print buffers");
|
||||
struct callout isn_callout;
|
||||
static struct mtx isn_mtx;
|
||||
|
||||
@ -2062,3 +2063,91 @@ sysctl_drop(SYSCTL_HANDLER_ARGS)
|
||||
SYSCTL_PROC(_net_inet_tcp, TCPCTL_DROP, drop,
|
||||
CTLTYPE_STRUCT|CTLFLAG_WR|CTLFLAG_SKIP, NULL,
|
||||
0, sysctl_drop, "", "Drop TCP connection");
|
||||
|
||||
/*
|
||||
* Generate a standardized TCP log line for use throughout the
|
||||
* tcp subsystem. Memory allocation is done with M_NOWAIT to
|
||||
* allow use in the interrupt context.
|
||||
*
|
||||
* NB: The caller MUST free(s, M_TCPLOG) the returned string.
|
||||
* NB: The function may return NULL if memory allocation failed.
|
||||
*
|
||||
* Due to header inclusion and ordering limitations the struct ip
|
||||
* and ip6_hdr pointers have to be passed as void pointers.
|
||||
*/
|
||||
char *
|
||||
tcp_log_addrs(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr,
|
||||
void *ip6hdr)
|
||||
{
|
||||
char *s, *sp;
|
||||
size_t size;
|
||||
struct ip *ip;
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
ip6 = (struct ip6_hdr *)ip6hdr;
|
||||
#endif /* INET6 */
|
||||
ip = (struct ip *)ip4hdr;
|
||||
|
||||
/*
|
||||
* XXX: The size calculation is evil.
|
||||
* "TCP: [1.2.3.4]:50332 to [1.2.3.4]:80 tcpflags <RST>"
|
||||
*/
|
||||
#ifdef INET6
|
||||
size = 5 + 2 * (INET6_ADDRSTRLEN + 10) + 12 + 12 * 4 + 1;
|
||||
#else
|
||||
size = 5 + 2 * (sizeof("192.168.172.190") + 10) + 12 + 12 *4 + 1;
|
||||
#endif /* INET6 */
|
||||
|
||||
s = sp = malloc(size, M_TCPLOG, (M_ZERO|M_NOWAIT));
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
|
||||
strcat(s, "TCP: [");
|
||||
sp = s + strlen(s);
|
||||
|
||||
if (inc && inc->inc_isipv6 == 0) {
|
||||
inet_ntoa_r(inc->inc_faddr, sp);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i to [", ntohs(inc->inc_fport));
|
||||
sp = s + strlen(s);
|
||||
inet_ntoa_r(inc->inc_laddr, sp);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i", ntohs(inc->inc_lport));
|
||||
#ifdef INET6
|
||||
} else if (inc) {
|
||||
ip6_sprintf(sp, &inc->inc6_faddr);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i to [", ntohs(inc->inc_fport));
|
||||
sp = s + strlen(s);
|
||||
ip6_sprintf(sp, &inc->inc6_laddr);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i", ntohs(inc->inc_lport));
|
||||
} else if (ip6 && th) {
|
||||
ip6_sprintf(sp, &ip6->ip6_src);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i to [", ntohs(th->th_sport));
|
||||
sp = s + strlen(s);
|
||||
ip6_sprintf(sp, &ip6->ip6_dst);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i", ntohs(th->th_dport));
|
||||
#endif /* INET6 */
|
||||
} else if (ip && th) {
|
||||
inet_ntoa_r(ip->ip_src, sp);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i to [", ntohs(th->th_sport));
|
||||
sp = s + strlen(s);
|
||||
inet_ntoa_r(ip->ip_dst, sp);
|
||||
sp = s + strlen(s);
|
||||
sprintf(sp, "]:%i", ntohs(th->th_dport));
|
||||
} else {
|
||||
free(s, M_TCPLOG);
|
||||
return (NULL);
|
||||
}
|
||||
sp = s + strlen(s);
|
||||
if (th)
|
||||
sprintf(sp, " tcpflags 0x%b", th->th_flags, PRINT_TH_FLAGS);
|
||||
if (s[size] != '\0')
|
||||
panic("%s: string too long", __func__);
|
||||
return (s);
|
||||
}
|
||||
|
@ -488,6 +488,7 @@ struct xtcpcb {
|
||||
#ifdef SYSCTL_DECL
|
||||
SYSCTL_DECL(_net_inet_tcp);
|
||||
SYSCTL_DECL(_net_inet_tcp_sack);
|
||||
MALLOC_DECLARE(M_TCPLOG);
|
||||
#endif
|
||||
|
||||
extern struct inpcbhead tcb; /* head of queue of active tcpcb's */
|
||||
@ -520,6 +521,8 @@ void tcp_drain(void);
|
||||
void tcp_fasttimo(void);
|
||||
void tcp_init(void);
|
||||
void tcp_fini(void *);
|
||||
char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *,
|
||||
void *);
|
||||
int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
|
||||
void tcp_reass_init(void);
|
||||
void tcp_input(struct mbuf *, int);
|
||||
|
Loading…
Reference in New Issue
Block a user