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