generateSocketErrorTracepoint creates the inet_sk_error_report tracepoint. This captures socket errors like ECONNREFUSED, ETIMEDOUT, etc.
()
| 279 | // generateSocketErrorTracepoint creates the inet_sk_error_report tracepoint. |
| 280 | // This captures socket errors like ECONNREFUSED, ETIMEDOUT, etc. |
| 281 | func (g *ScriptGenerator) generateSocketErrorTracepoint() string { |
| 282 | var sb strings.Builder |
| 283 | |
| 284 | sb.WriteString("tracepoint:sock:inet_sk_error_report\n") |
| 285 | sb.WriteString("{\n") |
| 286 | |
| 287 | // Only process IPv4 (family == 2) and skip error=0 (not a real error) |
| 288 | sb.WriteString(` if (args->family != 2) { return; } |
| 289 | if (args->error == 0) { return; } // Skip non-error events (socket cleanup) |
| 290 | |
| 291 | `) |
| 292 | |
| 293 | // Extract bytes into local vars first (required for BPF verifier) |
| 294 | if g.hasIPFilter() { |
| 295 | sb.WriteString(` // Read IP bytes into local vars for filtering |
| 296 | $s0 = args->saddr[0]; $s1 = args->saddr[1]; $s2 = args->saddr[2]; $s3 = args->saddr[3]; |
| 297 | $d0 = args->daddr[0]; $d1 = args->daddr[1]; $d2 = args->daddr[2]; $d3 = args->daddr[3]; |
| 298 | |
| 299 | `) |
| 300 | // Add IP filter using local vars |
| 301 | sb.WriteString(g.buildTCPIPFilterCheckFromLocalVars()) |
| 302 | } |
| 303 | |
| 304 | sb.WriteString(` $saddr = ntop(2, args->saddr); |
| 305 | $daddr = ntop(2, args->daddr); |
| 306 | $sport = args->sport; |
| 307 | $dport = args->dport; |
| 308 | $error = args->error; |
| 309 | |
| 310 | `) |
| 311 | |
| 312 | if g.config.OutputJSON { |
| 313 | // JSON output: use error code only (parsers can decode POSIX errno) |
| 314 | sb.WriteString(` printf("{\"time\":\"%s\",\"type\":\"SOCK_ERR\",\"errno\":%d,\"probe\":\"inet_sk_error_report\",\"src_ip\":\"%s\",\"src_port\":%d,\"dst_ip\":\"%s\",\"dst_port\":%d}\n", |
| 315 | strftime("%H:%M:%S", nsecs), |
| 316 | $error, |
| 317 | $saddr, $sport, |
| 318 | $daddr, $dport); |
| 319 | `) |
| 320 | } else { |
| 321 | // Table output: decode errno to human-readable name |
| 322 | sb.WriteString(` // Decode common socket errno values (POSIX standard) |
| 323 | $errno_name = $error == 104 ? "ECONNRESET" : |
| 324 | $error == 110 ? "ETIMEDOUT" : |
| 325 | $error == 111 ? "ECONNREFUSED" : |
| 326 | $error == 113 ? "EHOSTUNREACH" : |
| 327 | $error == 101 ? "ENETUNREACH" : |
| 328 | $error == 99 ? "EADDRNOTAVAIL" : |
| 329 | $error == 112 ? "EHOSTDOWN" : |
| 330 | $error == 103 ? "ECONNABORTED" : |
| 331 | "UNKNOWN"; |
| 332 | |
| 333 | printf("%-12s %-10s %-18s %-18s %-18s %s:%-5d -> %s:%-5d\n", |
| 334 | strftime("%H:%M:%S", nsecs), |
| 335 | "SOCK_ERR", |
| 336 | $errno_name, |
| 337 | "-", |
| 338 | "inet_sk_error_report", |
no test coverage detected