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