17c478bd9Sstevel@tonic-gate /* 2d6c23f6fSyx * Copyright (C) 2001-2008 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate * 6d6c23f6fSyx * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 77c478bd9Sstevel@tonic-gate * Use is subject to license terms. 894bdecd9SRob Gulewich * 994bdecd9SRob Gulewich * Copyright (c) 2014, Joyent, Inc. All rights reserved. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 12*ae7a42b1SToomas Soome #ifdef SOLARIS 13*ae7a42b1SToomas Soome #undef SOLARIS 14*ae7a42b1SToomas Soome #endif 15*ae7a42b1SToomas Soome #if (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 16*ae7a42b1SToomas Soome #define SOLARIS (1) 17*ae7a42b1SToomas Soome #else 18*ae7a42b1SToomas Soome #define SOLARIS (0) 197c478bd9Sstevel@tonic-gate #endif 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate #include <sys/types.h> 227c478bd9Sstevel@tonic-gate #include <sys/stat.h> 237c478bd9Sstevel@tonic-gate #include <sys/param.h> 247c478bd9Sstevel@tonic-gate #include <sys/file.h> 257c478bd9Sstevel@tonic-gate #include <sys/time.h> 267c478bd9Sstevel@tonic-gate #define _KERNEL 277c478bd9Sstevel@tonic-gate #include <sys/uio.h> 287c478bd9Sstevel@tonic-gate #undef _KERNEL 297c478bd9Sstevel@tonic-gate #include <sys/socket.h> 307c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <stdio.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <fcntl.h> 367c478bd9Sstevel@tonic-gate #include <errno.h> 37ab25eeb5Syz #include <time.h> 387c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__) 397c478bd9Sstevel@tonic-gate # if (__FreeBSD_version >= 300000) 407c478bd9Sstevel@tonic-gate # include <sys/dirent.h> 417c478bd9Sstevel@tonic-gate # else 427c478bd9Sstevel@tonic-gate # include <sys/dir.h> 437c478bd9Sstevel@tonic-gate # endif 447c478bd9Sstevel@tonic-gate #else 457c478bd9Sstevel@tonic-gate # include <sys/filio.h> 467c478bd9Sstevel@tonic-gate # include <sys/byteorder.h> 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate #if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__)) 497c478bd9Sstevel@tonic-gate # include <strings.h> 507c478bd9Sstevel@tonic-gate #endif 517c478bd9Sstevel@tonic-gate #include <signal.h> 527c478bd9Sstevel@tonic-gate #include <stdlib.h> 537c478bd9Sstevel@tonic-gate #include <stddef.h> 547c478bd9Sstevel@tonic-gate #include <netinet/in.h> 557c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 567c478bd9Sstevel@tonic-gate #include <net/if.h> 577c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 58ab25eeb5Syz #if !defined(__hpux) && !defined(linux) 597c478bd9Sstevel@tonic-gate # include <netinet/tcp_fsm.h> 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate #include <netdb.h> 627c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 637c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 647c478bd9Sstevel@tonic-gate #ifdef __hpux 657c478bd9Sstevel@tonic-gate # undef NOERROR 667c478bd9Sstevel@tonic-gate #endif 677c478bd9Sstevel@tonic-gate #include <resolv.h> 687c478bd9Sstevel@tonic-gate 69ab25eeb5Syz #if !defined(linux) 70ab25eeb5Syz # include <sys/protosw.h> 71ab25eeb5Syz # include <netinet/ip_var.h> 72ab25eeb5Syz #endif 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #include <netinet/tcp.h> 757c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h> 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate #include <ctype.h> 787c478bd9Sstevel@tonic-gate #include <syslog.h> 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 81ab25eeb5Syz #include <netinet/tcpip.h> 827c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 837c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h" 847c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h" 857c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h" 867c478bd9Sstevel@tonic-gate #include "ipmon.h" 8794bdecd9SRob Gulewich #include "ipfzone.h" 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate #if !defined(lint) 907c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; 91ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.10 2005/06/18 02:41:35 darrenr Exp $"; 927c478bd9Sstevel@tonic-gate #endif 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate #if defined(sun) && !defined(SOLARIS2) 967c478bd9Sstevel@tonic-gate #define STRERROR(x) sys_errlist[x] 977c478bd9Sstevel@tonic-gate extern char *sys_errlist[]; 987c478bd9Sstevel@tonic-gate #else 997c478bd9Sstevel@tonic-gate #define STRERROR(x) strerror(x) 1007c478bd9Sstevel@tonic-gate #endif 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate struct flags { 1047c478bd9Sstevel@tonic-gate int value; 1057c478bd9Sstevel@tonic-gate char flag; 1067c478bd9Sstevel@tonic-gate }; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate typedef struct icmp_subtype { 1107c478bd9Sstevel@tonic-gate int ist_val; 1117c478bd9Sstevel@tonic-gate char *ist_name; 1127c478bd9Sstevel@tonic-gate } icmp_subtype_t; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate typedef struct icmp_type { 1157c478bd9Sstevel@tonic-gate int it_val; 1167c478bd9Sstevel@tonic-gate struct icmp_subtype *it_subtable; 1177c478bd9Sstevel@tonic-gate size_t it_stsize; 1187c478bd9Sstevel@tonic-gate char *it_name; 1197c478bd9Sstevel@tonic-gate } icmp_type_t; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate #define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate struct flags tcpfl[] = { 1267c478bd9Sstevel@tonic-gate { TH_ACK, 'A' }, 1277c478bd9Sstevel@tonic-gate { TH_RST, 'R' }, 1287c478bd9Sstevel@tonic-gate { TH_SYN, 'S' }, 1297c478bd9Sstevel@tonic-gate { TH_FIN, 'F' }, 1307c478bd9Sstevel@tonic-gate { TH_URG, 'U' }, 1317c478bd9Sstevel@tonic-gate { TH_PUSH,'P' }, 1327c478bd9Sstevel@tonic-gate { TH_ECN, 'E' }, 1337c478bd9Sstevel@tonic-gate { TH_CWR, 'C' }, 1347c478bd9Sstevel@tonic-gate { 0, '\0' } 1357c478bd9Sstevel@tonic-gate }; 1367c478bd9Sstevel@tonic-gate 137af5f29ddSToomas Soome #if defined(__hpux) || (defined(SOLARIS) && (SOLARIS2 < 10)) 1387c478bd9Sstevel@tonic-gate static char *pidfile = "/etc/ipf/ipmon.pid"; 1397c478bd9Sstevel@tonic-gate #else 140af5f29ddSToomas Soome # if (BSD >= 199306) || defined(SOLARIS) 1417c478bd9Sstevel@tonic-gate static char *pidfile = "/var/run/ipmon.pid"; 1427c478bd9Sstevel@tonic-gate # else 1437c478bd9Sstevel@tonic-gate static char *pidfile = "/etc/ipmon.pid"; 1447c478bd9Sstevel@tonic-gate # endif 1457c478bd9Sstevel@tonic-gate #endif 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate static char line[2048]; 1487c478bd9Sstevel@tonic-gate static int opts = 0; 1497c478bd9Sstevel@tonic-gate static char *logfile = NULL; 1507c478bd9Sstevel@tonic-gate static FILE *binarylog = NULL; 1517c478bd9Sstevel@tonic-gate static char *binarylogfile = NULL; 1527c478bd9Sstevel@tonic-gate static int donehup = 0; 1537c478bd9Sstevel@tonic-gate static void usage __P((char *)); 1547c478bd9Sstevel@tonic-gate static void handlehup __P((int)); 1557c478bd9Sstevel@tonic-gate static void flushlogs __P((char *, FILE *)); 1567c478bd9Sstevel@tonic-gate static void print_log __P((int, FILE *, char *, int)); 1577c478bd9Sstevel@tonic-gate static void print_ipflog __P((FILE *, char *, int)); 1587c478bd9Sstevel@tonic-gate static void print_natlog __P((FILE *, char *, int)); 1597c478bd9Sstevel@tonic-gate static void print_statelog __P((FILE *, char *, int)); 1607c478bd9Sstevel@tonic-gate static int read_log __P((int, int *, char *, int)); 1617c478bd9Sstevel@tonic-gate static void write_pid __P((char *)); 1627c478bd9Sstevel@tonic-gate static char *icmpname __P((u_int, u_int)); 1637c478bd9Sstevel@tonic-gate static char *icmpname6 __P((u_int, u_int)); 1647c478bd9Sstevel@tonic-gate static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t)); 1657c478bd9Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t)); 1667c478bd9Sstevel@tonic-gate #ifdef __hpux 1677c478bd9Sstevel@tonic-gate static struct tm *get_tm __P((u_32_t)); 1687c478bd9Sstevel@tonic-gate #else 1697c478bd9Sstevel@tonic-gate static struct tm *get_tm __P((time_t)); 1707c478bd9Sstevel@tonic-gate #endif 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate char *hostname __P((int, int, u_32_t *)); 1737c478bd9Sstevel@tonic-gate char *portname __P((int, char *, u_int)); 1747c478bd9Sstevel@tonic-gate int main __P((int, char *[])); 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate static void logopts __P((int, char *)); 1777c478bd9Sstevel@tonic-gate static void init_tabs __P((void)); 1787c478bd9Sstevel@tonic-gate static char *getproto __P((u_int)); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate static char **protocols = NULL; 1817c478bd9Sstevel@tonic-gate static char **udp_ports = NULL; 1827c478bd9Sstevel@tonic-gate static char **tcp_ports = NULL; 1837c478bd9Sstevel@tonic-gate static char *conf_file = NULL; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate #define OPT_SYSLOG 0x001 1877c478bd9Sstevel@tonic-gate #define OPT_RESOLVE 0x002 1887c478bd9Sstevel@tonic-gate #define OPT_HEXBODY 0x004 1897c478bd9Sstevel@tonic-gate #define OPT_VERBOSE 0x008 1907c478bd9Sstevel@tonic-gate #define OPT_HEXHDR 0x010 1917c478bd9Sstevel@tonic-gate #define OPT_TAIL 0x020 1927c478bd9Sstevel@tonic-gate #define OPT_NAT 0x080 1937c478bd9Sstevel@tonic-gate #define OPT_STATE 0x100 1947c478bd9Sstevel@tonic-gate #define OPT_FILTER 0x200 1957c478bd9Sstevel@tonic-gate #define OPT_PORTNUM 0x400 1967c478bd9Sstevel@tonic-gate #define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) 1977c478bd9Sstevel@tonic-gate #define OPT_LOGBODY 0x800 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate #define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate #ifndef LOGFAC 2027c478bd9Sstevel@tonic-gate #define LOGFAC LOG_LOCAL0 2037c478bd9Sstevel@tonic-gate #endif 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpunreachnames[] = { 2077c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET, "net" }, 2087c478bd9Sstevel@tonic-gate { ICMP_UNREACH_HOST, "host" }, 2097c478bd9Sstevel@tonic-gate { ICMP_UNREACH_PROTOCOL, "protocol" }, 2107c478bd9Sstevel@tonic-gate { ICMP_UNREACH_PORT, "port" }, 2117c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NEEDFRAG, "needfrag" }, 2127c478bd9Sstevel@tonic-gate { ICMP_UNREACH_SRCFAIL, "srcfail" }, 2137c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, 2147c478bd9Sstevel@tonic-gate { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, 2157c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET, "isolated" }, 2167c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, 2177c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, 2187c478bd9Sstevel@tonic-gate { ICMP_UNREACH_TOSNET, "tosnet" }, 2197c478bd9Sstevel@tonic-gate { ICMP_UNREACH_TOSHOST, "toshost" }, 2207c478bd9Sstevel@tonic-gate { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, 2217c478bd9Sstevel@tonic-gate { -2, NULL } 2227c478bd9Sstevel@tonic-gate }; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate static icmp_subtype_t redirectnames[] = { 2257c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_NET, "net" }, 2267c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_HOST, "host" }, 2277c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_TOSNET, "tosnet" }, 2287c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_TOSHOST, "toshost" }, 2297c478bd9Sstevel@tonic-gate { -2, NULL } 2307c478bd9Sstevel@tonic-gate }; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate static icmp_subtype_t timxceednames[] = { 2337c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED_INTRANS, "transit" }, 2347c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED_REASS, "reassem" }, 2357c478bd9Sstevel@tonic-gate { -2, NULL } 2367c478bd9Sstevel@tonic-gate }; 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate static icmp_subtype_t paramnames[] = { 2397c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, 2407c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, 2417c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_LENGTH, "length" }, 2427c478bd9Sstevel@tonic-gate { -2, NULL } 2437c478bd9Sstevel@tonic-gate }; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate static icmp_type_t icmptypes[] = { 2467c478bd9Sstevel@tonic-gate { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, 2477c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2487c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2497c478bd9Sstevel@tonic-gate { ICMP_UNREACH, icmpunreachnames, 2507c478bd9Sstevel@tonic-gate IST_SZ(icmpunreachnames),"unreach" }, 2517c478bd9Sstevel@tonic-gate { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, 2527c478bd9Sstevel@tonic-gate { ICMP_REDIRECT, redirectnames, 2537c478bd9Sstevel@tonic-gate IST_SZ(redirectnames), "redirect" }, 2547c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2557c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2567c478bd9Sstevel@tonic-gate { ICMP_ECHO, NULL, 0, "echo" }, 2577c478bd9Sstevel@tonic-gate { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, 2587c478bd9Sstevel@tonic-gate { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, 2597c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED, timxceednames, 2607c478bd9Sstevel@tonic-gate IST_SZ(timxceednames), "timxceed" }, 2617c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB, paramnames, 2627c478bd9Sstevel@tonic-gate IST_SZ(paramnames), "paramprob" }, 2637c478bd9Sstevel@tonic-gate { ICMP_TSTAMP, NULL, 0, "timestamp" }, 2647c478bd9Sstevel@tonic-gate { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, 2657c478bd9Sstevel@tonic-gate { ICMP_IREQ, NULL, 0, "inforeq" }, 2667c478bd9Sstevel@tonic-gate { ICMP_IREQREPLY, NULL, 0, "inforeply" }, 2677c478bd9Sstevel@tonic-gate { ICMP_MASKREQ, NULL, 0, "maskreq" }, 2687c478bd9Sstevel@tonic-gate { ICMP_MASKREPLY, NULL, 0, "maskreply" }, 2697c478bd9Sstevel@tonic-gate { -2, NULL, 0, NULL } 2707c478bd9Sstevel@tonic-gate }; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpredirect6[] = { 2737c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, 2747c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADMIN, "admin" }, 2757c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, 2767c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADDR, "address" }, 2777c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOPORT, "noport" }, 2787c478bd9Sstevel@tonic-gate { -2, NULL } 2797c478bd9Sstevel@tonic-gate }; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate static icmp_subtype_t icmptimexceed6[] = { 2827c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, 2837c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, 2847c478bd9Sstevel@tonic-gate { -2, NULL } 2857c478bd9Sstevel@tonic-gate }; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpparamprob6[] = { 2887c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_HEADER, "header" }, 2897c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, 2907c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_OPTION, "option" }, 2917c478bd9Sstevel@tonic-gate { -2, NULL } 2927c478bd9Sstevel@tonic-gate }; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpquerysubject6[] = { 2957c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV6, "ipv6" }, 2967c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_FQDN, "fqdn" }, 2977c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV4, "ipv4" }, 2987c478bd9Sstevel@tonic-gate { -2, NULL }, 2997c478bd9Sstevel@tonic-gate }; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpnodeinfo6[] = { 3027c478bd9Sstevel@tonic-gate { ICMP6_NI_SUCCESS, "success" }, 3037c478bd9Sstevel@tonic-gate { ICMP6_NI_REFUSED, "refused" }, 3047c478bd9Sstevel@tonic-gate { ICMP6_NI_UNKNOWN, "unknown" }, 3057c478bd9Sstevel@tonic-gate { -2, NULL } 3067c478bd9Sstevel@tonic-gate }; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate static icmp_subtype_t icmprenumber6[] = { 3097c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, 3107c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, 3117c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, 3127c478bd9Sstevel@tonic-gate { -2, NULL } 3137c478bd9Sstevel@tonic-gate }; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate static icmp_type_t icmptypes6[] = { 3167c478bd9Sstevel@tonic-gate { 0, NULL, 0, NULL }, 3177c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH, icmpredirect6, 3187c478bd9Sstevel@tonic-gate IST_SZ(icmpredirect6), "unreach" }, 3197c478bd9Sstevel@tonic-gate { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, 3207c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEEDED, icmptimexceed6, 3217c478bd9Sstevel@tonic-gate IST_SZ(icmptimexceed6), "timxceed" }, 3227c478bd9Sstevel@tonic-gate { ICMP6_PARAM_PROB, icmpparamprob6, 3237c478bd9Sstevel@tonic-gate IST_SZ(icmpparamprob6), "paramprob" }, 3247c478bd9Sstevel@tonic-gate { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, 3257c478bd9Sstevel@tonic-gate { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, 3267c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, 3277c478bd9Sstevel@tonic-gate IST_SZ(icmpquerysubject6), "groupmemberquery" }, 3287c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, 3297c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, 3307c478bd9Sstevel@tonic-gate { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, 3317c478bd9Sstevel@tonic-gate { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, 3327c478bd9Sstevel@tonic-gate { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, 3337c478bd9Sstevel@tonic-gate { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, 3347c478bd9Sstevel@tonic-gate { ND_REDIRECT, NULL, 0, "redirect" }, 3357c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING, icmprenumber6, 3367c478bd9Sstevel@tonic-gate IST_SZ(icmprenumber6), "routerrenumber" }, 3377c478bd9Sstevel@tonic-gate { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, 3387c478bd9Sstevel@tonic-gate { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, 3397c478bd9Sstevel@tonic-gate { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, 3407c478bd9Sstevel@tonic-gate { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, 3417c478bd9Sstevel@tonic-gate { ICMP6_NI_QUERY, icmpnodeinfo6, 3427c478bd9Sstevel@tonic-gate IST_SZ(icmpnodeinfo6), "nodeinforequest" }, 3437c478bd9Sstevel@tonic-gate { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, 3447c478bd9Sstevel@tonic-gate { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, 3457c478bd9Sstevel@tonic-gate { MLD6_MTRACE, NULL, 0, "mtracerequest" }, 3467c478bd9Sstevel@tonic-gate { -2, NULL, 0, NULL } 3477c478bd9Sstevel@tonic-gate }; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) 3507c478bd9Sstevel@tonic-gate int type; 3517c478bd9Sstevel@tonic-gate icmp_subtype_t *table; 3527c478bd9Sstevel@tonic-gate size_t tablesz; 3537c478bd9Sstevel@tonic-gate { 3547c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 3557c478bd9Sstevel@tonic-gate int i; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate if (tablesz < 2) 3587c478bd9Sstevel@tonic-gate return NULL; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].ist_val)) 3617c478bd9Sstevel@tonic-gate return NULL; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate i = type; 3647c478bd9Sstevel@tonic-gate if (table[type].ist_val == type) 3657c478bd9Sstevel@tonic-gate return table + type; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) 3687c478bd9Sstevel@tonic-gate if (ist->ist_val == type) 3697c478bd9Sstevel@tonic-gate return ist; 3707c478bd9Sstevel@tonic-gate return NULL; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate static icmp_type_t *find_icmptype(type, table, tablesz) 3757c478bd9Sstevel@tonic-gate int type; 3767c478bd9Sstevel@tonic-gate icmp_type_t *table; 3777c478bd9Sstevel@tonic-gate size_t tablesz; 3787c478bd9Sstevel@tonic-gate { 3797c478bd9Sstevel@tonic-gate icmp_type_t *it; 3807c478bd9Sstevel@tonic-gate int i; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate if (tablesz < 2) 3837c478bd9Sstevel@tonic-gate return NULL; 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].it_val)) 3867c478bd9Sstevel@tonic-gate return NULL; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate i = type; 3897c478bd9Sstevel@tonic-gate if (table[type].it_val == type) 3907c478bd9Sstevel@tonic-gate return table + type; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate for (i = 0, it = table; it->it_val != -2; i++, it++) 3937c478bd9Sstevel@tonic-gate if (it->it_val == type) 3947c478bd9Sstevel@tonic-gate return it; 3957c478bd9Sstevel@tonic-gate return NULL; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate static void handlehup(sig) 4007c478bd9Sstevel@tonic-gate int sig; 4017c478bd9Sstevel@tonic-gate { 4027c478bd9Sstevel@tonic-gate signal(SIGHUP, handlehup); 4037c478bd9Sstevel@tonic-gate donehup = 1; 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate static void init_tabs() 4087c478bd9Sstevel@tonic-gate { 4097c478bd9Sstevel@tonic-gate struct protoent *p; 4107c478bd9Sstevel@tonic-gate struct servent *s; 4117c478bd9Sstevel@tonic-gate char *name, **tab; 4127c478bd9Sstevel@tonic-gate int port, i; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate if (protocols != NULL) { 4157c478bd9Sstevel@tonic-gate for (i = 0; i < 256; i++) 4167c478bd9Sstevel@tonic-gate if (protocols[i] != NULL) { 4177c478bd9Sstevel@tonic-gate free(protocols[i]); 4187c478bd9Sstevel@tonic-gate protocols[i] = NULL; 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate free(protocols); 4217c478bd9Sstevel@tonic-gate protocols = NULL; 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate protocols = (char **)malloc(256 * sizeof(*protocols)); 4247c478bd9Sstevel@tonic-gate if (protocols != NULL) { 4257c478bd9Sstevel@tonic-gate bzero((char *)protocols, 256 * sizeof(*protocols)); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate setprotoent(1); 4287c478bd9Sstevel@tonic-gate while ((p = getprotoent()) != NULL) 4297c478bd9Sstevel@tonic-gate if (p->p_proto >= 0 && p->p_proto <= 255 && 4307c478bd9Sstevel@tonic-gate p->p_name != NULL && protocols[p->p_proto] == NULL) 4317c478bd9Sstevel@tonic-gate protocols[p->p_proto] = strdup(p->p_name); 4327c478bd9Sstevel@tonic-gate endprotoent(); 433ab25eeb5Syz #if defined(_AIX51) 434ab25eeb5Syz if (protocols[0]) 435ab25eeb5Syz free(protocols[0]); 436ab25eeb5Syz if (protocols[252]) 437ab25eeb5Syz free(protocols[252]); 438ab25eeb5Syz protocols[0] = "ip"; 439ab25eeb5Syz protocols[252] = NULL; 440ab25eeb5Syz #endif 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (udp_ports != NULL) { 4447c478bd9Sstevel@tonic-gate for (i = 0; i < 65536; i++) 4457c478bd9Sstevel@tonic-gate if (udp_ports[i] != NULL) { 4467c478bd9Sstevel@tonic-gate free(udp_ports[i]); 4477c478bd9Sstevel@tonic-gate udp_ports[i] = NULL; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate free(udp_ports); 4507c478bd9Sstevel@tonic-gate udp_ports = NULL; 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); 4537c478bd9Sstevel@tonic-gate if (udp_ports != NULL) 4547c478bd9Sstevel@tonic-gate bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate if (tcp_ports != NULL) { 4577c478bd9Sstevel@tonic-gate for (i = 0; i < 65536; i++) 4587c478bd9Sstevel@tonic-gate if (tcp_ports[i] != NULL) { 4597c478bd9Sstevel@tonic-gate free(tcp_ports[i]); 4607c478bd9Sstevel@tonic-gate tcp_ports[i] = NULL; 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate free(tcp_ports); 4637c478bd9Sstevel@tonic-gate tcp_ports = NULL; 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); 4667c478bd9Sstevel@tonic-gate if (tcp_ports != NULL) 4677c478bd9Sstevel@tonic-gate bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate setservent(1); 4707c478bd9Sstevel@tonic-gate while ((s = getservent()) != NULL) { 4717c478bd9Sstevel@tonic-gate if (s->s_proto == NULL) 4727c478bd9Sstevel@tonic-gate continue; 4737c478bd9Sstevel@tonic-gate else if (!strcmp(s->s_proto, "tcp")) { 4747c478bd9Sstevel@tonic-gate port = ntohs(s->s_port); 4757c478bd9Sstevel@tonic-gate name = s->s_name; 4767c478bd9Sstevel@tonic-gate tab = tcp_ports; 4777c478bd9Sstevel@tonic-gate } else if (!strcmp(s->s_proto, "udp")) { 4787c478bd9Sstevel@tonic-gate port = ntohs(s->s_port); 4797c478bd9Sstevel@tonic-gate name = s->s_name; 4807c478bd9Sstevel@tonic-gate tab = udp_ports; 4817c478bd9Sstevel@tonic-gate } else 4827c478bd9Sstevel@tonic-gate continue; 4837c478bd9Sstevel@tonic-gate if ((port < 0 || port > 65535) || (name == NULL)) 4847c478bd9Sstevel@tonic-gate continue; 4857c478bd9Sstevel@tonic-gate if (tab != NULL) 4867c478bd9Sstevel@tonic-gate tab[port] = strdup(name); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate endservent(); 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate static char *getproto(p) 4937c478bd9Sstevel@tonic-gate u_int p; 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate static char pnum[4]; 4967c478bd9Sstevel@tonic-gate char *s; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate p &= 0xff; 4997c478bd9Sstevel@tonic-gate s = protocols ? protocols[p] : NULL; 5007c478bd9Sstevel@tonic-gate if (s == NULL) { 5017c478bd9Sstevel@tonic-gate sprintf(pnum, "%u", p); 5027c478bd9Sstevel@tonic-gate s = pnum; 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate return s; 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate static int read_log(fd, lenp, buf, bufsize) 5097c478bd9Sstevel@tonic-gate int fd, bufsize, *lenp; 5107c478bd9Sstevel@tonic-gate char *buf; 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate int nr; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate nr = read(fd, buf, bufsize); 5157c478bd9Sstevel@tonic-gate if (!nr) 5167c478bd9Sstevel@tonic-gate return 2; 5177c478bd9Sstevel@tonic-gate if ((nr < 0) && (errno != EINTR)) 5187c478bd9Sstevel@tonic-gate return -1; 5197c478bd9Sstevel@tonic-gate *lenp = nr; 5207c478bd9Sstevel@tonic-gate return 0; 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate char *hostname(res, v, ip) 5257c478bd9Sstevel@tonic-gate int res, v; 5267c478bd9Sstevel@tonic-gate u_32_t *ip; 5277c478bd9Sstevel@tonic-gate { 5287c478bd9Sstevel@tonic-gate # define MAX_INETA 16 5297c478bd9Sstevel@tonic-gate static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; 5307c478bd9Sstevel@tonic-gate #ifdef USE_INET6 5317c478bd9Sstevel@tonic-gate static char hostbuf[MAXHOSTNAMELEN+1]; 5327c478bd9Sstevel@tonic-gate #endif 5337c478bd9Sstevel@tonic-gate struct hostent *hp; 5347c478bd9Sstevel@tonic-gate struct in_addr ipa; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate if (v == 4) { 5377c478bd9Sstevel@tonic-gate ipa.s_addr = *ip; 5387c478bd9Sstevel@tonic-gate if (!res) 5397c478bd9Sstevel@tonic-gate return inet_ntoa(ipa); 5407c478bd9Sstevel@tonic-gate hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET); 5417c478bd9Sstevel@tonic-gate if (!hp) 5427c478bd9Sstevel@tonic-gate return inet_ntoa(ipa); 5437c478bd9Sstevel@tonic-gate sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, 5447c478bd9Sstevel@tonic-gate inet_ntoa(ipa)); 5457c478bd9Sstevel@tonic-gate return hname; 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate #ifdef USE_INET6 5487c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); 5497c478bd9Sstevel@tonic-gate hostbuf[MAXHOSTNAMELEN] = '\0'; 5507c478bd9Sstevel@tonic-gate return hostbuf; 5517c478bd9Sstevel@tonic-gate #else 5527c478bd9Sstevel@tonic-gate return "IPv6"; 5537c478bd9Sstevel@tonic-gate #endif 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate char *portname(res, proto, port) 5587c478bd9Sstevel@tonic-gate int res; 5597c478bd9Sstevel@tonic-gate char *proto; 5607c478bd9Sstevel@tonic-gate u_int port; 5617c478bd9Sstevel@tonic-gate { 5627c478bd9Sstevel@tonic-gate static char pname[8]; 5637c478bd9Sstevel@tonic-gate char *s; 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate port = ntohs(port); 5667c478bd9Sstevel@tonic-gate port &= 0xffff; 5677c478bd9Sstevel@tonic-gate (void) sprintf(pname, "%u", port); 5687c478bd9Sstevel@tonic-gate if (!res || (opts & OPT_PORTNUM)) 5697c478bd9Sstevel@tonic-gate return pname; 5707c478bd9Sstevel@tonic-gate s = NULL; 5717c478bd9Sstevel@tonic-gate if (!strcmp(proto, "tcp")) 5727c478bd9Sstevel@tonic-gate s = tcp_ports[port]; 5737c478bd9Sstevel@tonic-gate else if (!strcmp(proto, "udp")) 5747c478bd9Sstevel@tonic-gate s = udp_ports[port]; 5757c478bd9Sstevel@tonic-gate if (s == NULL) 5767c478bd9Sstevel@tonic-gate s = pname; 5777c478bd9Sstevel@tonic-gate return s; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate static char *icmpname(type, code) 5827c478bd9Sstevel@tonic-gate u_int type; 5837c478bd9Sstevel@tonic-gate u_int code; 5847c478bd9Sstevel@tonic-gate { 5857c478bd9Sstevel@tonic-gate static char name[80]; 5867c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 5877c478bd9Sstevel@tonic-gate icmp_type_t *it; 5887c478bd9Sstevel@tonic-gate char *s; 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate s = NULL; 5917c478bd9Sstevel@tonic-gate it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); 5927c478bd9Sstevel@tonic-gate if (it != NULL) 5937c478bd9Sstevel@tonic-gate s = it->it_name; 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate if (s == NULL) 5967c478bd9Sstevel@tonic-gate sprintf(name, "icmptype(%d)/", type); 5977c478bd9Sstevel@tonic-gate else 5987c478bd9Sstevel@tonic-gate sprintf(name, "%s/", s); 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate ist = NULL; 6017c478bd9Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 6027c478bd9Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 6057c478bd9Sstevel@tonic-gate strcat(name, ist->ist_name); 6067c478bd9Sstevel@tonic-gate else 6077c478bd9Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate return name; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate static char *icmpname6(type, code) 6137c478bd9Sstevel@tonic-gate u_int type; 6147c478bd9Sstevel@tonic-gate u_int code; 6157c478bd9Sstevel@tonic-gate { 6167c478bd9Sstevel@tonic-gate static char name[80]; 6177c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 6187c478bd9Sstevel@tonic-gate icmp_type_t *it; 6197c478bd9Sstevel@tonic-gate char *s; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate s = NULL; 6227c478bd9Sstevel@tonic-gate it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); 6237c478bd9Sstevel@tonic-gate if (it != NULL) 6247c478bd9Sstevel@tonic-gate s = it->it_name; 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate if (s == NULL) 6277c478bd9Sstevel@tonic-gate sprintf(name, "icmpv6type(%d)/", type); 6287c478bd9Sstevel@tonic-gate else 6297c478bd9Sstevel@tonic-gate sprintf(name, "%s/", s); 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate ist = NULL; 6327c478bd9Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 6337c478bd9Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 6367c478bd9Sstevel@tonic-gate strcat(name, ist->ist_name); 6377c478bd9Sstevel@tonic-gate else 6387c478bd9Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate return name; 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate void dumphex(log, dopts, buf, len) 6457c478bd9Sstevel@tonic-gate FILE *log; 6467c478bd9Sstevel@tonic-gate int dopts; 6477c478bd9Sstevel@tonic-gate char *buf; 6487c478bd9Sstevel@tonic-gate int len; 6497c478bd9Sstevel@tonic-gate { 6507c478bd9Sstevel@tonic-gate char hline[80]; 6517c478bd9Sstevel@tonic-gate int i, j, k; 6527c478bd9Sstevel@tonic-gate u_char *s = (u_char *)buf, *t = (u_char *)hline; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate if (buf == NULL || len == 0) 6557c478bd9Sstevel@tonic-gate return; 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate *hline = '\0'; 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate for (i = len, j = 0; i; i--, j++, s++) { 6607c478bd9Sstevel@tonic-gate if (j && !(j & 0xf)) { 6617c478bd9Sstevel@tonic-gate *t++ = '\n'; 6627c478bd9Sstevel@tonic-gate *t = '\0'; 6637c478bd9Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) 6647c478bd9Sstevel@tonic-gate fputs(hline, log); 6657c478bd9Sstevel@tonic-gate else 6667c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 6677c478bd9Sstevel@tonic-gate t = (u_char *)hline; 6687c478bd9Sstevel@tonic-gate *t = '\0'; 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate sprintf((char *)t, "%02x", *s & 0xff); 6717c478bd9Sstevel@tonic-gate t += 2; 6727c478bd9Sstevel@tonic-gate if (!((j + 1) & 0xf)) { 6737c478bd9Sstevel@tonic-gate s -= 15; 6747c478bd9Sstevel@tonic-gate sprintf((char *)t, " "); 6757c478bd9Sstevel@tonic-gate t += 8; 6767c478bd9Sstevel@tonic-gate for (k = 16; k; k--, s++) 677ab25eeb5Syz *t++ = (ISPRINT(*s) ? *s : '.'); 6787c478bd9Sstevel@tonic-gate s--; 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate if ((j + 1) & 0xf) 6827c478bd9Sstevel@tonic-gate *t++ = ' ';; 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate if (j & 0xf) { 6867c478bd9Sstevel@tonic-gate for (k = 16 - (j & 0xf); k; k--) { 6877c478bd9Sstevel@tonic-gate *t++ = ' '; 6887c478bd9Sstevel@tonic-gate *t++ = ' '; 6897c478bd9Sstevel@tonic-gate *t++ = ' '; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate sprintf((char *)t, " "); 6927c478bd9Sstevel@tonic-gate t += 7; 6937c478bd9Sstevel@tonic-gate s -= j & 0xf; 6947c478bd9Sstevel@tonic-gate for (k = j & 0xf; k; k--, s++) 695ab25eeb5Syz *t++ = (ISPRINT(*s) ? *s : '.'); 6967c478bd9Sstevel@tonic-gate *t++ = '\n'; 6977c478bd9Sstevel@tonic-gate *t = '\0'; 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) { 7007c478bd9Sstevel@tonic-gate fputs(hline, log); 7017c478bd9Sstevel@tonic-gate fflush(log); 7027c478bd9Sstevel@tonic-gate } else 7037c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 7047c478bd9Sstevel@tonic-gate } 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate static struct tm *get_tm(sec) 7087c478bd9Sstevel@tonic-gate #ifdef __hpux 7097c478bd9Sstevel@tonic-gate u_32_t sec; 7107c478bd9Sstevel@tonic-gate #else 7117c478bd9Sstevel@tonic-gate time_t sec; 7127c478bd9Sstevel@tonic-gate #endif 7137c478bd9Sstevel@tonic-gate { 7147c478bd9Sstevel@tonic-gate struct tm *tm; 7157c478bd9Sstevel@tonic-gate time_t t; 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate t = sec; 7187c478bd9Sstevel@tonic-gate tm = localtime(&t); 7197c478bd9Sstevel@tonic-gate return tm; 7207c478bd9Sstevel@tonic-gate } 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate static void print_natlog(log, buf, blen) 7237c478bd9Sstevel@tonic-gate FILE *log; 7247c478bd9Sstevel@tonic-gate char *buf; 7257c478bd9Sstevel@tonic-gate int blen; 7267c478bd9Sstevel@tonic-gate { 7277c478bd9Sstevel@tonic-gate struct natlog *nl; 7287c478bd9Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 7297c478bd9Sstevel@tonic-gate char *t = line; 7307c478bd9Sstevel@tonic-gate struct tm *tm; 7317c478bd9Sstevel@tonic-gate int res, i, len; 7327c478bd9Sstevel@tonic-gate char *proto; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); 7357c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 7367c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 7377c478bd9Sstevel@tonic-gate len = sizeof(line); 7387c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 7397c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 7407c478bd9Sstevel@tonic-gate i = strlen(t); 7417c478bd9Sstevel@tonic-gate len -= i; 7427c478bd9Sstevel@tonic-gate t += i; 7437c478bd9Sstevel@tonic-gate } 7447c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 7457c478bd9Sstevel@tonic-gate t += strlen(t); 746d6c23f6fSyx (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nlg_rule + 1); 7477c478bd9Sstevel@tonic-gate t += strlen(t); 7487c478bd9Sstevel@tonic-gate 749d6c23f6fSyx if (nl->nlg_type == NL_NEWMAP) 7507c478bd9Sstevel@tonic-gate strcpy(t, "NAT:MAP "); 751d6c23f6fSyx else if (nl->nlg_type == NL_NEWRDR) 7527c478bd9Sstevel@tonic-gate strcpy(t, "NAT:RDR "); 753d6c23f6fSyx else if (nl->nlg_type == NL_FLUSH) 7547c478bd9Sstevel@tonic-gate strcpy(t, "NAT:FLUSH "); 755d6c23f6fSyx else if (nl->nlg_type == NL_EXPIRE) 7567c478bd9Sstevel@tonic-gate strcpy(t, "NAT:EXPIRE "); 757d6c23f6fSyx else if (nl->nlg_type == NL_NEWBIMAP) 7587c478bd9Sstevel@tonic-gate strcpy(t, "NAT:BIMAP "); 759d6c23f6fSyx else if (nl->nlg_type == NL_NEWBLOCK) 7607c478bd9Sstevel@tonic-gate strcpy(t, "NAT:MAPBLOCK "); 761d6c23f6fSyx else if (nl->nlg_type == NL_CLONE) 7627c478bd9Sstevel@tonic-gate strcpy(t, "NAT:CLONE "); 7637c478bd9Sstevel@tonic-gate else 764d6c23f6fSyx sprintf(t, "Type: %d ", nl->nlg_type); 7657c478bd9Sstevel@tonic-gate t += strlen(t); 7667c478bd9Sstevel@tonic-gate 767d6c23f6fSyx proto = getproto(nl->nlg_p); 7687c478bd9Sstevel@tonic-gate 769d6c23f6fSyx (void) sprintf(t, "%s,%s <- -> ", hostname(res, nl->nlg_v, 770d6c23f6fSyx (u_32_t *)&nl->nlg_inip), 771d6c23f6fSyx portname(res, proto, (u_int)nl->nlg_inport)); 7727c478bd9Sstevel@tonic-gate t += strlen(t); 773d6c23f6fSyx (void) sprintf(t, "%s,%s ", hostname(res, nl->nlg_v, 774d6c23f6fSyx (u_32_t *)&nl->nlg_outip), 775d6c23f6fSyx portname(res, proto, (u_int)nl->nlg_outport)); 7767c478bd9Sstevel@tonic-gate t += strlen(t); 777d6c23f6fSyx (void) sprintf(t, "[%s,%s]", hostname(res, nl->nlg_v, 778d6c23f6fSyx (u_32_t *)&nl->nlg_origip), 779d6c23f6fSyx portname(res, proto, (u_int)nl->nlg_origport)); 7807c478bd9Sstevel@tonic-gate t += strlen(t); 781d6c23f6fSyx if (nl->nlg_type == NL_EXPIRE) { 7827c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 7837c478bd9Sstevel@tonic-gate (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", 784d6c23f6fSyx (long long)nl->nlg_pkts[0], 785d6c23f6fSyx (long long)nl->nlg_pkts[1], 786d6c23f6fSyx (long long)nl->nlg_bytes[0], 787d6c23f6fSyx (long long)nl->nlg_bytes[1]); 7887c478bd9Sstevel@tonic-gate #else 789ab25eeb5Syz (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", 790d6c23f6fSyx nl->nlg_pkts[0], nl->nlg_pkts[1], 791d6c23f6fSyx nl->nlg_bytes[0], nl->nlg_bytes[1]); 7927c478bd9Sstevel@tonic-gate #endif 7937c478bd9Sstevel@tonic-gate t += strlen(t); 7947c478bd9Sstevel@tonic-gate } 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate *t++ = '\n'; 7977c478bd9Sstevel@tonic-gate *t++ = '\0'; 7987c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 7997c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 8007c478bd9Sstevel@tonic-gate else 8017c478bd9Sstevel@tonic-gate (void) fprintf(log, "%s", line); 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate static void print_statelog(log, buf, blen) 8067c478bd9Sstevel@tonic-gate FILE *log; 8077c478bd9Sstevel@tonic-gate char *buf; 8087c478bd9Sstevel@tonic-gate int blen; 8097c478bd9Sstevel@tonic-gate { 8107c478bd9Sstevel@tonic-gate struct ipslog *sl; 8117c478bd9Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 8127c478bd9Sstevel@tonic-gate char *t = line, *proto; 8137c478bd9Sstevel@tonic-gate struct tm *tm; 8147c478bd9Sstevel@tonic-gate int res, i, len; 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); 8177c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 8187c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 8197c478bd9Sstevel@tonic-gate len = sizeof(line); 8207c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 8217c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 8227c478bd9Sstevel@tonic-gate i = strlen(t); 8237c478bd9Sstevel@tonic-gate len -= i; 8247c478bd9Sstevel@tonic-gate t += i; 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 8277c478bd9Sstevel@tonic-gate t += strlen(t); 8287c478bd9Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 8297c478bd9Sstevel@tonic-gate t += strlen(t); 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate if (sl->isl_type == ISL_NEW) 8327c478bd9Sstevel@tonic-gate strcpy(t, "STATE:NEW "); 8337c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_CLONE) 8347c478bd9Sstevel@tonic-gate strcpy(t, "STATE:CLONED "); 8357c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_EXPIRE) { 8367c478bd9Sstevel@tonic-gate if ((sl->isl_p == IPPROTO_TCP) && 8377c478bd9Sstevel@tonic-gate (sl->isl_state[0] > IPF_TCPS_ESTABLISHED || 8387c478bd9Sstevel@tonic-gate sl->isl_state[1] > IPF_TCPS_ESTABLISHED)) 8397c478bd9Sstevel@tonic-gate strcpy(t, "STATE:CLOSE "); 8407c478bd9Sstevel@tonic-gate else 8417c478bd9Sstevel@tonic-gate strcpy(t, "STATE:EXPIRE "); 8427c478bd9Sstevel@tonic-gate } else if (sl->isl_type == ISL_FLUSH) 8437c478bd9Sstevel@tonic-gate strcpy(t, "STATE:FLUSH "); 8447c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_INTERMEDIATE) 8457c478bd9Sstevel@tonic-gate strcpy(t, "STATE:INTERMEDIATE "); 8467c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_REMOVE) 8477c478bd9Sstevel@tonic-gate strcpy(t, "STATE:REMOVE "); 8487c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_KILLED) 8497c478bd9Sstevel@tonic-gate strcpy(t, "STATE:KILLED "); 8507c478bd9Sstevel@tonic-gate else 8517c478bd9Sstevel@tonic-gate sprintf(t, "Type: %d ", sl->isl_type); 8527c478bd9Sstevel@tonic-gate t += strlen(t); 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate proto = getproto(sl->isl_p); 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { 8577c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", 8587c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), 8597c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_sport)); 8607c478bd9Sstevel@tonic-gate t += strlen(t); 8617c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s", 8627c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8637c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_dport), proto); 8647c478bd9Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMP) { 8657c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 8667c478bd9Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 8677c478bd9Sstevel@tonic-gate t += strlen(t); 8687c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp %d", 8697c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8707c478bd9Sstevel@tonic-gate sl->isl_itype); 8717c478bd9Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMPV6) { 8727c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 8737c478bd9Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 8747c478bd9Sstevel@tonic-gate t += strlen(t); 8757c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 %d", 8767c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8777c478bd9Sstevel@tonic-gate sl->isl_itype); 878ab25eeb5Syz } else { 879ab25eeb5Syz (void) sprintf(t, "%s -> ", 880ab25eeb5Syz hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src)); 881ab25eeb5Syz t += strlen(t); 882ab25eeb5Syz (void) sprintf(t, "%s PR %s", 883ab25eeb5Syz hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 884ab25eeb5Syz proto); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate t += strlen(t); 8877c478bd9Sstevel@tonic-gate if (sl->isl_tag != FR_NOLOGTAG) { 8887c478bd9Sstevel@tonic-gate (void) sprintf(t, " tag %u", sl->isl_tag); 8897c478bd9Sstevel@tonic-gate t += strlen(t); 8907c478bd9Sstevel@tonic-gate } 8917c478bd9Sstevel@tonic-gate if (sl->isl_type != ISL_NEW) { 8927c478bd9Sstevel@tonic-gate sprintf(t, 8937c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 894ab25eeb5Syz #ifdef PRId64 895ab25eeb5Syz " Forward: Pkts in %" PRId64 " Bytes in %" PRId64 896ab25eeb5Syz " Pkts out %" PRId64 " Bytes out %" PRId64 897ab25eeb5Syz " Backward: Pkts in %" PRId64 " Bytes in %" PRId64 898ab25eeb5Syz " Pkts out %" PRId64 " Bytes out %" PRId64, 899ab25eeb5Syz #else 9007c478bd9Sstevel@tonic-gate " Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd", 901ab25eeb5Syz #endif /* PRId64 */ 9027c478bd9Sstevel@tonic-gate #else 9037c478bd9Sstevel@tonic-gate " Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld", 9047c478bd9Sstevel@tonic-gate #endif 9057c478bd9Sstevel@tonic-gate sl->isl_pkts[0], sl->isl_bytes[0], 9067c478bd9Sstevel@tonic-gate sl->isl_pkts[1], sl->isl_bytes[1], 9077c478bd9Sstevel@tonic-gate sl->isl_pkts[2], sl->isl_bytes[2], 9087c478bd9Sstevel@tonic-gate sl->isl_pkts[3], sl->isl_bytes[3]); 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate t += strlen(t); 9117c478bd9Sstevel@tonic-gate } 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate *t++ = '\n'; 9147c478bd9Sstevel@tonic-gate *t++ = '\0'; 9157c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 9167c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 9177c478bd9Sstevel@tonic-gate else 9187c478bd9Sstevel@tonic-gate (void) fprintf(log, "%s", line); 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate static void print_log(logtype, log, buf, blen) 9237c478bd9Sstevel@tonic-gate FILE *log; 9247c478bd9Sstevel@tonic-gate char *buf; 9257c478bd9Sstevel@tonic-gate int logtype, blen; 9267c478bd9Sstevel@tonic-gate { 9277c478bd9Sstevel@tonic-gate iplog_t *ipl; 9287c478bd9Sstevel@tonic-gate char *bp = NULL, *bpo = NULL; 9297c478bd9Sstevel@tonic-gate int psize; 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate while (blen > 0) { 9327c478bd9Sstevel@tonic-gate ipl = (iplog_t *)buf; 9337c478bd9Sstevel@tonic-gate if ((u_long)ipl & (sizeof(long)-1)) { 9347c478bd9Sstevel@tonic-gate if (bp) 9357c478bd9Sstevel@tonic-gate bpo = bp; 9367c478bd9Sstevel@tonic-gate bp = (char *)malloc(blen); 9375e985db5Sschuster if (bp == NULL) { 9385e985db5Sschuster perror("malloc"); 9395e985db5Sschuster exit(1); 9405e985db5Sschuster } 9417c478bd9Sstevel@tonic-gate bcopy((char *)ipl, bp, blen); 9427c478bd9Sstevel@tonic-gate if (bpo) { 9437c478bd9Sstevel@tonic-gate free(bpo); 9447c478bd9Sstevel@tonic-gate bpo = NULL; 9457c478bd9Sstevel@tonic-gate } 9467c478bd9Sstevel@tonic-gate buf = bp; 9477c478bd9Sstevel@tonic-gate continue; 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate psize = ipl->ipl_dsize; 9517c478bd9Sstevel@tonic-gate if (psize > blen) 9527c478bd9Sstevel@tonic-gate break; 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate if (binarylog) { 9557c478bd9Sstevel@tonic-gate fwrite(buf, psize, 1, binarylog); 9567c478bd9Sstevel@tonic-gate fflush(binarylog); 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate if (logtype == IPL_LOGIPF) { 960ab25eeb5Syz if (ipl->ipl_magic == IPL_MAGIC) 961ab25eeb5Syz print_ipflog(log, buf, psize); 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate } else if (logtype == IPL_LOGNAT) { 964ab25eeb5Syz if (ipl->ipl_magic == IPL_MAGIC_NAT) 965ab25eeb5Syz print_natlog(log, buf, psize); 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate } else if (logtype == IPL_LOGSTATE) { 968ab25eeb5Syz if (ipl->ipl_magic == IPL_MAGIC_STATE) 969ab25eeb5Syz print_statelog(log, buf, psize); 9707c478bd9Sstevel@tonic-gate } 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate blen -= psize; 9737c478bd9Sstevel@tonic-gate buf += psize; 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate if (bp) 9767c478bd9Sstevel@tonic-gate free(bp); 9777c478bd9Sstevel@tonic-gate return; 9787c478bd9Sstevel@tonic-gate } 9797c478bd9Sstevel@tonic-gate 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate static void print_ipflog(log, buf, blen) 9827c478bd9Sstevel@tonic-gate FILE *log; 9837c478bd9Sstevel@tonic-gate char *buf; 9847c478bd9Sstevel@tonic-gate int blen; 9857c478bd9Sstevel@tonic-gate { 9867c478bd9Sstevel@tonic-gate tcphdr_t *tp; 9877c478bd9Sstevel@tonic-gate struct icmp *ic; 9887c478bd9Sstevel@tonic-gate struct icmp *icmp; 9897c478bd9Sstevel@tonic-gate struct tm *tm; 9907c478bd9Sstevel@tonic-gate char *t, *proto; 991ab25eeb5Syz int i, v, lvl, res, len, off, plen, ipoff, defaction; 9927c478bd9Sstevel@tonic-gate ip_t *ipc, *ip; 993ab25eeb5Syz u_32_t *s, *d; 9947c478bd9Sstevel@tonic-gate u_short hl, p; 9957c478bd9Sstevel@tonic-gate ipflog_t *ipf; 9967c478bd9Sstevel@tonic-gate iplog_t *ipl; 9977c478bd9Sstevel@tonic-gate #ifdef USE_INET6 9987c478bd9Sstevel@tonic-gate ip6_t *ip6; 9997c478bd9Sstevel@tonic-gate #endif 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate ipl = (iplog_t *)buf; 10027c478bd9Sstevel@tonic-gate ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); 10037c478bd9Sstevel@tonic-gate ip = (ip_t *)((char *)ipf + sizeof(*ipf)); 10047c478bd9Sstevel@tonic-gate v = IP_V(ip); 10057c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 10067c478bd9Sstevel@tonic-gate t = line; 10077c478bd9Sstevel@tonic-gate *t = '\0'; 10087c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate len = sizeof(line); 10117c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 10127c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 10137c478bd9Sstevel@tonic-gate i = strlen(t); 10147c478bd9Sstevel@tonic-gate len -= i; 10157c478bd9Sstevel@tonic-gate t += i; 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 10187c478bd9Sstevel@tonic-gate t += strlen(t); 10197c478bd9Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 10207c478bd9Sstevel@tonic-gate t += strlen(t); 10217c478bd9Sstevel@tonic-gate if (ipl->ipl_count > 1) { 10227c478bd9Sstevel@tonic-gate (void) sprintf(t, "%dx ", ipl->ipl_count); 10237c478bd9Sstevel@tonic-gate t += strlen(t); 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate #if (defined(MENTAT) || \ 10267c478bd9Sstevel@tonic-gate (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ 1027ab25eeb5Syz (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \ 10287c478bd9Sstevel@tonic-gate (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux) 10297c478bd9Sstevel@tonic-gate { 10307c478bd9Sstevel@tonic-gate char ifname[sizeof(ipf->fl_ifname) + 1]; 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); 10337c478bd9Sstevel@tonic-gate ifname[sizeof(ipf->fl_ifname)] = '\0'; 10347c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s", ifname); 10357c478bd9Sstevel@tonic-gate t += strlen(t); 1036ab25eeb5Syz # if defined(MENTAT) || defined(linux) 1037ab25eeb5Syz if (ISALPHA(*(t - 1))) { 10387c478bd9Sstevel@tonic-gate sprintf(t, "%d", ipf->fl_unit); 10397c478bd9Sstevel@tonic-gate t += strlen(t); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate # endif 10427c478bd9Sstevel@tonic-gate } 10437c478bd9Sstevel@tonic-gate #else 10447c478bd9Sstevel@tonic-gate for (len = 0; len < 3; len++) 10457c478bd9Sstevel@tonic-gate if (ipf->fl_ifname[len] == '\0') 10467c478bd9Sstevel@tonic-gate break; 10477c478bd9Sstevel@tonic-gate if (ipf->fl_ifname[len]) 10487c478bd9Sstevel@tonic-gate len++; 10497c478bd9Sstevel@tonic-gate (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); 10507c478bd9Sstevel@tonic-gate t += strlen(t); 10517c478bd9Sstevel@tonic-gate #endif 1052ab25eeb5Syz #if defined(__sgi) || defined(_AIX51) || defined(__powerpc__) || \ 1053ab25eeb5Syz defined(__arm__) 1054ab25eeb5Syz if ((ipf->fl_group[0] == 255) && (ipf->fl_group[1] == '\0')) 1055ab25eeb5Syz #else 10567c478bd9Sstevel@tonic-gate if ((ipf->fl_group[0] == -1) && (ipf->fl_group[1] == '\0')) 1057ab25eeb5Syz #endif 10587c478bd9Sstevel@tonic-gate strcat(t, " @-1:"); 10597c478bd9Sstevel@tonic-gate else if (ipf->fl_group[0] == '\0') 10607c478bd9Sstevel@tonic-gate (void) strcpy(t, " @0:"); 10617c478bd9Sstevel@tonic-gate else 10627c478bd9Sstevel@tonic-gate (void) sprintf(t, " @%s:", ipf->fl_group); 10637c478bd9Sstevel@tonic-gate t += strlen(t); 10647c478bd9Sstevel@tonic-gate if (ipf->fl_rule == 0xffffffff) 10657c478bd9Sstevel@tonic-gate strcat(t, "-1 "); 10667c478bd9Sstevel@tonic-gate else 10677c478bd9Sstevel@tonic-gate (void) sprintf(t, "%u ", ipf->fl_rule + 1); 10687c478bd9Sstevel@tonic-gate t += strlen(t); 10697c478bd9Sstevel@tonic-gate 10707c478bd9Sstevel@tonic-gate lvl = LOG_NOTICE; 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate if (ipf->fl_lflags & FI_SHORT) { 10737c478bd9Sstevel@tonic-gate *t++ = 'S'; 10747c478bd9Sstevel@tonic-gate lvl = LOG_ERR; 10757c478bd9Sstevel@tonic-gate } 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate if (FR_ISPASS(ipf->fl_flags)) { 10787c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGP) 10797c478bd9Sstevel@tonic-gate *t++ = 'p'; 10807c478bd9Sstevel@tonic-gate else 10817c478bd9Sstevel@tonic-gate *t++ = 'P'; 10827c478bd9Sstevel@tonic-gate } else if (FR_ISBLOCK(ipf->fl_flags)) { 10837c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGB) 10847c478bd9Sstevel@tonic-gate *t++ = 'b'; 10857c478bd9Sstevel@tonic-gate else 10867c478bd9Sstevel@tonic-gate *t++ = 'B'; 10877c478bd9Sstevel@tonic-gate lvl = LOG_WARNING; 10887c478bd9Sstevel@tonic-gate } else if ((ipf->fl_flags & FR_LOGMASK) == FR_LOG) { 10897c478bd9Sstevel@tonic-gate *t++ = 'L'; 10907c478bd9Sstevel@tonic-gate lvl = LOG_INFO; 10917c478bd9Sstevel@tonic-gate } else if (ipf->fl_flags & FF_LOGNOMATCH) { 10927c478bd9Sstevel@tonic-gate *t++ = 'n'; 10937c478bd9Sstevel@tonic-gate } else { 10947c478bd9Sstevel@tonic-gate *t++ = '?'; 10957c478bd9Sstevel@tonic-gate lvl = LOG_EMERG; 10967c478bd9Sstevel@tonic-gate } 10977c478bd9Sstevel@tonic-gate if (ipf->fl_loglevel != 0xffff) 10987c478bd9Sstevel@tonic-gate lvl = ipf->fl_loglevel; 10997c478bd9Sstevel@tonic-gate *t++ = ' '; 11007c478bd9Sstevel@tonic-gate *t = '\0'; 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate if (v == 6) { 11037c478bd9Sstevel@tonic-gate #ifdef USE_INET6 11047c478bd9Sstevel@tonic-gate off = 0; 11057c478bd9Sstevel@tonic-gate ipoff = 0; 11067c478bd9Sstevel@tonic-gate hl = sizeof(ip6_t); 11077c478bd9Sstevel@tonic-gate ip6 = (ip6_t *)ip; 11087c478bd9Sstevel@tonic-gate p = (u_short)ip6->ip6_nxt; 11097c478bd9Sstevel@tonic-gate s = (u_32_t *)&ip6->ip6_src; 11107c478bd9Sstevel@tonic-gate d = (u_32_t *)&ip6->ip6_dst; 1111ab25eeb5Syz plen = hl + ntohs(ip6->ip6_plen); 11127c478bd9Sstevel@tonic-gate #else 11137c478bd9Sstevel@tonic-gate sprintf(t, "ipv6"); 11147c478bd9Sstevel@tonic-gate goto printipflog; 11157c478bd9Sstevel@tonic-gate #endif 11167c478bd9Sstevel@tonic-gate } else if (v == 4) { 11177c478bd9Sstevel@tonic-gate hl = IP_HL(ip) << 2; 11187c478bd9Sstevel@tonic-gate ipoff = ip->ip_off; 11197c478bd9Sstevel@tonic-gate off = ipoff & IP_OFFMASK; 11207c478bd9Sstevel@tonic-gate p = (u_short)ip->ip_p; 11217c478bd9Sstevel@tonic-gate s = (u_32_t *)&ip->ip_src; 11227c478bd9Sstevel@tonic-gate d = (u_32_t *)&ip->ip_dst; 11237c478bd9Sstevel@tonic-gate plen = ip->ip_len; 11247c478bd9Sstevel@tonic-gate } else { 11257c478bd9Sstevel@tonic-gate goto printipflog; 11267c478bd9Sstevel@tonic-gate } 11277c478bd9Sstevel@tonic-gate proto = getproto(p); 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gate if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { 11307c478bd9Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ip + hl); 11317c478bd9Sstevel@tonic-gate if (!(ipf->fl_lflags & FI_SHORT)) { 11327c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), 11337c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_sport)); 11347c478bd9Sstevel@tonic-gate t += strlen(t); 11357c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s len %hu %hu", 11367c478bd9Sstevel@tonic-gate hostname(res, v, d), 11377c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_dport), 11387c478bd9Sstevel@tonic-gate proto, hl, plen); 11397c478bd9Sstevel@tonic-gate t += strlen(t); 11407c478bd9Sstevel@tonic-gate 11417c478bd9Sstevel@tonic-gate if (p == IPPROTO_TCP) { 11427c478bd9Sstevel@tonic-gate *t++ = ' '; 11437c478bd9Sstevel@tonic-gate *t++ = '-'; 11447c478bd9Sstevel@tonic-gate for (i = 0; tcpfl[i].value; i++) 11457c478bd9Sstevel@tonic-gate if (tp->th_flags & tcpfl[i].value) 11467c478bd9Sstevel@tonic-gate *t++ = tcpfl[i].flag; 11477c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 11487c478bd9Sstevel@tonic-gate (void) sprintf(t, " %lu %lu %hu", 11497c478bd9Sstevel@tonic-gate (u_long)(ntohl(tp->th_seq)), 11507c478bd9Sstevel@tonic-gate (u_long)(ntohl(tp->th_ack)), 11517c478bd9Sstevel@tonic-gate ntohs(tp->th_win)); 11527c478bd9Sstevel@tonic-gate t += strlen(t); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate *t = '\0'; 11567c478bd9Sstevel@tonic-gate } else { 11577c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11587c478bd9Sstevel@tonic-gate t += strlen(t); 11597c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu %hu", 11607c478bd9Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { 11637c478bd9Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 11647c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11657c478bd9Sstevel@tonic-gate t += strlen(t); 11667c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", 11677c478bd9Sstevel@tonic-gate hostname(res, v, d), hl, plen, 11687c478bd9Sstevel@tonic-gate icmpname6(ic->icmp_type, ic->icmp_code)); 11697c478bd9Sstevel@tonic-gate } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { 11707c478bd9Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 11717c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11727c478bd9Sstevel@tonic-gate t += strlen(t); 11737c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", 11747c478bd9Sstevel@tonic-gate hostname(res, v, d), hl, plen, 11757c478bd9Sstevel@tonic-gate icmpname(ic->icmp_type, ic->icmp_code)); 11767c478bd9Sstevel@tonic-gate if (ic->icmp_type == ICMP_UNREACH || 11777c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_SOURCEQUENCH || 11787c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_PARAMPROB || 11797c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_REDIRECT || 11807c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_TIMXCEED) { 11817c478bd9Sstevel@tonic-gate ipc = &ic->icmp_ip; 11827c478bd9Sstevel@tonic-gate i = ntohs(ipc->ip_len); 11837c478bd9Sstevel@tonic-gate /* 11847c478bd9Sstevel@tonic-gate * XXX - try to guess endian of ip_len in ICMP 11857c478bd9Sstevel@tonic-gate * returned data. 11867c478bd9Sstevel@tonic-gate */ 11877c478bd9Sstevel@tonic-gate if (i > 1500) 11887c478bd9Sstevel@tonic-gate i = ipc->ip_len; 11897c478bd9Sstevel@tonic-gate ipoff = ntohs(ipc->ip_off); 11907c478bd9Sstevel@tonic-gate proto = getproto(ipc->ip_p); 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate if (!(ipoff & IP_OFFMASK) && 11937c478bd9Sstevel@tonic-gate ((ipc->ip_p == IPPROTO_TCP) || 11947c478bd9Sstevel@tonic-gate (ipc->ip_p == IPPROTO_UDP))) { 11957c478bd9Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ipc + hl); 11967c478bd9Sstevel@tonic-gate t += strlen(t); 11977c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s,%s -", 11987c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src), 11997c478bd9Sstevel@tonic-gate portname(res, proto, 12007c478bd9Sstevel@tonic-gate (u_int)tp->th_sport)); 12017c478bd9Sstevel@tonic-gate t += strlen(t); 12027c478bd9Sstevel@tonic-gate (void) sprintf(t, " %s,%s PR %s len %hu %hu", 12037c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 12047c478bd9Sstevel@tonic-gate portname(res, proto, 12057c478bd9Sstevel@tonic-gate (u_int)tp->th_dport), 12067c478bd9Sstevel@tonic-gate proto, IP_HL(ipc) << 2, i); 12077c478bd9Sstevel@tonic-gate } else if (!(ipoff & IP_OFFMASK) && 12087c478bd9Sstevel@tonic-gate (ipc->ip_p == IPPROTO_ICMP)) { 12097c478bd9Sstevel@tonic-gate icmp = (icmphdr_t *)((char *)ipc + hl); 12107c478bd9Sstevel@tonic-gate 12117c478bd9Sstevel@tonic-gate t += strlen(t); 12127c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s -", 12137c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 12147c478bd9Sstevel@tonic-gate t += strlen(t); 12157c478bd9Sstevel@tonic-gate (void) sprintf(t, 12167c478bd9Sstevel@tonic-gate " %s PR icmp len %hu %hu icmp %d/%d", 12177c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 12187c478bd9Sstevel@tonic-gate IP_HL(ipc) << 2, i, 12197c478bd9Sstevel@tonic-gate icmp->icmp_type, icmp->icmp_code); 12207c478bd9Sstevel@tonic-gate } else { 12217c478bd9Sstevel@tonic-gate t += strlen(t); 12227c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s -", 12237c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 12247c478bd9Sstevel@tonic-gate t += strlen(t); 12257c478bd9Sstevel@tonic-gate (void) sprintf(t, " %s PR %s len %hu (%hu)", 12267c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), proto, 12277c478bd9Sstevel@tonic-gate IP_HL(ipc) << 2, i); 12287c478bd9Sstevel@tonic-gate t += strlen(t); 12297c478bd9Sstevel@tonic-gate if (ipoff & IP_OFFMASK) { 1230ab25eeb5Syz (void) sprintf(t, 1231ab25eeb5Syz "(frag %d:%hu@%hu%s%s)", 1232ab25eeb5Syz ntohs(ipc->ip_id), 12337c478bd9Sstevel@tonic-gate i - (IP_HL(ipc) << 2), 1234ab25eeb5Syz (ipoff & IP_OFFMASK) << 3, 1235ab25eeb5Syz ipoff & IP_MF ? "+" : "", 1236ab25eeb5Syz ipoff & IP_DF ? "-" : ""); 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate } 12397c478bd9Sstevel@tonic-gate 12407c478bd9Sstevel@tonic-gate } 12417c478bd9Sstevel@tonic-gate } else { 12427c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 12437c478bd9Sstevel@tonic-gate t += strlen(t); 12447c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu (%hu)", 12457c478bd9Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 12467c478bd9Sstevel@tonic-gate t += strlen(t); 12477c478bd9Sstevel@tonic-gate if (off & IP_OFFMASK) 1248ab25eeb5Syz (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", 1249ab25eeb5Syz ntohs(ip->ip_id), 1250ab25eeb5Syz plen - hl, (off & IP_OFFMASK) << 3, 12517c478bd9Sstevel@tonic-gate ipoff & IP_MF ? "+" : "", 1252ab25eeb5Syz ipoff & IP_DF ? "-" : ""); 12537c478bd9Sstevel@tonic-gate } 12547c478bd9Sstevel@tonic-gate t += strlen(t); 12557c478bd9Sstevel@tonic-gate 1256ab25eeb5Syz printipflog: 12577c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPSTATE) { 12587c478bd9Sstevel@tonic-gate (void) strcpy(t, " K-S"); 12597c478bd9Sstevel@tonic-gate t += strlen(t); 12607c478bd9Sstevel@tonic-gate } 12617c478bd9Sstevel@tonic-gate 12627c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPFRAG) { 12637c478bd9Sstevel@tonic-gate (void) strcpy(t, " K-F"); 12647c478bd9Sstevel@tonic-gate t += strlen(t); 12657c478bd9Sstevel@tonic-gate } 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate if (ipf->fl_dir == 0) 12687c478bd9Sstevel@tonic-gate strcpy(t, " IN"); 12697c478bd9Sstevel@tonic-gate else if (ipf->fl_dir == 1) 12707c478bd9Sstevel@tonic-gate strcpy(t, " OUT"); 12717c478bd9Sstevel@tonic-gate t += strlen(t); 1272ab25eeb5Syz if (ipf->fl_logtag != 0) { 1273ab25eeb5Syz sprintf(t, " log-tag %d", ipf->fl_logtag); 12747c478bd9Sstevel@tonic-gate t += strlen(t); 12757c478bd9Sstevel@tonic-gate } 1276ab25eeb5Syz if (ipf->fl_nattag.ipt_num[0] != 0) { 1277ab25eeb5Syz strcpy(t, " nat-tag "); 1278ab25eeb5Syz t += strlen(t); 1279ab25eeb5Syz strncpy(t, ipf->fl_nattag.ipt_tag, sizeof(ipf->fl_nattag)); 1280ab25eeb5Syz t += strlen(t); 1281ab25eeb5Syz } 1282ab25eeb5Syz if ((ipf->fl_lflags & FI_LOWTTL) != 0) { 1283ab25eeb5Syz strcpy(t, " low-ttl"); 1284ab25eeb5Syz t += 8; 1285ab25eeb5Syz } 1286ab25eeb5Syz if ((ipf->fl_lflags & FI_OOW) != 0) { 128740cdc2e8SAlexandr Nedvedicky if (ipf->fl_lflags & FI_NEG_OOW) { 128840cdc2e8SAlexandr Nedvedicky strcpy(t, " NEG_OOW"); 128940cdc2e8SAlexandr Nedvedicky t += sizeof (" NEG_OOW") - 1; 129040cdc2e8SAlexandr Nedvedicky } else { 1291ab25eeb5Syz strcpy(t, " OOW"); 129240cdc2e8SAlexandr Nedvedicky t += sizeof (" OOW") - 1; 129340cdc2e8SAlexandr Nedvedicky } 1294ab25eeb5Syz } 1295ab25eeb5Syz if ((ipf->fl_lflags & FI_BAD) != 0) { 1296ab25eeb5Syz strcpy(t, " bad"); 1297ab25eeb5Syz t += 4; 1298ab25eeb5Syz } 1299ab25eeb5Syz if ((ipf->fl_lflags & FI_NATED) != 0) { 1300ab25eeb5Syz strcpy(t, " NAT"); 1301ab25eeb5Syz t += 4; 1302ab25eeb5Syz } 1303ab25eeb5Syz if ((ipf->fl_lflags & FI_BADNAT) != 0) { 1304ab25eeb5Syz strcpy(t, " bad-NAT"); 1305ab25eeb5Syz t += 8; 1306ab25eeb5Syz } 1307ab25eeb5Syz if ((ipf->fl_lflags & FI_BADSRC) != 0) { 1308ab25eeb5Syz strcpy(t, " bad-src"); 1309ab25eeb5Syz t += 8; 1310ab25eeb5Syz } 1311ab25eeb5Syz if ((ipf->fl_lflags & FI_MULTICAST) != 0) { 1312ab25eeb5Syz strcpy(t, " multicast"); 1313ab25eeb5Syz t += 10; 1314ab25eeb5Syz } 1315ab25eeb5Syz if ((ipf->fl_lflags & FI_BROADCAST) != 0) { 1316ab25eeb5Syz strcpy(t, " broadcast"); 1317ab25eeb5Syz t += 10; 1318ab25eeb5Syz } 1319ab25eeb5Syz if ((ipf->fl_lflags & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST)) == 1320ab25eeb5Syz FI_MBCAST) { 1321ab25eeb5Syz strcpy(t, " mbcast"); 1322ab25eeb5Syz t += 7; 1323ab25eeb5Syz } 13247c478bd9Sstevel@tonic-gate *t++ = '\n'; 13257c478bd9Sstevel@tonic-gate *t++ = '\0'; 1326ab25eeb5Syz defaction = 0; 1327ab25eeb5Syz if (conf_file != NULL) 1328ab25eeb5Syz defaction = check_action(buf, line, opts, lvl); 1329ab25eeb5Syz if (defaction == 0) { 1330ab25eeb5Syz if (opts & OPT_SYSLOG) 1331ab25eeb5Syz syslog(lvl, "%s", line); 1332ab25eeb5Syz else 1333ab25eeb5Syz (void) fprintf(log, "%s", line); 1334ab25eeb5Syz if (opts & OPT_HEXHDR) 1335ab25eeb5Syz dumphex(log, opts, buf, 1336ab25eeb5Syz sizeof(iplog_t) + sizeof(*ipf)); 1337ab25eeb5Syz if (opts & OPT_HEXBODY) 1338ab25eeb5Syz dumphex(log, opts, (char *)ip, 1339ab25eeb5Syz ipf->fl_plen + ipf->fl_hlen); 1340ab25eeb5Syz else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) 1341ab25eeb5Syz dumphex(log, opts, (char *)ip + ipf->fl_hlen, 1342ab25eeb5Syz ipf->fl_plen); 1343ab25eeb5Syz } 13447c478bd9Sstevel@tonic-gate } 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate 13477c478bd9Sstevel@tonic-gate static void usage(prog) 13487c478bd9Sstevel@tonic-gate char *prog; 13497c478bd9Sstevel@tonic-gate { 135094bdecd9SRob Gulewich fprintf(stderr, "%s: [-abDFhnpstvxX] %s %s %s %s %s %s %s\n", 135194bdecd9SRob Gulewich prog, "[-G|-z zonename]", "[-N device]", 135294bdecd9SRob Gulewich "[ [-o [NSI]] [-O [NSI]]", "[-P pidfile]", "[-S device]", 135394bdecd9SRob Gulewich "[-f device]", "filename"); 13547c478bd9Sstevel@tonic-gate exit(1); 13557c478bd9Sstevel@tonic-gate } 13567c478bd9Sstevel@tonic-gate 13577c478bd9Sstevel@tonic-gate 13587c478bd9Sstevel@tonic-gate static void write_pid(file) 13597c478bd9Sstevel@tonic-gate char *file; 13607c478bd9Sstevel@tonic-gate { 13617c478bd9Sstevel@tonic-gate FILE *fp = NULL; 13627c478bd9Sstevel@tonic-gate int fd; 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) { 13657c478bd9Sstevel@tonic-gate fp = fdopen(fd, "w"); 13667c478bd9Sstevel@tonic-gate if (fp == NULL) { 13677c478bd9Sstevel@tonic-gate close(fd); 13687c478bd9Sstevel@tonic-gate fprintf(stderr, 13697c478bd9Sstevel@tonic-gate "unable to open/create pid file: %s\n", file); 13707c478bd9Sstevel@tonic-gate return; 13717c478bd9Sstevel@tonic-gate } 13727c478bd9Sstevel@tonic-gate fprintf(fp, "%d", getpid()); 13737c478bd9Sstevel@tonic-gate fclose(fp); 13747c478bd9Sstevel@tonic-gate } 13757c478bd9Sstevel@tonic-gate } 13767c478bd9Sstevel@tonic-gate 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate static void flushlogs(file, log) 13797c478bd9Sstevel@tonic-gate char *file; 13807c478bd9Sstevel@tonic-gate FILE *log; 13817c478bd9Sstevel@tonic-gate { 13827c478bd9Sstevel@tonic-gate int fd, flushed = 0; 13837c478bd9Sstevel@tonic-gate 13847c478bd9Sstevel@tonic-gate if ((fd = open(file, O_RDWR)) == -1) { 13857c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: open: %s\n", 13867c478bd9Sstevel@tonic-gate file, STRERROR(errno)); 13877c478bd9Sstevel@tonic-gate exit(1); 13887c478bd9Sstevel@tonic-gate } 13897c478bd9Sstevel@tonic-gate 139094bdecd9SRob Gulewich if (setzone(fd) != 0) { 139194bdecd9SRob Gulewich close(fd); 139294bdecd9SRob Gulewich exit(1); 139394bdecd9SRob Gulewich } 139494bdecd9SRob Gulewich 13957c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { 13967c478bd9Sstevel@tonic-gate printf("%d bytes flushed from log buffer\n", 13977c478bd9Sstevel@tonic-gate flushed); 13987c478bd9Sstevel@tonic-gate fflush(stdout); 13997c478bd9Sstevel@tonic-gate } else 14007c478bd9Sstevel@tonic-gate perror("SIOCIPFFB"); 14017c478bd9Sstevel@tonic-gate (void) close(fd); 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate if (flushed) { 14047c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 14057c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%d bytes flushed from log\n", 14067c478bd9Sstevel@tonic-gate flushed); 14077c478bd9Sstevel@tonic-gate else if (log != stdout) 14087c478bd9Sstevel@tonic-gate fprintf(log, "%d bytes flushed from log\n", flushed); 14097c478bd9Sstevel@tonic-gate } 14107c478bd9Sstevel@tonic-gate } 14117c478bd9Sstevel@tonic-gate 14127c478bd9Sstevel@tonic-gate 14137c478bd9Sstevel@tonic-gate static void logopts(turnon, options) 14147c478bd9Sstevel@tonic-gate int turnon; 14157c478bd9Sstevel@tonic-gate char *options; 14167c478bd9Sstevel@tonic-gate { 14177c478bd9Sstevel@tonic-gate int flags = 0; 14187c478bd9Sstevel@tonic-gate char *s; 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate for (s = options; *s; s++) 14217c478bd9Sstevel@tonic-gate { 14227c478bd9Sstevel@tonic-gate switch (*s) 14237c478bd9Sstevel@tonic-gate { 14247c478bd9Sstevel@tonic-gate case 'N' : 14257c478bd9Sstevel@tonic-gate flags |= OPT_NAT; 14267c478bd9Sstevel@tonic-gate break; 14277c478bd9Sstevel@tonic-gate case 'S' : 14287c478bd9Sstevel@tonic-gate flags |= OPT_STATE; 14297c478bd9Sstevel@tonic-gate break; 14307c478bd9Sstevel@tonic-gate case 'I' : 14317c478bd9Sstevel@tonic-gate flags |= OPT_FILTER; 14327c478bd9Sstevel@tonic-gate break; 14337c478bd9Sstevel@tonic-gate default : 14347c478bd9Sstevel@tonic-gate fprintf(stderr, "Unknown log option %c\n", *s); 14357c478bd9Sstevel@tonic-gate exit(1); 14367c478bd9Sstevel@tonic-gate } 14377c478bd9Sstevel@tonic-gate } 14387c478bd9Sstevel@tonic-gate 14397c478bd9Sstevel@tonic-gate if (turnon) 14407c478bd9Sstevel@tonic-gate opts |= flags; 14417c478bd9Sstevel@tonic-gate else 14427c478bd9Sstevel@tonic-gate opts &= ~(flags); 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate 14467c478bd9Sstevel@tonic-gate int main(argc, argv) 14477c478bd9Sstevel@tonic-gate int argc; 14487c478bd9Sstevel@tonic-gate char *argv[]; 14497c478bd9Sstevel@tonic-gate { 14507c478bd9Sstevel@tonic-gate struct stat sb; 14517c478bd9Sstevel@tonic-gate FILE *log = stdout; 1452ab25eeb5Syz FILE *fp; 14537c478bd9Sstevel@tonic-gate int fd[3], doread, n, i; 14547c478bd9Sstevel@tonic-gate int tr, nr, regular[3], c; 14557c478bd9Sstevel@tonic-gate int fdt[3], devices = 0, make_daemon = 0; 14567c478bd9Sstevel@tonic-gate char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s; 14577c478bd9Sstevel@tonic-gate extern int optind; 14587c478bd9Sstevel@tonic-gate extern char *optarg; 145994bdecd9SRob Gulewich const char *optstr = "?abB:C:Df:G:FhnN:o:O:pP:sS:tvxXz:"; 14607c478bd9Sstevel@tonic-gate 14617c478bd9Sstevel@tonic-gate fd[0] = fd[1] = fd[2] = -1; 14627c478bd9Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 14637c478bd9Sstevel@tonic-gate iplfile[0] = IPL_NAME; 14647c478bd9Sstevel@tonic-gate iplfile[1] = IPNAT_NAME; 14657c478bd9Sstevel@tonic-gate iplfile[2] = IPSTATE_NAME; 14667c478bd9Sstevel@tonic-gate 146794bdecd9SRob Gulewich /* 146894bdecd9SRob Gulewich * We need to set the zone name before calling openlog in 146994bdecd9SRob Gulewich * the switch statement below 147094bdecd9SRob Gulewich */ 147194bdecd9SRob Gulewich getzoneopt(argc, argv, optstr); 147294bdecd9SRob Gulewich 147394bdecd9SRob Gulewich while ((c = getopt(argc, argv, optstr)) != -1) 14747c478bd9Sstevel@tonic-gate switch (c) 14757c478bd9Sstevel@tonic-gate { 14767c478bd9Sstevel@tonic-gate case 'a' : 14777c478bd9Sstevel@tonic-gate opts |= OPT_LOGALL; 14787c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 14797c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 14807c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 14817c478bd9Sstevel@tonic-gate break; 14827c478bd9Sstevel@tonic-gate case 'b' : 14837c478bd9Sstevel@tonic-gate opts |= OPT_LOGBODY; 14847c478bd9Sstevel@tonic-gate break; 14857c478bd9Sstevel@tonic-gate case 'B' : 14867c478bd9Sstevel@tonic-gate binarylogfile = optarg; 14877c478bd9Sstevel@tonic-gate binarylog = fopen(optarg, "a"); 14887c478bd9Sstevel@tonic-gate break; 14897c478bd9Sstevel@tonic-gate case 'C' : 14907c478bd9Sstevel@tonic-gate conf_file = optarg; 14917c478bd9Sstevel@tonic-gate break; 14927c478bd9Sstevel@tonic-gate case 'D' : 14937c478bd9Sstevel@tonic-gate make_daemon = 1; 14947c478bd9Sstevel@tonic-gate break; 14957c478bd9Sstevel@tonic-gate case 'f' : case 'I' : 14967c478bd9Sstevel@tonic-gate opts |= OPT_FILTER; 14977c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 14987c478bd9Sstevel@tonic-gate iplfile[0] = optarg; 14997c478bd9Sstevel@tonic-gate break; 15007c478bd9Sstevel@tonic-gate case 'F' : 15017c478bd9Sstevel@tonic-gate flushlogs(iplfile[0], log); 15027c478bd9Sstevel@tonic-gate flushlogs(iplfile[1], log); 15037c478bd9Sstevel@tonic-gate flushlogs(iplfile[2], log); 15047c478bd9Sstevel@tonic-gate break; 150594bdecd9SRob Gulewich case 'G' : 150694bdecd9SRob Gulewich /* Already handled by getzoneopt() above */ 150794bdecd9SRob Gulewich break; 15087c478bd9Sstevel@tonic-gate case 'n' : 15097c478bd9Sstevel@tonic-gate opts |= OPT_RESOLVE; 15107c478bd9Sstevel@tonic-gate break; 15117c478bd9Sstevel@tonic-gate case 'N' : 15127c478bd9Sstevel@tonic-gate opts |= OPT_NAT; 15137c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 15147c478bd9Sstevel@tonic-gate iplfile[1] = optarg; 15157c478bd9Sstevel@tonic-gate break; 15167c478bd9Sstevel@tonic-gate case 'o' : case 'O' : 15177c478bd9Sstevel@tonic-gate logopts(c == 'o', optarg); 15187c478bd9Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 15197c478bd9Sstevel@tonic-gate if (opts & OPT_FILTER) 15207c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 15217c478bd9Sstevel@tonic-gate if (opts & OPT_NAT) 15227c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 15237c478bd9Sstevel@tonic-gate if (opts & OPT_STATE) 15247c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 15257c478bd9Sstevel@tonic-gate break; 15267c478bd9Sstevel@tonic-gate case 'p' : 15277c478bd9Sstevel@tonic-gate opts |= OPT_PORTNUM; 15287c478bd9Sstevel@tonic-gate break; 15297c478bd9Sstevel@tonic-gate case 'P' : 15307c478bd9Sstevel@tonic-gate pidfile = optarg; 15317c478bd9Sstevel@tonic-gate break; 15327c478bd9Sstevel@tonic-gate case 's' : 15337c478bd9Sstevel@tonic-gate s = strrchr(argv[0], '/'); 15347c478bd9Sstevel@tonic-gate if (s == NULL) 15357c478bd9Sstevel@tonic-gate s = argv[0]; 15367c478bd9Sstevel@tonic-gate else 15377c478bd9Sstevel@tonic-gate s++; 15387c478bd9Sstevel@tonic-gate openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); 15397c478bd9Sstevel@tonic-gate s = NULL; 15407c478bd9Sstevel@tonic-gate opts |= OPT_SYSLOG; 15417c478bd9Sstevel@tonic-gate log = NULL; 15427c478bd9Sstevel@tonic-gate break; 15437c478bd9Sstevel@tonic-gate case 'S' : 15447c478bd9Sstevel@tonic-gate opts |= OPT_STATE; 15457c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 15467c478bd9Sstevel@tonic-gate iplfile[2] = optarg; 15477c478bd9Sstevel@tonic-gate break; 15487c478bd9Sstevel@tonic-gate case 't' : 15497c478bd9Sstevel@tonic-gate opts |= OPT_TAIL; 15507c478bd9Sstevel@tonic-gate break; 15517c478bd9Sstevel@tonic-gate case 'v' : 15527c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 15537c478bd9Sstevel@tonic-gate break; 15547c478bd9Sstevel@tonic-gate case 'x' : 15557c478bd9Sstevel@tonic-gate opts |= OPT_HEXBODY; 15567c478bd9Sstevel@tonic-gate break; 15577c478bd9Sstevel@tonic-gate case 'X' : 15587c478bd9Sstevel@tonic-gate opts |= OPT_HEXHDR; 15597c478bd9Sstevel@tonic-gate break; 156094bdecd9SRob Gulewich case 'z' : 156194bdecd9SRob Gulewich /* Already handled by getzoneopt() above */ 156294bdecd9SRob Gulewich break; 15637c478bd9Sstevel@tonic-gate default : 15647c478bd9Sstevel@tonic-gate case 'h' : 15657c478bd9Sstevel@tonic-gate case '?' : 15667c478bd9Sstevel@tonic-gate usage(argv[0]); 15677c478bd9Sstevel@tonic-gate } 15687c478bd9Sstevel@tonic-gate 15697c478bd9Sstevel@tonic-gate init_tabs(); 15707c478bd9Sstevel@tonic-gate if (conf_file) 15717c478bd9Sstevel@tonic-gate if (load_config(conf_file) == -1) 15727c478bd9Sstevel@tonic-gate exit(1); 15737c478bd9Sstevel@tonic-gate 15747c478bd9Sstevel@tonic-gate /* 15757c478bd9Sstevel@tonic-gate * Default action is to only open the filter log file. 15767c478bd9Sstevel@tonic-gate */ 15777c478bd9Sstevel@tonic-gate if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) 15787c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 15797c478bd9Sstevel@tonic-gate 15807c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 15817c478bd9Sstevel@tonic-gate if (fdt[i] == -1) 15827c478bd9Sstevel@tonic-gate continue; 15837c478bd9Sstevel@tonic-gate if (!strcmp(iplfile[i], "-")) 15847c478bd9Sstevel@tonic-gate fd[i] = 0; 15857c478bd9Sstevel@tonic-gate else { 15867c478bd9Sstevel@tonic-gate if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { 15877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 15887c478bd9Sstevel@tonic-gate "%s: open: %s\n", iplfile[i], 15897c478bd9Sstevel@tonic-gate STRERROR(errno)); 15907c478bd9Sstevel@tonic-gate exit(1); 15917c478bd9Sstevel@tonic-gate /* NOTREACHED */ 15927c478bd9Sstevel@tonic-gate } 15937c478bd9Sstevel@tonic-gate if (fstat(fd[i], &sb) == -1) { 15947c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%d: fstat: %s\n", 15957c478bd9Sstevel@tonic-gate fd[i], STRERROR(errno)); 15967c478bd9Sstevel@tonic-gate exit(1); 15977c478bd9Sstevel@tonic-gate /* NOTREACHED */ 15987c478bd9Sstevel@tonic-gate } 159994bdecd9SRob Gulewich 160094bdecd9SRob Gulewich if (setzone(fd[i]) != 0) { 160194bdecd9SRob Gulewich close(fd[i]); 160294bdecd9SRob Gulewich exit(1); 160394bdecd9SRob Gulewich } 160494bdecd9SRob Gulewich 16057c478bd9Sstevel@tonic-gate if (!(regular[i] = !S_ISCHR(sb.st_mode))) 16067c478bd9Sstevel@tonic-gate devices++; 16077c478bd9Sstevel@tonic-gate } 16087c478bd9Sstevel@tonic-gate } 16097c478bd9Sstevel@tonic-gate 16107c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 16117c478bd9Sstevel@tonic-gate logfile = argv[optind]; 16127c478bd9Sstevel@tonic-gate log = logfile ? fopen(logfile, "a") : stdout; 16137c478bd9Sstevel@tonic-gate if (log == NULL) { 16147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: fopen: %s\n", 16157c478bd9Sstevel@tonic-gate argv[optind], STRERROR(errno)); 16167c478bd9Sstevel@tonic-gate exit(1); 16177c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate setvbuf(log, NULL, _IONBF, 0); 16207c478bd9Sstevel@tonic-gate } else 16217c478bd9Sstevel@tonic-gate log = NULL; 16227c478bd9Sstevel@tonic-gate 16237c478bd9Sstevel@tonic-gate if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { 16247c478bd9Sstevel@tonic-gate #if BSD >= 199306 16257c478bd9Sstevel@tonic-gate daemon(0, !(opts & OPT_SYSLOG)); 16267c478bd9Sstevel@tonic-gate #else 16277c478bd9Sstevel@tonic-gate int pid; 16287c478bd9Sstevel@tonic-gate if ((pid = fork()) > 0) 16297c478bd9Sstevel@tonic-gate exit(0); 16307c478bd9Sstevel@tonic-gate if (pid < 0) { 16317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: fork() failed: %s\n", 16327c478bd9Sstevel@tonic-gate argv[0], STRERROR(errno)); 16337c478bd9Sstevel@tonic-gate exit(1); 16347c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16357c478bd9Sstevel@tonic-gate } 16367c478bd9Sstevel@tonic-gate setsid(); 16377c478bd9Sstevel@tonic-gate if ((opts & OPT_SYSLOG)) 16387c478bd9Sstevel@tonic-gate close(2); 16397c478bd9Sstevel@tonic-gate #endif /* !BSD */ 16407c478bd9Sstevel@tonic-gate close(0); 16417c478bd9Sstevel@tonic-gate close(1); 16427c478bd9Sstevel@tonic-gate } 16437c478bd9Sstevel@tonic-gate write_pid(pidfile); 16447c478bd9Sstevel@tonic-gate 16457c478bd9Sstevel@tonic-gate signal(SIGHUP, handlehup); 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate for (doread = 1; doread; ) { 16487c478bd9Sstevel@tonic-gate nr = 0; 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 16517c478bd9Sstevel@tonic-gate tr = 0; 16527c478bd9Sstevel@tonic-gate if (fdt[i] == -1) 16537c478bd9Sstevel@tonic-gate continue; 16547c478bd9Sstevel@tonic-gate if (!regular[i]) { 16557c478bd9Sstevel@tonic-gate if (ioctl(fd[i], FIONREAD, &tr) == -1) { 16567c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 16577c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, 16587c478bd9Sstevel@tonic-gate "ioctl(FIONREAD): %m"); 16597c478bd9Sstevel@tonic-gate else 16607c478bd9Sstevel@tonic-gate perror("ioctl(FIONREAD)"); 16617c478bd9Sstevel@tonic-gate exit(1); 16627c478bd9Sstevel@tonic-gate /* NOTREACHED */ 16637c478bd9Sstevel@tonic-gate } 16647c478bd9Sstevel@tonic-gate } else { 16657c478bd9Sstevel@tonic-gate tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); 16667c478bd9Sstevel@tonic-gate if (!tr && !(opts & OPT_TAIL)) 16677c478bd9Sstevel@tonic-gate doread = 0; 16687c478bd9Sstevel@tonic-gate } 16697c478bd9Sstevel@tonic-gate if (!tr) 16707c478bd9Sstevel@tonic-gate continue; 16717c478bd9Sstevel@tonic-gate nr += tr; 16727c478bd9Sstevel@tonic-gate 16737c478bd9Sstevel@tonic-gate tr = read_log(fd[i], &n, buf, sizeof(buf)); 16747c478bd9Sstevel@tonic-gate if (donehup) { 1675ab25eeb5Syz if (logfile && (fp = fopen(logfile, "a"))) { 16767c478bd9Sstevel@tonic-gate fclose(log); 1677ab25eeb5Syz log = fp; 16787c478bd9Sstevel@tonic-gate } 1679ab25eeb5Syz if (binarylogfile && (fp = fopen(binarylogfile, "a"))) { 16807c478bd9Sstevel@tonic-gate fclose(binarylog); 1681ab25eeb5Syz binarylog = fp; 16827c478bd9Sstevel@tonic-gate } 1683ab25eeb5Syz init_tabs(); 1684ab25eeb5Syz if (conf_file != NULL) 1685ab25eeb5Syz load_config(conf_file); 1686ab25eeb5Syz donehup = 0; 16877c478bd9Sstevel@tonic-gate } 16887c478bd9Sstevel@tonic-gate 16897c478bd9Sstevel@tonic-gate switch (tr) 16907c478bd9Sstevel@tonic-gate { 16917c478bd9Sstevel@tonic-gate case -1 : 16927c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 16937c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "read: %m\n"); 16947c478bd9Sstevel@tonic-gate else 16957c478bd9Sstevel@tonic-gate perror("read"); 16967c478bd9Sstevel@tonic-gate doread = 0; 16977c478bd9Sstevel@tonic-gate break; 16987c478bd9Sstevel@tonic-gate case 1 : 16997c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 17007c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "aborting logging\n"); 17017c478bd9Sstevel@tonic-gate else 17027c478bd9Sstevel@tonic-gate fprintf(log, "aborting logging\n"); 17037c478bd9Sstevel@tonic-gate doread = 0; 17047c478bd9Sstevel@tonic-gate break; 17057c478bd9Sstevel@tonic-gate case 2 : 17067c478bd9Sstevel@tonic-gate break; 17077c478bd9Sstevel@tonic-gate case 0 : 17087c478bd9Sstevel@tonic-gate if (n > 0) { 17097c478bd9Sstevel@tonic-gate print_log(fdt[i], log, buf, n); 17107c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) 17117c478bd9Sstevel@tonic-gate fflush(log); 17127c478bd9Sstevel@tonic-gate } 17137c478bd9Sstevel@tonic-gate break; 17147c478bd9Sstevel@tonic-gate } 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate if (!nr && ((opts & OPT_TAIL) || devices)) 17177c478bd9Sstevel@tonic-gate sleep(1); 17187c478bd9Sstevel@tonic-gate } 17197c478bd9Sstevel@tonic-gate return(0); 17207c478bd9Sstevel@tonic-gate /* NOTREACHED */ 17217c478bd9Sstevel@tonic-gate } 1722