summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp.h1
-rw-r--r--sys/netinet/tcp_input.c30
-rw-r--r--sys/netinet/tcp_subr.c89
-rw-r--r--sys/netinet/tcp_var.h3
4 files changed, 101 insertions, 22 deletions
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 3f7424d..6c31b5f 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -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 */
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 163b588..02a9c22 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -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 @@ findpcb:
*/
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
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index ffa6cf1..ae05125 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -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);
+}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index c1c0a80..5b5eff0 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -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);
OpenPOWER on IntegriCloud