1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 5*7c478bd9Sstevel@tonic-gate * 6*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 7*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 8*7c478bd9Sstevel@tonic-gate */ 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS 13*7c478bd9Sstevel@tonic-gate #define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun) 14*7c478bd9Sstevel@tonic-gate #endif 15*7c478bd9Sstevel@tonic-gate 16*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 17*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 18*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 19*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 20*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 21*7c478bd9Sstevel@tonic-gate #define _KERNEL 22*7c478bd9Sstevel@tonic-gate #include <sys/uio.h> 23*7c478bd9Sstevel@tonic-gate #undef _KERNEL 24*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 25*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #include <stdio.h> 28*7c478bd9Sstevel@tonic-gate #include <unistd.h> 29*7c478bd9Sstevel@tonic-gate #include <string.h> 30*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 31*7c478bd9Sstevel@tonic-gate #include <errno.h> 32*7c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__) 33*7c478bd9Sstevel@tonic-gate # if (__FreeBSD_version >= 300000) 34*7c478bd9Sstevel@tonic-gate # include <sys/dirent.h> 35*7c478bd9Sstevel@tonic-gate # else 36*7c478bd9Sstevel@tonic-gate # include <sys/dir.h> 37*7c478bd9Sstevel@tonic-gate # endif 38*7c478bd9Sstevel@tonic-gate #else 39*7c478bd9Sstevel@tonic-gate # include <sys/filio.h> 40*7c478bd9Sstevel@tonic-gate # include <sys/byteorder.h> 41*7c478bd9Sstevel@tonic-gate #endif 42*7c478bd9Sstevel@tonic-gate #if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__)) 43*7c478bd9Sstevel@tonic-gate # include <strings.h> 44*7c478bd9Sstevel@tonic-gate #endif 45*7c478bd9Sstevel@tonic-gate #include <signal.h> 46*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 47*7c478bd9Sstevel@tonic-gate #include <stddef.h> 48*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 49*7c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 50*7c478bd9Sstevel@tonic-gate #include <net/if.h> 51*7c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 52*7c478bd9Sstevel@tonic-gate #if !defined(__hpux) 53*7c478bd9Sstevel@tonic-gate # include <netinet/tcp_fsm.h> 54*7c478bd9Sstevel@tonic-gate #endif 55*7c478bd9Sstevel@tonic-gate #include <netdb.h> 56*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 57*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 58*7c478bd9Sstevel@tonic-gate #ifdef __hpux 59*7c478bd9Sstevel@tonic-gate # undef NOERROR 60*7c478bd9Sstevel@tonic-gate #endif 61*7c478bd9Sstevel@tonic-gate #include <resolv.h> 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate #include <sys/protosw.h> 64*7c478bd9Sstevel@tonic-gate #include <netinet/ip_var.h> 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate #include <netinet/tcp.h> 67*7c478bd9Sstevel@tonic-gate #include <netinet/ip_icmp.h> 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #include <ctype.h> 70*7c478bd9Sstevel@tonic-gate #include <syslog.h> 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h> 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate #if SOLARIS2 >= 10 75*7c478bd9Sstevel@tonic-gate #include "ip_compat.h" 76*7c478bd9Sstevel@tonic-gate #include "ip_fil.h" 77*7c478bd9Sstevel@tonic-gate #include "ip_nat.h" 78*7c478bd9Sstevel@tonic-gate #include "ip_state.h" 79*7c478bd9Sstevel@tonic-gate #include "ip_proxy.h" 80*7c478bd9Sstevel@tonic-gate #else 81*7c478bd9Sstevel@tonic-gate #include "netinet/ip_compat.h" 82*7c478bd9Sstevel@tonic-gate #include "netinet/ip_fil.h" 83*7c478bd9Sstevel@tonic-gate #include "netinet/ip_nat.h" 84*7c478bd9Sstevel@tonic-gate #include "netinet/ip_state.h" 85*7c478bd9Sstevel@tonic-gate #include "netinet/ip_proxy.h" 86*7c478bd9Sstevel@tonic-gate #endif 87*7c478bd9Sstevel@tonic-gate #include "ipmon.h" 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate #if !defined(lint) 90*7c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; 91*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.22 2003/06/14 02:56:57 darrenr Exp $"; 92*7c478bd9Sstevel@tonic-gate #endif 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate #if defined(sun) && !defined(SOLARIS2) 96*7c478bd9Sstevel@tonic-gate #define STRERROR(x) sys_errlist[x] 97*7c478bd9Sstevel@tonic-gate extern char *sys_errlist[]; 98*7c478bd9Sstevel@tonic-gate #else 99*7c478bd9Sstevel@tonic-gate #define STRERROR(x) strerror(x) 100*7c478bd9Sstevel@tonic-gate #endif 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate struct flags { 104*7c478bd9Sstevel@tonic-gate int value; 105*7c478bd9Sstevel@tonic-gate char flag; 106*7c478bd9Sstevel@tonic-gate }; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate typedef struct icmp_subtype { 110*7c478bd9Sstevel@tonic-gate int ist_val; 111*7c478bd9Sstevel@tonic-gate char *ist_name; 112*7c478bd9Sstevel@tonic-gate } icmp_subtype_t; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate typedef struct icmp_type { 115*7c478bd9Sstevel@tonic-gate int it_val; 116*7c478bd9Sstevel@tonic-gate struct icmp_subtype *it_subtable; 117*7c478bd9Sstevel@tonic-gate size_t it_stsize; 118*7c478bd9Sstevel@tonic-gate char *it_name; 119*7c478bd9Sstevel@tonic-gate } icmp_type_t; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate #define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate struct flags tcpfl[] = { 126*7c478bd9Sstevel@tonic-gate { TH_ACK, 'A' }, 127*7c478bd9Sstevel@tonic-gate { TH_RST, 'R' }, 128*7c478bd9Sstevel@tonic-gate { TH_SYN, 'S' }, 129*7c478bd9Sstevel@tonic-gate { TH_FIN, 'F' }, 130*7c478bd9Sstevel@tonic-gate { TH_URG, 'U' }, 131*7c478bd9Sstevel@tonic-gate { TH_PUSH,'P' }, 132*7c478bd9Sstevel@tonic-gate { TH_ECN, 'E' }, 133*7c478bd9Sstevel@tonic-gate { TH_CWR, 'C' }, 134*7c478bd9Sstevel@tonic-gate { 0, '\0' } 135*7c478bd9Sstevel@tonic-gate }; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate #ifdef MENTAT 138*7c478bd9Sstevel@tonic-gate static char *pidfile = "/etc/ipf/ipmon.pid"; 139*7c478bd9Sstevel@tonic-gate #else 140*7c478bd9Sstevel@tonic-gate # if BSD >= 199306 141*7c478bd9Sstevel@tonic-gate static char *pidfile = "/var/run/ipmon.pid"; 142*7c478bd9Sstevel@tonic-gate # else 143*7c478bd9Sstevel@tonic-gate static char *pidfile = "/etc/ipmon.pid"; 144*7c478bd9Sstevel@tonic-gate # endif 145*7c478bd9Sstevel@tonic-gate #endif 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate static char line[2048]; 148*7c478bd9Sstevel@tonic-gate static int opts = 0; 149*7c478bd9Sstevel@tonic-gate static FILE *newlog = NULL; 150*7c478bd9Sstevel@tonic-gate static char *logfile = NULL; 151*7c478bd9Sstevel@tonic-gate static FILE *binarylog = NULL; 152*7c478bd9Sstevel@tonic-gate static FILE *newbinarylog = NULL; 153*7c478bd9Sstevel@tonic-gate static char *binarylogfile = NULL; 154*7c478bd9Sstevel@tonic-gate static int donehup = 0; 155*7c478bd9Sstevel@tonic-gate static void usage __P((char *)); 156*7c478bd9Sstevel@tonic-gate static void handlehup __P((int)); 157*7c478bd9Sstevel@tonic-gate static void flushlogs __P((char *, FILE *)); 158*7c478bd9Sstevel@tonic-gate static void print_log __P((int, FILE *, char *, int)); 159*7c478bd9Sstevel@tonic-gate static void print_ipflog __P((FILE *, char *, int)); 160*7c478bd9Sstevel@tonic-gate static void print_natlog __P((FILE *, char *, int)); 161*7c478bd9Sstevel@tonic-gate static void print_statelog __P((FILE *, char *, int)); 162*7c478bd9Sstevel@tonic-gate static int read_log __P((int, int *, char *, int)); 163*7c478bd9Sstevel@tonic-gate static void write_pid __P((char *)); 164*7c478bd9Sstevel@tonic-gate static char *icmpname __P((u_int, u_int)); 165*7c478bd9Sstevel@tonic-gate static char *icmpname6 __P((u_int, u_int)); 166*7c478bd9Sstevel@tonic-gate static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t)); 167*7c478bd9Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t)); 168*7c478bd9Sstevel@tonic-gate #ifdef __hpux 169*7c478bd9Sstevel@tonic-gate static struct tm *get_tm __P((u_32_t)); 170*7c478bd9Sstevel@tonic-gate #else 171*7c478bd9Sstevel@tonic-gate static struct tm *get_tm __P((time_t)); 172*7c478bd9Sstevel@tonic-gate #endif 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate char *hostname __P((int, int, u_32_t *)); 175*7c478bd9Sstevel@tonic-gate char *portname __P((int, char *, u_int)); 176*7c478bd9Sstevel@tonic-gate int main __P((int, char *[])); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate static void logopts __P((int, char *)); 179*7c478bd9Sstevel@tonic-gate static void init_tabs __P((void)); 180*7c478bd9Sstevel@tonic-gate static char *getproto __P((u_int)); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate static char **protocols = NULL; 183*7c478bd9Sstevel@tonic-gate static char **udp_ports = NULL; 184*7c478bd9Sstevel@tonic-gate static char **tcp_ports = NULL; 185*7c478bd9Sstevel@tonic-gate static char *conf_file = NULL; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate #define OPT_SYSLOG 0x001 189*7c478bd9Sstevel@tonic-gate #define OPT_RESOLVE 0x002 190*7c478bd9Sstevel@tonic-gate #define OPT_HEXBODY 0x004 191*7c478bd9Sstevel@tonic-gate #define OPT_VERBOSE 0x008 192*7c478bd9Sstevel@tonic-gate #define OPT_HEXHDR 0x010 193*7c478bd9Sstevel@tonic-gate #define OPT_TAIL 0x020 194*7c478bd9Sstevel@tonic-gate #define OPT_NAT 0x080 195*7c478bd9Sstevel@tonic-gate #define OPT_STATE 0x100 196*7c478bd9Sstevel@tonic-gate #define OPT_FILTER 0x200 197*7c478bd9Sstevel@tonic-gate #define OPT_PORTNUM 0x400 198*7c478bd9Sstevel@tonic-gate #define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) 199*7c478bd9Sstevel@tonic-gate #define OPT_LOGBODY 0x800 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate #define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate #ifndef LOGFAC 204*7c478bd9Sstevel@tonic-gate #define LOGFAC LOG_LOCAL0 205*7c478bd9Sstevel@tonic-gate #endif 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpunreachnames[] = { 209*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET, "net" }, 210*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_HOST, "host" }, 211*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_PROTOCOL, "protocol" }, 212*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_PORT, "port" }, 213*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NEEDFRAG, "needfrag" }, 214*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_SRCFAIL, "srcfail" }, 215*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, 216*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, 217*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET, "isolated" }, 218*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, 219*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, 220*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_TOSNET, "tosnet" }, 221*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_TOSHOST, "toshost" }, 222*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, 223*7c478bd9Sstevel@tonic-gate { -2, NULL } 224*7c478bd9Sstevel@tonic-gate }; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate static icmp_subtype_t redirectnames[] = { 227*7c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_NET, "net" }, 228*7c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_HOST, "host" }, 229*7c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_TOSNET, "tosnet" }, 230*7c478bd9Sstevel@tonic-gate { ICMP_REDIRECT_TOSHOST, "toshost" }, 231*7c478bd9Sstevel@tonic-gate { -2, NULL } 232*7c478bd9Sstevel@tonic-gate }; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate static icmp_subtype_t timxceednames[] = { 235*7c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED_INTRANS, "transit" }, 236*7c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED_REASS, "reassem" }, 237*7c478bd9Sstevel@tonic-gate { -2, NULL } 238*7c478bd9Sstevel@tonic-gate }; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate static icmp_subtype_t paramnames[] = { 241*7c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, 242*7c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, 243*7c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB_LENGTH, "length" }, 244*7c478bd9Sstevel@tonic-gate { -2, NULL } 245*7c478bd9Sstevel@tonic-gate }; 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate static icmp_type_t icmptypes[] = { 248*7c478bd9Sstevel@tonic-gate { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, 249*7c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 250*7c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 251*7c478bd9Sstevel@tonic-gate { ICMP_UNREACH, icmpunreachnames, 252*7c478bd9Sstevel@tonic-gate IST_SZ(icmpunreachnames),"unreach" }, 253*7c478bd9Sstevel@tonic-gate { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, 254*7c478bd9Sstevel@tonic-gate { ICMP_REDIRECT, redirectnames, 255*7c478bd9Sstevel@tonic-gate IST_SZ(redirectnames), "redirect" }, 256*7c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 257*7c478bd9Sstevel@tonic-gate { -1, NULL, 0, NULL }, 258*7c478bd9Sstevel@tonic-gate { ICMP_ECHO, NULL, 0, "echo" }, 259*7c478bd9Sstevel@tonic-gate { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, 260*7c478bd9Sstevel@tonic-gate { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, 261*7c478bd9Sstevel@tonic-gate { ICMP_TIMXCEED, timxceednames, 262*7c478bd9Sstevel@tonic-gate IST_SZ(timxceednames), "timxceed" }, 263*7c478bd9Sstevel@tonic-gate { ICMP_PARAMPROB, paramnames, 264*7c478bd9Sstevel@tonic-gate IST_SZ(paramnames), "paramprob" }, 265*7c478bd9Sstevel@tonic-gate { ICMP_TSTAMP, NULL, 0, "timestamp" }, 266*7c478bd9Sstevel@tonic-gate { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, 267*7c478bd9Sstevel@tonic-gate { ICMP_IREQ, NULL, 0, "inforeq" }, 268*7c478bd9Sstevel@tonic-gate { ICMP_IREQREPLY, NULL, 0, "inforeply" }, 269*7c478bd9Sstevel@tonic-gate { ICMP_MASKREQ, NULL, 0, "maskreq" }, 270*7c478bd9Sstevel@tonic-gate { ICMP_MASKREPLY, NULL, 0, "maskreply" }, 271*7c478bd9Sstevel@tonic-gate { -2, NULL, 0, NULL } 272*7c478bd9Sstevel@tonic-gate }; 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpredirect6[] = { 275*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, 276*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADMIN, "admin" }, 277*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, 278*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADDR, "address" }, 279*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOPORT, "noport" }, 280*7c478bd9Sstevel@tonic-gate { -2, NULL } 281*7c478bd9Sstevel@tonic-gate }; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmptimexceed6[] = { 284*7c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, 285*7c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, 286*7c478bd9Sstevel@tonic-gate { -2, NULL } 287*7c478bd9Sstevel@tonic-gate }; 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpparamprob6[] = { 290*7c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_HEADER, "header" }, 291*7c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, 292*7c478bd9Sstevel@tonic-gate { ICMP6_PARAMPROB_OPTION, "option" }, 293*7c478bd9Sstevel@tonic-gate { -2, NULL } 294*7c478bd9Sstevel@tonic-gate }; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpquerysubject6[] = { 297*7c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV6, "ipv6" }, 298*7c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_FQDN, "fqdn" }, 299*7c478bd9Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV4, "ipv4" }, 300*7c478bd9Sstevel@tonic-gate { -2, NULL }, 301*7c478bd9Sstevel@tonic-gate }; 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmpnodeinfo6[] = { 304*7c478bd9Sstevel@tonic-gate { ICMP6_NI_SUCCESS, "success" }, 305*7c478bd9Sstevel@tonic-gate { ICMP6_NI_REFUSED, "refused" }, 306*7c478bd9Sstevel@tonic-gate { ICMP6_NI_UNKNOWN, "unknown" }, 307*7c478bd9Sstevel@tonic-gate { -2, NULL } 308*7c478bd9Sstevel@tonic-gate }; 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate static icmp_subtype_t icmprenumber6[] = { 311*7c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, 312*7c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, 313*7c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, 314*7c478bd9Sstevel@tonic-gate { -2, NULL } 315*7c478bd9Sstevel@tonic-gate }; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate static icmp_type_t icmptypes6[] = { 318*7c478bd9Sstevel@tonic-gate { 0, NULL, 0, NULL }, 319*7c478bd9Sstevel@tonic-gate { ICMP6_DST_UNREACH, icmpredirect6, 320*7c478bd9Sstevel@tonic-gate IST_SZ(icmpredirect6), "unreach" }, 321*7c478bd9Sstevel@tonic-gate { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, 322*7c478bd9Sstevel@tonic-gate { ICMP6_TIME_EXCEEDED, icmptimexceed6, 323*7c478bd9Sstevel@tonic-gate IST_SZ(icmptimexceed6), "timxceed" }, 324*7c478bd9Sstevel@tonic-gate { ICMP6_PARAM_PROB, icmpparamprob6, 325*7c478bd9Sstevel@tonic-gate IST_SZ(icmpparamprob6), "paramprob" }, 326*7c478bd9Sstevel@tonic-gate { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, 327*7c478bd9Sstevel@tonic-gate { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, 328*7c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, 329*7c478bd9Sstevel@tonic-gate IST_SZ(icmpquerysubject6), "groupmemberquery" }, 330*7c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, 331*7c478bd9Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, 332*7c478bd9Sstevel@tonic-gate { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, 333*7c478bd9Sstevel@tonic-gate { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, 334*7c478bd9Sstevel@tonic-gate { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, 335*7c478bd9Sstevel@tonic-gate { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, 336*7c478bd9Sstevel@tonic-gate { ND_REDIRECT, NULL, 0, "redirect" }, 337*7c478bd9Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING, icmprenumber6, 338*7c478bd9Sstevel@tonic-gate IST_SZ(icmprenumber6), "routerrenumber" }, 339*7c478bd9Sstevel@tonic-gate { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, 340*7c478bd9Sstevel@tonic-gate { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, 341*7c478bd9Sstevel@tonic-gate { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, 342*7c478bd9Sstevel@tonic-gate { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, 343*7c478bd9Sstevel@tonic-gate { ICMP6_NI_QUERY, icmpnodeinfo6, 344*7c478bd9Sstevel@tonic-gate IST_SZ(icmpnodeinfo6), "nodeinforequest" }, 345*7c478bd9Sstevel@tonic-gate { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, 346*7c478bd9Sstevel@tonic-gate { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, 347*7c478bd9Sstevel@tonic-gate { MLD6_MTRACE, NULL, 0, "mtracerequest" }, 348*7c478bd9Sstevel@tonic-gate { -2, NULL, 0, NULL } 349*7c478bd9Sstevel@tonic-gate }; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) 352*7c478bd9Sstevel@tonic-gate int type; 353*7c478bd9Sstevel@tonic-gate icmp_subtype_t *table; 354*7c478bd9Sstevel@tonic-gate size_t tablesz; 355*7c478bd9Sstevel@tonic-gate { 356*7c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 357*7c478bd9Sstevel@tonic-gate int i; 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate if (tablesz < 2) 360*7c478bd9Sstevel@tonic-gate return NULL; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].ist_val)) 363*7c478bd9Sstevel@tonic-gate return NULL; 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate i = type; 366*7c478bd9Sstevel@tonic-gate if (table[type].ist_val == type) 367*7c478bd9Sstevel@tonic-gate return table + type; 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) 370*7c478bd9Sstevel@tonic-gate if (ist->ist_val == type) 371*7c478bd9Sstevel@tonic-gate return ist; 372*7c478bd9Sstevel@tonic-gate return NULL; 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate static icmp_type_t *find_icmptype(type, table, tablesz) 377*7c478bd9Sstevel@tonic-gate int type; 378*7c478bd9Sstevel@tonic-gate icmp_type_t *table; 379*7c478bd9Sstevel@tonic-gate size_t tablesz; 380*7c478bd9Sstevel@tonic-gate { 381*7c478bd9Sstevel@tonic-gate icmp_type_t *it; 382*7c478bd9Sstevel@tonic-gate int i; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate if (tablesz < 2) 385*7c478bd9Sstevel@tonic-gate return NULL; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].it_val)) 388*7c478bd9Sstevel@tonic-gate return NULL; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate i = type; 391*7c478bd9Sstevel@tonic-gate if (table[type].it_val == type) 392*7c478bd9Sstevel@tonic-gate return table + type; 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate for (i = 0, it = table; it->it_val != -2; i++, it++) 395*7c478bd9Sstevel@tonic-gate if (it->it_val == type) 396*7c478bd9Sstevel@tonic-gate return it; 397*7c478bd9Sstevel@tonic-gate return NULL; 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate static void handlehup(sig) 402*7c478bd9Sstevel@tonic-gate int sig; 403*7c478bd9Sstevel@tonic-gate { 404*7c478bd9Sstevel@tonic-gate FILE *fp; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate signal(SIGHUP, handlehup); 407*7c478bd9Sstevel@tonic-gate if (logfile && (fp = fopen(logfile, "a"))) 408*7c478bd9Sstevel@tonic-gate newlog = fp; 409*7c478bd9Sstevel@tonic-gate if (binarylogfile && (fp = fopen(binarylogfile, "a"))) 410*7c478bd9Sstevel@tonic-gate newbinarylog = fp; 411*7c478bd9Sstevel@tonic-gate init_tabs(); 412*7c478bd9Sstevel@tonic-gate if (conf_file) 413*7c478bd9Sstevel@tonic-gate if (load_config(conf_file) == -1) 414*7c478bd9Sstevel@tonic-gate exit(1); 415*7c478bd9Sstevel@tonic-gate donehup = 1; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate static void init_tabs() 420*7c478bd9Sstevel@tonic-gate { 421*7c478bd9Sstevel@tonic-gate struct protoent *p; 422*7c478bd9Sstevel@tonic-gate struct servent *s; 423*7c478bd9Sstevel@tonic-gate char *name, **tab; 424*7c478bd9Sstevel@tonic-gate int port, i; 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate if (protocols != NULL) { 427*7c478bd9Sstevel@tonic-gate for (i = 0; i < 256; i++) 428*7c478bd9Sstevel@tonic-gate if (protocols[i] != NULL) { 429*7c478bd9Sstevel@tonic-gate free(protocols[i]); 430*7c478bd9Sstevel@tonic-gate protocols[i] = NULL; 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate free(protocols); 433*7c478bd9Sstevel@tonic-gate protocols = NULL; 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate protocols = (char **)malloc(256 * sizeof(*protocols)); 436*7c478bd9Sstevel@tonic-gate if (protocols != NULL) { 437*7c478bd9Sstevel@tonic-gate bzero((char *)protocols, 256 * sizeof(*protocols)); 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate setprotoent(1); 440*7c478bd9Sstevel@tonic-gate while ((p = getprotoent()) != NULL) 441*7c478bd9Sstevel@tonic-gate if (p->p_proto >= 0 && p->p_proto <= 255 && 442*7c478bd9Sstevel@tonic-gate p->p_name != NULL && protocols[p->p_proto] == NULL) 443*7c478bd9Sstevel@tonic-gate protocols[p->p_proto] = strdup(p->p_name); 444*7c478bd9Sstevel@tonic-gate endprotoent(); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate if (udp_ports != NULL) { 448*7c478bd9Sstevel@tonic-gate for (i = 0; i < 65536; i++) 449*7c478bd9Sstevel@tonic-gate if (udp_ports[i] != NULL) { 450*7c478bd9Sstevel@tonic-gate free(udp_ports[i]); 451*7c478bd9Sstevel@tonic-gate udp_ports[i] = NULL; 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate free(udp_ports); 454*7c478bd9Sstevel@tonic-gate udp_ports = NULL; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); 457*7c478bd9Sstevel@tonic-gate if (udp_ports != NULL) 458*7c478bd9Sstevel@tonic-gate bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate if (tcp_ports != NULL) { 461*7c478bd9Sstevel@tonic-gate for (i = 0; i < 65536; i++) 462*7c478bd9Sstevel@tonic-gate if (tcp_ports[i] != NULL) { 463*7c478bd9Sstevel@tonic-gate free(tcp_ports[i]); 464*7c478bd9Sstevel@tonic-gate tcp_ports[i] = NULL; 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate free(tcp_ports); 467*7c478bd9Sstevel@tonic-gate tcp_ports = NULL; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); 470*7c478bd9Sstevel@tonic-gate if (tcp_ports != NULL) 471*7c478bd9Sstevel@tonic-gate bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate setservent(1); 474*7c478bd9Sstevel@tonic-gate while ((s = getservent()) != NULL) { 475*7c478bd9Sstevel@tonic-gate if (s->s_proto == NULL) 476*7c478bd9Sstevel@tonic-gate continue; 477*7c478bd9Sstevel@tonic-gate else if (!strcmp(s->s_proto, "tcp")) { 478*7c478bd9Sstevel@tonic-gate port = ntohs(s->s_port); 479*7c478bd9Sstevel@tonic-gate name = s->s_name; 480*7c478bd9Sstevel@tonic-gate tab = tcp_ports; 481*7c478bd9Sstevel@tonic-gate } else if (!strcmp(s->s_proto, "udp")) { 482*7c478bd9Sstevel@tonic-gate port = ntohs(s->s_port); 483*7c478bd9Sstevel@tonic-gate name = s->s_name; 484*7c478bd9Sstevel@tonic-gate tab = udp_ports; 485*7c478bd9Sstevel@tonic-gate } else 486*7c478bd9Sstevel@tonic-gate continue; 487*7c478bd9Sstevel@tonic-gate if ((port < 0 || port > 65535) || (name == NULL)) 488*7c478bd9Sstevel@tonic-gate continue; 489*7c478bd9Sstevel@tonic-gate if (tab != NULL) 490*7c478bd9Sstevel@tonic-gate tab[port] = strdup(name); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate endservent(); 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate static char *getproto(p) 497*7c478bd9Sstevel@tonic-gate u_int p; 498*7c478bd9Sstevel@tonic-gate { 499*7c478bd9Sstevel@tonic-gate static char pnum[4]; 500*7c478bd9Sstevel@tonic-gate char *s; 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate p &= 0xff; 503*7c478bd9Sstevel@tonic-gate s = protocols ? protocols[p] : NULL; 504*7c478bd9Sstevel@tonic-gate if (s == NULL) { 505*7c478bd9Sstevel@tonic-gate sprintf(pnum, "%u", p); 506*7c478bd9Sstevel@tonic-gate s = pnum; 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate return s; 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate static int read_log(fd, lenp, buf, bufsize) 513*7c478bd9Sstevel@tonic-gate int fd, bufsize, *lenp; 514*7c478bd9Sstevel@tonic-gate char *buf; 515*7c478bd9Sstevel@tonic-gate { 516*7c478bd9Sstevel@tonic-gate int nr; 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate nr = read(fd, buf, bufsize); 519*7c478bd9Sstevel@tonic-gate if (!nr) 520*7c478bd9Sstevel@tonic-gate return 2; 521*7c478bd9Sstevel@tonic-gate if ((nr < 0) && (errno != EINTR)) 522*7c478bd9Sstevel@tonic-gate return -1; 523*7c478bd9Sstevel@tonic-gate *lenp = nr; 524*7c478bd9Sstevel@tonic-gate return 0; 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate char *hostname(res, v, ip) 529*7c478bd9Sstevel@tonic-gate int res, v; 530*7c478bd9Sstevel@tonic-gate u_32_t *ip; 531*7c478bd9Sstevel@tonic-gate { 532*7c478bd9Sstevel@tonic-gate # define MAX_INETA 16 533*7c478bd9Sstevel@tonic-gate static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; 534*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 535*7c478bd9Sstevel@tonic-gate static char hostbuf[MAXHOSTNAMELEN+1]; 536*7c478bd9Sstevel@tonic-gate #endif 537*7c478bd9Sstevel@tonic-gate struct hostent *hp; 538*7c478bd9Sstevel@tonic-gate struct in_addr ipa; 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate if (v == 4) { 541*7c478bd9Sstevel@tonic-gate ipa.s_addr = *ip; 542*7c478bd9Sstevel@tonic-gate if (!res) 543*7c478bd9Sstevel@tonic-gate return inet_ntoa(ipa); 544*7c478bd9Sstevel@tonic-gate hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET); 545*7c478bd9Sstevel@tonic-gate if (!hp) 546*7c478bd9Sstevel@tonic-gate return inet_ntoa(ipa); 547*7c478bd9Sstevel@tonic-gate sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, 548*7c478bd9Sstevel@tonic-gate inet_ntoa(ipa)); 549*7c478bd9Sstevel@tonic-gate return hname; 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 552*7c478bd9Sstevel@tonic-gate (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); 553*7c478bd9Sstevel@tonic-gate hostbuf[MAXHOSTNAMELEN] = '\0'; 554*7c478bd9Sstevel@tonic-gate return hostbuf; 555*7c478bd9Sstevel@tonic-gate #else 556*7c478bd9Sstevel@tonic-gate return "IPv6"; 557*7c478bd9Sstevel@tonic-gate #endif 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate char *portname(res, proto, port) 562*7c478bd9Sstevel@tonic-gate int res; 563*7c478bd9Sstevel@tonic-gate char *proto; 564*7c478bd9Sstevel@tonic-gate u_int port; 565*7c478bd9Sstevel@tonic-gate { 566*7c478bd9Sstevel@tonic-gate static char pname[8]; 567*7c478bd9Sstevel@tonic-gate char *s; 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate port = ntohs(port); 570*7c478bd9Sstevel@tonic-gate port &= 0xffff; 571*7c478bd9Sstevel@tonic-gate (void) sprintf(pname, "%u", port); 572*7c478bd9Sstevel@tonic-gate if (!res || (opts & OPT_PORTNUM)) 573*7c478bd9Sstevel@tonic-gate return pname; 574*7c478bd9Sstevel@tonic-gate s = NULL; 575*7c478bd9Sstevel@tonic-gate if (!strcmp(proto, "tcp")) 576*7c478bd9Sstevel@tonic-gate s = tcp_ports[port]; 577*7c478bd9Sstevel@tonic-gate else if (!strcmp(proto, "udp")) 578*7c478bd9Sstevel@tonic-gate s = udp_ports[port]; 579*7c478bd9Sstevel@tonic-gate if (s == NULL) 580*7c478bd9Sstevel@tonic-gate s = pname; 581*7c478bd9Sstevel@tonic-gate return s; 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate static char *icmpname(type, code) 586*7c478bd9Sstevel@tonic-gate u_int type; 587*7c478bd9Sstevel@tonic-gate u_int code; 588*7c478bd9Sstevel@tonic-gate { 589*7c478bd9Sstevel@tonic-gate static char name[80]; 590*7c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 591*7c478bd9Sstevel@tonic-gate icmp_type_t *it; 592*7c478bd9Sstevel@tonic-gate char *s; 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate s = NULL; 595*7c478bd9Sstevel@tonic-gate it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); 596*7c478bd9Sstevel@tonic-gate if (it != NULL) 597*7c478bd9Sstevel@tonic-gate s = it->it_name; 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate if (s == NULL) 600*7c478bd9Sstevel@tonic-gate sprintf(name, "icmptype(%d)/", type); 601*7c478bd9Sstevel@tonic-gate else 602*7c478bd9Sstevel@tonic-gate sprintf(name, "%s/", s); 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate ist = NULL; 605*7c478bd9Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 606*7c478bd9Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 609*7c478bd9Sstevel@tonic-gate strcat(name, ist->ist_name); 610*7c478bd9Sstevel@tonic-gate else 611*7c478bd9Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate return name; 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate static char *icmpname6(type, code) 617*7c478bd9Sstevel@tonic-gate u_int type; 618*7c478bd9Sstevel@tonic-gate u_int code; 619*7c478bd9Sstevel@tonic-gate { 620*7c478bd9Sstevel@tonic-gate static char name[80]; 621*7c478bd9Sstevel@tonic-gate icmp_subtype_t *ist; 622*7c478bd9Sstevel@tonic-gate icmp_type_t *it; 623*7c478bd9Sstevel@tonic-gate char *s; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate s = NULL; 626*7c478bd9Sstevel@tonic-gate it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); 627*7c478bd9Sstevel@tonic-gate if (it != NULL) 628*7c478bd9Sstevel@tonic-gate s = it->it_name; 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate if (s == NULL) 631*7c478bd9Sstevel@tonic-gate sprintf(name, "icmpv6type(%d)/", type); 632*7c478bd9Sstevel@tonic-gate else 633*7c478bd9Sstevel@tonic-gate sprintf(name, "%s/", s); 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate ist = NULL; 636*7c478bd9Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 637*7c478bd9Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 640*7c478bd9Sstevel@tonic-gate strcat(name, ist->ist_name); 641*7c478bd9Sstevel@tonic-gate else 642*7c478bd9Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate return name; 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate void dumphex(log, dopts, buf, len) 649*7c478bd9Sstevel@tonic-gate FILE *log; 650*7c478bd9Sstevel@tonic-gate int dopts; 651*7c478bd9Sstevel@tonic-gate char *buf; 652*7c478bd9Sstevel@tonic-gate int len; 653*7c478bd9Sstevel@tonic-gate { 654*7c478bd9Sstevel@tonic-gate char hline[80]; 655*7c478bd9Sstevel@tonic-gate int i, j, k; 656*7c478bd9Sstevel@tonic-gate u_char *s = (u_char *)buf, *t = (u_char *)hline; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate if (buf == NULL || len == 0) 659*7c478bd9Sstevel@tonic-gate return; 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate *hline = '\0'; 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate for (i = len, j = 0; i; i--, j++, s++) { 664*7c478bd9Sstevel@tonic-gate if (j && !(j & 0xf)) { 665*7c478bd9Sstevel@tonic-gate *t++ = '\n'; 666*7c478bd9Sstevel@tonic-gate *t = '\0'; 667*7c478bd9Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) 668*7c478bd9Sstevel@tonic-gate fputs(hline, log); 669*7c478bd9Sstevel@tonic-gate else 670*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 671*7c478bd9Sstevel@tonic-gate t = (u_char *)hline; 672*7c478bd9Sstevel@tonic-gate *t = '\0'; 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate sprintf((char *)t, "%02x", *s & 0xff); 675*7c478bd9Sstevel@tonic-gate t += 2; 676*7c478bd9Sstevel@tonic-gate if (!((j + 1) & 0xf)) { 677*7c478bd9Sstevel@tonic-gate s -= 15; 678*7c478bd9Sstevel@tonic-gate sprintf((char *)t, " "); 679*7c478bd9Sstevel@tonic-gate t += 8; 680*7c478bd9Sstevel@tonic-gate for (k = 16; k; k--, s++) 681*7c478bd9Sstevel@tonic-gate *t++ = (isprint(*s) ? *s : '.'); 682*7c478bd9Sstevel@tonic-gate s--; 683*7c478bd9Sstevel@tonic-gate } 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate if ((j + 1) & 0xf) 686*7c478bd9Sstevel@tonic-gate *t++ = ' ';; 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate if (j & 0xf) { 690*7c478bd9Sstevel@tonic-gate for (k = 16 - (j & 0xf); k; k--) { 691*7c478bd9Sstevel@tonic-gate *t++ = ' '; 692*7c478bd9Sstevel@tonic-gate *t++ = ' '; 693*7c478bd9Sstevel@tonic-gate *t++ = ' '; 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate sprintf((char *)t, " "); 696*7c478bd9Sstevel@tonic-gate t += 7; 697*7c478bd9Sstevel@tonic-gate s -= j & 0xf; 698*7c478bd9Sstevel@tonic-gate for (k = j & 0xf; k; k--, s++) 699*7c478bd9Sstevel@tonic-gate *t++ = (isprint(*s) ? *s : '.'); 700*7c478bd9Sstevel@tonic-gate *t++ = '\n'; 701*7c478bd9Sstevel@tonic-gate *t = '\0'; 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) { 704*7c478bd9Sstevel@tonic-gate fputs(hline, log); 705*7c478bd9Sstevel@tonic-gate fflush(log); 706*7c478bd9Sstevel@tonic-gate } else 707*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 708*7c478bd9Sstevel@tonic-gate } 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate static struct tm *get_tm(sec) 712*7c478bd9Sstevel@tonic-gate #ifdef __hpux 713*7c478bd9Sstevel@tonic-gate u_32_t sec; 714*7c478bd9Sstevel@tonic-gate #else 715*7c478bd9Sstevel@tonic-gate time_t sec; 716*7c478bd9Sstevel@tonic-gate #endif 717*7c478bd9Sstevel@tonic-gate { 718*7c478bd9Sstevel@tonic-gate struct tm *tm; 719*7c478bd9Sstevel@tonic-gate time_t t; 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate t = sec; 722*7c478bd9Sstevel@tonic-gate tm = localtime(&t); 723*7c478bd9Sstevel@tonic-gate return tm; 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate static void print_natlog(log, buf, blen) 727*7c478bd9Sstevel@tonic-gate FILE *log; 728*7c478bd9Sstevel@tonic-gate char *buf; 729*7c478bd9Sstevel@tonic-gate int blen; 730*7c478bd9Sstevel@tonic-gate { 731*7c478bd9Sstevel@tonic-gate struct natlog *nl; 732*7c478bd9Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 733*7c478bd9Sstevel@tonic-gate char *t = line; 734*7c478bd9Sstevel@tonic-gate struct tm *tm; 735*7c478bd9Sstevel@tonic-gate int res, i, len; 736*7c478bd9Sstevel@tonic-gate char *proto; 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); 739*7c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 740*7c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 741*7c478bd9Sstevel@tonic-gate len = sizeof(line); 742*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 743*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 744*7c478bd9Sstevel@tonic-gate i = strlen(t); 745*7c478bd9Sstevel@tonic-gate len -= i; 746*7c478bd9Sstevel@tonic-gate t += i; 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 749*7c478bd9Sstevel@tonic-gate t += strlen(t); 750*7c478bd9Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); 751*7c478bd9Sstevel@tonic-gate t += strlen(t); 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate if (nl->nl_type == NL_NEWMAP) 754*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:MAP "); 755*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_NEWRDR) 756*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:RDR "); 757*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_FLUSH) 758*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:FLUSH "); 759*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_EXPIRE) 760*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:EXPIRE "); 761*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_NEWBIMAP) 762*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:BIMAP "); 763*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_NEWBLOCK) 764*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:MAPBLOCK "); 765*7c478bd9Sstevel@tonic-gate else if (nl->nl_type == NL_CLONE) 766*7c478bd9Sstevel@tonic-gate strcpy(t, "NAT:CLONE "); 767*7c478bd9Sstevel@tonic-gate else 768*7c478bd9Sstevel@tonic-gate sprintf(t, "Type: %d ", nl->nl_type); 769*7c478bd9Sstevel@tonic-gate t += strlen(t); 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate proto = getproto(nl->nl_p); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), 774*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_inport)); 775*7c478bd9Sstevel@tonic-gate t += strlen(t); 776*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), 777*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_outport)); 778*7c478bd9Sstevel@tonic-gate t += strlen(t); 779*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip), 780*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_origport)); 781*7c478bd9Sstevel@tonic-gate t += strlen(t); 782*7c478bd9Sstevel@tonic-gate if (nl->nl_type == NL_EXPIRE) { 783*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 784*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", 785*7c478bd9Sstevel@tonic-gate (long long)nl->nl_pkts[0], 786*7c478bd9Sstevel@tonic-gate (long long)nl->nl_pkts[1], 787*7c478bd9Sstevel@tonic-gate (long long)nl->nl_bytes[0], 788*7c478bd9Sstevel@tonic-gate (long long)nl->nl_bytes[1]); 789*7c478bd9Sstevel@tonic-gate #else 790*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " Pkts %ld Bytes %ld", 791*7c478bd9Sstevel@tonic-gate nl->nl_pkts[0], nl->nl_pkts[1], 792*7c478bd9Sstevel@tonic-gate nl->nl_bytes[0], nl->nl_bytes[1]); 793*7c478bd9Sstevel@tonic-gate #endif 794*7c478bd9Sstevel@tonic-gate t += strlen(t); 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate *t++ = '\n'; 798*7c478bd9Sstevel@tonic-gate *t++ = '\0'; 799*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 800*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 801*7c478bd9Sstevel@tonic-gate else 802*7c478bd9Sstevel@tonic-gate (void) fprintf(log, "%s", line); 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate static void print_statelog(log, buf, blen) 807*7c478bd9Sstevel@tonic-gate FILE *log; 808*7c478bd9Sstevel@tonic-gate char *buf; 809*7c478bd9Sstevel@tonic-gate int blen; 810*7c478bd9Sstevel@tonic-gate { 811*7c478bd9Sstevel@tonic-gate struct ipslog *sl; 812*7c478bd9Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 813*7c478bd9Sstevel@tonic-gate char *t = line, *proto; 814*7c478bd9Sstevel@tonic-gate struct tm *tm; 815*7c478bd9Sstevel@tonic-gate int res, i, len; 816*7c478bd9Sstevel@tonic-gate 817*7c478bd9Sstevel@tonic-gate sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); 818*7c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 819*7c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 820*7c478bd9Sstevel@tonic-gate len = sizeof(line); 821*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 822*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 823*7c478bd9Sstevel@tonic-gate i = strlen(t); 824*7c478bd9Sstevel@tonic-gate len -= i; 825*7c478bd9Sstevel@tonic-gate t += i; 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 828*7c478bd9Sstevel@tonic-gate t += strlen(t); 829*7c478bd9Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 830*7c478bd9Sstevel@tonic-gate t += strlen(t); 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate if (sl->isl_type == ISL_NEW) 833*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:NEW "); 834*7c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_CLONE) 835*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:CLONED "); 836*7c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_EXPIRE) { 837*7c478bd9Sstevel@tonic-gate if ((sl->isl_p == IPPROTO_TCP) && 838*7c478bd9Sstevel@tonic-gate (sl->isl_state[0] > IPF_TCPS_ESTABLISHED || 839*7c478bd9Sstevel@tonic-gate sl->isl_state[1] > IPF_TCPS_ESTABLISHED)) 840*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:CLOSE "); 841*7c478bd9Sstevel@tonic-gate else 842*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:EXPIRE "); 843*7c478bd9Sstevel@tonic-gate } else if (sl->isl_type == ISL_FLUSH) 844*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:FLUSH "); 845*7c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_INTERMEDIATE) 846*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:INTERMEDIATE "); 847*7c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_REMOVE) 848*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:REMOVE "); 849*7c478bd9Sstevel@tonic-gate else if (sl->isl_type == ISL_KILLED) 850*7c478bd9Sstevel@tonic-gate strcpy(t, "STATE:KILLED "); 851*7c478bd9Sstevel@tonic-gate else 852*7c478bd9Sstevel@tonic-gate sprintf(t, "Type: %d ", sl->isl_type); 853*7c478bd9Sstevel@tonic-gate t += strlen(t); 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate proto = getproto(sl->isl_p); 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { 858*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", 859*7c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), 860*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_sport)); 861*7c478bd9Sstevel@tonic-gate t += strlen(t); 862*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s", 863*7c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 864*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_dport), proto); 865*7c478bd9Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMP) { 866*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 867*7c478bd9Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 868*7c478bd9Sstevel@tonic-gate t += strlen(t); 869*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp %d", 870*7c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 871*7c478bd9Sstevel@tonic-gate sl->isl_itype); 872*7c478bd9Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMPV6) { 873*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 874*7c478bd9Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 875*7c478bd9Sstevel@tonic-gate t += strlen(t); 876*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 %d", 877*7c478bd9Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 878*7c478bd9Sstevel@tonic-gate sl->isl_itype); 879*7c478bd9Sstevel@tonic-gate } 880*7c478bd9Sstevel@tonic-gate t += strlen(t); 881*7c478bd9Sstevel@tonic-gate if (sl->isl_tag != FR_NOLOGTAG) { 882*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " tag %u", sl->isl_tag); 883*7c478bd9Sstevel@tonic-gate t += strlen(t); 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate if (sl->isl_type != ISL_NEW) { 886*7c478bd9Sstevel@tonic-gate sprintf(t, 887*7c478bd9Sstevel@tonic-gate #ifdef USE_QUAD_T 888*7c478bd9Sstevel@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", 889*7c478bd9Sstevel@tonic-gate #else 890*7c478bd9Sstevel@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", 891*7c478bd9Sstevel@tonic-gate #endif 892*7c478bd9Sstevel@tonic-gate sl->isl_pkts[0], sl->isl_bytes[0], 893*7c478bd9Sstevel@tonic-gate sl->isl_pkts[1], sl->isl_bytes[1], 894*7c478bd9Sstevel@tonic-gate sl->isl_pkts[2], sl->isl_bytes[2], 895*7c478bd9Sstevel@tonic-gate sl->isl_pkts[3], sl->isl_bytes[3]); 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate t += strlen(t); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate *t++ = '\n'; 901*7c478bd9Sstevel@tonic-gate *t++ = '\0'; 902*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 903*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 904*7c478bd9Sstevel@tonic-gate else 905*7c478bd9Sstevel@tonic-gate (void) fprintf(log, "%s", line); 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate static void print_log(logtype, log, buf, blen) 910*7c478bd9Sstevel@tonic-gate FILE *log; 911*7c478bd9Sstevel@tonic-gate char *buf; 912*7c478bd9Sstevel@tonic-gate int logtype, blen; 913*7c478bd9Sstevel@tonic-gate { 914*7c478bd9Sstevel@tonic-gate iplog_t *ipl; 915*7c478bd9Sstevel@tonic-gate char *bp = NULL, *bpo = NULL; 916*7c478bd9Sstevel@tonic-gate int psize; 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate while (blen > 0) { 919*7c478bd9Sstevel@tonic-gate ipl = (iplog_t *)buf; 920*7c478bd9Sstevel@tonic-gate if ((u_long)ipl & (sizeof(long)-1)) { 921*7c478bd9Sstevel@tonic-gate if (bp) 922*7c478bd9Sstevel@tonic-gate bpo = bp; 923*7c478bd9Sstevel@tonic-gate bp = (char *)malloc(blen); 924*7c478bd9Sstevel@tonic-gate bcopy((char *)ipl, bp, blen); 925*7c478bd9Sstevel@tonic-gate if (bpo) { 926*7c478bd9Sstevel@tonic-gate free(bpo); 927*7c478bd9Sstevel@tonic-gate bpo = NULL; 928*7c478bd9Sstevel@tonic-gate } 929*7c478bd9Sstevel@tonic-gate buf = bp; 930*7c478bd9Sstevel@tonic-gate continue; 931*7c478bd9Sstevel@tonic-gate } 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate psize = ipl->ipl_dsize; 934*7c478bd9Sstevel@tonic-gate if (psize > blen) 935*7c478bd9Sstevel@tonic-gate break; 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate if (binarylog) { 938*7c478bd9Sstevel@tonic-gate fwrite(buf, psize, 1, binarylog); 939*7c478bd9Sstevel@tonic-gate fflush(binarylog); 940*7c478bd9Sstevel@tonic-gate } 941*7c478bd9Sstevel@tonic-gate 942*7c478bd9Sstevel@tonic-gate if (logtype == IPL_LOGIPF) { 943*7c478bd9Sstevel@tonic-gate if (ipl->ipl_magic != IPL_MAGIC) { 944*7c478bd9Sstevel@tonic-gate /* invalid data or out of sync */ 945*7c478bd9Sstevel@tonic-gate break; 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate print_ipflog(log, buf, psize); 948*7c478bd9Sstevel@tonic-gate 949*7c478bd9Sstevel@tonic-gate } else if (logtype == IPL_LOGNAT) { 950*7c478bd9Sstevel@tonic-gate if (ipl->ipl_magic != IPL_MAGIC) { 951*7c478bd9Sstevel@tonic-gate /* invalid data or out of sync */ 952*7c478bd9Sstevel@tonic-gate break; 953*7c478bd9Sstevel@tonic-gate } 954*7c478bd9Sstevel@tonic-gate print_natlog(log, buf, psize); 955*7c478bd9Sstevel@tonic-gate 956*7c478bd9Sstevel@tonic-gate } else if (logtype == IPL_LOGSTATE) { 957*7c478bd9Sstevel@tonic-gate if (ipl->ipl_magic != IPL_MAGIC) { 958*7c478bd9Sstevel@tonic-gate /* invalid data or out of sync */ 959*7c478bd9Sstevel@tonic-gate break; 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate print_statelog(log, buf, psize); 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate 964*7c478bd9Sstevel@tonic-gate blen -= psize; 965*7c478bd9Sstevel@tonic-gate buf += psize; 966*7c478bd9Sstevel@tonic-gate } 967*7c478bd9Sstevel@tonic-gate if (bp) 968*7c478bd9Sstevel@tonic-gate free(bp); 969*7c478bd9Sstevel@tonic-gate return; 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate static void print_ipflog(log, buf, blen) 974*7c478bd9Sstevel@tonic-gate FILE *log; 975*7c478bd9Sstevel@tonic-gate char *buf; 976*7c478bd9Sstevel@tonic-gate int blen; 977*7c478bd9Sstevel@tonic-gate { 978*7c478bd9Sstevel@tonic-gate tcphdr_t *tp; 979*7c478bd9Sstevel@tonic-gate struct icmp *ic; 980*7c478bd9Sstevel@tonic-gate struct icmp *icmp; 981*7c478bd9Sstevel@tonic-gate struct tm *tm; 982*7c478bd9Sstevel@tonic-gate char *t, *proto; 983*7c478bd9Sstevel@tonic-gate int i, v, lvl, res, len, off, plen, ipoff; 984*7c478bd9Sstevel@tonic-gate u_32_t *s, *d, cmdflags; 985*7c478bd9Sstevel@tonic-gate ip_t *ipc, *ip; 986*7c478bd9Sstevel@tonic-gate u_short hl, p; 987*7c478bd9Sstevel@tonic-gate ipflog_t *ipf; 988*7c478bd9Sstevel@tonic-gate iplog_t *ipl; 989*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 990*7c478bd9Sstevel@tonic-gate ip6_t *ip6; 991*7c478bd9Sstevel@tonic-gate #endif 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate ipl = (iplog_t *)buf; 994*7c478bd9Sstevel@tonic-gate ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); 995*7c478bd9Sstevel@tonic-gate ip = (ip_t *)((char *)ipf + sizeof(*ipf)); 996*7c478bd9Sstevel@tonic-gate v = IP_V(ip); 997*7c478bd9Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 998*7c478bd9Sstevel@tonic-gate t = line; 999*7c478bd9Sstevel@tonic-gate *t = '\0'; 1000*7c478bd9Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 1001*7c478bd9Sstevel@tonic-gate 1002*7c478bd9Sstevel@tonic-gate len = sizeof(line); 1003*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 1004*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 1005*7c478bd9Sstevel@tonic-gate i = strlen(t); 1006*7c478bd9Sstevel@tonic-gate len -= i; 1007*7c478bd9Sstevel@tonic-gate t += i; 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 1010*7c478bd9Sstevel@tonic-gate t += strlen(t); 1011*7c478bd9Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 1012*7c478bd9Sstevel@tonic-gate t += strlen(t); 1013*7c478bd9Sstevel@tonic-gate if (ipl->ipl_count > 1) { 1014*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%dx ", ipl->ipl_count); 1015*7c478bd9Sstevel@tonic-gate t += strlen(t); 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate #if (defined(MENTAT) || \ 1018*7c478bd9Sstevel@tonic-gate (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ 1019*7c478bd9Sstevel@tonic-gate (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux) 1020*7c478bd9Sstevel@tonic-gate { 1021*7c478bd9Sstevel@tonic-gate char ifname[sizeof(ipf->fl_ifname) + 1]; 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); 1024*7c478bd9Sstevel@tonic-gate ifname[sizeof(ipf->fl_ifname)] = '\0'; 1025*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s", ifname); 1026*7c478bd9Sstevel@tonic-gate t += strlen(t); 1027*7c478bd9Sstevel@tonic-gate # if defined(MENTAT) 1028*7c478bd9Sstevel@tonic-gate if (isalpha(*(t - 1))) { 1029*7c478bd9Sstevel@tonic-gate sprintf(t, "%d", ipf->fl_unit); 1030*7c478bd9Sstevel@tonic-gate t += strlen(t); 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate # endif 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate #else 1035*7c478bd9Sstevel@tonic-gate for (len = 0; len < 3; len++) 1036*7c478bd9Sstevel@tonic-gate if (ipf->fl_ifname[len] == '\0') 1037*7c478bd9Sstevel@tonic-gate break; 1038*7c478bd9Sstevel@tonic-gate if (ipf->fl_ifname[len]) 1039*7c478bd9Sstevel@tonic-gate len++; 1040*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); 1041*7c478bd9Sstevel@tonic-gate t += strlen(t); 1042*7c478bd9Sstevel@tonic-gate #endif 1043*7c478bd9Sstevel@tonic-gate if ((ipf->fl_group[0] == -1) && (ipf->fl_group[1] == '\0')) 1044*7c478bd9Sstevel@tonic-gate strcat(t, " @-1:"); 1045*7c478bd9Sstevel@tonic-gate else if (ipf->fl_group[0] == '\0') 1046*7c478bd9Sstevel@tonic-gate (void) strcpy(t, " @0:"); 1047*7c478bd9Sstevel@tonic-gate else 1048*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " @%s:", ipf->fl_group); 1049*7c478bd9Sstevel@tonic-gate t += strlen(t); 1050*7c478bd9Sstevel@tonic-gate if (ipf->fl_rule == 0xffffffff) 1051*7c478bd9Sstevel@tonic-gate strcat(t, "-1 "); 1052*7c478bd9Sstevel@tonic-gate else 1053*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%u ", ipf->fl_rule + 1); 1054*7c478bd9Sstevel@tonic-gate t += strlen(t); 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate lvl = LOG_NOTICE; 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate if (ipf->fl_lflags & FI_SHORT) { 1059*7c478bd9Sstevel@tonic-gate *t++ = 'S'; 1060*7c478bd9Sstevel@tonic-gate lvl = LOG_ERR; 1061*7c478bd9Sstevel@tonic-gate } 1062*7c478bd9Sstevel@tonic-gate 1063*7c478bd9Sstevel@tonic-gate cmdflags = ipf->fl_flags & FR_CMDMASK; 1064*7c478bd9Sstevel@tonic-gate if (FR_ISPASS(ipf->fl_flags)) { 1065*7c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGP) 1066*7c478bd9Sstevel@tonic-gate *t++ = 'p'; 1067*7c478bd9Sstevel@tonic-gate else 1068*7c478bd9Sstevel@tonic-gate *t++ = 'P'; 1069*7c478bd9Sstevel@tonic-gate } else if (FR_ISBLOCK(ipf->fl_flags)) { 1070*7c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGB) 1071*7c478bd9Sstevel@tonic-gate *t++ = 'b'; 1072*7c478bd9Sstevel@tonic-gate else 1073*7c478bd9Sstevel@tonic-gate *t++ = 'B'; 1074*7c478bd9Sstevel@tonic-gate lvl = LOG_WARNING; 1075*7c478bd9Sstevel@tonic-gate } else if ((ipf->fl_flags & FR_LOGMASK) == FR_LOG) { 1076*7c478bd9Sstevel@tonic-gate *t++ = 'L'; 1077*7c478bd9Sstevel@tonic-gate lvl = LOG_INFO; 1078*7c478bd9Sstevel@tonic-gate } else if (ipf->fl_flags & FF_LOGNOMATCH) { 1079*7c478bd9Sstevel@tonic-gate *t++ = 'n'; 1080*7c478bd9Sstevel@tonic-gate } else { 1081*7c478bd9Sstevel@tonic-gate *t++ = '?'; 1082*7c478bd9Sstevel@tonic-gate lvl = LOG_EMERG; 1083*7c478bd9Sstevel@tonic-gate } 1084*7c478bd9Sstevel@tonic-gate if (ipf->fl_loglevel != 0xffff) 1085*7c478bd9Sstevel@tonic-gate lvl = ipf->fl_loglevel; 1086*7c478bd9Sstevel@tonic-gate *t++ = ' '; 1087*7c478bd9Sstevel@tonic-gate *t = '\0'; 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate if (v == 6) { 1090*7c478bd9Sstevel@tonic-gate #ifdef USE_INET6 1091*7c478bd9Sstevel@tonic-gate off = 0; 1092*7c478bd9Sstevel@tonic-gate ipoff = 0; 1093*7c478bd9Sstevel@tonic-gate hl = sizeof(ip6_t); 1094*7c478bd9Sstevel@tonic-gate ip6 = (ip6_t *)ip; 1095*7c478bd9Sstevel@tonic-gate p = (u_short)ip6->ip6_nxt; 1096*7c478bd9Sstevel@tonic-gate s = (u_32_t *)&ip6->ip6_src; 1097*7c478bd9Sstevel@tonic-gate d = (u_32_t *)&ip6->ip6_dst; 1098*7c478bd9Sstevel@tonic-gate plen = ntohs(ip6->ip6_plen); 1099*7c478bd9Sstevel@tonic-gate #else 1100*7c478bd9Sstevel@tonic-gate sprintf(t, "ipv6"); 1101*7c478bd9Sstevel@tonic-gate goto printipflog; 1102*7c478bd9Sstevel@tonic-gate #endif 1103*7c478bd9Sstevel@tonic-gate } else if (v == 4) { 1104*7c478bd9Sstevel@tonic-gate hl = IP_HL(ip) << 2; 1105*7c478bd9Sstevel@tonic-gate ipoff = ip->ip_off; 1106*7c478bd9Sstevel@tonic-gate off = ipoff & IP_OFFMASK; 1107*7c478bd9Sstevel@tonic-gate p = (u_short)ip->ip_p; 1108*7c478bd9Sstevel@tonic-gate s = (u_32_t *)&ip->ip_src; 1109*7c478bd9Sstevel@tonic-gate d = (u_32_t *)&ip->ip_dst; 1110*7c478bd9Sstevel@tonic-gate plen = ip->ip_len; 1111*7c478bd9Sstevel@tonic-gate } else { 1112*7c478bd9Sstevel@tonic-gate goto printipflog; 1113*7c478bd9Sstevel@tonic-gate } 1114*7c478bd9Sstevel@tonic-gate proto = getproto(p); 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { 1117*7c478bd9Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ip + hl); 1118*7c478bd9Sstevel@tonic-gate if (!(ipf->fl_lflags & FI_SHORT)) { 1119*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), 1120*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_sport)); 1121*7c478bd9Sstevel@tonic-gate t += strlen(t); 1122*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s len %hu %hu", 1123*7c478bd9Sstevel@tonic-gate hostname(res, v, d), 1124*7c478bd9Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_dport), 1125*7c478bd9Sstevel@tonic-gate proto, hl, plen); 1126*7c478bd9Sstevel@tonic-gate t += strlen(t); 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate if (p == IPPROTO_TCP) { 1129*7c478bd9Sstevel@tonic-gate *t++ = ' '; 1130*7c478bd9Sstevel@tonic-gate *t++ = '-'; 1131*7c478bd9Sstevel@tonic-gate for (i = 0; tcpfl[i].value; i++) 1132*7c478bd9Sstevel@tonic-gate if (tp->th_flags & tcpfl[i].value) 1133*7c478bd9Sstevel@tonic-gate *t++ = tcpfl[i].flag; 1134*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 1135*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " %lu %lu %hu", 1136*7c478bd9Sstevel@tonic-gate (u_long)(ntohl(tp->th_seq)), 1137*7c478bd9Sstevel@tonic-gate (u_long)(ntohl(tp->th_ack)), 1138*7c478bd9Sstevel@tonic-gate ntohs(tp->th_win)); 1139*7c478bd9Sstevel@tonic-gate t += strlen(t); 1140*7c478bd9Sstevel@tonic-gate } 1141*7c478bd9Sstevel@tonic-gate } 1142*7c478bd9Sstevel@tonic-gate *t = '\0'; 1143*7c478bd9Sstevel@tonic-gate } else { 1144*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 1145*7c478bd9Sstevel@tonic-gate t += strlen(t); 1146*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu %hu", 1147*7c478bd9Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 1148*7c478bd9Sstevel@tonic-gate } 1149*7c478bd9Sstevel@tonic-gate } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { 1150*7c478bd9Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 1151*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 1152*7c478bd9Sstevel@tonic-gate t += strlen(t); 1153*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", 1154*7c478bd9Sstevel@tonic-gate hostname(res, v, d), hl, plen, 1155*7c478bd9Sstevel@tonic-gate icmpname6(ic->icmp_type, ic->icmp_code)); 1156*7c478bd9Sstevel@tonic-gate } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { 1157*7c478bd9Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 1158*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 1159*7c478bd9Sstevel@tonic-gate t += strlen(t); 1160*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", 1161*7c478bd9Sstevel@tonic-gate hostname(res, v, d), hl, plen, 1162*7c478bd9Sstevel@tonic-gate icmpname(ic->icmp_type, ic->icmp_code)); 1163*7c478bd9Sstevel@tonic-gate if (ic->icmp_type == ICMP_UNREACH || 1164*7c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_SOURCEQUENCH || 1165*7c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_PARAMPROB || 1166*7c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_REDIRECT || 1167*7c478bd9Sstevel@tonic-gate ic->icmp_type == ICMP_TIMXCEED) { 1168*7c478bd9Sstevel@tonic-gate ipc = &ic->icmp_ip; 1169*7c478bd9Sstevel@tonic-gate i = ntohs(ipc->ip_len); 1170*7c478bd9Sstevel@tonic-gate /* 1171*7c478bd9Sstevel@tonic-gate * XXX - try to guess endian of ip_len in ICMP 1172*7c478bd9Sstevel@tonic-gate * returned data. 1173*7c478bd9Sstevel@tonic-gate */ 1174*7c478bd9Sstevel@tonic-gate if (i > 1500) 1175*7c478bd9Sstevel@tonic-gate i = ipc->ip_len; 1176*7c478bd9Sstevel@tonic-gate ipoff = ntohs(ipc->ip_off); 1177*7c478bd9Sstevel@tonic-gate proto = getproto(ipc->ip_p); 1178*7c478bd9Sstevel@tonic-gate 1179*7c478bd9Sstevel@tonic-gate if (!(ipoff & IP_OFFMASK) && 1180*7c478bd9Sstevel@tonic-gate ((ipc->ip_p == IPPROTO_TCP) || 1181*7c478bd9Sstevel@tonic-gate (ipc->ip_p == IPPROTO_UDP))) { 1182*7c478bd9Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ipc + hl); 1183*7c478bd9Sstevel@tonic-gate t += strlen(t); 1184*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s,%s -", 1185*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src), 1186*7c478bd9Sstevel@tonic-gate portname(res, proto, 1187*7c478bd9Sstevel@tonic-gate (u_int)tp->th_sport)); 1188*7c478bd9Sstevel@tonic-gate t += strlen(t); 1189*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " %s,%s PR %s len %hu %hu", 1190*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 1191*7c478bd9Sstevel@tonic-gate portname(res, proto, 1192*7c478bd9Sstevel@tonic-gate (u_int)tp->th_dport), 1193*7c478bd9Sstevel@tonic-gate proto, IP_HL(ipc) << 2, i); 1194*7c478bd9Sstevel@tonic-gate } else if (!(ipoff & IP_OFFMASK) && 1195*7c478bd9Sstevel@tonic-gate (ipc->ip_p == IPPROTO_ICMP)) { 1196*7c478bd9Sstevel@tonic-gate icmp = (icmphdr_t *)((char *)ipc + hl); 1197*7c478bd9Sstevel@tonic-gate 1198*7c478bd9Sstevel@tonic-gate t += strlen(t); 1199*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s -", 1200*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 1201*7c478bd9Sstevel@tonic-gate t += strlen(t); 1202*7c478bd9Sstevel@tonic-gate (void) sprintf(t, 1203*7c478bd9Sstevel@tonic-gate " %s PR icmp len %hu %hu icmp %d/%d", 1204*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 1205*7c478bd9Sstevel@tonic-gate IP_HL(ipc) << 2, i, 1206*7c478bd9Sstevel@tonic-gate icmp->icmp_type, icmp->icmp_code); 1207*7c478bd9Sstevel@tonic-gate } else { 1208*7c478bd9Sstevel@tonic-gate t += strlen(t); 1209*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " for %s -", 1210*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 1211*7c478bd9Sstevel@tonic-gate t += strlen(t); 1212*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " %s PR %s len %hu (%hu)", 1213*7c478bd9Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), proto, 1214*7c478bd9Sstevel@tonic-gate IP_HL(ipc) << 2, i); 1215*7c478bd9Sstevel@tonic-gate t += strlen(t); 1216*7c478bd9Sstevel@tonic-gate if (ipoff & IP_OFFMASK) { 1217*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " frag %s%s%hu@%hu", 1218*7c478bd9Sstevel@tonic-gate ipoff & IP_MF ? "+" : "", 1219*7c478bd9Sstevel@tonic-gate ipoff & IP_DF ? "-" : "", 1220*7c478bd9Sstevel@tonic-gate i - (IP_HL(ipc) << 2), 1221*7c478bd9Sstevel@tonic-gate (ipoff & IP_OFFMASK) << 3); 1222*7c478bd9Sstevel@tonic-gate } 1223*7c478bd9Sstevel@tonic-gate } 1224*7c478bd9Sstevel@tonic-gate 1225*7c478bd9Sstevel@tonic-gate } 1226*7c478bd9Sstevel@tonic-gate } else { 1227*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 1228*7c478bd9Sstevel@tonic-gate t += strlen(t); 1229*7c478bd9Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu (%hu)", 1230*7c478bd9Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 1231*7c478bd9Sstevel@tonic-gate t += strlen(t); 1232*7c478bd9Sstevel@tonic-gate if (off & IP_OFFMASK) 1233*7c478bd9Sstevel@tonic-gate (void) sprintf(t, " frag %s%s%hu@%hu", 1234*7c478bd9Sstevel@tonic-gate ipoff & IP_MF ? "+" : "", 1235*7c478bd9Sstevel@tonic-gate ipoff & IP_DF ? "-" : "", 1236*7c478bd9Sstevel@tonic-gate plen - hl, (off & IP_OFFMASK) << 3); 1237*7c478bd9Sstevel@tonic-gate } 1238*7c478bd9Sstevel@tonic-gate t += strlen(t); 1239*7c478bd9Sstevel@tonic-gate 1240*7c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPSTATE) { 1241*7c478bd9Sstevel@tonic-gate (void) strcpy(t, " K-S"); 1242*7c478bd9Sstevel@tonic-gate t += strlen(t); 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPFRAG) { 1246*7c478bd9Sstevel@tonic-gate (void) strcpy(t, " K-F"); 1247*7c478bd9Sstevel@tonic-gate t += strlen(t); 1248*7c478bd9Sstevel@tonic-gate } 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate if (ipf->fl_dir == 0) 1251*7c478bd9Sstevel@tonic-gate strcpy(t, " IN"); 1252*7c478bd9Sstevel@tonic-gate else if (ipf->fl_dir == 1) 1253*7c478bd9Sstevel@tonic-gate strcpy(t, " OUT"); 1254*7c478bd9Sstevel@tonic-gate t += strlen(t); 1255*7c478bd9Sstevel@tonic-gate if (ipf->fl_tag) { 1256*7c478bd9Sstevel@tonic-gate sprintf(t, " tag %d", ipf->fl_tag); 1257*7c478bd9Sstevel@tonic-gate t += strlen(t); 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate printipflog: 1260*7c478bd9Sstevel@tonic-gate *t++ = '\n'; 1261*7c478bd9Sstevel@tonic-gate *t++ = '\0'; 1262*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 1263*7c478bd9Sstevel@tonic-gate syslog(lvl, "%s", line); 1264*7c478bd9Sstevel@tonic-gate else 1265*7c478bd9Sstevel@tonic-gate (void) fprintf(log, "%s", line); 1266*7c478bd9Sstevel@tonic-gate if (opts & OPT_HEXHDR) 1267*7c478bd9Sstevel@tonic-gate dumphex(log, opts, buf, sizeof(iplog_t) + sizeof(*ipf)); 1268*7c478bd9Sstevel@tonic-gate if (opts & OPT_HEXBODY) 1269*7c478bd9Sstevel@tonic-gate dumphex(log, opts, (char *)ip, ipf->fl_plen + ipf->fl_hlen); 1270*7c478bd9Sstevel@tonic-gate else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) 1271*7c478bd9Sstevel@tonic-gate dumphex(log, opts, (char *)ip + ipf->fl_hlen, ipf->fl_plen); 1272*7c478bd9Sstevel@tonic-gate if (conf_file) 1273*7c478bd9Sstevel@tonic-gate check_action(buf, opts, line); 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate 1277*7c478bd9Sstevel@tonic-gate static void usage(prog) 1278*7c478bd9Sstevel@tonic-gate char *prog; 1279*7c478bd9Sstevel@tonic-gate { 1280*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: [-abDFhnpstvxX] %s %s %s %s %s %s\n", 1281*7c478bd9Sstevel@tonic-gate prog, "[-N device]", "[ [-o [NSI]] [-O [NSI]]", 1282*7c478bd9Sstevel@tonic-gate "[-P pidfile]", "[-S device]", "[-f device]", 1283*7c478bd9Sstevel@tonic-gate "filename"); 1284*7c478bd9Sstevel@tonic-gate exit(1); 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate static void write_pid(file) 1289*7c478bd9Sstevel@tonic-gate char *file; 1290*7c478bd9Sstevel@tonic-gate { 1291*7c478bd9Sstevel@tonic-gate FILE *fp = NULL; 1292*7c478bd9Sstevel@tonic-gate int fd; 1293*7c478bd9Sstevel@tonic-gate 1294*7c478bd9Sstevel@tonic-gate if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) { 1295*7c478bd9Sstevel@tonic-gate fp = fdopen(fd, "w"); 1296*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 1297*7c478bd9Sstevel@tonic-gate close(fd); 1298*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1299*7c478bd9Sstevel@tonic-gate "unable to open/create pid file: %s\n", file); 1300*7c478bd9Sstevel@tonic-gate return; 1301*7c478bd9Sstevel@tonic-gate } 1302*7c478bd9Sstevel@tonic-gate fprintf(fp, "%d", getpid()); 1303*7c478bd9Sstevel@tonic-gate fclose(fp); 1304*7c478bd9Sstevel@tonic-gate } 1305*7c478bd9Sstevel@tonic-gate } 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate 1308*7c478bd9Sstevel@tonic-gate static void flushlogs(file, log) 1309*7c478bd9Sstevel@tonic-gate char *file; 1310*7c478bd9Sstevel@tonic-gate FILE *log; 1311*7c478bd9Sstevel@tonic-gate { 1312*7c478bd9Sstevel@tonic-gate int fd, flushed = 0; 1313*7c478bd9Sstevel@tonic-gate 1314*7c478bd9Sstevel@tonic-gate if ((fd = open(file, O_RDWR)) == -1) { 1315*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: open: %s\n", 1316*7c478bd9Sstevel@tonic-gate file, STRERROR(errno)); 1317*7c478bd9Sstevel@tonic-gate exit(1); 1318*7c478bd9Sstevel@tonic-gate } 1319*7c478bd9Sstevel@tonic-gate 1320*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { 1321*7c478bd9Sstevel@tonic-gate printf("%d bytes flushed from log buffer\n", 1322*7c478bd9Sstevel@tonic-gate flushed); 1323*7c478bd9Sstevel@tonic-gate fflush(stdout); 1324*7c478bd9Sstevel@tonic-gate } else 1325*7c478bd9Sstevel@tonic-gate perror("SIOCIPFFB"); 1326*7c478bd9Sstevel@tonic-gate (void) close(fd); 1327*7c478bd9Sstevel@tonic-gate 1328*7c478bd9Sstevel@tonic-gate if (flushed) { 1329*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 1330*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, "%d bytes flushed from log\n", 1331*7c478bd9Sstevel@tonic-gate flushed); 1332*7c478bd9Sstevel@tonic-gate else if (log != stdout) 1333*7c478bd9Sstevel@tonic-gate fprintf(log, "%d bytes flushed from log\n", flushed); 1334*7c478bd9Sstevel@tonic-gate } 1335*7c478bd9Sstevel@tonic-gate } 1336*7c478bd9Sstevel@tonic-gate 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate static void logopts(turnon, options) 1339*7c478bd9Sstevel@tonic-gate int turnon; 1340*7c478bd9Sstevel@tonic-gate char *options; 1341*7c478bd9Sstevel@tonic-gate { 1342*7c478bd9Sstevel@tonic-gate int flags = 0; 1343*7c478bd9Sstevel@tonic-gate char *s; 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate for (s = options; *s; s++) 1346*7c478bd9Sstevel@tonic-gate { 1347*7c478bd9Sstevel@tonic-gate switch (*s) 1348*7c478bd9Sstevel@tonic-gate { 1349*7c478bd9Sstevel@tonic-gate case 'N' : 1350*7c478bd9Sstevel@tonic-gate flags |= OPT_NAT; 1351*7c478bd9Sstevel@tonic-gate break; 1352*7c478bd9Sstevel@tonic-gate case 'S' : 1353*7c478bd9Sstevel@tonic-gate flags |= OPT_STATE; 1354*7c478bd9Sstevel@tonic-gate break; 1355*7c478bd9Sstevel@tonic-gate case 'I' : 1356*7c478bd9Sstevel@tonic-gate flags |= OPT_FILTER; 1357*7c478bd9Sstevel@tonic-gate break; 1358*7c478bd9Sstevel@tonic-gate default : 1359*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Unknown log option %c\n", *s); 1360*7c478bd9Sstevel@tonic-gate exit(1); 1361*7c478bd9Sstevel@tonic-gate } 1362*7c478bd9Sstevel@tonic-gate } 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate if (turnon) 1365*7c478bd9Sstevel@tonic-gate opts |= flags; 1366*7c478bd9Sstevel@tonic-gate else 1367*7c478bd9Sstevel@tonic-gate opts &= ~(flags); 1368*7c478bd9Sstevel@tonic-gate } 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate 1371*7c478bd9Sstevel@tonic-gate int main(argc, argv) 1372*7c478bd9Sstevel@tonic-gate int argc; 1373*7c478bd9Sstevel@tonic-gate char *argv[]; 1374*7c478bd9Sstevel@tonic-gate { 1375*7c478bd9Sstevel@tonic-gate struct stat sb; 1376*7c478bd9Sstevel@tonic-gate FILE *log = stdout; 1377*7c478bd9Sstevel@tonic-gate int fd[3], doread, n, i; 1378*7c478bd9Sstevel@tonic-gate int tr, nr, regular[3], c; 1379*7c478bd9Sstevel@tonic-gate int fdt[3], devices = 0, make_daemon = 0; 1380*7c478bd9Sstevel@tonic-gate char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s; 1381*7c478bd9Sstevel@tonic-gate extern int optind; 1382*7c478bd9Sstevel@tonic-gate extern char *optarg; 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate fd[0] = fd[1] = fd[2] = -1; 1385*7c478bd9Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 1386*7c478bd9Sstevel@tonic-gate iplfile[0] = IPL_NAME; 1387*7c478bd9Sstevel@tonic-gate iplfile[1] = IPNAT_NAME; 1388*7c478bd9Sstevel@tonic-gate iplfile[2] = IPSTATE_NAME; 1389*7c478bd9Sstevel@tonic-gate 1390*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "?abB:C:Df:FhnN:o:O:pP:sS:tvxX")) != -1) 1391*7c478bd9Sstevel@tonic-gate switch (c) 1392*7c478bd9Sstevel@tonic-gate { 1393*7c478bd9Sstevel@tonic-gate case 'a' : 1394*7c478bd9Sstevel@tonic-gate opts |= OPT_LOGALL; 1395*7c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 1396*7c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 1397*7c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 1398*7c478bd9Sstevel@tonic-gate break; 1399*7c478bd9Sstevel@tonic-gate case 'b' : 1400*7c478bd9Sstevel@tonic-gate opts |= OPT_LOGBODY; 1401*7c478bd9Sstevel@tonic-gate break; 1402*7c478bd9Sstevel@tonic-gate case 'B' : 1403*7c478bd9Sstevel@tonic-gate binarylogfile = optarg; 1404*7c478bd9Sstevel@tonic-gate binarylog = fopen(optarg, "a"); 1405*7c478bd9Sstevel@tonic-gate break; 1406*7c478bd9Sstevel@tonic-gate case 'C' : 1407*7c478bd9Sstevel@tonic-gate conf_file = optarg; 1408*7c478bd9Sstevel@tonic-gate break; 1409*7c478bd9Sstevel@tonic-gate case 'D' : 1410*7c478bd9Sstevel@tonic-gate make_daemon = 1; 1411*7c478bd9Sstevel@tonic-gate break; 1412*7c478bd9Sstevel@tonic-gate case 'f' : case 'I' : 1413*7c478bd9Sstevel@tonic-gate opts |= OPT_FILTER; 1414*7c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 1415*7c478bd9Sstevel@tonic-gate iplfile[0] = optarg; 1416*7c478bd9Sstevel@tonic-gate break; 1417*7c478bd9Sstevel@tonic-gate case 'F' : 1418*7c478bd9Sstevel@tonic-gate flushlogs(iplfile[0], log); 1419*7c478bd9Sstevel@tonic-gate flushlogs(iplfile[1], log); 1420*7c478bd9Sstevel@tonic-gate flushlogs(iplfile[2], log); 1421*7c478bd9Sstevel@tonic-gate break; 1422*7c478bd9Sstevel@tonic-gate case 'n' : 1423*7c478bd9Sstevel@tonic-gate opts |= OPT_RESOLVE; 1424*7c478bd9Sstevel@tonic-gate break; 1425*7c478bd9Sstevel@tonic-gate case 'N' : 1426*7c478bd9Sstevel@tonic-gate opts |= OPT_NAT; 1427*7c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 1428*7c478bd9Sstevel@tonic-gate iplfile[1] = optarg; 1429*7c478bd9Sstevel@tonic-gate break; 1430*7c478bd9Sstevel@tonic-gate case 'o' : case 'O' : 1431*7c478bd9Sstevel@tonic-gate logopts(c == 'o', optarg); 1432*7c478bd9Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 1433*7c478bd9Sstevel@tonic-gate if (opts & OPT_FILTER) 1434*7c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 1435*7c478bd9Sstevel@tonic-gate if (opts & OPT_NAT) 1436*7c478bd9Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 1437*7c478bd9Sstevel@tonic-gate if (opts & OPT_STATE) 1438*7c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 1439*7c478bd9Sstevel@tonic-gate break; 1440*7c478bd9Sstevel@tonic-gate case 'p' : 1441*7c478bd9Sstevel@tonic-gate opts |= OPT_PORTNUM; 1442*7c478bd9Sstevel@tonic-gate break; 1443*7c478bd9Sstevel@tonic-gate case 'P' : 1444*7c478bd9Sstevel@tonic-gate pidfile = optarg; 1445*7c478bd9Sstevel@tonic-gate break; 1446*7c478bd9Sstevel@tonic-gate case 's' : 1447*7c478bd9Sstevel@tonic-gate s = strrchr(argv[0], '/'); 1448*7c478bd9Sstevel@tonic-gate if (s == NULL) 1449*7c478bd9Sstevel@tonic-gate s = argv[0]; 1450*7c478bd9Sstevel@tonic-gate else 1451*7c478bd9Sstevel@tonic-gate s++; 1452*7c478bd9Sstevel@tonic-gate openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); 1453*7c478bd9Sstevel@tonic-gate s = NULL; 1454*7c478bd9Sstevel@tonic-gate opts |= OPT_SYSLOG; 1455*7c478bd9Sstevel@tonic-gate log = NULL; 1456*7c478bd9Sstevel@tonic-gate break; 1457*7c478bd9Sstevel@tonic-gate case 'S' : 1458*7c478bd9Sstevel@tonic-gate opts |= OPT_STATE; 1459*7c478bd9Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 1460*7c478bd9Sstevel@tonic-gate iplfile[2] = optarg; 1461*7c478bd9Sstevel@tonic-gate break; 1462*7c478bd9Sstevel@tonic-gate case 't' : 1463*7c478bd9Sstevel@tonic-gate opts |= OPT_TAIL; 1464*7c478bd9Sstevel@tonic-gate break; 1465*7c478bd9Sstevel@tonic-gate case 'v' : 1466*7c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 1467*7c478bd9Sstevel@tonic-gate break; 1468*7c478bd9Sstevel@tonic-gate case 'x' : 1469*7c478bd9Sstevel@tonic-gate opts |= OPT_HEXBODY; 1470*7c478bd9Sstevel@tonic-gate break; 1471*7c478bd9Sstevel@tonic-gate case 'X' : 1472*7c478bd9Sstevel@tonic-gate opts |= OPT_HEXHDR; 1473*7c478bd9Sstevel@tonic-gate break; 1474*7c478bd9Sstevel@tonic-gate default : 1475*7c478bd9Sstevel@tonic-gate case 'h' : 1476*7c478bd9Sstevel@tonic-gate case '?' : 1477*7c478bd9Sstevel@tonic-gate usage(argv[0]); 1478*7c478bd9Sstevel@tonic-gate } 1479*7c478bd9Sstevel@tonic-gate 1480*7c478bd9Sstevel@tonic-gate init_tabs(); 1481*7c478bd9Sstevel@tonic-gate if (conf_file) 1482*7c478bd9Sstevel@tonic-gate if (load_config(conf_file) == -1) 1483*7c478bd9Sstevel@tonic-gate exit(1); 1484*7c478bd9Sstevel@tonic-gate 1485*7c478bd9Sstevel@tonic-gate /* 1486*7c478bd9Sstevel@tonic-gate * Default action is to only open the filter log file. 1487*7c478bd9Sstevel@tonic-gate */ 1488*7c478bd9Sstevel@tonic-gate if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) 1489*7c478bd9Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 1490*7c478bd9Sstevel@tonic-gate 1491*7c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 1492*7c478bd9Sstevel@tonic-gate if (fdt[i] == -1) 1493*7c478bd9Sstevel@tonic-gate continue; 1494*7c478bd9Sstevel@tonic-gate if (!strcmp(iplfile[i], "-")) 1495*7c478bd9Sstevel@tonic-gate fd[i] = 0; 1496*7c478bd9Sstevel@tonic-gate else { 1497*7c478bd9Sstevel@tonic-gate if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { 1498*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1499*7c478bd9Sstevel@tonic-gate "%s: open: %s\n", iplfile[i], 1500*7c478bd9Sstevel@tonic-gate STRERROR(errno)); 1501*7c478bd9Sstevel@tonic-gate exit(1); 1502*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1503*7c478bd9Sstevel@tonic-gate } 1504*7c478bd9Sstevel@tonic-gate if (fstat(fd[i], &sb) == -1) { 1505*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%d: fstat: %s\n", 1506*7c478bd9Sstevel@tonic-gate fd[i], STRERROR(errno)); 1507*7c478bd9Sstevel@tonic-gate exit(1); 1508*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1509*7c478bd9Sstevel@tonic-gate } 1510*7c478bd9Sstevel@tonic-gate if (!(regular[i] = !S_ISCHR(sb.st_mode))) 1511*7c478bd9Sstevel@tonic-gate devices++; 1512*7c478bd9Sstevel@tonic-gate } 1513*7c478bd9Sstevel@tonic-gate } 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 1516*7c478bd9Sstevel@tonic-gate logfile = argv[optind]; 1517*7c478bd9Sstevel@tonic-gate log = logfile ? fopen(logfile, "a") : stdout; 1518*7c478bd9Sstevel@tonic-gate if (log == NULL) { 1519*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: fopen: %s\n", 1520*7c478bd9Sstevel@tonic-gate argv[optind], STRERROR(errno)); 1521*7c478bd9Sstevel@tonic-gate exit(1); 1522*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1523*7c478bd9Sstevel@tonic-gate } 1524*7c478bd9Sstevel@tonic-gate setvbuf(log, NULL, _IONBF, 0); 1525*7c478bd9Sstevel@tonic-gate } else 1526*7c478bd9Sstevel@tonic-gate log = NULL; 1527*7c478bd9Sstevel@tonic-gate 1528*7c478bd9Sstevel@tonic-gate if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { 1529*7c478bd9Sstevel@tonic-gate #if BSD >= 199306 1530*7c478bd9Sstevel@tonic-gate daemon(0, !(opts & OPT_SYSLOG)); 1531*7c478bd9Sstevel@tonic-gate #else 1532*7c478bd9Sstevel@tonic-gate int pid; 1533*7c478bd9Sstevel@tonic-gate if ((pid = fork()) > 0) 1534*7c478bd9Sstevel@tonic-gate exit(0); 1535*7c478bd9Sstevel@tonic-gate if (pid < 0) { 1536*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: fork() failed: %s\n", 1537*7c478bd9Sstevel@tonic-gate argv[0], STRERROR(errno)); 1538*7c478bd9Sstevel@tonic-gate exit(1); 1539*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1540*7c478bd9Sstevel@tonic-gate } 1541*7c478bd9Sstevel@tonic-gate setsid(); 1542*7c478bd9Sstevel@tonic-gate if ((opts & OPT_SYSLOG)) 1543*7c478bd9Sstevel@tonic-gate close(2); 1544*7c478bd9Sstevel@tonic-gate #endif /* !BSD */ 1545*7c478bd9Sstevel@tonic-gate close(0); 1546*7c478bd9Sstevel@tonic-gate close(1); 1547*7c478bd9Sstevel@tonic-gate } 1548*7c478bd9Sstevel@tonic-gate write_pid(pidfile); 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate signal(SIGHUP, handlehup); 1551*7c478bd9Sstevel@tonic-gate 1552*7c478bd9Sstevel@tonic-gate for (doread = 1; doread; ) { 1553*7c478bd9Sstevel@tonic-gate nr = 0; 1554*7c478bd9Sstevel@tonic-gate 1555*7c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 1556*7c478bd9Sstevel@tonic-gate tr = 0; 1557*7c478bd9Sstevel@tonic-gate if (fdt[i] == -1) 1558*7c478bd9Sstevel@tonic-gate continue; 1559*7c478bd9Sstevel@tonic-gate if (!regular[i]) { 1560*7c478bd9Sstevel@tonic-gate if (ioctl(fd[i], FIONREAD, &tr) == -1) { 1561*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 1562*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, 1563*7c478bd9Sstevel@tonic-gate "ioctl(FIONREAD): %m"); 1564*7c478bd9Sstevel@tonic-gate else 1565*7c478bd9Sstevel@tonic-gate perror("ioctl(FIONREAD)"); 1566*7c478bd9Sstevel@tonic-gate exit(1); 1567*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1568*7c478bd9Sstevel@tonic-gate } 1569*7c478bd9Sstevel@tonic-gate } else { 1570*7c478bd9Sstevel@tonic-gate tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); 1571*7c478bd9Sstevel@tonic-gate if (!tr && !(opts & OPT_TAIL)) 1572*7c478bd9Sstevel@tonic-gate doread = 0; 1573*7c478bd9Sstevel@tonic-gate } 1574*7c478bd9Sstevel@tonic-gate if (!tr) 1575*7c478bd9Sstevel@tonic-gate continue; 1576*7c478bd9Sstevel@tonic-gate nr += tr; 1577*7c478bd9Sstevel@tonic-gate 1578*7c478bd9Sstevel@tonic-gate tr = read_log(fd[i], &n, buf, sizeof(buf)); 1579*7c478bd9Sstevel@tonic-gate if (donehup) { 1580*7c478bd9Sstevel@tonic-gate donehup = 0; 1581*7c478bd9Sstevel@tonic-gate if (newlog) { 1582*7c478bd9Sstevel@tonic-gate fclose(log); 1583*7c478bd9Sstevel@tonic-gate log = newlog; 1584*7c478bd9Sstevel@tonic-gate newlog = NULL; 1585*7c478bd9Sstevel@tonic-gate } 1586*7c478bd9Sstevel@tonic-gate if (newbinarylog) { 1587*7c478bd9Sstevel@tonic-gate fclose(binarylog); 1588*7c478bd9Sstevel@tonic-gate binarylog = newbinarylog; 1589*7c478bd9Sstevel@tonic-gate newbinarylog = NULL; 1590*7c478bd9Sstevel@tonic-gate } 1591*7c478bd9Sstevel@tonic-gate } 1592*7c478bd9Sstevel@tonic-gate 1593*7c478bd9Sstevel@tonic-gate switch (tr) 1594*7c478bd9Sstevel@tonic-gate { 1595*7c478bd9Sstevel@tonic-gate case -1 : 1596*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 1597*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "read: %m\n"); 1598*7c478bd9Sstevel@tonic-gate else 1599*7c478bd9Sstevel@tonic-gate perror("read"); 1600*7c478bd9Sstevel@tonic-gate doread = 0; 1601*7c478bd9Sstevel@tonic-gate break; 1602*7c478bd9Sstevel@tonic-gate case 1 : 1603*7c478bd9Sstevel@tonic-gate if (opts & OPT_SYSLOG) 1604*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "aborting logging\n"); 1605*7c478bd9Sstevel@tonic-gate else 1606*7c478bd9Sstevel@tonic-gate fprintf(log, "aborting logging\n"); 1607*7c478bd9Sstevel@tonic-gate doread = 0; 1608*7c478bd9Sstevel@tonic-gate break; 1609*7c478bd9Sstevel@tonic-gate case 2 : 1610*7c478bd9Sstevel@tonic-gate break; 1611*7c478bd9Sstevel@tonic-gate case 0 : 1612*7c478bd9Sstevel@tonic-gate if (n > 0) { 1613*7c478bd9Sstevel@tonic-gate print_log(fdt[i], log, buf, n); 1614*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) 1615*7c478bd9Sstevel@tonic-gate fflush(log); 1616*7c478bd9Sstevel@tonic-gate } 1617*7c478bd9Sstevel@tonic-gate break; 1618*7c478bd9Sstevel@tonic-gate } 1619*7c478bd9Sstevel@tonic-gate } 1620*7c478bd9Sstevel@tonic-gate if (!nr && ((opts & OPT_TAIL) || devices)) 1621*7c478bd9Sstevel@tonic-gate sleep(1); 1622*7c478bd9Sstevel@tonic-gate } 1623*7c478bd9Sstevel@tonic-gate return(0); 1624*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1625*7c478bd9Sstevel@tonic-gate } 1626