1# -*- tab-width: 4 -*- ;; Emacs 2# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM 3############################################################ IDENT(1) 4# 5# $Title: dwatch(8) JSON module for network activity $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# $FrauBSD: dwatch-json/json-net-config-raw 2018-10-01 16:20:48 -0700 freebsdfrau $ 8# 9############################################################ DESCRIPTION 10# 11# Produce JSON custom log format for network activity 12# 13############################################################ PROBE 14 15: ${PROBE:=profile-10s} 16 17############################################################ CONFIG 18 19# Defaults 20: ${REPORT_TYPE:=${PROFILE%-raw}} 21: ${HOSTNAME:=$( hostname )} 22 23# Configured variables before loading config 24vars="$( set | awk 'match($0, 25 /^[a-zA-Z_][a-zA-Z0-9_]*=/) { print substr($0, 1, RLENGTH - 1) }' 26) vars" 27 28# Config 29. /usr/local/etc/dwatch-${PROFILE%-config*}.conf || exit 30 31# Variables found in config 32export vars 33conf=$( set | awk ' 34BEGIN { 35 conf = "" 36 delete env 37 nvars = split(ENVIRON["vars"], vars) 38 for (n = 1; n <= nvars; n++) env[vars[n]] 39} 40match($0, /^[a-zA-Z_][a-zA-Z0-9_]*=/) { 41 name = substr($0, 1, RLENGTH - 1) 42 if (name in env) next 43 conf = conf " " name 44} 45END { print substr(conf, 2) }' ) 46 47############################################################ OVERRIDES 48 49MAX_ARGS=0 # -B num 50MAX_DEPTH=0 # -K num 51 52# 53# Unsupported features 54# 55unset EXECREGEX # -z regex 56unset GROUP # -g group 57unset PID # -p pid 58unset PROBE_COALESCE # -F 59unset PSTREE # -R 60unset USER # -u user 61 62############################################################ EVENT ACTION 63 64_EVENT_TEST="${EVENT_TEST:+($EVENT_TEST)}" 65_EVENT_TEST="${CUSTOM_TEST:+$CUSTOM_TEST${EVENT_TEST:+ && }}$_EVENT_TEST" 66if [ "$JID" ]; then 67 pr_id="curthread->td_proc->p_ucred->cr_prison->pr_id" 68 _EVENT_TEST="$pr_id == $JID${_EVENT_TEST:+ && ($_EVENT_TEST)}" 69 unset JID 70fi 71EVENT_TEST="cpu == 0" 72CUSTOM_TEST= 73 74_CONF_OTHER= 75IFS=" " 76nconf=0 77for var in $conf; do 78 nconf=$(( $nconf + 1 )) 79 eval val=\"\$$var\" 80 _CONF_OTHER="$_CONF_OTHER || ($val)" 81done 82[ "$_CONF_OTHER" ] && _CONF_OTHER="!(${_CONF_OTHER# || })" 83 84############################################################ ACTIONS 85 86exec 9<<EOF 87this string event; 88this string family; 89this string local; 90this string remote; 91this u_char local6; 92this u_char remote6; 93this uint16_t lport; 94this uint16_t rport; 95this uint32_t length; 96 97uint32_t tcp_rcvd; 98uint32_t tcp_sent; 99uint32_t udp_rcvd; 100uint32_t udp_sent; 101 102$( IFS=" " 103 for var in $conf; do 104 printf "uint32_t\t%s_tcp_rcvd;\n" $var 105 printf "uint32_t\t%s_tcp_sent;\n" $var 106 printf "uint32_t\t%s_udp_rcvd;\n" $var 107 printf "uint32_t\t%s_udp_sent;\n" $var 108 done 109) 110 111struct socket * urecv_socket; 112struct inpcb * urecv_inpcb; 113string urecv_local; 114string urecv_remote; 115u_char urecv_local6; 116u_char urecv_remote6; 117uint16_t urecv_lport; 118uint16_t urecv_rport; 119uint32_t urecv_length; 120 121BEGIN /* probe ID $ID */ 122{${TRACE:+ 123 printf("<$ID>");} 124 tcp_rcvd = tcp_sent = 0; 125 udp_rcvd = udp_sent = 0;$( IFS=" " 126 for var in $conf; do 127 printf "\n\t%s_tcp_rcvd = %s_tcp_sent = 0;" $var $var 128 printf "\n\t%s_udp_rcvd = %s_udp_sent = 0;" $var $var 129 done 130) 131} 132 133/****************************** TCP ******************************/ 134 135tcp:::send, 136tcp:::receive /* probe ID $(( $ID + 1 )) */ 137{${TRACE:+ 138 printf("<$(( $ID + 1 ))>");} 139 this->length = (uint32_t)args[2]->ip_plength - 140 (uint8_t)args[4]->tcp_offset; 141} 142 143tcp:::debug-user /* probe ID $(( $ID + 2 )) */ 144{${TRACE:+ 145 printf("<$(( $ID + 2 ))>"); 146} 147 /* 148 * tcpsinfo_t * 149 */ 150 this->local = args[0]->tcps_laddr; 151 this->lport = args[0]->tcps_lport; 152 this->remote = args[0]->tcps_raddr; 153 this->rport = args[0]->tcps_rport; 154 155 /* 156 * IPv6 support 157 */ 158 this->local6 = strstr(this->local, ":") != NULL ? 1 : 0; 159 this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0; 160 this->local = strjoin(strjoin(this->local6 ? "[" : "", 161 this->local), this->local6 ? "]" : ""); 162 this->remote = strjoin(strjoin(this->remote6 ? "[" : "", 163 this->remote), this->remote6 ? "]" : ""); 164 165 this->family = "tcp"; 166 this->event = prureq_string[arg1]; 167} 168 169$( IFS=" " 170 id=$(( $ID + 3 )) 171 for var in $conf; do 172 eval val=\"\$$var\" 173 printf "tcp:::debug-user\n" 174 printf "\t/this->event == \"RCVD\"" 175 [ "$_EVENT_TEST" ] && printf " && %s" "$_EVENT_TEST" 176 printf " && (%s)/\n" "$val" 177 printf "\t/* probe ID %u */\n" $id 178 printf "{${TRACE:+\n\tprintf(\"<$id>\");}\n" 179 printf "\t%s_tcp_rcvd += this->length;\n" $var 180 printf "\tthis->length = 0;\n" 181 printf "}\n\n" 182 id=$(( $id + 1 )) 183 done 184) 185 186tcp:::debug-user 187 /this->event == "RCVD"${_EVENT_TEST:+ && 188 $_EVENT_TEST}${_CONF_OTHER:+ && 189 $_CONF_OTHER}/ 190 /* probe ID $(( $ID + 3 + $nconf )) */ 191{${TRACE:+ 192 printf("<$(( $ID + 3 + $nconf ))>");} 193 tcp_rcvd += this->length; 194 this->length = 0; 195} 196 197$( IFS=" " 198 id=$(( $ID + 4 + $nconf )) 199 for var in $conf; do 200 eval val=\"\$$var\" 201 printf "tcp:::send\n" 202 printf "\t/" 203 [ "$_EVENT_TEST" ] && printf "%s && " "$_EVENT_TEST" 204 printf "(%s)/\n" "$val" 205 printf "\t/* probe ID %u */\n" $id 206 printf "{${TRACE:+\n\tprintf(\"<$id>\");}\n" 207 printf "\t%s_tcp_sent += this->length;\n" $var 208 printf "\tthis->length = 0;\n" 209 printf "}\n\n" 210 id=$(( $id + 1 )) 211 done 212) 213 214tcp:::send /1${_EVENT_TEST:+ && $_EVENT_TEST}${_CONF_OTHER:+ && 215 $_CONF_OTHER}/ /* probe ID $(( $ID + 4 + $nconf * 2 )) */ 216{${TRACE:+ 217 printf("<$(( $ID + 4 + $nconf * 2 ))>");} 218 tcp_sent += this->length; 219 this->length = 0; 220} 221 222/****************************** UDP ******************************/ 223 224udp:::send /* probe ID $(( $ID + 5 + $nconf * 2 )) */ 225{${TRACE:+ 226 printf("<$(( $ID + 5 + $nconf * 2 ))"); 227} 228 /* 229 * ipinfo_t * 230 */ 231 this->local = args[2]->ip_saddr; 232 this->remote = args[2]->ip_daddr; 233 234 /* 235 * udpinfo_t * 236 */ 237 this->length = (uint16_t)args[4]->udp_length; 238 this->lport = args[4]->udp_sport; 239 this->rport = args[4]->udp_dport; 240 241 /* 242 * IPv6 support 243 */ 244 this->local6 = strstr(this->local, ":") != NULL ? 1 : 0; 245 this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0; 246 this->local = strjoin(strjoin(this->local6 ? "[" : "", 247 this->local), this->local6 ? "]" : ""); 248 this->remote = strjoin(strjoin(this->remote6 ? "[" : "", 249 this->remote), this->remote6 ? "]" : ""); 250 251 this->family = "udp"; 252 this->event = "SEND"; 253} 254 255$( IFS=" " 256 id=$(( $ID + 6 + $nconf * 2 )) 257 for var in $conf; do 258 eval val=\"\$$var\" 259 printf "udp:::send\n" 260 printf "\t/" 261 [ "$_EVENT_TEST" ] && printf "%s && " "$_EVENT_TEST" 262 printf "(%s)/\n" "$val" 263 printf "\t/* probe ID %u */\n" $id 264 printf "{${TRACE:+\n\tprintf(\"<$id>\");}\n" 265 printf "\t%s_udp_sent += this->length;\n" $var 266 printf "\tthis->length = 0;\n" 267 printf "}\n\n" 268 id=$(( $id + 1 )) 269 done 270) 271 272udp:::send /1${_EVENT_TEST:+ && $_EVENT_TEST}${_CONF_OTHER:+ && 273 $_CONF_OTHER}/ /* probe ID $(( $ID + 6 + $nconf * 3 )) */ 274{${TRACE:+ 275 printf("<$(( $ID + 6 + $nconf * 3 ))>");} 276 udp_sent += this->length; 277 this->length = 0; 278} 279 280udp:::receive /* probe ID $(( $ID + 7 + $nconf * 3 )) */ 281{${TRACE:+ 282 printf("<$(( $ID + 7 + $nconf * 3 ))>"); 283} 284 /* 285 * csinfo_t * 286 */ 287 urecv_inpcb = (struct inpcb *)args[1]->cs_cid; 288 urecv_socket = urecv_inpcb->inp_socket; 289 290 /* 291 * ipinfo_t * 292 */ 293 urecv_local = args[2]->ip_daddr; 294 urecv_remote = args[2]->ip_saddr; 295 296 /* 297 * udpinfo_t * 298 */ 299 urecv_length = (uint16_t)args[4]->udp_length; 300 urecv_lport = args[4]->udp_dport; 301 urecv_rport = args[4]->udp_sport; 302 303 /* 304 * IPv6 support 305 */ 306 urecv_local6 = strstr(urecv_local, ":") != NULL ? 1 : 0; 307 urecv_remote6 = strstr(urecv_remote, ":") != NULL ? 1 : 0; 308 urecv_local = strjoin(strjoin(urecv_local6 ? "[" : "", 309 urecv_local), urecv_local6 ? "]" : ""); 310 urecv_remote = strjoin(strjoin(urecv_remote6 ? "[" : "", 311 urecv_remote), urecv_remote6 ? "]" : ""); 312} 313 314fbt::soreceive_dgram:entry 315 /args[0] == urecv_socket/ 316 /* probe ID $(( $ID + 8 + $nconf * 3 )) */ 317{${TRACE:+ 318 printf("<$(( $ID + 8 + $nconf * 3 ))>");} 319 this->local = urecv_local; 320 this->remote = urecv_remote; 321 this->length = urecv_length; 322 this->lport = urecv_lport; 323 this->rport = urecv_rport; 324 this->local6 = urecv_local6; 325 this->remote6 = urecv_remote6; 326 327 this->family = "udp"; 328 this->event = "RCVD"; 329} 330 331$( IFS=" " 332 id=$(( $ID + 9 + $nconf * 3 )) 333 for var in $conf; do 334 eval val=\"\$$var\" 335 printf "fbt::soreceive_dgram:entry\n" 336 printf "\t/args[0] == urecv_socket" 337 [ "$_EVENT_TEST" ] && printf " && %s" "$_EVENT_TEST" 338 printf " && (%s)/\n" "$val" 339 printf "\t/* probe ID %u */\n" $id 340 printf "{${TRACE:+\n\tprintf(\"<$id>\");}\n" 341 printf "\t%s_udp_rcvd += this->length;\n" $var 342 printf "\tthis->length = 0;\n" 343 printf "}\n\n" 344 id=$(( $id + 1 )) 345 done 346) 347 348fbt::soreceive_dgram:entry 349 /args[0] == urecv_socket${_EVENT_TEST:+ && 350 $_EVENT_TEST}${_CONF_OTHER:+ && 351 $_CONF_OTHER}/ 352 /* probe ID $(( $ID + 9 + $nconf * 4 )) */ 353{${TRACE:+ 354 printf("<$(( $ID + 9 + $nconf * 4 ))>");} 355 udp_rcvd += this->length; 356 this->length = 0; 357} 358EOF 359ACTIONS=$( cat <&9 ) 360ID=$(( $ID + 10 + $nconf * 4 )) 361 362############################################################ EVENT TAG 363 364# The EVENT_TAG is run inside the print action after the timestamp has been 365# printed. By default, `UID.GID CMD[PID]: ' of the process is printed. 366 367EVENT_TAG="printf(\"${PROFILE%-raw}: \")" 368 369############################################################ EVENT DETAILS 370 371exec 9<<EOF 372 /* 373 * Print path details 374 */ 375 printf("{\"report_type\":\"$REPORT_TYPE\",\"hostname\":\"$HOSTNAME\",\"epoch\":%u,\"tcp_rcvd\":%u,\"tcp_sent\":%u,\"udp_rcvd\":%u,\"udp_sent\":%u$( IFS=" " 376 for var in $conf; do 377 printf ",\\\\\"%s_tcp_rcvd\\\\\":%%u" $var 378 printf ",\\\\\"%s_tcp_sent\\\\\":%%u" $var 379 printf ",\\\\\"%s_udp_rcvd\\\\\":%%u" $var 380 printf ",\\\\\"%s_udp_sent\\\\\":%%u" $var 381 done 382 )}", 383 walltimestamp / 1000000000, 384 tcp_rcvd, tcp_sent, 385 udp_rcvd, udp_sent$( IFS=" " 386 for var in $conf; do 387 printf ",\n\t\t\t%s_tcp_rcvd" $var 388 printf ", %s_tcp_sent" $var 389 printf ",\n\t\t\t%s_udp_rcvd" $var 390 printf ", %s_udp_sent" $var 391 done 392 )); 393 394 /* 395 * Reset counters 396 */ 397 tcp_rcvd = tcp_sent = 0; 398 udp_rcvd = udp_sent = 0; 399$( IFS=" " 400 for var in $conf; do 401 printf "\t%s_tcp_rcvd = %s_tcp_sent = 0;\n" $var $var 402 printf "\t%s_udp_rcvd = %s_udp_sent = 0;\n" $var $var 403 done 404) 405EOF 406EVENT_DETAILS=$( cat <&9 ) 407 408################################################################################ 409# END 410################################################################################ 411