mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 20:01:08 +01:00
b3e7694832
Remove /^\s*\*\n \*\s+\$FreeBSD\$$\n/
413 lines
10 KiB
C
413 lines
10 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2019 Alexander V. Chernikov
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _NET_ROUTING_RTSOCK_PRINT_H_
|
|
#define _NET_ROUTING_RTSOCK_PRINT_H_
|
|
|
|
|
|
#define RLOG(_fmt, ...) printf("%s: " _fmt "\n", __func__, ##__VA_ARGS__)
|
|
#define RLOG_ERRNO(_fmt, ...) do { \
|
|
printf("%s: " _fmt, __func__, ##__VA_ARGS__); \
|
|
printf(": %s\n", strerror(errno)); \
|
|
} while(0)
|
|
|
|
#define RTSOCK_ATF_REQUIRE_MSG(_rtm, _cond, _fmt, ...) do { \
|
|
if (!(_cond)) { \
|
|
printf("-- CONDITION FAILED, rtm dump --\n\n");\
|
|
rtsock_print_message(_rtm); \
|
|
rtsock_print_table(AF_INET); \
|
|
rtsock_print_table(AF_INET6); \
|
|
printf("===================================\n");\
|
|
} \
|
|
ATF_REQUIRE_MSG(_cond, _fmt, ##__VA_ARGS__); \
|
|
} while (0);
|
|
|
|
#define RTSOCKHD_ATF_REQUIRE_MSG(_rtm, _cond, _fmt, ...) do { \
|
|
if (!(_cond)) { \
|
|
printf("-- CONDITION FAILED, rtm hexdump--\n\n");\
|
|
rtsock_print_message_hd(_rtm); \
|
|
} \
|
|
ATF_REQUIRE_MSG(_cond, _fmt, ##__VA_ARGS__); \
|
|
} while (0);
|
|
|
|
|
|
/* from route.c */
|
|
static const char *const msgtypes[] = {
|
|
"",
|
|
"RTM_ADD",
|
|
"RTM_DELETE",
|
|
"RTM_CHANGE",
|
|
"RTM_GET",
|
|
"RTM_LOSING",
|
|
"RTM_REDIRECT",
|
|
"RTM_MISS",
|
|
"RTM_LOCK",
|
|
"RTM_OLDADD",
|
|
"RTM_OLDDEL",
|
|
"RTM_RESOLVE",
|
|
"RTM_NEWADDR",
|
|
"RTM_DELADDR",
|
|
"RTM_IFINFO",
|
|
"RTM_NEWMADDR",
|
|
"RTM_DELMADDR",
|
|
"RTM_IFANNOUNCE",
|
|
"RTM_IEEE80211",
|
|
};
|
|
|
|
static const char metricnames[] =
|
|
"\011weight\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire"
|
|
"\1mtu";
|
|
static const char routeflags[] =
|
|
"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
|
|
"\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
|
|
"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
|
|
"\024FIXEDMTU\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
|
|
static const char ifnetflags[] =
|
|
"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
|
|
"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
|
|
"\017LINK2\020MULTICAST";
|
|
static const char addrnames[] =
|
|
"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
|
|
|
|
static int
|
|
_printb(char *buf, size_t bufsize, int b, const char *str)
|
|
{
|
|
int i;
|
|
int gotsome = 0;
|
|
|
|
char *pbuf = buf;
|
|
|
|
if (b == 0) {
|
|
*pbuf = '\0';
|
|
return (0);
|
|
}
|
|
while ((i = *str++) != 0) {
|
|
if (b & (1 << (i-1))) {
|
|
if (gotsome == 0)
|
|
i = '<';
|
|
else
|
|
i = ',';
|
|
*pbuf++ = i;
|
|
gotsome = 1;
|
|
for (; (i = *str) > 32; str++)
|
|
*pbuf++ = i;
|
|
} else
|
|
while (*str > 32)
|
|
str++;
|
|
}
|
|
if (gotsome)
|
|
*pbuf++ = '>';
|
|
*pbuf = '\0';
|
|
|
|
return (int)(pbuf - buf);
|
|
}
|
|
|
|
const char *
|
|
rtsock_print_cmdtype(int cmd)
|
|
{
|
|
|
|
return (msgtypes[cmd]);
|
|
}
|
|
|
|
char *
|
|
rtsock_print_rtm_flags(char *buf, int buflen, int rtm_flags)
|
|
{
|
|
|
|
_printb(buf, buflen, rtm_flags, routeflags);
|
|
return (buf);
|
|
}
|
|
|
|
|
|
#define _PRINTX(fmt, ...) do { \
|
|
one_len = snprintf(ptr, rem_len, fmt, __VA_ARGS__); \
|
|
ptr += one_len; \
|
|
rem_len -= one_len; \
|
|
} while(0)
|
|
|
|
|
|
void
|
|
sa_print_hd(char *buf, int buflen, const char *data, int len)
|
|
{
|
|
char *ptr;
|
|
int one_len, rem_len;
|
|
|
|
ptr = buf;
|
|
rem_len = buflen;
|
|
|
|
const char *last_char = NULL;
|
|
unsigned char v;
|
|
int repeat_count = 0;
|
|
for (int i = 0; i < len; i++) {
|
|
if (last_char && *last_char == data[i] && data[i] == 0x00) {
|
|
repeat_count++;
|
|
continue;
|
|
}
|
|
|
|
if (repeat_count > 1) {
|
|
_PRINTX("{%d}", repeat_count);
|
|
repeat_count = 0;
|
|
}
|
|
|
|
v = ((const unsigned char *)data)[i];
|
|
if (last_char == NULL)
|
|
_PRINTX("x%02X", v);
|
|
else
|
|
_PRINTX(", x%02X", v);
|
|
|
|
last_char = &data[i];
|
|
repeat_count = 1;
|
|
}
|
|
|
|
if (repeat_count > 1)
|
|
snprintf(ptr, rem_len, "{%d}", repeat_count);
|
|
}
|
|
|
|
#undef _PRINTX
|
|
|
|
void
|
|
sa_print(const struct sockaddr *sa, int include_hexdump)
|
|
{
|
|
char hdbuf[512], abuf[64];
|
|
char ifbuf[128];
|
|
const struct sockaddr_dl *sdl;
|
|
const struct sockaddr_in6 *sin6;
|
|
const struct sockaddr_in *sin;
|
|
int i;
|
|
|
|
switch (sa->sa_family) {
|
|
case AF_INET:
|
|
sin = (struct sockaddr_in *)sa;
|
|
inet_ntop(AF_INET, &sin->sin_addr, abuf, sizeof(abuf));
|
|
printf(" af=inet len=%d addr=%s", sa->sa_len, abuf);
|
|
break;
|
|
case AF_INET6:
|
|
sin6 = (struct sockaddr_in6 *)sa;
|
|
inet_ntop(AF_INET6, &sin6->sin6_addr, abuf, sizeof(abuf));
|
|
int scope_id = sin6->sin6_scope_id;
|
|
printf(" af=inet6 len=%d addr=%s", sa->sa_len, abuf);
|
|
if (scope_id != 0) {
|
|
memset(ifbuf, 0, sizeof(ifbuf));
|
|
if_indextoname(scope_id, ifbuf);
|
|
printf(" scope_id=%d if_name=%s", scope_id, ifbuf);
|
|
}
|
|
break;
|
|
case AF_LINK:
|
|
sdl = (const struct sockaddr_dl *)sa;
|
|
int sdl_index = sdl->sdl_index;
|
|
if (sdl_index != 0) {
|
|
memset(ifbuf, 0, sizeof(ifbuf));
|
|
if_indextoname(sdl_index, ifbuf);
|
|
printf(" af=link len=%d sdl_index=%d if_name=%s", sdl->sdl_len, sdl_index, ifbuf);
|
|
}
|
|
if (sdl->sdl_nlen) {
|
|
char _ifname[IFNAMSIZ];
|
|
memcpy(_ifname, sdl->sdl_data, sdl->sdl_nlen);
|
|
_ifname[sdl->sdl_nlen] = '\0';
|
|
printf(" name=%s", _ifname);
|
|
}
|
|
if (sdl->sdl_alen) {
|
|
printf(" addr=");
|
|
const char *lladdr = LLADDR(sdl);
|
|
for (int i = 0; i < sdl->sdl_alen; i++) {
|
|
if (i + 1 < sdl->sdl_alen)
|
|
printf("%02X:", ((const unsigned char *)lladdr)[i]);
|
|
else
|
|
printf("%02X", ((const unsigned char *)lladdr)[i]);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
printf(" af=%d len=%d", sa->sa_family, sa->sa_len);
|
|
}
|
|
|
|
if (include_hexdump) {
|
|
sa_print_hd(hdbuf, sizeof(hdbuf), ((char *)sa), sa->sa_len);
|
|
printf(" hd={%s}", hdbuf);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
/*
|
|
got message of size 240 on Mon Dec 16 09:23:31 2019
|
|
RTM_ADD: Add Route: len 240, pid: 25534, seq 2, errno 0, flags:<HOST,DONE,LLINFO,STATIC>
|
|
locks: inits:
|
|
sockaddrs: <DST,GATEWAY>
|
|
*/
|
|
|
|
void
|
|
rtsock_print_rtm(struct rt_msghdr *rtm)
|
|
{
|
|
struct timeval tv;
|
|
struct tm tm_res;
|
|
char buf[64];
|
|
|
|
gettimeofday(&tv, NULL);
|
|
localtime_r(&tv.tv_sec, &tm_res);
|
|
strftime(buf, sizeof(buf), "%F %T", &tm_res);
|
|
printf("Got message of size %hu on %s\n", rtm->rtm_msglen, buf);
|
|
|
|
char flags_buf[256];
|
|
rtsock_print_rtm_flags(flags_buf, sizeof(flags_buf), rtm->rtm_flags);
|
|
|
|
printf("%s: len %hu, pid: %d, seq %d, errno %d, flags: %s\n", msgtypes[rtm->rtm_type],
|
|
rtm->rtm_msglen, rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno, flags_buf);
|
|
|
|
if (rtm->rtm_inits > 0) {
|
|
_printb(flags_buf, sizeof(flags_buf), rtm->rtm_inits, metricnames);
|
|
printf("metrics: %s\n", flags_buf);
|
|
if (rtm->rtm_inits & RTV_MTU)
|
|
printf("mtu: %lu\n", rtm->rtm_rmx.rmx_mtu);
|
|
if (rtm->rtm_inits & RTV_EXPIRE) {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
printf("expire: %d (%lu raw)\n",
|
|
(int)(rtm->rtm_rmx.rmx_expire - tv.tv_sec), rtm->rtm_rmx.rmx_expire);
|
|
}
|
|
}
|
|
|
|
_printb(flags_buf, sizeof(flags_buf), rtm->rtm_addrs, addrnames);
|
|
printf("sockaddrs: 0x%X %s\n", rtm->rtm_addrs, flags_buf);
|
|
|
|
char *ptr = (char *)(rtm + 1);
|
|
for (int i = 0; i < RTAX_MAX; i++) {
|
|
if (rtm->rtm_addrs & (1 << i)) {
|
|
struct sockaddr *sa = (struct sockaddr *)ptr;
|
|
sa_print(sa, 1);
|
|
|
|
/* add */
|
|
ptr += ALIGN(((struct sockaddr *)ptr)->sa_len);
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
void
|
|
rtsock_print_ifa(struct ifa_msghdr *ifam)
|
|
{
|
|
struct timeval tv;
|
|
struct tm tm_res;
|
|
char buf[64];
|
|
|
|
gettimeofday(&tv, NULL);
|
|
localtime_r(&tv.tv_sec, &tm_res);
|
|
strftime(buf, sizeof(buf), "%F %T", &tm_res);
|
|
printf("Got message of size %hu on %s\n", ifam->ifam_msglen, buf);
|
|
|
|
char flags_buf[256];
|
|
_printb(flags_buf, sizeof(flags_buf), ifam->ifam_flags, routeflags);
|
|
|
|
printf("%s: len %hu, ifindex: %d, flags: %s\n", msgtypes[ifam->ifam_type],
|
|
ifam->ifam_msglen, ifam->ifam_index, flags_buf);
|
|
|
|
_printb(flags_buf, sizeof(flags_buf), ifam->ifam_addrs, addrnames);
|
|
printf("sockaddrs: 0x%X %s\n", ifam->ifam_addrs, flags_buf);
|
|
|
|
char *ptr = (char *)(ifam + 1);
|
|
for (int i = 0; i < RTAX_MAX; i++) {
|
|
if (ifam->ifam_addrs & (1 << i)) {
|
|
struct sockaddr *sa = (struct sockaddr *)ptr;
|
|
sa_print(sa, 1);
|
|
|
|
/* add */
|
|
ptr += ALIGN(((struct sockaddr *)ptr)->sa_len);
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
void
|
|
rtsock_print_message_hd(struct rt_msghdr *rtm)
|
|
{
|
|
struct timeval tv;
|
|
struct tm tm_res;
|
|
char buf[64];
|
|
char dumpbuf[2048];
|
|
|
|
gettimeofday(&tv, NULL);
|
|
localtime_r(&tv.tv_sec, &tm_res);
|
|
strftime(buf, sizeof(buf), "%F %T", &tm_res);
|
|
printf("Got message type %s of size %hu on %s\n",
|
|
rtsock_print_cmdtype(rtm->rtm_type),
|
|
rtm->rtm_msglen, buf);
|
|
|
|
sa_print_hd(dumpbuf, sizeof(dumpbuf), (char *)rtm, rtm->rtm_msglen);
|
|
printf(" %s\n", dumpbuf);
|
|
}
|
|
|
|
void
|
|
rtsock_print_message(struct rt_msghdr *rtm)
|
|
{
|
|
|
|
switch (rtm->rtm_type) {
|
|
case RTM_GET:
|
|
case RTM_ADD:
|
|
case RTM_DELETE:
|
|
case RTM_CHANGE:
|
|
rtsock_print_rtm(rtm);
|
|
break;
|
|
case RTM_DELADDR:
|
|
case RTM_NEWADDR:
|
|
rtsock_print_ifa((struct ifa_msghdr *)rtm);
|
|
break;
|
|
default:
|
|
printf("unknown rt message type %X\n", rtm->rtm_type);
|
|
}
|
|
}
|
|
|
|
static void
|
|
print_command(char *cmd)
|
|
{
|
|
char line[1024];
|
|
|
|
FILE *fp = popen(cmd, "r");
|
|
if (fp != NULL) {
|
|
while (fgets(line, sizeof(line), fp) != NULL)
|
|
printf("%s", line);
|
|
pclose(fp);
|
|
}
|
|
}
|
|
|
|
void
|
|
rtsock_print_table(int family)
|
|
{
|
|
char cmdbuf[128];
|
|
char *key = (family == AF_INET) ? "4" : "6";
|
|
|
|
snprintf(cmdbuf, sizeof(cmdbuf), "/usr/bin/netstat -%srnW", key);
|
|
printf("==== %s ===\n", cmdbuf);
|
|
print_command(cmdbuf);
|
|
snprintf(cmdbuf, sizeof(cmdbuf), "/usr/bin/netstat -%sonW", key);
|
|
printf("==== %s ===\n", cmdbuf);
|
|
print_command(cmdbuf);
|
|
}
|
|
|
|
#endif
|