54#include "pfctl_parser.h" 55#include "pfctl.h" 56 57void print_op (u_int8_t, const char *, const char *); 58void print_port (u_int8_t, u_int16_t, u_int16_t, const char *); 59void print_ugid (u_int8_t, unsigned, unsigned, const char *, unsigned); 60void print_flags (u_int8_t); 61void print_fromto(struct pf_rule_addr *, pf_osfp_t, 62 struct pf_rule_addr *, u_int8_t, u_int8_t, int); 63 64struct node_host *host_if(const char *, int); 65struct node_host *host_v4(const char *, int); 66struct node_host *host_v6(const char *, int); 67struct node_host *host_dns(const char *, int, int); 68 69const char *tcpflags = "FSRPAUEW"; 70 71static const struct icmptypeent icmp_type[] = { 72 { "echoreq", ICMP_ECHO }, 73 { "echorep", ICMP_ECHOREPLY }, 74 { "unreach", ICMP_UNREACH }, 75 { "squench", ICMP_SOURCEQUENCH }, 76 { "redir", ICMP_REDIRECT }, 77 { "althost", ICMP_ALTHOSTADDR }, 78 { "routeradv", ICMP_ROUTERADVERT }, 79 { "routersol", ICMP_ROUTERSOLICIT }, 80 { "timex", ICMP_TIMXCEED }, 81 { "paramprob", ICMP_PARAMPROB }, 82 { "timereq", ICMP_TSTAMP }, 83 { "timerep", ICMP_TSTAMPREPLY }, 84 { "inforeq", ICMP_IREQ }, 85 { "inforep", ICMP_IREQREPLY }, 86 { "maskreq", ICMP_MASKREQ }, 87 { "maskrep", ICMP_MASKREPLY }, 88 { "trace", ICMP_TRACEROUTE }, 89 { "dataconv", ICMP_DATACONVERR }, 90 { "mobredir", ICMP_MOBILE_REDIRECT }, 91 { "ipv6-where", ICMP_IPV6_WHEREAREYOU }, 92 { "ipv6-here", ICMP_IPV6_IAMHERE }, 93 { "mobregreq", ICMP_MOBILE_REGREQUEST }, 94 { "mobregrep", ICMP_MOBILE_REGREPLY }, 95 { "skip", ICMP_SKIP }, 96 { "photuris", ICMP_PHOTURIS } 97}; 98 99static const struct icmptypeent icmp6_type[] = { 100 { "unreach", ICMP6_DST_UNREACH }, 101 { "toobig", ICMP6_PACKET_TOO_BIG }, 102 { "timex", ICMP6_TIME_EXCEEDED }, 103 { "paramprob", ICMP6_PARAM_PROB }, 104 { "echoreq", ICMP6_ECHO_REQUEST }, 105 { "echorep", ICMP6_ECHO_REPLY }, 106 { "groupqry", ICMP6_MEMBERSHIP_QUERY }, 107 { "listqry", MLD_LISTENER_QUERY }, 108 { "grouprep", ICMP6_MEMBERSHIP_REPORT }, 109 { "listenrep", MLD_LISTENER_REPORT }, 110 { "groupterm", ICMP6_MEMBERSHIP_REDUCTION }, 111 { "listendone", MLD_LISTENER_DONE }, 112 { "routersol", ND_ROUTER_SOLICIT }, 113 { "routeradv", ND_ROUTER_ADVERT }, 114 { "neighbrsol", ND_NEIGHBOR_SOLICIT }, 115 { "neighbradv", ND_NEIGHBOR_ADVERT }, 116 { "redir", ND_REDIRECT }, 117 { "routrrenum", ICMP6_ROUTER_RENUMBERING }, 118 { "wrureq", ICMP6_WRUREQUEST }, 119 { "wrurep", ICMP6_WRUREPLY }, 120 { "fqdnreq", ICMP6_FQDN_QUERY }, 121 { "fqdnrep", ICMP6_FQDN_REPLY }, 122 { "niqry", ICMP6_NI_QUERY }, 123 { "nirep", ICMP6_NI_REPLY }, 124 { "mtraceresp", MLD_MTRACE_RESP }, 125 { "mtrace", MLD_MTRACE } 126}; 127 128static const struct icmpcodeent icmp_code[] = { 129 { "net-unr", ICMP_UNREACH, ICMP_UNREACH_NET }, 130 { "host-unr", ICMP_UNREACH, ICMP_UNREACH_HOST }, 131 { "proto-unr", ICMP_UNREACH, ICMP_UNREACH_PROTOCOL }, 132 { "port-unr", ICMP_UNREACH, ICMP_UNREACH_PORT }, 133 { "needfrag", ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG }, 134 { "srcfail", ICMP_UNREACH, ICMP_UNREACH_SRCFAIL }, 135 { "net-unk", ICMP_UNREACH, ICMP_UNREACH_NET_UNKNOWN }, 136 { "host-unk", ICMP_UNREACH, ICMP_UNREACH_HOST_UNKNOWN }, 137 { "isolate", ICMP_UNREACH, ICMP_UNREACH_ISOLATED }, 138 { "net-prohib", ICMP_UNREACH, ICMP_UNREACH_NET_PROHIB }, 139 { "host-prohib", ICMP_UNREACH, ICMP_UNREACH_HOST_PROHIB }, 140 { "net-tos", ICMP_UNREACH, ICMP_UNREACH_TOSNET }, 141 { "host-tos", ICMP_UNREACH, ICMP_UNREACH_TOSHOST }, 142 { "filter-prohib", ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB }, 143 { "host-preced", ICMP_UNREACH, ICMP_UNREACH_HOST_PRECEDENCE }, 144 { "cutoff-preced", ICMP_UNREACH, ICMP_UNREACH_PRECEDENCE_CUTOFF }, 145 { "redir-net", ICMP_REDIRECT, ICMP_REDIRECT_NET }, 146 { "redir-host", ICMP_REDIRECT, ICMP_REDIRECT_HOST }, 147 { "redir-tos-net", ICMP_REDIRECT, ICMP_REDIRECT_TOSNET }, 148 { "redir-tos-host", ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST }, 149 { "normal-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NORMAL }, 150 { "common-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NOROUTE_COMMON }, 151 { "transit", ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS }, 152 { "reassemb", ICMP_TIMXCEED, ICMP_TIMXCEED_REASS }, 153 { "badhead", ICMP_PARAMPROB, ICMP_PARAMPROB_ERRATPTR }, 154 { "optmiss", ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT }, 155 { "badlen", ICMP_PARAMPROB, ICMP_PARAMPROB_LENGTH }, 156 { "unknown-ind", ICMP_PHOTURIS, ICMP_PHOTURIS_UNKNOWN_INDEX }, 157 { "auth-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_AUTH_FAILED }, 158 { "decrypt-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_DECRYPT_FAILED } 159}; 160 161static const struct icmpcodeent icmp6_code[] = { 162 { "admin-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN }, 163 { "noroute-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE }, 164 { "notnbr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOTNEIGHBOR }, 165 { "beyond-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_BEYONDSCOPE }, 166 { "addr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR }, 167 { "port-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT }, 168 { "transit", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT }, 169 { "reassemb", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY }, 170 { "badhead", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER }, 171 { "nxthdr", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER }, 172 { "redironlink", ND_REDIRECT, ND_REDIRECT_ONLINK }, 173 { "redirrouter", ND_REDIRECT, ND_REDIRECT_ROUTER } 174}; 175 176const struct pf_timeout pf_timeouts[] = { 177 { "tcp.first", PFTM_TCP_FIRST_PACKET }, 178 { "tcp.opening", PFTM_TCP_OPENING }, 179 { "tcp.established", PFTM_TCP_ESTABLISHED }, 180 { "tcp.closing", PFTM_TCP_CLOSING }, 181 { "tcp.finwait", PFTM_TCP_FIN_WAIT }, 182 { "tcp.closed", PFTM_TCP_CLOSED }, 183 { "udp.first", PFTM_UDP_FIRST_PACKET }, 184 { "udp.single", PFTM_UDP_SINGLE }, 185 { "udp.multiple", PFTM_UDP_MULTIPLE }, 186 { "icmp.first", PFTM_ICMP_FIRST_PACKET }, 187 { "icmp.error", PFTM_ICMP_ERROR_REPLY }, 188 { "other.first", PFTM_OTHER_FIRST_PACKET }, 189 { "other.single", PFTM_OTHER_SINGLE }, 190 { "other.multiple", PFTM_OTHER_MULTIPLE }, 191 { "frag", PFTM_FRAG }, 192 { "interval", PFTM_INTERVAL }, 193 { "adaptive.start", PFTM_ADAPTIVE_START }, 194 { "adaptive.end", PFTM_ADAPTIVE_END }, 195 { NULL, 0 } 196}; 197 198const struct icmptypeent * 199geticmptypebynumber(u_int8_t type, sa_family_t af) 200{ 201 unsigned int i; 202 203 if (af != AF_INET6) { 204 for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); 205 i++) { 206 if (type == icmp_type[i].type) 207 return (&icmp_type[i]); 208 } 209 } else { 210 for (i=0; i < (sizeof (icmp6_type) / 211 sizeof(icmp6_type[0])); i++) { 212 if (type == icmp6_type[i].type) 213 return (&icmp6_type[i]); 214 } 215 } 216 return (NULL); 217} 218 219const struct icmptypeent * 220geticmptypebyname(char *w, sa_family_t af) 221{ 222 unsigned int i; 223 224 if (af != AF_INET6) { 225 for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); 226 i++) { 227 if (!strcmp(w, icmp_type[i].name)) 228 return (&icmp_type[i]); 229 } 230 } else { 231 for (i=0; i < (sizeof (icmp6_type) / 232 sizeof(icmp6_type[0])); i++) { 233 if (!strcmp(w, icmp6_type[i].name)) 234 return (&icmp6_type[i]); 235 } 236 } 237 return (NULL); 238} 239 240const struct icmpcodeent * 241geticmpcodebynumber(u_int8_t type, u_int8_t code, sa_family_t af) 242{ 243 unsigned int i; 244 245 if (af != AF_INET6) { 246 for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); 247 i++) { 248 if (type == icmp_code[i].type && 249 code == icmp_code[i].code) 250 return (&icmp_code[i]); 251 } 252 } else { 253 for (i=0; i < (sizeof (icmp6_code) / 254 sizeof(icmp6_code[0])); i++) { 255 if (type == icmp6_code[i].type && 256 code == icmp6_code[i].code) 257 return (&icmp6_code[i]); 258 } 259 } 260 return (NULL); 261} 262 263const struct icmpcodeent * 264geticmpcodebyname(u_long type, char *w, sa_family_t af) 265{ 266 unsigned int i; 267 268 if (af != AF_INET6) { 269 for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); 270 i++) { 271 if (type == icmp_code[i].type && 272 !strcmp(w, icmp_code[i].name)) 273 return (&icmp_code[i]); 274 } 275 } else { 276 for (i=0; i < (sizeof (icmp6_code) / 277 sizeof(icmp6_code[0])); i++) { 278 if (type == icmp6_code[i].type && 279 !strcmp(w, icmp6_code[i].name)) 280 return (&icmp6_code[i]); 281 } 282 } 283 return (NULL); 284} 285 286void 287print_op(u_int8_t op, const char *a1, const char *a2) 288{ 289 if (op == PF_OP_IRG) 290 printf(" %s >< %s", a1, a2); 291 else if (op == PF_OP_XRG) 292 printf(" %s <> %s", a1, a2); 293 else if (op == PF_OP_EQ) 294 printf(" = %s", a1); 295 else if (op == PF_OP_NE) 296 printf(" != %s", a1); 297 else if (op == PF_OP_LT) 298 printf(" < %s", a1); 299 else if (op == PF_OP_LE) 300 printf(" <= %s", a1); 301 else if (op == PF_OP_GT) 302 printf(" > %s", a1); 303 else if (op == PF_OP_GE) 304 printf(" >= %s", a1); 305 else if (op == PF_OP_RRG) 306 printf(" %s:%s", a1, a2); 307} 308 309void 310print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, const char *proto) 311{ 312 char a1[6], a2[6]; 313 struct servent *s; 314 315 s = getservbyport(p1, proto); 316 p1 = ntohs(p1); 317 p2 = ntohs(p2); 318 snprintf(a1, sizeof(a1), "%u", p1); 319 snprintf(a2, sizeof(a2), "%u", p2); 320 printf(" port"); 321 if (s != NULL && (op == PF_OP_EQ || op == PF_OP_NE)) 322 print_op(op, s->s_name, a2); 323 else 324 print_op(op, a1, a2); 325} 326 327void 328print_ugid(u_int8_t op, unsigned u1, unsigned u2, const char *t, unsigned umax) 329{ 330 char a1[11], a2[11]; 331 332 snprintf(a1, sizeof(a1), "%u", u1); 333 snprintf(a2, sizeof(a2), "%u", u2); 334 printf(" %s", t); 335 if (u1 == umax && (op == PF_OP_EQ || op == PF_OP_NE)) 336 print_op(op, "unknown", a2); 337 else 338 print_op(op, a1, a2); 339} 340 341void 342print_flags(u_int8_t f) 343{ 344 int i; 345 346 for (i = 0; tcpflags[i]; ++i) 347 if (f & (1 << i)) 348 printf("%c", tcpflags[i]); 349} 350 351void 352print_fromto(struct pf_rule_addr *src, pf_osfp_t osfp, struct pf_rule_addr *dst, 353 sa_family_t af, u_int8_t proto, int verbose) 354{ 355 char buf[PF_OSFP_LEN*3]; 356 if (src->addr.type == PF_ADDR_ADDRMASK && 357 dst->addr.type == PF_ADDR_ADDRMASK && 358 PF_AZERO(&src->addr.v.a.addr, AF_INET6) && 359 PF_AZERO(&src->addr.v.a.mask, AF_INET6) && 360 PF_AZERO(&dst->addr.v.a.addr, AF_INET6) && 361 PF_AZERO(&dst->addr.v.a.mask, AF_INET6) && 362 !src->not && !dst->not && 363 !src->port_op && !dst->port_op && 364 osfp == PF_OSFP_ANY) 365 printf(" all"); 366 else { 367 printf(" from "); 368 if (src->not) 369 printf("! "); 370 print_addr(&src->addr, af, verbose); 371 if (src->port_op) 372 print_port(src->port_op, src->port[0], 373 src->port[1], 374 proto == IPPROTO_TCP ? "tcp" : "udp"); 375 if (osfp != PF_OSFP_ANY) 376 printf(" os \"%s\"", pfctl_lookup_fingerprint(osfp, buf, 377 sizeof(buf))); 378 379 printf(" to "); 380 if (dst->not) 381 printf("! "); 382 print_addr(&dst->addr, af, verbose); 383 if (dst->port_op) 384 print_port(dst->port_op, dst->port[0], 385 dst->port[1], 386 proto == IPPROTO_TCP ? "tcp" : "udp"); 387 } 388} 389 390void 391print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, 392 sa_family_t af, int id) 393{ 394 struct pf_pooladdr *pooladdr; 395 396 if ((TAILQ_FIRST(&pool->list) != NULL) && 397 TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 398 printf("{ "); 399 TAILQ_FOREACH(pooladdr, &pool->list, entries){ 400 switch (id) { 401 case PF_NAT: 402 case PF_RDR: 403 case PF_BINAT: 404 print_addr(&pooladdr->addr, af, 0); 405 break; 406 case PF_PASS: 407 if (PF_AZERO(&pooladdr->addr.v.a.addr, af)) 408 printf("%s", pooladdr->ifname); 409 else { 410 printf("(%s ", pooladdr->ifname); 411 print_addr(&pooladdr->addr, af, 0); 412 printf(")"); 413 } 414 break; 415 default: 416 break; 417 } 418 if (TAILQ_NEXT(pooladdr, entries) != NULL) 419 printf(", "); 420 else if (TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 421 printf(" }"); 422 } 423 switch (id) { 424 case PF_NAT: 425 if ((p1 != PF_NAT_PROXY_PORT_LOW || 426 p2 != PF_NAT_PROXY_PORT_HIGH) && (p1 != 0 || p2 != 0)) { 427 if (p1 == p2) 428 printf(" port %u", p1); 429 else 430 printf(" port %u:%u", p1, p2); 431 } 432 break; 433 case PF_RDR: 434 if (p1) { 435 printf(" port %u", p1); 436 if (p2 && (p2 != p1)) 437 printf(":%u", p2); 438 } 439 break; 440 default: 441 break; 442 } 443 switch (pool->opts & PF_POOL_TYPEMASK) { 444 case PF_POOL_NONE: 445 break; 446 case PF_POOL_BITMASK: 447 printf(" bitmask"); 448 break; 449 case PF_POOL_RANDOM: 450 printf(" random"); 451 break; 452 case PF_POOL_SRCHASH: 453 printf(" source-hash 0x%08x%08x%08x%08x", 454 pool->key.key32[0], pool->key.key32[1], 455 pool->key.key32[2], pool->key.key32[3]); 456 break; 457 case PF_POOL_ROUNDROBIN: 458 printf(" round-robin"); 459 break; 460 } 461 if (id == PF_NAT && p1 == 0 && p2 == 0) 462 printf(" static-port"); 463} 464 465const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 466const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; 467 468void 469print_status(struct pf_status *s) 470{ 471 char statline[80]; 472 time_t runtime; 473 int i; 474 475 runtime = time(NULL) - s->since; 476 477 if (s->running) { 478 unsigned sec, min, hrs, day = runtime; 479 480 sec = day % 60; 481 day /= 60; 482 min = day % 60; 483 day /= 60; 484 hrs = day % 24; 485 day /= 24; 486 snprintf(statline, sizeof(statline), 487 "Status: Enabled for %u days %.2u:%.2u:%.2u", 488 day, hrs, min, sec); 489 } else 490 snprintf(statline, sizeof(statline), "Status: Disabled"); 491 printf("%-44s", statline); 492 switch (s->debug) { 493 case 0: 494 printf("%15s\n\n", "Debug: None"); 495 break; 496 case 1: 497 printf("%15s\n\n", "Debug: Urgent"); 498 break; 499 case 2: 500 printf("%15s\n\n", "Debug: Misc"); 501 break; 502 } 503 if (s->ifname[0] != 0) { 504 printf("Interface Stats for %-16s %5s %16s\n", 505 s->ifname, "IPv4", "IPv6");
| 62#include "pfctl_parser.h" 63#include "pfctl.h" 64 65void print_op (u_int8_t, const char *, const char *); 66void print_port (u_int8_t, u_int16_t, u_int16_t, const char *); 67void print_ugid (u_int8_t, unsigned, unsigned, const char *, unsigned); 68void print_flags (u_int8_t); 69void print_fromto(struct pf_rule_addr *, pf_osfp_t, 70 struct pf_rule_addr *, u_int8_t, u_int8_t, int); 71 72struct node_host *host_if(const char *, int); 73struct node_host *host_v4(const char *, int); 74struct node_host *host_v6(const char *, int); 75struct node_host *host_dns(const char *, int, int); 76 77const char *tcpflags = "FSRPAUEW"; 78 79static const struct icmptypeent icmp_type[] = { 80 { "echoreq", ICMP_ECHO }, 81 { "echorep", ICMP_ECHOREPLY }, 82 { "unreach", ICMP_UNREACH }, 83 { "squench", ICMP_SOURCEQUENCH }, 84 { "redir", ICMP_REDIRECT }, 85 { "althost", ICMP_ALTHOSTADDR }, 86 { "routeradv", ICMP_ROUTERADVERT }, 87 { "routersol", ICMP_ROUTERSOLICIT }, 88 { "timex", ICMP_TIMXCEED }, 89 { "paramprob", ICMP_PARAMPROB }, 90 { "timereq", ICMP_TSTAMP }, 91 { "timerep", ICMP_TSTAMPREPLY }, 92 { "inforeq", ICMP_IREQ }, 93 { "inforep", ICMP_IREQREPLY }, 94 { "maskreq", ICMP_MASKREQ }, 95 { "maskrep", ICMP_MASKREPLY }, 96 { "trace", ICMP_TRACEROUTE }, 97 { "dataconv", ICMP_DATACONVERR }, 98 { "mobredir", ICMP_MOBILE_REDIRECT }, 99 { "ipv6-where", ICMP_IPV6_WHEREAREYOU }, 100 { "ipv6-here", ICMP_IPV6_IAMHERE }, 101 { "mobregreq", ICMP_MOBILE_REGREQUEST }, 102 { "mobregrep", ICMP_MOBILE_REGREPLY }, 103 { "skip", ICMP_SKIP }, 104 { "photuris", ICMP_PHOTURIS } 105}; 106 107static const struct icmptypeent icmp6_type[] = { 108 { "unreach", ICMP6_DST_UNREACH }, 109 { "toobig", ICMP6_PACKET_TOO_BIG }, 110 { "timex", ICMP6_TIME_EXCEEDED }, 111 { "paramprob", ICMP6_PARAM_PROB }, 112 { "echoreq", ICMP6_ECHO_REQUEST }, 113 { "echorep", ICMP6_ECHO_REPLY }, 114 { "groupqry", ICMP6_MEMBERSHIP_QUERY }, 115 { "listqry", MLD_LISTENER_QUERY }, 116 { "grouprep", ICMP6_MEMBERSHIP_REPORT }, 117 { "listenrep", MLD_LISTENER_REPORT }, 118 { "groupterm", ICMP6_MEMBERSHIP_REDUCTION }, 119 { "listendone", MLD_LISTENER_DONE }, 120 { "routersol", ND_ROUTER_SOLICIT }, 121 { "routeradv", ND_ROUTER_ADVERT }, 122 { "neighbrsol", ND_NEIGHBOR_SOLICIT }, 123 { "neighbradv", ND_NEIGHBOR_ADVERT }, 124 { "redir", ND_REDIRECT }, 125 { "routrrenum", ICMP6_ROUTER_RENUMBERING }, 126 { "wrureq", ICMP6_WRUREQUEST }, 127 { "wrurep", ICMP6_WRUREPLY }, 128 { "fqdnreq", ICMP6_FQDN_QUERY }, 129 { "fqdnrep", ICMP6_FQDN_REPLY }, 130 { "niqry", ICMP6_NI_QUERY }, 131 { "nirep", ICMP6_NI_REPLY }, 132 { "mtraceresp", MLD_MTRACE_RESP }, 133 { "mtrace", MLD_MTRACE } 134}; 135 136static const struct icmpcodeent icmp_code[] = { 137 { "net-unr", ICMP_UNREACH, ICMP_UNREACH_NET }, 138 { "host-unr", ICMP_UNREACH, ICMP_UNREACH_HOST }, 139 { "proto-unr", ICMP_UNREACH, ICMP_UNREACH_PROTOCOL }, 140 { "port-unr", ICMP_UNREACH, ICMP_UNREACH_PORT }, 141 { "needfrag", ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG }, 142 { "srcfail", ICMP_UNREACH, ICMP_UNREACH_SRCFAIL }, 143 { "net-unk", ICMP_UNREACH, ICMP_UNREACH_NET_UNKNOWN }, 144 { "host-unk", ICMP_UNREACH, ICMP_UNREACH_HOST_UNKNOWN }, 145 { "isolate", ICMP_UNREACH, ICMP_UNREACH_ISOLATED }, 146 { "net-prohib", ICMP_UNREACH, ICMP_UNREACH_NET_PROHIB }, 147 { "host-prohib", ICMP_UNREACH, ICMP_UNREACH_HOST_PROHIB }, 148 { "net-tos", ICMP_UNREACH, ICMP_UNREACH_TOSNET }, 149 { "host-tos", ICMP_UNREACH, ICMP_UNREACH_TOSHOST }, 150 { "filter-prohib", ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB }, 151 { "host-preced", ICMP_UNREACH, ICMP_UNREACH_HOST_PRECEDENCE }, 152 { "cutoff-preced", ICMP_UNREACH, ICMP_UNREACH_PRECEDENCE_CUTOFF }, 153 { "redir-net", ICMP_REDIRECT, ICMP_REDIRECT_NET }, 154 { "redir-host", ICMP_REDIRECT, ICMP_REDIRECT_HOST }, 155 { "redir-tos-net", ICMP_REDIRECT, ICMP_REDIRECT_TOSNET }, 156 { "redir-tos-host", ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST }, 157 { "normal-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NORMAL }, 158 { "common-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NOROUTE_COMMON }, 159 { "transit", ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS }, 160 { "reassemb", ICMP_TIMXCEED, ICMP_TIMXCEED_REASS }, 161 { "badhead", ICMP_PARAMPROB, ICMP_PARAMPROB_ERRATPTR }, 162 { "optmiss", ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT }, 163 { "badlen", ICMP_PARAMPROB, ICMP_PARAMPROB_LENGTH }, 164 { "unknown-ind", ICMP_PHOTURIS, ICMP_PHOTURIS_UNKNOWN_INDEX }, 165 { "auth-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_AUTH_FAILED }, 166 { "decrypt-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_DECRYPT_FAILED } 167}; 168 169static const struct icmpcodeent icmp6_code[] = { 170 { "admin-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN }, 171 { "noroute-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE }, 172 { "notnbr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOTNEIGHBOR }, 173 { "beyond-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_BEYONDSCOPE }, 174 { "addr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR }, 175 { "port-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT }, 176 { "transit", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT }, 177 { "reassemb", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY }, 178 { "badhead", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER }, 179 { "nxthdr", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER }, 180 { "redironlink", ND_REDIRECT, ND_REDIRECT_ONLINK }, 181 { "redirrouter", ND_REDIRECT, ND_REDIRECT_ROUTER } 182}; 183 184const struct pf_timeout pf_timeouts[] = { 185 { "tcp.first", PFTM_TCP_FIRST_PACKET }, 186 { "tcp.opening", PFTM_TCP_OPENING }, 187 { "tcp.established", PFTM_TCP_ESTABLISHED }, 188 { "tcp.closing", PFTM_TCP_CLOSING }, 189 { "tcp.finwait", PFTM_TCP_FIN_WAIT }, 190 { "tcp.closed", PFTM_TCP_CLOSED }, 191 { "udp.first", PFTM_UDP_FIRST_PACKET }, 192 { "udp.single", PFTM_UDP_SINGLE }, 193 { "udp.multiple", PFTM_UDP_MULTIPLE }, 194 { "icmp.first", PFTM_ICMP_FIRST_PACKET }, 195 { "icmp.error", PFTM_ICMP_ERROR_REPLY }, 196 { "other.first", PFTM_OTHER_FIRST_PACKET }, 197 { "other.single", PFTM_OTHER_SINGLE }, 198 { "other.multiple", PFTM_OTHER_MULTIPLE }, 199 { "frag", PFTM_FRAG }, 200 { "interval", PFTM_INTERVAL }, 201 { "adaptive.start", PFTM_ADAPTIVE_START }, 202 { "adaptive.end", PFTM_ADAPTIVE_END }, 203 { NULL, 0 } 204}; 205 206const struct icmptypeent * 207geticmptypebynumber(u_int8_t type, sa_family_t af) 208{ 209 unsigned int i; 210 211 if (af != AF_INET6) { 212 for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); 213 i++) { 214 if (type == icmp_type[i].type) 215 return (&icmp_type[i]); 216 } 217 } else { 218 for (i=0; i < (sizeof (icmp6_type) / 219 sizeof(icmp6_type[0])); i++) { 220 if (type == icmp6_type[i].type) 221 return (&icmp6_type[i]); 222 } 223 } 224 return (NULL); 225} 226 227const struct icmptypeent * 228geticmptypebyname(char *w, sa_family_t af) 229{ 230 unsigned int i; 231 232 if (af != AF_INET6) { 233 for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); 234 i++) { 235 if (!strcmp(w, icmp_type[i].name)) 236 return (&icmp_type[i]); 237 } 238 } else { 239 for (i=0; i < (sizeof (icmp6_type) / 240 sizeof(icmp6_type[0])); i++) { 241 if (!strcmp(w, icmp6_type[i].name)) 242 return (&icmp6_type[i]); 243 } 244 } 245 return (NULL); 246} 247 248const struct icmpcodeent * 249geticmpcodebynumber(u_int8_t type, u_int8_t code, sa_family_t af) 250{ 251 unsigned int i; 252 253 if (af != AF_INET6) { 254 for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); 255 i++) { 256 if (type == icmp_code[i].type && 257 code == icmp_code[i].code) 258 return (&icmp_code[i]); 259 } 260 } else { 261 for (i=0; i < (sizeof (icmp6_code) / 262 sizeof(icmp6_code[0])); i++) { 263 if (type == icmp6_code[i].type && 264 code == icmp6_code[i].code) 265 return (&icmp6_code[i]); 266 } 267 } 268 return (NULL); 269} 270 271const struct icmpcodeent * 272geticmpcodebyname(u_long type, char *w, sa_family_t af) 273{ 274 unsigned int i; 275 276 if (af != AF_INET6) { 277 for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); 278 i++) { 279 if (type == icmp_code[i].type && 280 !strcmp(w, icmp_code[i].name)) 281 return (&icmp_code[i]); 282 } 283 } else { 284 for (i=0; i < (sizeof (icmp6_code) / 285 sizeof(icmp6_code[0])); i++) { 286 if (type == icmp6_code[i].type && 287 !strcmp(w, icmp6_code[i].name)) 288 return (&icmp6_code[i]); 289 } 290 } 291 return (NULL); 292} 293 294void 295print_op(u_int8_t op, const char *a1, const char *a2) 296{ 297 if (op == PF_OP_IRG) 298 printf(" %s >< %s", a1, a2); 299 else if (op == PF_OP_XRG) 300 printf(" %s <> %s", a1, a2); 301 else if (op == PF_OP_EQ) 302 printf(" = %s", a1); 303 else if (op == PF_OP_NE) 304 printf(" != %s", a1); 305 else if (op == PF_OP_LT) 306 printf(" < %s", a1); 307 else if (op == PF_OP_LE) 308 printf(" <= %s", a1); 309 else if (op == PF_OP_GT) 310 printf(" > %s", a1); 311 else if (op == PF_OP_GE) 312 printf(" >= %s", a1); 313 else if (op == PF_OP_RRG) 314 printf(" %s:%s", a1, a2); 315} 316 317void 318print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, const char *proto) 319{ 320 char a1[6], a2[6]; 321 struct servent *s; 322 323 s = getservbyport(p1, proto); 324 p1 = ntohs(p1); 325 p2 = ntohs(p2); 326 snprintf(a1, sizeof(a1), "%u", p1); 327 snprintf(a2, sizeof(a2), "%u", p2); 328 printf(" port"); 329 if (s != NULL && (op == PF_OP_EQ || op == PF_OP_NE)) 330 print_op(op, s->s_name, a2); 331 else 332 print_op(op, a1, a2); 333} 334 335void 336print_ugid(u_int8_t op, unsigned u1, unsigned u2, const char *t, unsigned umax) 337{ 338 char a1[11], a2[11]; 339 340 snprintf(a1, sizeof(a1), "%u", u1); 341 snprintf(a2, sizeof(a2), "%u", u2); 342 printf(" %s", t); 343 if (u1 == umax && (op == PF_OP_EQ || op == PF_OP_NE)) 344 print_op(op, "unknown", a2); 345 else 346 print_op(op, a1, a2); 347} 348 349void 350print_flags(u_int8_t f) 351{ 352 int i; 353 354 for (i = 0; tcpflags[i]; ++i) 355 if (f & (1 << i)) 356 printf("%c", tcpflags[i]); 357} 358 359void 360print_fromto(struct pf_rule_addr *src, pf_osfp_t osfp, struct pf_rule_addr *dst, 361 sa_family_t af, u_int8_t proto, int verbose) 362{ 363 char buf[PF_OSFP_LEN*3]; 364 if (src->addr.type == PF_ADDR_ADDRMASK && 365 dst->addr.type == PF_ADDR_ADDRMASK && 366 PF_AZERO(&src->addr.v.a.addr, AF_INET6) && 367 PF_AZERO(&src->addr.v.a.mask, AF_INET6) && 368 PF_AZERO(&dst->addr.v.a.addr, AF_INET6) && 369 PF_AZERO(&dst->addr.v.a.mask, AF_INET6) && 370 !src->not && !dst->not && 371 !src->port_op && !dst->port_op && 372 osfp == PF_OSFP_ANY) 373 printf(" all"); 374 else { 375 printf(" from "); 376 if (src->not) 377 printf("! "); 378 print_addr(&src->addr, af, verbose); 379 if (src->port_op) 380 print_port(src->port_op, src->port[0], 381 src->port[1], 382 proto == IPPROTO_TCP ? "tcp" : "udp"); 383 if (osfp != PF_OSFP_ANY) 384 printf(" os \"%s\"", pfctl_lookup_fingerprint(osfp, buf, 385 sizeof(buf))); 386 387 printf(" to "); 388 if (dst->not) 389 printf("! "); 390 print_addr(&dst->addr, af, verbose); 391 if (dst->port_op) 392 print_port(dst->port_op, dst->port[0], 393 dst->port[1], 394 proto == IPPROTO_TCP ? "tcp" : "udp"); 395 } 396} 397 398void 399print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, 400 sa_family_t af, int id) 401{ 402 struct pf_pooladdr *pooladdr; 403 404 if ((TAILQ_FIRST(&pool->list) != NULL) && 405 TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 406 printf("{ "); 407 TAILQ_FOREACH(pooladdr, &pool->list, entries){ 408 switch (id) { 409 case PF_NAT: 410 case PF_RDR: 411 case PF_BINAT: 412 print_addr(&pooladdr->addr, af, 0); 413 break; 414 case PF_PASS: 415 if (PF_AZERO(&pooladdr->addr.v.a.addr, af)) 416 printf("%s", pooladdr->ifname); 417 else { 418 printf("(%s ", pooladdr->ifname); 419 print_addr(&pooladdr->addr, af, 0); 420 printf(")"); 421 } 422 break; 423 default: 424 break; 425 } 426 if (TAILQ_NEXT(pooladdr, entries) != NULL) 427 printf(", "); 428 else if (TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 429 printf(" }"); 430 } 431 switch (id) { 432 case PF_NAT: 433 if ((p1 != PF_NAT_PROXY_PORT_LOW || 434 p2 != PF_NAT_PROXY_PORT_HIGH) && (p1 != 0 || p2 != 0)) { 435 if (p1 == p2) 436 printf(" port %u", p1); 437 else 438 printf(" port %u:%u", p1, p2); 439 } 440 break; 441 case PF_RDR: 442 if (p1) { 443 printf(" port %u", p1); 444 if (p2 && (p2 != p1)) 445 printf(":%u", p2); 446 } 447 break; 448 default: 449 break; 450 } 451 switch (pool->opts & PF_POOL_TYPEMASK) { 452 case PF_POOL_NONE: 453 break; 454 case PF_POOL_BITMASK: 455 printf(" bitmask"); 456 break; 457 case PF_POOL_RANDOM: 458 printf(" random"); 459 break; 460 case PF_POOL_SRCHASH: 461 printf(" source-hash 0x%08x%08x%08x%08x", 462 pool->key.key32[0], pool->key.key32[1], 463 pool->key.key32[2], pool->key.key32[3]); 464 break; 465 case PF_POOL_ROUNDROBIN: 466 printf(" round-robin"); 467 break; 468 } 469 if (id == PF_NAT && p1 == 0 && p2 == 0) 470 printf(" static-port"); 471} 472 473const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 474const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; 475 476void 477print_status(struct pf_status *s) 478{ 479 char statline[80]; 480 time_t runtime; 481 int i; 482 483 runtime = time(NULL) - s->since; 484 485 if (s->running) { 486 unsigned sec, min, hrs, day = runtime; 487 488 sec = day % 60; 489 day /= 60; 490 min = day % 60; 491 day /= 60; 492 hrs = day % 24; 493 day /= 24; 494 snprintf(statline, sizeof(statline), 495 "Status: Enabled for %u days %.2u:%.2u:%.2u", 496 day, hrs, min, sec); 497 } else 498 snprintf(statline, sizeof(statline), "Status: Disabled"); 499 printf("%-44s", statline); 500 switch (s->debug) { 501 case 0: 502 printf("%15s\n\n", "Debug: None"); 503 break; 504 case 1: 505 printf("%15s\n\n", "Debug: Urgent"); 506 break; 507 case 2: 508 printf("%15s\n\n", "Debug: Misc"); 509 break; 510 } 511 if (s->ifname[0] != 0) { 512 printf("Interface Stats for %-16s %5s %16s\n", 513 s->ifname, "IPv4", "IPv6");
|
540 if (runtime > 0) 541 printf("%14.1f/s\n", 542 (double)s->counters[i] / (double)runtime); 543 else 544 printf("%14s\n", ""); 545 } 546} 547 548void 549print_rule(struct pf_rule *r, int verbose) 550{ 551 static const char *actiontypes[] = { "pass", "block", "scrub", "nat", 552 "no nat", "binat", "no binat", "rdr", "no rdr" }; 553 static const char *anchortypes[] = { "anchor", "anchor", "anchor", 554 "nat-anchor", "nat-anchor", "binat-anchor", "binat-anchor", 555 "rdr-anchor", "rdr-anchor" }; 556 int i, opts; 557 558 if (verbose) 559 printf("@%d ", r->nr); 560 if (r->action > PF_NORDR) 561 printf("action(%d)", r->action); 562 else if (r->anchorname[0]) 563 printf("%s %s", anchortypes[r->action], r->anchorname); 564 else { 565 printf("%s", actiontypes[r->action]); 566 if (r->natpass) 567 printf(" pass"); 568 } 569 if (r->action == PF_DROP) { 570 if (r->rule_flag & PFRULE_RETURN) 571 printf(" return"); 572 else if (r->rule_flag & PFRULE_RETURNRST) { 573 if (!r->return_ttl) 574 printf(" return-rst"); 575 else 576 printf(" return-rst(ttl %d)", r->return_ttl); 577 } else if (r->rule_flag & PFRULE_RETURNICMP) { 578 const struct icmpcodeent *ic, *ic6; 579 580 ic = geticmpcodebynumber(r->return_icmp >> 8, 581 r->return_icmp & 255, AF_INET); 582 ic6 = geticmpcodebynumber(r->return_icmp6 >> 8, 583 r->return_icmp6 & 255, AF_INET6); 584 585 switch(r->af) { 586 case AF_INET: 587 printf(" return-icmp"); 588 if (ic == NULL) 589 printf("(%u)", r->return_icmp & 255); 590 else 591 printf("(%s)", ic->name); 592 break; 593 case AF_INET6: 594 printf(" return-icmp6"); 595 if (ic6 == NULL) 596 printf("(%u)", r->return_icmp6 & 255); 597 else 598 printf("(%s)", ic6->name); 599 break; 600 default: 601 printf(" return-icmp"); 602 if (ic == NULL) 603 printf("(%u, ", r->return_icmp & 255); 604 else 605 printf("(%s, ", ic->name); 606 if (ic6 == NULL) 607 printf("%u)", r->return_icmp6 & 255); 608 else 609 printf("%s)", ic6->name); 610 break; 611 } 612 } else 613 printf(" drop"); 614 } 615 if (r->direction == PF_IN) 616 printf(" in"); 617 else if (r->direction == PF_OUT) 618 printf(" out"); 619 if (r->log == 1) 620 printf(" log"); 621 else if (r->log == 2) 622 printf(" log-all"); 623 if (r->quick) 624 printf(" quick"); 625 if (r->ifname[0]) { 626 if (r->ifnot) 627 printf(" on ! %s", r->ifname); 628 else 629 printf(" on %s", r->ifname); 630 } 631 if (r->rt) { 632 if (r->rt == PF_ROUTETO) 633 printf(" route-to"); 634 else if (r->rt == PF_REPLYTO) 635 printf(" reply-to"); 636 else if (r->rt == PF_DUPTO) 637 printf(" dup-to"); 638 else if (r->rt == PF_FASTROUTE) 639 printf(" fastroute"); 640 if (r->rt != PF_FASTROUTE) { 641 printf(" "); 642 print_pool(&r->rpool, 0, 0, r->af, PF_PASS); 643 } 644 } 645 if (r->af) { 646 if (r->af == AF_INET) 647 printf(" inet"); 648 else 649 printf(" inet6"); 650 } 651 if (r->proto) { 652 struct protoent *p; 653 654 if ((p = getprotobynumber(r->proto)) != NULL) 655 printf(" proto %s", p->p_name); 656 else 657 printf(" proto %u", r->proto); 658 } 659 print_fromto(&r->src, r->os_fingerprint, &r->dst, r->af, r->proto, 660 verbose); 661 if (r->uid.op) 662 print_ugid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user", 663 UID_MAX); 664 if (r->gid.op) 665 print_ugid(r->gid.op, r->gid.gid[0], r->gid.gid[1], "group", 666 GID_MAX); 667 if (r->flags || r->flagset) { 668 printf(" flags "); 669 print_flags(r->flags); 670 printf("/"); 671 print_flags(r->flagset); 672 } 673 if (r->type) { 674 const struct icmptypeent *it; 675 676 it = geticmptypebynumber(r->type-1, r->af); 677 if (r->af != AF_INET6) 678 printf(" icmp-type"); 679 else 680 printf(" icmp6-type"); 681 if (it != NULL) 682 printf(" %s", it->name); 683 else 684 printf(" %u", r->type-1); 685 if (r->code) { 686 const struct icmpcodeent *ic; 687 688 ic = geticmpcodebynumber(r->type-1, r->code-1, r->af); 689 if (ic != NULL) 690 printf(" code %s", ic->name); 691 else 692 printf(" code %u", r->code-1); 693 } 694 } 695 if (r->tos) 696 printf(" tos 0x%2.2x", r->tos); 697 if (r->keep_state == PF_STATE_NORMAL) 698 printf(" keep state"); 699 else if (r->keep_state == PF_STATE_MODULATE) 700 printf(" modulate state"); 701 else if (r->keep_state == PF_STATE_SYNPROXY) 702 printf(" synproxy state"); 703 opts = 0; 704 if (r->max_states) 705 opts = 1; 706 for (i = 0; !opts && i < PFTM_MAX; ++i) 707 if (r->timeout[i]) 708 opts = 1; 709 if (opts) { 710 printf(" ("); 711 if (r->max_states) { 712 printf("max %u", r->max_states); 713 opts = 0; 714 } 715 for (i = 0; i < PFTM_MAX; ++i) 716 if (r->timeout[i]) { 717 if (!opts) 718 printf(", "); 719 opts = 0; 720 printf("%s %u", pf_timeouts[i].name, 721 r->timeout[i]); 722 } 723 printf(")"); 724 } 725 if (r->rule_flag & PFRULE_FRAGMENT) 726 printf(" fragment"); 727 if (r->rule_flag & PFRULE_NODF) 728 printf(" no-df"); 729 if (r->rule_flag & PFRULE_RANDOMID) 730 printf(" random-id"); 731 if (r->min_ttl) 732 printf(" min-ttl %d", r->min_ttl); 733 if (r->max_mss) 734 printf(" max-mss %d", r->max_mss); 735 if (r->allow_opts) 736 printf(" allow-opts"); 737 if (r->action == PF_SCRUB) { 738 if (r->rule_flag & PFRULE_REASSEMBLE_TCP) 739 printf(" reassemble tcp"); 740 741 if (r->rule_flag & PFRULE_FRAGDROP) 742 printf(" fragment drop-ovl"); 743 else if (r->rule_flag & PFRULE_FRAGCROP) 744 printf(" fragment crop"); 745 else 746 printf(" fragment reassemble"); 747 } 748 if (r->label[0]) 749 printf(" label \"%s\"", r->label); 750 if (r->qname[0] && r->pqname[0]) 751 printf(" queue(%s, %s)", r->qname, r->pqname); 752 else if (r->qname[0]) 753 printf(" queue %s", r->qname); 754 if (r->tagname[0]) 755 printf(" tag %s", r->tagname); 756 if (r->match_tagname[0]) { 757 if (r->match_tag_not) 758 printf(" !"); 759 printf(" tagged %s", r->match_tagname); 760 } 761 if (!r->anchorname[0] && (r->action == PF_NAT || 762 r->action == PF_BINAT || r->action == PF_RDR)) { 763 printf(" -> "); 764 print_pool(&r->rpool, r->rpool.proxy_port[0], 765 r->rpool.proxy_port[1], r->af, r->action); 766 } 767 printf("\n"); 768} 769 770void 771print_tabledef(const char *name, int flags, int addrs, 772 struct node_tinithead *nodes) 773{ 774 struct node_tinit *ti, *nti; 775 struct node_host *h; 776 777 printf("table <%s>", name); 778 if (flags & PFR_TFLAG_CONST) 779 printf(" const"); 780 if (flags & PFR_TFLAG_PERSIST) 781 printf(" persist"); 782 SIMPLEQ_FOREACH(ti, nodes, entries) { 783 if (ti->file) { 784 printf(" file \"%s\"", ti->file); 785 continue; 786 } 787 printf(" {"); 788 for (;;) { 789 for (h = ti->host; h != NULL; h = h->next) { 790 printf(h->not ? " !" : " "); 791 print_addr(&h->addr, h->af, 0); 792 } 793 nti = SIMPLEQ_NEXT(ti, entries); 794 if (nti != NULL && nti->file == NULL) 795 ti = nti; /* merge lists */ 796 else 797 break; 798 } 799 printf(" }"); 800 } 801 if (addrs && SIMPLEQ_EMPTY(nodes)) 802 printf(" { }"); 803 printf("\n"); 804} 805 806int 807parse_flags(char *s) 808{ 809 char *p, *q; 810 u_int8_t f = 0; 811 812 for (p = s; *p; p++) { 813 if ((q = strchr(tcpflags, *p)) == NULL) 814 return -1; 815 else 816 f |= 1 << (q - tcpflags); 817 } 818 return (f ? f : PF_TH_ALL); 819} 820 821void 822set_ipmask(struct node_host *h, u_int8_t b) 823{ 824 struct pf_addr *m, *n; 825 int i, j = 0; 826 827 m = &h->addr.v.a.mask; 828 829 for (i = 0; i < 4; i++) 830 m->addr32[i] = 0; 831 832 while (b >= 32) { 833 m->addr32[j++] = 0xffffffff; 834 b -= 32; 835 } 836 for (i = 31; i > 31-b; --i) 837 m->addr32[j] |= (1 << i); 838 if (b) 839 m->addr32[j] = htonl(m->addr32[j]); 840 841 /* Mask off bits of the address that will never be used. */ 842 n = &h->addr.v.a.addr; 843 if (h->addr.type == PF_ADDR_ADDRMASK) 844 for (i = 0; i < 4; i++) 845 n->addr32[i] = n->addr32[i] & m->addr32[i]; 846} 847 848int 849check_netmask(struct node_host *h, sa_family_t af) 850{ 851 struct node_host *n = NULL; 852 struct pf_addr *m; 853 854 for (n = h; n != NULL; n = n->next) { 855 if (h->addr.type == PF_ADDR_TABLE) 856 continue; 857 m = &h->addr.v.a.mask; 858 /* fix up netmask for dynaddr */ 859 if (af == AF_INET && h->addr.type == PF_ADDR_DYNIFTL && 860 unmask(m, AF_INET6) > 32) 861 set_ipmask(n, 32); 862 /* netmasks > 32 bit are invalid on v4 */ 863 if (af == AF_INET && 864 (m->addr32[1] || m->addr32[2] || m->addr32[3])) { 865 fprintf(stderr, "netmask %u invalid for IPv4 address\n", 866 unmask(m, AF_INET6)); 867 return (1); 868 } 869 } 870 return (0); 871} 872 873/* interface lookup routines */ 874 875struct node_host *iftab; 876 877void 878ifa_load(void) 879{ 880 struct ifaddrs *ifap, *ifa; 881 struct node_host *n = NULL, *h = NULL; 882 883 if (getifaddrs(&ifap) < 0) 884 err(1, "getifaddrs"); 885 886 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 887 if (!(ifa->ifa_addr->sa_family == AF_INET || 888 ifa->ifa_addr->sa_family == AF_INET6 || 889 ifa->ifa_addr->sa_family == AF_LINK)) 890 continue; 891 n = calloc(1, sizeof(struct node_host)); 892 if (n == NULL) 893 err(1, "address: calloc"); 894 n->af = ifa->ifa_addr->sa_family; 895 n->ifa_flags = ifa->ifa_flags; 896#ifdef __KAME__ 897 if (n->af == AF_INET6 && 898 IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) 899 ifa->ifa_addr)->sin6_addr) && 900 ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id == 0) { 901 struct sockaddr_in6 *sin6; 902 903 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 904 sin6->sin6_scope_id = sin6->sin6_addr.s6_addr[2] << 8 | 905 sin6->sin6_addr.s6_addr[3]; 906 sin6->sin6_addr.s6_addr[2] = 0; 907 sin6->sin6_addr.s6_addr[3] = 0; 908 } 909#endif 910 n->ifindex = 0; 911 if (n->af == AF_INET) { 912 memcpy(&n->addr.v.a.addr, &((struct sockaddr_in *) 913 ifa->ifa_addr)->sin_addr.s_addr, 914 sizeof(struct in_addr)); 915 memcpy(&n->addr.v.a.mask, &((struct sockaddr_in *) 916 ifa->ifa_netmask)->sin_addr.s_addr, 917 sizeof(struct in_addr)); 918 if (ifa->ifa_broadaddr != NULL) 919 memcpy(&n->bcast, &((struct sockaddr_in *) 920 ifa->ifa_broadaddr)->sin_addr.s_addr, 921 sizeof(struct in_addr)); 922 } else if (n->af == AF_INET6) { 923 memcpy(&n->addr.v.a.addr, &((struct sockaddr_in6 *) 924 ifa->ifa_addr)->sin6_addr.s6_addr, 925 sizeof(struct in6_addr)); 926 memcpy(&n->addr.v.a.mask, &((struct sockaddr_in6 *) 927 ifa->ifa_netmask)->sin6_addr.s6_addr, 928 sizeof(struct in6_addr)); 929 if (ifa->ifa_broadaddr != NULL) 930 memcpy(&n->bcast, &((struct sockaddr_in6 *) 931 ifa->ifa_broadaddr)->sin6_addr.s6_addr, 932 sizeof(struct in6_addr)); 933 n->ifindex = ((struct sockaddr_in6 *) 934 ifa->ifa_addr)->sin6_scope_id; 935 } 936 if ((n->ifname = strdup(ifa->ifa_name)) == NULL) 937 err(1, "ifa_load: strdup"); 938 n->next = NULL; 939 n->tail = n; 940 if (h == NULL) 941 h = n; 942 else { 943 h->tail->next = n; 944 h->tail = n; 945 } 946 } 947 iftab = h; 948 freeifaddrs(ifap); 949} 950 951struct node_host * 952ifa_exists(const char *ifa_name) 953{ 954 struct node_host *n; 955 956 if (iftab == NULL) 957 ifa_load(); 958 959 for (n = iftab; n; n = n->next) { 960 if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ)) 961 return (n); 962 } 963 return (NULL); 964} 965 966struct node_host * 967ifa_lookup(const char *ifa_name, enum pfctl_iflookup_mode mode) 968{ 969 struct node_host *p = NULL, *h = NULL, *n = NULL; 970 int return_all = 0; 971 972 if (!strncmp(ifa_name, "self", IFNAMSIZ)) 973 return_all = 1; 974 975 if (iftab == NULL) 976 ifa_load(); 977 978 for (p = iftab; p; p = p->next) { 979 if (!((p->af == AF_INET || p->af == AF_INET6) && 980 (!strncmp(p->ifname, ifa_name, IFNAMSIZ) || return_all))) 981 continue; 982 if (mode == PFCTL_IFLOOKUP_BCAST && p->af != AF_INET) 983 continue; 984 if (mode == PFCTL_IFLOOKUP_NET && p->ifindex > 0) 985 continue; 986 n = calloc(1, sizeof(struct node_host)); 987 if (n == NULL) 988 err(1, "address: calloc"); 989 n->af = p->af; 990 if (mode == PFCTL_IFLOOKUP_BCAST) 991 memcpy(&n->addr.v.a.addr, &p->bcast, 992 sizeof(struct pf_addr)); 993 else 994 memcpy(&n->addr.v.a.addr, &p->addr.v.a.addr, 995 sizeof(struct pf_addr)); 996 if (mode == PFCTL_IFLOOKUP_NET) 997 set_ipmask(n, unmask(&p->addr.v.a.mask, n->af)); 998 else { 999 if (n->af == AF_INET) { 1000 if (p->ifa_flags & IFF_LOOPBACK && 1001 p->ifa_flags & IFF_LINK1) 1002 memcpy(&n->addr.v.a.mask, 1003 &p->addr.v.a.mask, 1004 sizeof(struct pf_addr)); 1005 else 1006 set_ipmask(n, 32); 1007 } else 1008 set_ipmask(n, 128); 1009 } 1010 n->ifindex = p->ifindex; 1011 1012 n->next = NULL; 1013 n->tail = n; 1014 if (h == NULL) 1015 h = n; 1016 else { 1017 h->tail->next = n; 1018 h->tail = n; 1019 } 1020 } 1021 if (h == NULL && mode == PFCTL_IFLOOKUP_HOST) { 1022 fprintf(stderr, "no IP address found for %s\n", ifa_name); 1023 } 1024 return (h); 1025} 1026 1027struct node_host * 1028host(const char *s) 1029{ 1030 struct node_host *h = NULL; 1031 int mask, v4mask, v6mask, cont = 1; 1032 char *p, *q, *ps; 1033 1034 if ((p = strrchr(s, '/')) != NULL) { 1035 mask = strtol(p+1, &q, 0); 1036 if (!q || *q || mask > 128 || q == (p+1)) { 1037 fprintf(stderr, "invalid netmask\n"); 1038 return (NULL); 1039 } 1040 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1041 err(1, "host: malloc"); 1042 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1043 v4mask = v6mask = mask; 1044 } else { 1045 if ((ps = strdup(s)) == NULL) 1046 err(1, "host: strdup"); 1047 v4mask = 32; 1048 v6mask = 128; 1049 mask = -1; 1050 } 1051 1052 /* interface with this name exists? */ 1053 if (cont && (h = host_if(ps, mask)) != NULL) 1054 cont = 0; 1055 1056 /* IPv4 address? */ 1057 if (cont && (h = host_v4(s, mask)) != NULL) 1058 cont = 0; 1059 1060 /* IPv6 address? */ 1061 if (cont && (h = host_v6(ps, v6mask)) != NULL) 1062 cont = 0; 1063 1064 /* dns lookup */ 1065 if (cont && (h = host_dns(ps, v4mask, v6mask)) != NULL) 1066 cont = 0; 1067 free(ps); 1068 1069 if (h == NULL || cont == 1) { 1070 fprintf(stderr, "no IP address found for %s\n", s); 1071 return (NULL); 1072 } 1073 return (h); 1074} 1075 1076struct node_host * 1077host_if(const char *s, int mask) 1078{ 1079 struct node_host *n, *h = NULL; 1080 char *p, *ps; 1081 int mode = PFCTL_IFLOOKUP_HOST; 1082 1083 if ((p = strrchr(s, ':')) != NULL && 1084 (!strcmp(p+1, "network") || !strcmp(p+1, "broadcast"))) { 1085 if (!strcmp(p+1, "network")) 1086 mode = PFCTL_IFLOOKUP_NET; 1087 if (!strcmp(p+1, "broadcast")) 1088 mode = PFCTL_IFLOOKUP_BCAST; 1089 if (mask > -1) { 1090 fprintf(stderr, "network or broadcast lookup, but " 1091 "extra netmask given\n"); 1092 return (NULL); 1093 } 1094 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1095 err(1, "host: malloc"); 1096 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1097 } else 1098 if ((ps = strdup(s)) == NULL) 1099 err(1, "host_if: strdup"); 1100 1101 if (ifa_exists(ps) || !strncmp(ps, "self", IFNAMSIZ)) { 1102 /* interface with this name exists */ 1103 h = ifa_lookup(ps, mode); 1104 for (n = h; n != NULL && mask > -1; n = n->next) 1105 set_ipmask(n, mask); 1106 } 1107 1108 free(ps); 1109 return (h); 1110} 1111 1112struct node_host * 1113host_v4(const char *s, int mask) 1114{ 1115 struct node_host *h = NULL; 1116 struct in_addr ina; 1117 int bits; 1118 1119 memset(&ina, 0, sizeof(struct in_addr)); 1120 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) > -1) { 1121 h = calloc(1, sizeof(struct node_host)); 1122 if (h == NULL) 1123 err(1, "address: calloc"); 1124 h->ifname = NULL; 1125 h->af = AF_INET; 1126 h->addr.v.a.addr.addr32[0] = ina.s_addr;
| 548 if (runtime > 0) 549 printf("%14.1f/s\n", 550 (double)s->counters[i] / (double)runtime); 551 else 552 printf("%14s\n", ""); 553 } 554} 555 556void 557print_rule(struct pf_rule *r, int verbose) 558{ 559 static const char *actiontypes[] = { "pass", "block", "scrub", "nat", 560 "no nat", "binat", "no binat", "rdr", "no rdr" }; 561 static const char *anchortypes[] = { "anchor", "anchor", "anchor", 562 "nat-anchor", "nat-anchor", "binat-anchor", "binat-anchor", 563 "rdr-anchor", "rdr-anchor" }; 564 int i, opts; 565 566 if (verbose) 567 printf("@%d ", r->nr); 568 if (r->action > PF_NORDR) 569 printf("action(%d)", r->action); 570 else if (r->anchorname[0]) 571 printf("%s %s", anchortypes[r->action], r->anchorname); 572 else { 573 printf("%s", actiontypes[r->action]); 574 if (r->natpass) 575 printf(" pass"); 576 } 577 if (r->action == PF_DROP) { 578 if (r->rule_flag & PFRULE_RETURN) 579 printf(" return"); 580 else if (r->rule_flag & PFRULE_RETURNRST) { 581 if (!r->return_ttl) 582 printf(" return-rst"); 583 else 584 printf(" return-rst(ttl %d)", r->return_ttl); 585 } else if (r->rule_flag & PFRULE_RETURNICMP) { 586 const struct icmpcodeent *ic, *ic6; 587 588 ic = geticmpcodebynumber(r->return_icmp >> 8, 589 r->return_icmp & 255, AF_INET); 590 ic6 = geticmpcodebynumber(r->return_icmp6 >> 8, 591 r->return_icmp6 & 255, AF_INET6); 592 593 switch(r->af) { 594 case AF_INET: 595 printf(" return-icmp"); 596 if (ic == NULL) 597 printf("(%u)", r->return_icmp & 255); 598 else 599 printf("(%s)", ic->name); 600 break; 601 case AF_INET6: 602 printf(" return-icmp6"); 603 if (ic6 == NULL) 604 printf("(%u)", r->return_icmp6 & 255); 605 else 606 printf("(%s)", ic6->name); 607 break; 608 default: 609 printf(" return-icmp"); 610 if (ic == NULL) 611 printf("(%u, ", r->return_icmp & 255); 612 else 613 printf("(%s, ", ic->name); 614 if (ic6 == NULL) 615 printf("%u)", r->return_icmp6 & 255); 616 else 617 printf("%s)", ic6->name); 618 break; 619 } 620 } else 621 printf(" drop"); 622 } 623 if (r->direction == PF_IN) 624 printf(" in"); 625 else if (r->direction == PF_OUT) 626 printf(" out"); 627 if (r->log == 1) 628 printf(" log"); 629 else if (r->log == 2) 630 printf(" log-all"); 631 if (r->quick) 632 printf(" quick"); 633 if (r->ifname[0]) { 634 if (r->ifnot) 635 printf(" on ! %s", r->ifname); 636 else 637 printf(" on %s", r->ifname); 638 } 639 if (r->rt) { 640 if (r->rt == PF_ROUTETO) 641 printf(" route-to"); 642 else if (r->rt == PF_REPLYTO) 643 printf(" reply-to"); 644 else if (r->rt == PF_DUPTO) 645 printf(" dup-to"); 646 else if (r->rt == PF_FASTROUTE) 647 printf(" fastroute"); 648 if (r->rt != PF_FASTROUTE) { 649 printf(" "); 650 print_pool(&r->rpool, 0, 0, r->af, PF_PASS); 651 } 652 } 653 if (r->af) { 654 if (r->af == AF_INET) 655 printf(" inet"); 656 else 657 printf(" inet6"); 658 } 659 if (r->proto) { 660 struct protoent *p; 661 662 if ((p = getprotobynumber(r->proto)) != NULL) 663 printf(" proto %s", p->p_name); 664 else 665 printf(" proto %u", r->proto); 666 } 667 print_fromto(&r->src, r->os_fingerprint, &r->dst, r->af, r->proto, 668 verbose); 669 if (r->uid.op) 670 print_ugid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user", 671 UID_MAX); 672 if (r->gid.op) 673 print_ugid(r->gid.op, r->gid.gid[0], r->gid.gid[1], "group", 674 GID_MAX); 675 if (r->flags || r->flagset) { 676 printf(" flags "); 677 print_flags(r->flags); 678 printf("/"); 679 print_flags(r->flagset); 680 } 681 if (r->type) { 682 const struct icmptypeent *it; 683 684 it = geticmptypebynumber(r->type-1, r->af); 685 if (r->af != AF_INET6) 686 printf(" icmp-type"); 687 else 688 printf(" icmp6-type"); 689 if (it != NULL) 690 printf(" %s", it->name); 691 else 692 printf(" %u", r->type-1); 693 if (r->code) { 694 const struct icmpcodeent *ic; 695 696 ic = geticmpcodebynumber(r->type-1, r->code-1, r->af); 697 if (ic != NULL) 698 printf(" code %s", ic->name); 699 else 700 printf(" code %u", r->code-1); 701 } 702 } 703 if (r->tos) 704 printf(" tos 0x%2.2x", r->tos); 705 if (r->keep_state == PF_STATE_NORMAL) 706 printf(" keep state"); 707 else if (r->keep_state == PF_STATE_MODULATE) 708 printf(" modulate state"); 709 else if (r->keep_state == PF_STATE_SYNPROXY) 710 printf(" synproxy state"); 711 opts = 0; 712 if (r->max_states) 713 opts = 1; 714 for (i = 0; !opts && i < PFTM_MAX; ++i) 715 if (r->timeout[i]) 716 opts = 1; 717 if (opts) { 718 printf(" ("); 719 if (r->max_states) { 720 printf("max %u", r->max_states); 721 opts = 0; 722 } 723 for (i = 0; i < PFTM_MAX; ++i) 724 if (r->timeout[i]) { 725 if (!opts) 726 printf(", "); 727 opts = 0; 728 printf("%s %u", pf_timeouts[i].name, 729 r->timeout[i]); 730 } 731 printf(")"); 732 } 733 if (r->rule_flag & PFRULE_FRAGMENT) 734 printf(" fragment"); 735 if (r->rule_flag & PFRULE_NODF) 736 printf(" no-df"); 737 if (r->rule_flag & PFRULE_RANDOMID) 738 printf(" random-id"); 739 if (r->min_ttl) 740 printf(" min-ttl %d", r->min_ttl); 741 if (r->max_mss) 742 printf(" max-mss %d", r->max_mss); 743 if (r->allow_opts) 744 printf(" allow-opts"); 745 if (r->action == PF_SCRUB) { 746 if (r->rule_flag & PFRULE_REASSEMBLE_TCP) 747 printf(" reassemble tcp"); 748 749 if (r->rule_flag & PFRULE_FRAGDROP) 750 printf(" fragment drop-ovl"); 751 else if (r->rule_flag & PFRULE_FRAGCROP) 752 printf(" fragment crop"); 753 else 754 printf(" fragment reassemble"); 755 } 756 if (r->label[0]) 757 printf(" label \"%s\"", r->label); 758 if (r->qname[0] && r->pqname[0]) 759 printf(" queue(%s, %s)", r->qname, r->pqname); 760 else if (r->qname[0]) 761 printf(" queue %s", r->qname); 762 if (r->tagname[0]) 763 printf(" tag %s", r->tagname); 764 if (r->match_tagname[0]) { 765 if (r->match_tag_not) 766 printf(" !"); 767 printf(" tagged %s", r->match_tagname); 768 } 769 if (!r->anchorname[0] && (r->action == PF_NAT || 770 r->action == PF_BINAT || r->action == PF_RDR)) { 771 printf(" -> "); 772 print_pool(&r->rpool, r->rpool.proxy_port[0], 773 r->rpool.proxy_port[1], r->af, r->action); 774 } 775 printf("\n"); 776} 777 778void 779print_tabledef(const char *name, int flags, int addrs, 780 struct node_tinithead *nodes) 781{ 782 struct node_tinit *ti, *nti; 783 struct node_host *h; 784 785 printf("table <%s>", name); 786 if (flags & PFR_TFLAG_CONST) 787 printf(" const"); 788 if (flags & PFR_TFLAG_PERSIST) 789 printf(" persist"); 790 SIMPLEQ_FOREACH(ti, nodes, entries) { 791 if (ti->file) { 792 printf(" file \"%s\"", ti->file); 793 continue; 794 } 795 printf(" {"); 796 for (;;) { 797 for (h = ti->host; h != NULL; h = h->next) { 798 printf(h->not ? " !" : " "); 799 print_addr(&h->addr, h->af, 0); 800 } 801 nti = SIMPLEQ_NEXT(ti, entries); 802 if (nti != NULL && nti->file == NULL) 803 ti = nti; /* merge lists */ 804 else 805 break; 806 } 807 printf(" }"); 808 } 809 if (addrs && SIMPLEQ_EMPTY(nodes)) 810 printf(" { }"); 811 printf("\n"); 812} 813 814int 815parse_flags(char *s) 816{ 817 char *p, *q; 818 u_int8_t f = 0; 819 820 for (p = s; *p; p++) { 821 if ((q = strchr(tcpflags, *p)) == NULL) 822 return -1; 823 else 824 f |= 1 << (q - tcpflags); 825 } 826 return (f ? f : PF_TH_ALL); 827} 828 829void 830set_ipmask(struct node_host *h, u_int8_t b) 831{ 832 struct pf_addr *m, *n; 833 int i, j = 0; 834 835 m = &h->addr.v.a.mask; 836 837 for (i = 0; i < 4; i++) 838 m->addr32[i] = 0; 839 840 while (b >= 32) { 841 m->addr32[j++] = 0xffffffff; 842 b -= 32; 843 } 844 for (i = 31; i > 31-b; --i) 845 m->addr32[j] |= (1 << i); 846 if (b) 847 m->addr32[j] = htonl(m->addr32[j]); 848 849 /* Mask off bits of the address that will never be used. */ 850 n = &h->addr.v.a.addr; 851 if (h->addr.type == PF_ADDR_ADDRMASK) 852 for (i = 0; i < 4; i++) 853 n->addr32[i] = n->addr32[i] & m->addr32[i]; 854} 855 856int 857check_netmask(struct node_host *h, sa_family_t af) 858{ 859 struct node_host *n = NULL; 860 struct pf_addr *m; 861 862 for (n = h; n != NULL; n = n->next) { 863 if (h->addr.type == PF_ADDR_TABLE) 864 continue; 865 m = &h->addr.v.a.mask; 866 /* fix up netmask for dynaddr */ 867 if (af == AF_INET && h->addr.type == PF_ADDR_DYNIFTL && 868 unmask(m, AF_INET6) > 32) 869 set_ipmask(n, 32); 870 /* netmasks > 32 bit are invalid on v4 */ 871 if (af == AF_INET && 872 (m->addr32[1] || m->addr32[2] || m->addr32[3])) { 873 fprintf(stderr, "netmask %u invalid for IPv4 address\n", 874 unmask(m, AF_INET6)); 875 return (1); 876 } 877 } 878 return (0); 879} 880 881/* interface lookup routines */ 882 883struct node_host *iftab; 884 885void 886ifa_load(void) 887{ 888 struct ifaddrs *ifap, *ifa; 889 struct node_host *n = NULL, *h = NULL; 890 891 if (getifaddrs(&ifap) < 0) 892 err(1, "getifaddrs"); 893 894 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 895 if (!(ifa->ifa_addr->sa_family == AF_INET || 896 ifa->ifa_addr->sa_family == AF_INET6 || 897 ifa->ifa_addr->sa_family == AF_LINK)) 898 continue; 899 n = calloc(1, sizeof(struct node_host)); 900 if (n == NULL) 901 err(1, "address: calloc"); 902 n->af = ifa->ifa_addr->sa_family; 903 n->ifa_flags = ifa->ifa_flags; 904#ifdef __KAME__ 905 if (n->af == AF_INET6 && 906 IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) 907 ifa->ifa_addr)->sin6_addr) && 908 ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id == 0) { 909 struct sockaddr_in6 *sin6; 910 911 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 912 sin6->sin6_scope_id = sin6->sin6_addr.s6_addr[2] << 8 | 913 sin6->sin6_addr.s6_addr[3]; 914 sin6->sin6_addr.s6_addr[2] = 0; 915 sin6->sin6_addr.s6_addr[3] = 0; 916 } 917#endif 918 n->ifindex = 0; 919 if (n->af == AF_INET) { 920 memcpy(&n->addr.v.a.addr, &((struct sockaddr_in *) 921 ifa->ifa_addr)->sin_addr.s_addr, 922 sizeof(struct in_addr)); 923 memcpy(&n->addr.v.a.mask, &((struct sockaddr_in *) 924 ifa->ifa_netmask)->sin_addr.s_addr, 925 sizeof(struct in_addr)); 926 if (ifa->ifa_broadaddr != NULL) 927 memcpy(&n->bcast, &((struct sockaddr_in *) 928 ifa->ifa_broadaddr)->sin_addr.s_addr, 929 sizeof(struct in_addr)); 930 } else if (n->af == AF_INET6) { 931 memcpy(&n->addr.v.a.addr, &((struct sockaddr_in6 *) 932 ifa->ifa_addr)->sin6_addr.s6_addr, 933 sizeof(struct in6_addr)); 934 memcpy(&n->addr.v.a.mask, &((struct sockaddr_in6 *) 935 ifa->ifa_netmask)->sin6_addr.s6_addr, 936 sizeof(struct in6_addr)); 937 if (ifa->ifa_broadaddr != NULL) 938 memcpy(&n->bcast, &((struct sockaddr_in6 *) 939 ifa->ifa_broadaddr)->sin6_addr.s6_addr, 940 sizeof(struct in6_addr)); 941 n->ifindex = ((struct sockaddr_in6 *) 942 ifa->ifa_addr)->sin6_scope_id; 943 } 944 if ((n->ifname = strdup(ifa->ifa_name)) == NULL) 945 err(1, "ifa_load: strdup"); 946 n->next = NULL; 947 n->tail = n; 948 if (h == NULL) 949 h = n; 950 else { 951 h->tail->next = n; 952 h->tail = n; 953 } 954 } 955 iftab = h; 956 freeifaddrs(ifap); 957} 958 959struct node_host * 960ifa_exists(const char *ifa_name) 961{ 962 struct node_host *n; 963 964 if (iftab == NULL) 965 ifa_load(); 966 967 for (n = iftab; n; n = n->next) { 968 if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ)) 969 return (n); 970 } 971 return (NULL); 972} 973 974struct node_host * 975ifa_lookup(const char *ifa_name, enum pfctl_iflookup_mode mode) 976{ 977 struct node_host *p = NULL, *h = NULL, *n = NULL; 978 int return_all = 0; 979 980 if (!strncmp(ifa_name, "self", IFNAMSIZ)) 981 return_all = 1; 982 983 if (iftab == NULL) 984 ifa_load(); 985 986 for (p = iftab; p; p = p->next) { 987 if (!((p->af == AF_INET || p->af == AF_INET6) && 988 (!strncmp(p->ifname, ifa_name, IFNAMSIZ) || return_all))) 989 continue; 990 if (mode == PFCTL_IFLOOKUP_BCAST && p->af != AF_INET) 991 continue; 992 if (mode == PFCTL_IFLOOKUP_NET && p->ifindex > 0) 993 continue; 994 n = calloc(1, sizeof(struct node_host)); 995 if (n == NULL) 996 err(1, "address: calloc"); 997 n->af = p->af; 998 if (mode == PFCTL_IFLOOKUP_BCAST) 999 memcpy(&n->addr.v.a.addr, &p->bcast, 1000 sizeof(struct pf_addr)); 1001 else 1002 memcpy(&n->addr.v.a.addr, &p->addr.v.a.addr, 1003 sizeof(struct pf_addr)); 1004 if (mode == PFCTL_IFLOOKUP_NET) 1005 set_ipmask(n, unmask(&p->addr.v.a.mask, n->af)); 1006 else { 1007 if (n->af == AF_INET) { 1008 if (p->ifa_flags & IFF_LOOPBACK && 1009 p->ifa_flags & IFF_LINK1) 1010 memcpy(&n->addr.v.a.mask, 1011 &p->addr.v.a.mask, 1012 sizeof(struct pf_addr)); 1013 else 1014 set_ipmask(n, 32); 1015 } else 1016 set_ipmask(n, 128); 1017 } 1018 n->ifindex = p->ifindex; 1019 1020 n->next = NULL; 1021 n->tail = n; 1022 if (h == NULL) 1023 h = n; 1024 else { 1025 h->tail->next = n; 1026 h->tail = n; 1027 } 1028 } 1029 if (h == NULL && mode == PFCTL_IFLOOKUP_HOST) { 1030 fprintf(stderr, "no IP address found for %s\n", ifa_name); 1031 } 1032 return (h); 1033} 1034 1035struct node_host * 1036host(const char *s) 1037{ 1038 struct node_host *h = NULL; 1039 int mask, v4mask, v6mask, cont = 1; 1040 char *p, *q, *ps; 1041 1042 if ((p = strrchr(s, '/')) != NULL) { 1043 mask = strtol(p+1, &q, 0); 1044 if (!q || *q || mask > 128 || q == (p+1)) { 1045 fprintf(stderr, "invalid netmask\n"); 1046 return (NULL); 1047 } 1048 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1049 err(1, "host: malloc"); 1050 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1051 v4mask = v6mask = mask; 1052 } else { 1053 if ((ps = strdup(s)) == NULL) 1054 err(1, "host: strdup"); 1055 v4mask = 32; 1056 v6mask = 128; 1057 mask = -1; 1058 } 1059 1060 /* interface with this name exists? */ 1061 if (cont && (h = host_if(ps, mask)) != NULL) 1062 cont = 0; 1063 1064 /* IPv4 address? */ 1065 if (cont && (h = host_v4(s, mask)) != NULL) 1066 cont = 0; 1067 1068 /* IPv6 address? */ 1069 if (cont && (h = host_v6(ps, v6mask)) != NULL) 1070 cont = 0; 1071 1072 /* dns lookup */ 1073 if (cont && (h = host_dns(ps, v4mask, v6mask)) != NULL) 1074 cont = 0; 1075 free(ps); 1076 1077 if (h == NULL || cont == 1) { 1078 fprintf(stderr, "no IP address found for %s\n", s); 1079 return (NULL); 1080 } 1081 return (h); 1082} 1083 1084struct node_host * 1085host_if(const char *s, int mask) 1086{ 1087 struct node_host *n, *h = NULL; 1088 char *p, *ps; 1089 int mode = PFCTL_IFLOOKUP_HOST; 1090 1091 if ((p = strrchr(s, ':')) != NULL && 1092 (!strcmp(p+1, "network") || !strcmp(p+1, "broadcast"))) { 1093 if (!strcmp(p+1, "network")) 1094 mode = PFCTL_IFLOOKUP_NET; 1095 if (!strcmp(p+1, "broadcast")) 1096 mode = PFCTL_IFLOOKUP_BCAST; 1097 if (mask > -1) { 1098 fprintf(stderr, "network or broadcast lookup, but " 1099 "extra netmask given\n"); 1100 return (NULL); 1101 } 1102 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1103 err(1, "host: malloc"); 1104 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1105 } else 1106 if ((ps = strdup(s)) == NULL) 1107 err(1, "host_if: strdup"); 1108 1109 if (ifa_exists(ps) || !strncmp(ps, "self", IFNAMSIZ)) { 1110 /* interface with this name exists */ 1111 h = ifa_lookup(ps, mode); 1112 for (n = h; n != NULL && mask > -1; n = n->next) 1113 set_ipmask(n, mask); 1114 } 1115 1116 free(ps); 1117 return (h); 1118} 1119 1120struct node_host * 1121host_v4(const char *s, int mask) 1122{ 1123 struct node_host *h = NULL; 1124 struct in_addr ina; 1125 int bits; 1126 1127 memset(&ina, 0, sizeof(struct in_addr)); 1128 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) > -1) { 1129 h = calloc(1, sizeof(struct node_host)); 1130 if (h == NULL) 1131 err(1, "address: calloc"); 1132 h->ifname = NULL; 1133 h->af = AF_INET; 1134 h->addr.v.a.addr.addr32[0] = ina.s_addr;
|