10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (C) 1993-2001, 2003 by Darren Reed. 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 50Sstevel@tonic-gate * 62085Sdr146992 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 70Sstevel@tonic-gate * Use is subject to license terms. 80Sstevel@tonic-gate */ 90Sstevel@tonic-gate 100Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 110Sstevel@tonic-gate 120Sstevel@tonic-gate #ifndef SOLARIS 130Sstevel@tonic-gate #define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun) 140Sstevel@tonic-gate #endif 150Sstevel@tonic-gate 160Sstevel@tonic-gate #include <sys/types.h> 170Sstevel@tonic-gate #include <sys/stat.h> 180Sstevel@tonic-gate #include <sys/param.h> 190Sstevel@tonic-gate #include <sys/file.h> 200Sstevel@tonic-gate #include <sys/time.h> 210Sstevel@tonic-gate #define _KERNEL 220Sstevel@tonic-gate #include <sys/uio.h> 230Sstevel@tonic-gate #undef _KERNEL 240Sstevel@tonic-gate #include <sys/socket.h> 250Sstevel@tonic-gate #include <sys/ioctl.h> 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <stdio.h> 280Sstevel@tonic-gate #include <unistd.h> 290Sstevel@tonic-gate #include <string.h> 300Sstevel@tonic-gate #include <fcntl.h> 310Sstevel@tonic-gate #include <errno.h> 32*2393Syz155240 #include <time.h> 330Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__) 340Sstevel@tonic-gate # if (__FreeBSD_version >= 300000) 350Sstevel@tonic-gate # include <sys/dirent.h> 360Sstevel@tonic-gate # else 370Sstevel@tonic-gate # include <sys/dir.h> 380Sstevel@tonic-gate # endif 390Sstevel@tonic-gate #else 400Sstevel@tonic-gate # include <sys/filio.h> 410Sstevel@tonic-gate # include <sys/byteorder.h> 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate #if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__)) 440Sstevel@tonic-gate # include <strings.h> 450Sstevel@tonic-gate #endif 460Sstevel@tonic-gate #include <signal.h> 470Sstevel@tonic-gate #include <stdlib.h> 480Sstevel@tonic-gate #include <stddef.h> 490Sstevel@tonic-gate #include <netinet/in.h> 500Sstevel@tonic-gate #include <netinet/in_systm.h> 510Sstevel@tonic-gate #include <net/if.h> 520Sstevel@tonic-gate #include <netinet/ip.h> 53*2393Syz155240 #if !defined(__hpux) && !defined(linux) 540Sstevel@tonic-gate # include <netinet/tcp_fsm.h> 550Sstevel@tonic-gate #endif 560Sstevel@tonic-gate #include <netdb.h> 570Sstevel@tonic-gate #include <arpa/inet.h> 580Sstevel@tonic-gate #include <arpa/nameser.h> 590Sstevel@tonic-gate #ifdef __hpux 600Sstevel@tonic-gate # undef NOERROR 610Sstevel@tonic-gate #endif 620Sstevel@tonic-gate #include <resolv.h> 630Sstevel@tonic-gate 64*2393Syz155240 #if !defined(linux) 65*2393Syz155240 # include <sys/protosw.h> 66*2393Syz155240 # include <netinet/ip_var.h> 67*2393Syz155240 #endif 680Sstevel@tonic-gate 690Sstevel@tonic-gate #include <netinet/tcp.h> 700Sstevel@tonic-gate #include <netinet/ip_icmp.h> 710Sstevel@tonic-gate 720Sstevel@tonic-gate #include <ctype.h> 730Sstevel@tonic-gate #include <syslog.h> 740Sstevel@tonic-gate 75*2393Syz155240 #include "netinet/ip_compat.h" 760Sstevel@tonic-gate #include <netinet/tcpip.h> 770Sstevel@tonic-gate #include "netinet/ip_fil.h" 780Sstevel@tonic-gate #include "netinet/ip_nat.h" 790Sstevel@tonic-gate #include "netinet/ip_state.h" 800Sstevel@tonic-gate #include "netinet/ip_proxy.h" 810Sstevel@tonic-gate #include "ipmon.h" 820Sstevel@tonic-gate 830Sstevel@tonic-gate #if !defined(lint) 840Sstevel@tonic-gate static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; 85*2393Syz155240 static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.10 2005/06/18 02:41:35 darrenr Exp $"; 860Sstevel@tonic-gate #endif 870Sstevel@tonic-gate 880Sstevel@tonic-gate 890Sstevel@tonic-gate #if defined(sun) && !defined(SOLARIS2) 900Sstevel@tonic-gate #define STRERROR(x) sys_errlist[x] 910Sstevel@tonic-gate extern char *sys_errlist[]; 920Sstevel@tonic-gate #else 930Sstevel@tonic-gate #define STRERROR(x) strerror(x) 940Sstevel@tonic-gate #endif 950Sstevel@tonic-gate 960Sstevel@tonic-gate 970Sstevel@tonic-gate struct flags { 980Sstevel@tonic-gate int value; 990Sstevel@tonic-gate char flag; 1000Sstevel@tonic-gate }; 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate typedef struct icmp_subtype { 1040Sstevel@tonic-gate int ist_val; 1050Sstevel@tonic-gate char *ist_name; 1060Sstevel@tonic-gate } icmp_subtype_t; 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate typedef struct icmp_type { 1090Sstevel@tonic-gate int it_val; 1100Sstevel@tonic-gate struct icmp_subtype *it_subtable; 1110Sstevel@tonic-gate size_t it_stsize; 1120Sstevel@tonic-gate char *it_name; 1130Sstevel@tonic-gate } icmp_type_t; 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate #define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate struct flags tcpfl[] = { 1200Sstevel@tonic-gate { TH_ACK, 'A' }, 1210Sstevel@tonic-gate { TH_RST, 'R' }, 1220Sstevel@tonic-gate { TH_SYN, 'S' }, 1230Sstevel@tonic-gate { TH_FIN, 'F' }, 1240Sstevel@tonic-gate { TH_URG, 'U' }, 1250Sstevel@tonic-gate { TH_PUSH,'P' }, 1260Sstevel@tonic-gate { TH_ECN, 'E' }, 1270Sstevel@tonic-gate { TH_CWR, 'C' }, 1280Sstevel@tonic-gate { 0, '\0' } 1290Sstevel@tonic-gate }; 1300Sstevel@tonic-gate 1312085Sdr146992 #if defined(__hpux) || (SOLARIS && (SOLARIS2 < 10)) 1320Sstevel@tonic-gate static char *pidfile = "/etc/ipf/ipmon.pid"; 1330Sstevel@tonic-gate #else 1342085Sdr146992 # if (BSD >= 199306) || SOLARIS 1350Sstevel@tonic-gate static char *pidfile = "/var/run/ipmon.pid"; 1360Sstevel@tonic-gate # else 1370Sstevel@tonic-gate static char *pidfile = "/etc/ipmon.pid"; 1380Sstevel@tonic-gate # endif 1390Sstevel@tonic-gate #endif 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate static char line[2048]; 1420Sstevel@tonic-gate static int opts = 0; 1430Sstevel@tonic-gate static char *logfile = NULL; 1440Sstevel@tonic-gate static FILE *binarylog = NULL; 1450Sstevel@tonic-gate static char *binarylogfile = NULL; 1460Sstevel@tonic-gate static int donehup = 0; 1470Sstevel@tonic-gate static void usage __P((char *)); 1480Sstevel@tonic-gate static void handlehup __P((int)); 1490Sstevel@tonic-gate static void flushlogs __P((char *, FILE *)); 1500Sstevel@tonic-gate static void print_log __P((int, FILE *, char *, int)); 1510Sstevel@tonic-gate static void print_ipflog __P((FILE *, char *, int)); 1520Sstevel@tonic-gate static void print_natlog __P((FILE *, char *, int)); 1530Sstevel@tonic-gate static void print_statelog __P((FILE *, char *, int)); 1540Sstevel@tonic-gate static int read_log __P((int, int *, char *, int)); 1550Sstevel@tonic-gate static void write_pid __P((char *)); 1560Sstevel@tonic-gate static char *icmpname __P((u_int, u_int)); 1570Sstevel@tonic-gate static char *icmpname6 __P((u_int, u_int)); 1580Sstevel@tonic-gate static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t)); 1590Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t)); 1600Sstevel@tonic-gate #ifdef __hpux 1610Sstevel@tonic-gate static struct tm *get_tm __P((u_32_t)); 1620Sstevel@tonic-gate #else 1630Sstevel@tonic-gate static struct tm *get_tm __P((time_t)); 1640Sstevel@tonic-gate #endif 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate char *hostname __P((int, int, u_32_t *)); 1670Sstevel@tonic-gate char *portname __P((int, char *, u_int)); 1680Sstevel@tonic-gate int main __P((int, char *[])); 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate static void logopts __P((int, char *)); 1710Sstevel@tonic-gate static void init_tabs __P((void)); 1720Sstevel@tonic-gate static char *getproto __P((u_int)); 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate static char **protocols = NULL; 1750Sstevel@tonic-gate static char **udp_ports = NULL; 1760Sstevel@tonic-gate static char **tcp_ports = NULL; 1770Sstevel@tonic-gate static char *conf_file = NULL; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate #define OPT_SYSLOG 0x001 1810Sstevel@tonic-gate #define OPT_RESOLVE 0x002 1820Sstevel@tonic-gate #define OPT_HEXBODY 0x004 1830Sstevel@tonic-gate #define OPT_VERBOSE 0x008 1840Sstevel@tonic-gate #define OPT_HEXHDR 0x010 1850Sstevel@tonic-gate #define OPT_TAIL 0x020 1860Sstevel@tonic-gate #define OPT_NAT 0x080 1870Sstevel@tonic-gate #define OPT_STATE 0x100 1880Sstevel@tonic-gate #define OPT_FILTER 0x200 1890Sstevel@tonic-gate #define OPT_PORTNUM 0x400 1900Sstevel@tonic-gate #define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) 1910Sstevel@tonic-gate #define OPT_LOGBODY 0x800 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate #define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate #ifndef LOGFAC 1960Sstevel@tonic-gate #define LOGFAC LOG_LOCAL0 1970Sstevel@tonic-gate #endif 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate static icmp_subtype_t icmpunreachnames[] = { 2010Sstevel@tonic-gate { ICMP_UNREACH_NET, "net" }, 2020Sstevel@tonic-gate { ICMP_UNREACH_HOST, "host" }, 2030Sstevel@tonic-gate { ICMP_UNREACH_PROTOCOL, "protocol" }, 2040Sstevel@tonic-gate { ICMP_UNREACH_PORT, "port" }, 2050Sstevel@tonic-gate { ICMP_UNREACH_NEEDFRAG, "needfrag" }, 2060Sstevel@tonic-gate { ICMP_UNREACH_SRCFAIL, "srcfail" }, 2070Sstevel@tonic-gate { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, 2080Sstevel@tonic-gate { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, 2090Sstevel@tonic-gate { ICMP_UNREACH_NET, "isolated" }, 2100Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, 2110Sstevel@tonic-gate { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, 2120Sstevel@tonic-gate { ICMP_UNREACH_TOSNET, "tosnet" }, 2130Sstevel@tonic-gate { ICMP_UNREACH_TOSHOST, "toshost" }, 2140Sstevel@tonic-gate { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, 2150Sstevel@tonic-gate { -2, NULL } 2160Sstevel@tonic-gate }; 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate static icmp_subtype_t redirectnames[] = { 2190Sstevel@tonic-gate { ICMP_REDIRECT_NET, "net" }, 2200Sstevel@tonic-gate { ICMP_REDIRECT_HOST, "host" }, 2210Sstevel@tonic-gate { ICMP_REDIRECT_TOSNET, "tosnet" }, 2220Sstevel@tonic-gate { ICMP_REDIRECT_TOSHOST, "toshost" }, 2230Sstevel@tonic-gate { -2, NULL } 2240Sstevel@tonic-gate }; 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate static icmp_subtype_t timxceednames[] = { 2270Sstevel@tonic-gate { ICMP_TIMXCEED_INTRANS, "transit" }, 2280Sstevel@tonic-gate { ICMP_TIMXCEED_REASS, "reassem" }, 2290Sstevel@tonic-gate { -2, NULL } 2300Sstevel@tonic-gate }; 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate static icmp_subtype_t paramnames[] = { 2330Sstevel@tonic-gate { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, 2340Sstevel@tonic-gate { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, 2350Sstevel@tonic-gate { ICMP_PARAMPROB_LENGTH, "length" }, 2360Sstevel@tonic-gate { -2, NULL } 2370Sstevel@tonic-gate }; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate static icmp_type_t icmptypes[] = { 2400Sstevel@tonic-gate { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, 2410Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2420Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2430Sstevel@tonic-gate { ICMP_UNREACH, icmpunreachnames, 2440Sstevel@tonic-gate IST_SZ(icmpunreachnames),"unreach" }, 2450Sstevel@tonic-gate { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, 2460Sstevel@tonic-gate { ICMP_REDIRECT, redirectnames, 2470Sstevel@tonic-gate IST_SZ(redirectnames), "redirect" }, 2480Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2490Sstevel@tonic-gate { -1, NULL, 0, NULL }, 2500Sstevel@tonic-gate { ICMP_ECHO, NULL, 0, "echo" }, 2510Sstevel@tonic-gate { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, 2520Sstevel@tonic-gate { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, 2530Sstevel@tonic-gate { ICMP_TIMXCEED, timxceednames, 2540Sstevel@tonic-gate IST_SZ(timxceednames), "timxceed" }, 2550Sstevel@tonic-gate { ICMP_PARAMPROB, paramnames, 2560Sstevel@tonic-gate IST_SZ(paramnames), "paramprob" }, 2570Sstevel@tonic-gate { ICMP_TSTAMP, NULL, 0, "timestamp" }, 2580Sstevel@tonic-gate { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, 2590Sstevel@tonic-gate { ICMP_IREQ, NULL, 0, "inforeq" }, 2600Sstevel@tonic-gate { ICMP_IREQREPLY, NULL, 0, "inforeply" }, 2610Sstevel@tonic-gate { ICMP_MASKREQ, NULL, 0, "maskreq" }, 2620Sstevel@tonic-gate { ICMP_MASKREPLY, NULL, 0, "maskreply" }, 2630Sstevel@tonic-gate { -2, NULL, 0, NULL } 2640Sstevel@tonic-gate }; 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate static icmp_subtype_t icmpredirect6[] = { 2670Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, 2680Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADMIN, "admin" }, 2690Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, 2700Sstevel@tonic-gate { ICMP6_DST_UNREACH_ADDR, "address" }, 2710Sstevel@tonic-gate { ICMP6_DST_UNREACH_NOPORT, "noport" }, 2720Sstevel@tonic-gate { -2, NULL } 2730Sstevel@tonic-gate }; 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate static icmp_subtype_t icmptimexceed6[] = { 2760Sstevel@tonic-gate { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, 2770Sstevel@tonic-gate { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, 2780Sstevel@tonic-gate { -2, NULL } 2790Sstevel@tonic-gate }; 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate static icmp_subtype_t icmpparamprob6[] = { 2820Sstevel@tonic-gate { ICMP6_PARAMPROB_HEADER, "header" }, 2830Sstevel@tonic-gate { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, 2840Sstevel@tonic-gate { ICMP6_PARAMPROB_OPTION, "option" }, 2850Sstevel@tonic-gate { -2, NULL } 2860Sstevel@tonic-gate }; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate static icmp_subtype_t icmpquerysubject6[] = { 2890Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV6, "ipv6" }, 2900Sstevel@tonic-gate { ICMP6_NI_SUBJ_FQDN, "fqdn" }, 2910Sstevel@tonic-gate { ICMP6_NI_SUBJ_IPV4, "ipv4" }, 2920Sstevel@tonic-gate { -2, NULL }, 2930Sstevel@tonic-gate }; 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate static icmp_subtype_t icmpnodeinfo6[] = { 2960Sstevel@tonic-gate { ICMP6_NI_SUCCESS, "success" }, 2970Sstevel@tonic-gate { ICMP6_NI_REFUSED, "refused" }, 2980Sstevel@tonic-gate { ICMP6_NI_UNKNOWN, "unknown" }, 2990Sstevel@tonic-gate { -2, NULL } 3000Sstevel@tonic-gate }; 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate static icmp_subtype_t icmprenumber6[] = { 3030Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, 3040Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, 3050Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, 3060Sstevel@tonic-gate { -2, NULL } 3070Sstevel@tonic-gate }; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate static icmp_type_t icmptypes6[] = { 3100Sstevel@tonic-gate { 0, NULL, 0, NULL }, 3110Sstevel@tonic-gate { ICMP6_DST_UNREACH, icmpredirect6, 3120Sstevel@tonic-gate IST_SZ(icmpredirect6), "unreach" }, 3130Sstevel@tonic-gate { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, 3140Sstevel@tonic-gate { ICMP6_TIME_EXCEEDED, icmptimexceed6, 3150Sstevel@tonic-gate IST_SZ(icmptimexceed6), "timxceed" }, 3160Sstevel@tonic-gate { ICMP6_PARAM_PROB, icmpparamprob6, 3170Sstevel@tonic-gate IST_SZ(icmpparamprob6), "paramprob" }, 3180Sstevel@tonic-gate { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, 3190Sstevel@tonic-gate { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, 3200Sstevel@tonic-gate { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, 3210Sstevel@tonic-gate IST_SZ(icmpquerysubject6), "groupmemberquery" }, 3220Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, 3230Sstevel@tonic-gate { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, 3240Sstevel@tonic-gate { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, 3250Sstevel@tonic-gate { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, 3260Sstevel@tonic-gate { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, 3270Sstevel@tonic-gate { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, 3280Sstevel@tonic-gate { ND_REDIRECT, NULL, 0, "redirect" }, 3290Sstevel@tonic-gate { ICMP6_ROUTER_RENUMBERING, icmprenumber6, 3300Sstevel@tonic-gate IST_SZ(icmprenumber6), "routerrenumber" }, 3310Sstevel@tonic-gate { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, 3320Sstevel@tonic-gate { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, 3330Sstevel@tonic-gate { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, 3340Sstevel@tonic-gate { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, 3350Sstevel@tonic-gate { ICMP6_NI_QUERY, icmpnodeinfo6, 3360Sstevel@tonic-gate IST_SZ(icmpnodeinfo6), "nodeinforequest" }, 3370Sstevel@tonic-gate { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, 3380Sstevel@tonic-gate { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, 3390Sstevel@tonic-gate { MLD6_MTRACE, NULL, 0, "mtracerequest" }, 3400Sstevel@tonic-gate { -2, NULL, 0, NULL } 3410Sstevel@tonic-gate }; 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) 3440Sstevel@tonic-gate int type; 3450Sstevel@tonic-gate icmp_subtype_t *table; 3460Sstevel@tonic-gate size_t tablesz; 3470Sstevel@tonic-gate { 3480Sstevel@tonic-gate icmp_subtype_t *ist; 3490Sstevel@tonic-gate int i; 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate if (tablesz < 2) 3520Sstevel@tonic-gate return NULL; 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].ist_val)) 3550Sstevel@tonic-gate return NULL; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate i = type; 3580Sstevel@tonic-gate if (table[type].ist_val == type) 3590Sstevel@tonic-gate return table + type; 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) 3620Sstevel@tonic-gate if (ist->ist_val == type) 3630Sstevel@tonic-gate return ist; 3640Sstevel@tonic-gate return NULL; 3650Sstevel@tonic-gate } 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate static icmp_type_t *find_icmptype(type, table, tablesz) 3690Sstevel@tonic-gate int type; 3700Sstevel@tonic-gate icmp_type_t *table; 3710Sstevel@tonic-gate size_t tablesz; 3720Sstevel@tonic-gate { 3730Sstevel@tonic-gate icmp_type_t *it; 3740Sstevel@tonic-gate int i; 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate if (tablesz < 2) 3770Sstevel@tonic-gate return NULL; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate if ((type < 0) || (type > table[tablesz - 2].it_val)) 3800Sstevel@tonic-gate return NULL; 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate i = type; 3830Sstevel@tonic-gate if (table[type].it_val == type) 3840Sstevel@tonic-gate return table + type; 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate for (i = 0, it = table; it->it_val != -2; i++, it++) 3870Sstevel@tonic-gate if (it->it_val == type) 3880Sstevel@tonic-gate return it; 3890Sstevel@tonic-gate return NULL; 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate static void handlehup(sig) 3940Sstevel@tonic-gate int sig; 3950Sstevel@tonic-gate { 3960Sstevel@tonic-gate signal(SIGHUP, handlehup); 3970Sstevel@tonic-gate donehup = 1; 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate static void init_tabs() 4020Sstevel@tonic-gate { 4030Sstevel@tonic-gate struct protoent *p; 4040Sstevel@tonic-gate struct servent *s; 4050Sstevel@tonic-gate char *name, **tab; 4060Sstevel@tonic-gate int port, i; 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate if (protocols != NULL) { 4090Sstevel@tonic-gate for (i = 0; i < 256; i++) 4100Sstevel@tonic-gate if (protocols[i] != NULL) { 4110Sstevel@tonic-gate free(protocols[i]); 4120Sstevel@tonic-gate protocols[i] = NULL; 4130Sstevel@tonic-gate } 4140Sstevel@tonic-gate free(protocols); 4150Sstevel@tonic-gate protocols = NULL; 4160Sstevel@tonic-gate } 4170Sstevel@tonic-gate protocols = (char **)malloc(256 * sizeof(*protocols)); 4180Sstevel@tonic-gate if (protocols != NULL) { 4190Sstevel@tonic-gate bzero((char *)protocols, 256 * sizeof(*protocols)); 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate setprotoent(1); 4220Sstevel@tonic-gate while ((p = getprotoent()) != NULL) 4230Sstevel@tonic-gate if (p->p_proto >= 0 && p->p_proto <= 255 && 4240Sstevel@tonic-gate p->p_name != NULL && protocols[p->p_proto] == NULL) 4250Sstevel@tonic-gate protocols[p->p_proto] = strdup(p->p_name); 4260Sstevel@tonic-gate endprotoent(); 427*2393Syz155240 #if defined(_AIX51) 428*2393Syz155240 if (protocols[0]) 429*2393Syz155240 free(protocols[0]); 430*2393Syz155240 if (protocols[252]) 431*2393Syz155240 free(protocols[252]); 432*2393Syz155240 protocols[0] = "ip"; 433*2393Syz155240 protocols[252] = NULL; 434*2393Syz155240 #endif 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate if (udp_ports != NULL) { 4380Sstevel@tonic-gate for (i = 0; i < 65536; i++) 4390Sstevel@tonic-gate if (udp_ports[i] != NULL) { 4400Sstevel@tonic-gate free(udp_ports[i]); 4410Sstevel@tonic-gate udp_ports[i] = NULL; 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate free(udp_ports); 4440Sstevel@tonic-gate udp_ports = NULL; 4450Sstevel@tonic-gate } 4460Sstevel@tonic-gate udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); 4470Sstevel@tonic-gate if (udp_ports != NULL) 4480Sstevel@tonic-gate bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate if (tcp_ports != NULL) { 4510Sstevel@tonic-gate for (i = 0; i < 65536; i++) 4520Sstevel@tonic-gate if (tcp_ports[i] != NULL) { 4530Sstevel@tonic-gate free(tcp_ports[i]); 4540Sstevel@tonic-gate tcp_ports[i] = NULL; 4550Sstevel@tonic-gate } 4560Sstevel@tonic-gate free(tcp_ports); 4570Sstevel@tonic-gate tcp_ports = NULL; 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); 4600Sstevel@tonic-gate if (tcp_ports != NULL) 4610Sstevel@tonic-gate bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); 4620Sstevel@tonic-gate 4630Sstevel@tonic-gate setservent(1); 4640Sstevel@tonic-gate while ((s = getservent()) != NULL) { 4650Sstevel@tonic-gate if (s->s_proto == NULL) 4660Sstevel@tonic-gate continue; 4670Sstevel@tonic-gate else if (!strcmp(s->s_proto, "tcp")) { 4680Sstevel@tonic-gate port = ntohs(s->s_port); 4690Sstevel@tonic-gate name = s->s_name; 4700Sstevel@tonic-gate tab = tcp_ports; 4710Sstevel@tonic-gate } else if (!strcmp(s->s_proto, "udp")) { 4720Sstevel@tonic-gate port = ntohs(s->s_port); 4730Sstevel@tonic-gate name = s->s_name; 4740Sstevel@tonic-gate tab = udp_ports; 4750Sstevel@tonic-gate } else 4760Sstevel@tonic-gate continue; 4770Sstevel@tonic-gate if ((port < 0 || port > 65535) || (name == NULL)) 4780Sstevel@tonic-gate continue; 4790Sstevel@tonic-gate if (tab != NULL) 4800Sstevel@tonic-gate tab[port] = strdup(name); 4810Sstevel@tonic-gate } 4820Sstevel@tonic-gate endservent(); 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate static char *getproto(p) 4870Sstevel@tonic-gate u_int p; 4880Sstevel@tonic-gate { 4890Sstevel@tonic-gate static char pnum[4]; 4900Sstevel@tonic-gate char *s; 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate p &= 0xff; 4930Sstevel@tonic-gate s = protocols ? protocols[p] : NULL; 4940Sstevel@tonic-gate if (s == NULL) { 4950Sstevel@tonic-gate sprintf(pnum, "%u", p); 4960Sstevel@tonic-gate s = pnum; 4970Sstevel@tonic-gate } 4980Sstevel@tonic-gate return s; 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate static int read_log(fd, lenp, buf, bufsize) 5030Sstevel@tonic-gate int fd, bufsize, *lenp; 5040Sstevel@tonic-gate char *buf; 5050Sstevel@tonic-gate { 5060Sstevel@tonic-gate int nr; 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate nr = read(fd, buf, bufsize); 5090Sstevel@tonic-gate if (!nr) 5100Sstevel@tonic-gate return 2; 5110Sstevel@tonic-gate if ((nr < 0) && (errno != EINTR)) 5120Sstevel@tonic-gate return -1; 5130Sstevel@tonic-gate *lenp = nr; 5140Sstevel@tonic-gate return 0; 5150Sstevel@tonic-gate } 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate char *hostname(res, v, ip) 5190Sstevel@tonic-gate int res, v; 5200Sstevel@tonic-gate u_32_t *ip; 5210Sstevel@tonic-gate { 5220Sstevel@tonic-gate # define MAX_INETA 16 5230Sstevel@tonic-gate static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; 5240Sstevel@tonic-gate #ifdef USE_INET6 5250Sstevel@tonic-gate static char hostbuf[MAXHOSTNAMELEN+1]; 5260Sstevel@tonic-gate #endif 5270Sstevel@tonic-gate struct hostent *hp; 5280Sstevel@tonic-gate struct in_addr ipa; 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate if (v == 4) { 5310Sstevel@tonic-gate ipa.s_addr = *ip; 5320Sstevel@tonic-gate if (!res) 5330Sstevel@tonic-gate return inet_ntoa(ipa); 5340Sstevel@tonic-gate hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET); 5350Sstevel@tonic-gate if (!hp) 5360Sstevel@tonic-gate return inet_ntoa(ipa); 5370Sstevel@tonic-gate sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, 5380Sstevel@tonic-gate inet_ntoa(ipa)); 5390Sstevel@tonic-gate return hname; 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate #ifdef USE_INET6 5420Sstevel@tonic-gate (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); 5430Sstevel@tonic-gate hostbuf[MAXHOSTNAMELEN] = '\0'; 5440Sstevel@tonic-gate return hostbuf; 5450Sstevel@tonic-gate #else 5460Sstevel@tonic-gate return "IPv6"; 5470Sstevel@tonic-gate #endif 5480Sstevel@tonic-gate } 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate char *portname(res, proto, port) 5520Sstevel@tonic-gate int res; 5530Sstevel@tonic-gate char *proto; 5540Sstevel@tonic-gate u_int port; 5550Sstevel@tonic-gate { 5560Sstevel@tonic-gate static char pname[8]; 5570Sstevel@tonic-gate char *s; 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate port = ntohs(port); 5600Sstevel@tonic-gate port &= 0xffff; 5610Sstevel@tonic-gate (void) sprintf(pname, "%u", port); 5620Sstevel@tonic-gate if (!res || (opts & OPT_PORTNUM)) 5630Sstevel@tonic-gate return pname; 5640Sstevel@tonic-gate s = NULL; 5650Sstevel@tonic-gate if (!strcmp(proto, "tcp")) 5660Sstevel@tonic-gate s = tcp_ports[port]; 5670Sstevel@tonic-gate else if (!strcmp(proto, "udp")) 5680Sstevel@tonic-gate s = udp_ports[port]; 5690Sstevel@tonic-gate if (s == NULL) 5700Sstevel@tonic-gate s = pname; 5710Sstevel@tonic-gate return s; 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate static char *icmpname(type, code) 5760Sstevel@tonic-gate u_int type; 5770Sstevel@tonic-gate u_int code; 5780Sstevel@tonic-gate { 5790Sstevel@tonic-gate static char name[80]; 5800Sstevel@tonic-gate icmp_subtype_t *ist; 5810Sstevel@tonic-gate icmp_type_t *it; 5820Sstevel@tonic-gate char *s; 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate s = NULL; 5850Sstevel@tonic-gate it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); 5860Sstevel@tonic-gate if (it != NULL) 5870Sstevel@tonic-gate s = it->it_name; 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate if (s == NULL) 5900Sstevel@tonic-gate sprintf(name, "icmptype(%d)/", type); 5910Sstevel@tonic-gate else 5920Sstevel@tonic-gate sprintf(name, "%s/", s); 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate ist = NULL; 5950Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 5960Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 5990Sstevel@tonic-gate strcat(name, ist->ist_name); 6000Sstevel@tonic-gate else 6010Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate return name; 6040Sstevel@tonic-gate } 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate static char *icmpname6(type, code) 6070Sstevel@tonic-gate u_int type; 6080Sstevel@tonic-gate u_int code; 6090Sstevel@tonic-gate { 6100Sstevel@tonic-gate static char name[80]; 6110Sstevel@tonic-gate icmp_subtype_t *ist; 6120Sstevel@tonic-gate icmp_type_t *it; 6130Sstevel@tonic-gate char *s; 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate s = NULL; 6160Sstevel@tonic-gate it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); 6170Sstevel@tonic-gate if (it != NULL) 6180Sstevel@tonic-gate s = it->it_name; 6190Sstevel@tonic-gate 6200Sstevel@tonic-gate if (s == NULL) 6210Sstevel@tonic-gate sprintf(name, "icmpv6type(%d)/", type); 6220Sstevel@tonic-gate else 6230Sstevel@tonic-gate sprintf(name, "%s/", s); 6240Sstevel@tonic-gate 6250Sstevel@tonic-gate ist = NULL; 6260Sstevel@tonic-gate if (it != NULL && it->it_subtable != NULL) 6270Sstevel@tonic-gate ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate if (ist != NULL && ist->ist_name != NULL) 6300Sstevel@tonic-gate strcat(name, ist->ist_name); 6310Sstevel@tonic-gate else 6320Sstevel@tonic-gate sprintf(name + strlen(name), "%d", code); 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate return name; 6350Sstevel@tonic-gate } 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate 6380Sstevel@tonic-gate void dumphex(log, dopts, buf, len) 6390Sstevel@tonic-gate FILE *log; 6400Sstevel@tonic-gate int dopts; 6410Sstevel@tonic-gate char *buf; 6420Sstevel@tonic-gate int len; 6430Sstevel@tonic-gate { 6440Sstevel@tonic-gate char hline[80]; 6450Sstevel@tonic-gate int i, j, k; 6460Sstevel@tonic-gate u_char *s = (u_char *)buf, *t = (u_char *)hline; 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate if (buf == NULL || len == 0) 6490Sstevel@tonic-gate return; 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate *hline = '\0'; 6520Sstevel@tonic-gate 6530Sstevel@tonic-gate for (i = len, j = 0; i; i--, j++, s++) { 6540Sstevel@tonic-gate if (j && !(j & 0xf)) { 6550Sstevel@tonic-gate *t++ = '\n'; 6560Sstevel@tonic-gate *t = '\0'; 6570Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) 6580Sstevel@tonic-gate fputs(hline, log); 6590Sstevel@tonic-gate else 6600Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 6610Sstevel@tonic-gate t = (u_char *)hline; 6620Sstevel@tonic-gate *t = '\0'; 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate sprintf((char *)t, "%02x", *s & 0xff); 6650Sstevel@tonic-gate t += 2; 6660Sstevel@tonic-gate if (!((j + 1) & 0xf)) { 6670Sstevel@tonic-gate s -= 15; 6680Sstevel@tonic-gate sprintf((char *)t, " "); 6690Sstevel@tonic-gate t += 8; 6700Sstevel@tonic-gate for (k = 16; k; k--, s++) 671*2393Syz155240 *t++ = (ISPRINT(*s) ? *s : '.'); 6720Sstevel@tonic-gate s--; 6730Sstevel@tonic-gate } 6740Sstevel@tonic-gate 6750Sstevel@tonic-gate if ((j + 1) & 0xf) 6760Sstevel@tonic-gate *t++ = ' ';; 6770Sstevel@tonic-gate } 6780Sstevel@tonic-gate 6790Sstevel@tonic-gate if (j & 0xf) { 6800Sstevel@tonic-gate for (k = 16 - (j & 0xf); k; k--) { 6810Sstevel@tonic-gate *t++ = ' '; 6820Sstevel@tonic-gate *t++ = ' '; 6830Sstevel@tonic-gate *t++ = ' '; 6840Sstevel@tonic-gate } 6850Sstevel@tonic-gate sprintf((char *)t, " "); 6860Sstevel@tonic-gate t += 7; 6870Sstevel@tonic-gate s -= j & 0xf; 6880Sstevel@tonic-gate for (k = j & 0xf; k; k--, s++) 689*2393Syz155240 *t++ = (ISPRINT(*s) ? *s : '.'); 6900Sstevel@tonic-gate *t++ = '\n'; 6910Sstevel@tonic-gate *t = '\0'; 6920Sstevel@tonic-gate } 6930Sstevel@tonic-gate if (!(dopts & OPT_SYSLOG)) { 6940Sstevel@tonic-gate fputs(hline, log); 6950Sstevel@tonic-gate fflush(log); 6960Sstevel@tonic-gate } else 6970Sstevel@tonic-gate syslog(LOG_INFO, "%s", hline); 6980Sstevel@tonic-gate } 6990Sstevel@tonic-gate 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate static struct tm *get_tm(sec) 7020Sstevel@tonic-gate #ifdef __hpux 7030Sstevel@tonic-gate u_32_t sec; 7040Sstevel@tonic-gate #else 7050Sstevel@tonic-gate time_t sec; 7060Sstevel@tonic-gate #endif 7070Sstevel@tonic-gate { 7080Sstevel@tonic-gate struct tm *tm; 7090Sstevel@tonic-gate time_t t; 7100Sstevel@tonic-gate 7110Sstevel@tonic-gate t = sec; 7120Sstevel@tonic-gate tm = localtime(&t); 7130Sstevel@tonic-gate return tm; 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate static void print_natlog(log, buf, blen) 7170Sstevel@tonic-gate FILE *log; 7180Sstevel@tonic-gate char *buf; 7190Sstevel@tonic-gate int blen; 7200Sstevel@tonic-gate { 7210Sstevel@tonic-gate struct natlog *nl; 7220Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 7230Sstevel@tonic-gate char *t = line; 7240Sstevel@tonic-gate struct tm *tm; 7250Sstevel@tonic-gate int res, i, len; 7260Sstevel@tonic-gate char *proto; 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); 7290Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 7300Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 7310Sstevel@tonic-gate len = sizeof(line); 7320Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 7330Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 7340Sstevel@tonic-gate i = strlen(t); 7350Sstevel@tonic-gate len -= i; 7360Sstevel@tonic-gate t += i; 7370Sstevel@tonic-gate } 7380Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 7390Sstevel@tonic-gate t += strlen(t); 7400Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); 7410Sstevel@tonic-gate t += strlen(t); 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate if (nl->nl_type == NL_NEWMAP) 7440Sstevel@tonic-gate strcpy(t, "NAT:MAP "); 7450Sstevel@tonic-gate else if (nl->nl_type == NL_NEWRDR) 7460Sstevel@tonic-gate strcpy(t, "NAT:RDR "); 7470Sstevel@tonic-gate else if (nl->nl_type == NL_FLUSH) 7480Sstevel@tonic-gate strcpy(t, "NAT:FLUSH "); 7490Sstevel@tonic-gate else if (nl->nl_type == NL_EXPIRE) 7500Sstevel@tonic-gate strcpy(t, "NAT:EXPIRE "); 7510Sstevel@tonic-gate else if (nl->nl_type == NL_NEWBIMAP) 7520Sstevel@tonic-gate strcpy(t, "NAT:BIMAP "); 7530Sstevel@tonic-gate else if (nl->nl_type == NL_NEWBLOCK) 7540Sstevel@tonic-gate strcpy(t, "NAT:MAPBLOCK "); 7550Sstevel@tonic-gate else if (nl->nl_type == NL_CLONE) 7560Sstevel@tonic-gate strcpy(t, "NAT:CLONE "); 7570Sstevel@tonic-gate else 7580Sstevel@tonic-gate sprintf(t, "Type: %d ", nl->nl_type); 7590Sstevel@tonic-gate t += strlen(t); 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate proto = getproto(nl->nl_p); 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), 7640Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_inport)); 7650Sstevel@tonic-gate t += strlen(t); 7660Sstevel@tonic-gate (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), 7670Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_outport)); 7680Sstevel@tonic-gate t += strlen(t); 7690Sstevel@tonic-gate (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip), 7700Sstevel@tonic-gate portname(res, proto, (u_int)nl->nl_origport)); 7710Sstevel@tonic-gate t += strlen(t); 7720Sstevel@tonic-gate if (nl->nl_type == NL_EXPIRE) { 7730Sstevel@tonic-gate #ifdef USE_QUAD_T 7740Sstevel@tonic-gate (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", 7750Sstevel@tonic-gate (long long)nl->nl_pkts[0], 7760Sstevel@tonic-gate (long long)nl->nl_pkts[1], 7770Sstevel@tonic-gate (long long)nl->nl_bytes[0], 7780Sstevel@tonic-gate (long long)nl->nl_bytes[1]); 7790Sstevel@tonic-gate #else 780*2393Syz155240 (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", 7810Sstevel@tonic-gate nl->nl_pkts[0], nl->nl_pkts[1], 7820Sstevel@tonic-gate nl->nl_bytes[0], nl->nl_bytes[1]); 7830Sstevel@tonic-gate #endif 7840Sstevel@tonic-gate t += strlen(t); 7850Sstevel@tonic-gate } 7860Sstevel@tonic-gate 7870Sstevel@tonic-gate *t++ = '\n'; 7880Sstevel@tonic-gate *t++ = '\0'; 7890Sstevel@tonic-gate if (opts & OPT_SYSLOG) 7900Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 7910Sstevel@tonic-gate else 7920Sstevel@tonic-gate (void) fprintf(log, "%s", line); 7930Sstevel@tonic-gate } 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate static void print_statelog(log, buf, blen) 7970Sstevel@tonic-gate FILE *log; 7980Sstevel@tonic-gate char *buf; 7990Sstevel@tonic-gate int blen; 8000Sstevel@tonic-gate { 8010Sstevel@tonic-gate struct ipslog *sl; 8020Sstevel@tonic-gate iplog_t *ipl = (iplog_t *)buf; 8030Sstevel@tonic-gate char *t = line, *proto; 8040Sstevel@tonic-gate struct tm *tm; 8050Sstevel@tonic-gate int res, i, len; 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); 8080Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 8090Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 8100Sstevel@tonic-gate len = sizeof(line); 8110Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 8120Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 8130Sstevel@tonic-gate i = strlen(t); 8140Sstevel@tonic-gate len -= i; 8150Sstevel@tonic-gate t += i; 8160Sstevel@tonic-gate } 8170Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 8180Sstevel@tonic-gate t += strlen(t); 8190Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 8200Sstevel@tonic-gate t += strlen(t); 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate if (sl->isl_type == ISL_NEW) 8230Sstevel@tonic-gate strcpy(t, "STATE:NEW "); 8240Sstevel@tonic-gate else if (sl->isl_type == ISL_CLONE) 8250Sstevel@tonic-gate strcpy(t, "STATE:CLONED "); 8260Sstevel@tonic-gate else if (sl->isl_type == ISL_EXPIRE) { 8270Sstevel@tonic-gate if ((sl->isl_p == IPPROTO_TCP) && 8280Sstevel@tonic-gate (sl->isl_state[0] > IPF_TCPS_ESTABLISHED || 8290Sstevel@tonic-gate sl->isl_state[1] > IPF_TCPS_ESTABLISHED)) 8300Sstevel@tonic-gate strcpy(t, "STATE:CLOSE "); 8310Sstevel@tonic-gate else 8320Sstevel@tonic-gate strcpy(t, "STATE:EXPIRE "); 8330Sstevel@tonic-gate } else if (sl->isl_type == ISL_FLUSH) 8340Sstevel@tonic-gate strcpy(t, "STATE:FLUSH "); 8350Sstevel@tonic-gate else if (sl->isl_type == ISL_INTERMEDIATE) 8360Sstevel@tonic-gate strcpy(t, "STATE:INTERMEDIATE "); 8370Sstevel@tonic-gate else if (sl->isl_type == ISL_REMOVE) 8380Sstevel@tonic-gate strcpy(t, "STATE:REMOVE "); 8390Sstevel@tonic-gate else if (sl->isl_type == ISL_KILLED) 8400Sstevel@tonic-gate strcpy(t, "STATE:KILLED "); 8410Sstevel@tonic-gate else 8420Sstevel@tonic-gate sprintf(t, "Type: %d ", sl->isl_type); 8430Sstevel@tonic-gate t += strlen(t); 8440Sstevel@tonic-gate 8450Sstevel@tonic-gate proto = getproto(sl->isl_p); 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { 8480Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", 8490Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), 8500Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_sport)); 8510Sstevel@tonic-gate t += strlen(t); 8520Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s", 8530Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8540Sstevel@tonic-gate portname(res, proto, (u_int)sl->isl_dport), proto); 8550Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMP) { 8560Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 8570Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 8580Sstevel@tonic-gate t += strlen(t); 8590Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp %d", 8600Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8610Sstevel@tonic-gate sl->isl_itype); 8620Sstevel@tonic-gate } else if (sl->isl_p == IPPROTO_ICMPV6) { 8630Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, 8640Sstevel@tonic-gate (u_32_t *)&sl->isl_src)); 8650Sstevel@tonic-gate t += strlen(t); 8660Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 %d", 8670Sstevel@tonic-gate hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 8680Sstevel@tonic-gate sl->isl_itype); 869*2393Syz155240 } else { 870*2393Syz155240 (void) sprintf(t, "%s -> ", 871*2393Syz155240 hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src)); 872*2393Syz155240 t += strlen(t); 873*2393Syz155240 (void) sprintf(t, "%s PR %s", 874*2393Syz155240 hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), 875*2393Syz155240 proto); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate t += strlen(t); 8780Sstevel@tonic-gate if (sl->isl_tag != FR_NOLOGTAG) { 8790Sstevel@tonic-gate (void) sprintf(t, " tag %u", sl->isl_tag); 8800Sstevel@tonic-gate t += strlen(t); 8810Sstevel@tonic-gate } 8820Sstevel@tonic-gate if (sl->isl_type != ISL_NEW) { 8830Sstevel@tonic-gate sprintf(t, 8840Sstevel@tonic-gate #ifdef USE_QUAD_T 885*2393Syz155240 #ifdef PRId64 886*2393Syz155240 " Forward: Pkts in %" PRId64 " Bytes in %" PRId64 887*2393Syz155240 " Pkts out %" PRId64 " Bytes out %" PRId64 888*2393Syz155240 " Backward: Pkts in %" PRId64 " Bytes in %" PRId64 889*2393Syz155240 " Pkts out %" PRId64 " Bytes out %" PRId64, 890*2393Syz155240 #else 8910Sstevel@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*2393Syz155240 #endif /* PRId64 */ 8930Sstevel@tonic-gate #else 8940Sstevel@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", 8950Sstevel@tonic-gate #endif 8960Sstevel@tonic-gate sl->isl_pkts[0], sl->isl_bytes[0], 8970Sstevel@tonic-gate sl->isl_pkts[1], sl->isl_bytes[1], 8980Sstevel@tonic-gate sl->isl_pkts[2], sl->isl_bytes[2], 8990Sstevel@tonic-gate sl->isl_pkts[3], sl->isl_bytes[3]); 9000Sstevel@tonic-gate 9010Sstevel@tonic-gate t += strlen(t); 9020Sstevel@tonic-gate } 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate *t++ = '\n'; 9050Sstevel@tonic-gate *t++ = '\0'; 9060Sstevel@tonic-gate if (opts & OPT_SYSLOG) 9070Sstevel@tonic-gate syslog(LOG_INFO, "%s", line); 9080Sstevel@tonic-gate else 9090Sstevel@tonic-gate (void) fprintf(log, "%s", line); 9100Sstevel@tonic-gate } 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate 9130Sstevel@tonic-gate static void print_log(logtype, log, buf, blen) 9140Sstevel@tonic-gate FILE *log; 9150Sstevel@tonic-gate char *buf; 9160Sstevel@tonic-gate int logtype, blen; 9170Sstevel@tonic-gate { 9180Sstevel@tonic-gate iplog_t *ipl; 9190Sstevel@tonic-gate char *bp = NULL, *bpo = NULL; 9200Sstevel@tonic-gate int psize; 9210Sstevel@tonic-gate 9220Sstevel@tonic-gate while (blen > 0) { 9230Sstevel@tonic-gate ipl = (iplog_t *)buf; 9240Sstevel@tonic-gate if ((u_long)ipl & (sizeof(long)-1)) { 9250Sstevel@tonic-gate if (bp) 9260Sstevel@tonic-gate bpo = bp; 9270Sstevel@tonic-gate bp = (char *)malloc(blen); 9281448Sschuster if (bp == NULL) { 9291448Sschuster perror("malloc"); 9301448Sschuster exit(1); 9311448Sschuster } 9320Sstevel@tonic-gate bcopy((char *)ipl, bp, blen); 9330Sstevel@tonic-gate if (bpo) { 9340Sstevel@tonic-gate free(bpo); 9350Sstevel@tonic-gate bpo = NULL; 9360Sstevel@tonic-gate } 9370Sstevel@tonic-gate buf = bp; 9380Sstevel@tonic-gate continue; 9390Sstevel@tonic-gate } 9400Sstevel@tonic-gate 9410Sstevel@tonic-gate psize = ipl->ipl_dsize; 9420Sstevel@tonic-gate if (psize > blen) 9430Sstevel@tonic-gate break; 9440Sstevel@tonic-gate 9450Sstevel@tonic-gate if (binarylog) { 9460Sstevel@tonic-gate fwrite(buf, psize, 1, binarylog); 9470Sstevel@tonic-gate fflush(binarylog); 9480Sstevel@tonic-gate } 9490Sstevel@tonic-gate 9500Sstevel@tonic-gate if (logtype == IPL_LOGIPF) { 951*2393Syz155240 if (ipl->ipl_magic == IPL_MAGIC) 952*2393Syz155240 print_ipflog(log, buf, psize); 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate } else if (logtype == IPL_LOGNAT) { 955*2393Syz155240 if (ipl->ipl_magic == IPL_MAGIC_NAT) 956*2393Syz155240 print_natlog(log, buf, psize); 9570Sstevel@tonic-gate 9580Sstevel@tonic-gate } else if (logtype == IPL_LOGSTATE) { 959*2393Syz155240 if (ipl->ipl_magic == IPL_MAGIC_STATE) 960*2393Syz155240 print_statelog(log, buf, psize); 9610Sstevel@tonic-gate } 9620Sstevel@tonic-gate 9630Sstevel@tonic-gate blen -= psize; 9640Sstevel@tonic-gate buf += psize; 9650Sstevel@tonic-gate } 9660Sstevel@tonic-gate if (bp) 9670Sstevel@tonic-gate free(bp); 9680Sstevel@tonic-gate return; 9690Sstevel@tonic-gate } 9700Sstevel@tonic-gate 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate static void print_ipflog(log, buf, blen) 9730Sstevel@tonic-gate FILE *log; 9740Sstevel@tonic-gate char *buf; 9750Sstevel@tonic-gate int blen; 9760Sstevel@tonic-gate { 9770Sstevel@tonic-gate tcphdr_t *tp; 9780Sstevel@tonic-gate struct icmp *ic; 9790Sstevel@tonic-gate struct icmp *icmp; 9800Sstevel@tonic-gate struct tm *tm; 9810Sstevel@tonic-gate char *t, *proto; 982*2393Syz155240 int i, v, lvl, res, len, off, plen, ipoff, defaction; 9830Sstevel@tonic-gate ip_t *ipc, *ip; 984*2393Syz155240 u_32_t *s, *d; 9850Sstevel@tonic-gate u_short hl, p; 9860Sstevel@tonic-gate ipflog_t *ipf; 9870Sstevel@tonic-gate iplog_t *ipl; 9880Sstevel@tonic-gate #ifdef USE_INET6 9890Sstevel@tonic-gate ip6_t *ip6; 9900Sstevel@tonic-gate #endif 9910Sstevel@tonic-gate 9920Sstevel@tonic-gate ipl = (iplog_t *)buf; 9930Sstevel@tonic-gate ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); 9940Sstevel@tonic-gate ip = (ip_t *)((char *)ipf + sizeof(*ipf)); 9950Sstevel@tonic-gate v = IP_V(ip); 9960Sstevel@tonic-gate res = (opts & OPT_RESOLVE) ? 1 : 0; 9970Sstevel@tonic-gate t = line; 9980Sstevel@tonic-gate *t = '\0'; 9990Sstevel@tonic-gate tm = get_tm(ipl->ipl_sec); 10000Sstevel@tonic-gate 10010Sstevel@tonic-gate len = sizeof(line); 10020Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 10030Sstevel@tonic-gate (void) strftime(t, len, "%d/%m/%Y ", tm); 10040Sstevel@tonic-gate i = strlen(t); 10050Sstevel@tonic-gate len -= i; 10060Sstevel@tonic-gate t += i; 10070Sstevel@tonic-gate } 10080Sstevel@tonic-gate (void) strftime(t, len, "%T", tm); 10090Sstevel@tonic-gate t += strlen(t); 10100Sstevel@tonic-gate (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); 10110Sstevel@tonic-gate t += strlen(t); 10120Sstevel@tonic-gate if (ipl->ipl_count > 1) { 10130Sstevel@tonic-gate (void) sprintf(t, "%dx ", ipl->ipl_count); 10140Sstevel@tonic-gate t += strlen(t); 10150Sstevel@tonic-gate } 10160Sstevel@tonic-gate #if (defined(MENTAT) || \ 10170Sstevel@tonic-gate (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ 1018*2393Syz155240 (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \ 10190Sstevel@tonic-gate (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux) 10200Sstevel@tonic-gate { 10210Sstevel@tonic-gate char ifname[sizeof(ipf->fl_ifname) + 1]; 10220Sstevel@tonic-gate 10230Sstevel@tonic-gate strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); 10240Sstevel@tonic-gate ifname[sizeof(ipf->fl_ifname)] = '\0'; 10250Sstevel@tonic-gate (void) sprintf(t, "%s", ifname); 10260Sstevel@tonic-gate t += strlen(t); 1027*2393Syz155240 # if defined(MENTAT) || defined(linux) 1028*2393Syz155240 if (ISALPHA(*(t - 1))) { 10290Sstevel@tonic-gate sprintf(t, "%d", ipf->fl_unit); 10300Sstevel@tonic-gate t += strlen(t); 10310Sstevel@tonic-gate } 10320Sstevel@tonic-gate # endif 10330Sstevel@tonic-gate } 10340Sstevel@tonic-gate #else 10350Sstevel@tonic-gate for (len = 0; len < 3; len++) 10360Sstevel@tonic-gate if (ipf->fl_ifname[len] == '\0') 10370Sstevel@tonic-gate break; 10380Sstevel@tonic-gate if (ipf->fl_ifname[len]) 10390Sstevel@tonic-gate len++; 10400Sstevel@tonic-gate (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); 10410Sstevel@tonic-gate t += strlen(t); 10420Sstevel@tonic-gate #endif 1043*2393Syz155240 #if defined(__sgi) || defined(_AIX51) || defined(__powerpc__) || \ 1044*2393Syz155240 defined(__arm__) 1045*2393Syz155240 if ((ipf->fl_group[0] == 255) && (ipf->fl_group[1] == '\0')) 1046*2393Syz155240 #else 10470Sstevel@tonic-gate if ((ipf->fl_group[0] == -1) && (ipf->fl_group[1] == '\0')) 1048*2393Syz155240 #endif 10490Sstevel@tonic-gate strcat(t, " @-1:"); 10500Sstevel@tonic-gate else if (ipf->fl_group[0] == '\0') 10510Sstevel@tonic-gate (void) strcpy(t, " @0:"); 10520Sstevel@tonic-gate else 10530Sstevel@tonic-gate (void) sprintf(t, " @%s:", ipf->fl_group); 10540Sstevel@tonic-gate t += strlen(t); 10550Sstevel@tonic-gate if (ipf->fl_rule == 0xffffffff) 10560Sstevel@tonic-gate strcat(t, "-1 "); 10570Sstevel@tonic-gate else 10580Sstevel@tonic-gate (void) sprintf(t, "%u ", ipf->fl_rule + 1); 10590Sstevel@tonic-gate t += strlen(t); 10600Sstevel@tonic-gate 10610Sstevel@tonic-gate lvl = LOG_NOTICE; 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate if (ipf->fl_lflags & FI_SHORT) { 10640Sstevel@tonic-gate *t++ = 'S'; 10650Sstevel@tonic-gate lvl = LOG_ERR; 10660Sstevel@tonic-gate } 10670Sstevel@tonic-gate 10680Sstevel@tonic-gate if (FR_ISPASS(ipf->fl_flags)) { 10690Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGP) 10700Sstevel@tonic-gate *t++ = 'p'; 10710Sstevel@tonic-gate else 10720Sstevel@tonic-gate *t++ = 'P'; 10730Sstevel@tonic-gate } else if (FR_ISBLOCK(ipf->fl_flags)) { 10740Sstevel@tonic-gate if (ipf->fl_flags & FR_LOGB) 10750Sstevel@tonic-gate *t++ = 'b'; 10760Sstevel@tonic-gate else 10770Sstevel@tonic-gate *t++ = 'B'; 10780Sstevel@tonic-gate lvl = LOG_WARNING; 10790Sstevel@tonic-gate } else if ((ipf->fl_flags & FR_LOGMASK) == FR_LOG) { 10800Sstevel@tonic-gate *t++ = 'L'; 10810Sstevel@tonic-gate lvl = LOG_INFO; 10820Sstevel@tonic-gate } else if (ipf->fl_flags & FF_LOGNOMATCH) { 10830Sstevel@tonic-gate *t++ = 'n'; 10840Sstevel@tonic-gate } else { 10850Sstevel@tonic-gate *t++ = '?'; 10860Sstevel@tonic-gate lvl = LOG_EMERG; 10870Sstevel@tonic-gate } 10880Sstevel@tonic-gate if (ipf->fl_loglevel != 0xffff) 10890Sstevel@tonic-gate lvl = ipf->fl_loglevel; 10900Sstevel@tonic-gate *t++ = ' '; 10910Sstevel@tonic-gate *t = '\0'; 10920Sstevel@tonic-gate 10930Sstevel@tonic-gate if (v == 6) { 10940Sstevel@tonic-gate #ifdef USE_INET6 10950Sstevel@tonic-gate off = 0; 10960Sstevel@tonic-gate ipoff = 0; 10970Sstevel@tonic-gate hl = sizeof(ip6_t); 10980Sstevel@tonic-gate ip6 = (ip6_t *)ip; 10990Sstevel@tonic-gate p = (u_short)ip6->ip6_nxt; 11000Sstevel@tonic-gate s = (u_32_t *)&ip6->ip6_src; 11010Sstevel@tonic-gate d = (u_32_t *)&ip6->ip6_dst; 1102*2393Syz155240 plen = hl + ntohs(ip6->ip6_plen); 11030Sstevel@tonic-gate #else 11040Sstevel@tonic-gate sprintf(t, "ipv6"); 11050Sstevel@tonic-gate goto printipflog; 11060Sstevel@tonic-gate #endif 11070Sstevel@tonic-gate } else if (v == 4) { 11080Sstevel@tonic-gate hl = IP_HL(ip) << 2; 11090Sstevel@tonic-gate ipoff = ip->ip_off; 11100Sstevel@tonic-gate off = ipoff & IP_OFFMASK; 11110Sstevel@tonic-gate p = (u_short)ip->ip_p; 11120Sstevel@tonic-gate s = (u_32_t *)&ip->ip_src; 11130Sstevel@tonic-gate d = (u_32_t *)&ip->ip_dst; 11140Sstevel@tonic-gate plen = ip->ip_len; 11150Sstevel@tonic-gate } else { 11160Sstevel@tonic-gate goto printipflog; 11170Sstevel@tonic-gate } 11180Sstevel@tonic-gate proto = getproto(p); 11190Sstevel@tonic-gate 11200Sstevel@tonic-gate if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { 11210Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ip + hl); 11220Sstevel@tonic-gate if (!(ipf->fl_lflags & FI_SHORT)) { 11230Sstevel@tonic-gate (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), 11240Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_sport)); 11250Sstevel@tonic-gate t += strlen(t); 11260Sstevel@tonic-gate (void) sprintf(t, "%s,%s PR %s len %hu %hu", 11270Sstevel@tonic-gate hostname(res, v, d), 11280Sstevel@tonic-gate portname(res, proto, (u_int)tp->th_dport), 11290Sstevel@tonic-gate proto, hl, plen); 11300Sstevel@tonic-gate t += strlen(t); 11310Sstevel@tonic-gate 11320Sstevel@tonic-gate if (p == IPPROTO_TCP) { 11330Sstevel@tonic-gate *t++ = ' '; 11340Sstevel@tonic-gate *t++ = '-'; 11350Sstevel@tonic-gate for (i = 0; tcpfl[i].value; i++) 11360Sstevel@tonic-gate if (tp->th_flags & tcpfl[i].value) 11370Sstevel@tonic-gate *t++ = tcpfl[i].flag; 11380Sstevel@tonic-gate if (opts & OPT_VERBOSE) { 11390Sstevel@tonic-gate (void) sprintf(t, " %lu %lu %hu", 11400Sstevel@tonic-gate (u_long)(ntohl(tp->th_seq)), 11410Sstevel@tonic-gate (u_long)(ntohl(tp->th_ack)), 11420Sstevel@tonic-gate ntohs(tp->th_win)); 11430Sstevel@tonic-gate t += strlen(t); 11440Sstevel@tonic-gate } 11450Sstevel@tonic-gate } 11460Sstevel@tonic-gate *t = '\0'; 11470Sstevel@tonic-gate } else { 11480Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11490Sstevel@tonic-gate t += strlen(t); 11500Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu %hu", 11510Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 11520Sstevel@tonic-gate } 11530Sstevel@tonic-gate } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { 11540Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 11550Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11560Sstevel@tonic-gate t += strlen(t); 11570Sstevel@tonic-gate (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", 11580Sstevel@tonic-gate hostname(res, v, d), hl, plen, 11590Sstevel@tonic-gate icmpname6(ic->icmp_type, ic->icmp_code)); 11600Sstevel@tonic-gate } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { 11610Sstevel@tonic-gate ic = (struct icmp *)((char *)ip + hl); 11620Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 11630Sstevel@tonic-gate t += strlen(t); 11640Sstevel@tonic-gate (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", 11650Sstevel@tonic-gate hostname(res, v, d), hl, plen, 11660Sstevel@tonic-gate icmpname(ic->icmp_type, ic->icmp_code)); 11670Sstevel@tonic-gate if (ic->icmp_type == ICMP_UNREACH || 11680Sstevel@tonic-gate ic->icmp_type == ICMP_SOURCEQUENCH || 11690Sstevel@tonic-gate ic->icmp_type == ICMP_PARAMPROB || 11700Sstevel@tonic-gate ic->icmp_type == ICMP_REDIRECT || 11710Sstevel@tonic-gate ic->icmp_type == ICMP_TIMXCEED) { 11720Sstevel@tonic-gate ipc = &ic->icmp_ip; 11730Sstevel@tonic-gate i = ntohs(ipc->ip_len); 11740Sstevel@tonic-gate /* 11750Sstevel@tonic-gate * XXX - try to guess endian of ip_len in ICMP 11760Sstevel@tonic-gate * returned data. 11770Sstevel@tonic-gate */ 11780Sstevel@tonic-gate if (i > 1500) 11790Sstevel@tonic-gate i = ipc->ip_len; 11800Sstevel@tonic-gate ipoff = ntohs(ipc->ip_off); 11810Sstevel@tonic-gate proto = getproto(ipc->ip_p); 11820Sstevel@tonic-gate 11830Sstevel@tonic-gate if (!(ipoff & IP_OFFMASK) && 11840Sstevel@tonic-gate ((ipc->ip_p == IPPROTO_TCP) || 11850Sstevel@tonic-gate (ipc->ip_p == IPPROTO_UDP))) { 11860Sstevel@tonic-gate tp = (tcphdr_t *)((char *)ipc + hl); 11870Sstevel@tonic-gate t += strlen(t); 11880Sstevel@tonic-gate (void) sprintf(t, " for %s,%s -", 11890Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src), 11900Sstevel@tonic-gate portname(res, proto, 11910Sstevel@tonic-gate (u_int)tp->th_sport)); 11920Sstevel@tonic-gate t += strlen(t); 11930Sstevel@tonic-gate (void) sprintf(t, " %s,%s PR %s len %hu %hu", 11940Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 11950Sstevel@tonic-gate portname(res, proto, 11960Sstevel@tonic-gate (u_int)tp->th_dport), 11970Sstevel@tonic-gate proto, IP_HL(ipc) << 2, i); 11980Sstevel@tonic-gate } else if (!(ipoff & IP_OFFMASK) && 11990Sstevel@tonic-gate (ipc->ip_p == IPPROTO_ICMP)) { 12000Sstevel@tonic-gate icmp = (icmphdr_t *)((char *)ipc + hl); 12010Sstevel@tonic-gate 12020Sstevel@tonic-gate t += strlen(t); 12030Sstevel@tonic-gate (void) sprintf(t, " for %s -", 12040Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 12050Sstevel@tonic-gate t += strlen(t); 12060Sstevel@tonic-gate (void) sprintf(t, 12070Sstevel@tonic-gate " %s PR icmp len %hu %hu icmp %d/%d", 12080Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), 12090Sstevel@tonic-gate IP_HL(ipc) << 2, i, 12100Sstevel@tonic-gate icmp->icmp_type, icmp->icmp_code); 12110Sstevel@tonic-gate } else { 12120Sstevel@tonic-gate t += strlen(t); 12130Sstevel@tonic-gate (void) sprintf(t, " for %s -", 12140Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_src)); 12150Sstevel@tonic-gate t += strlen(t); 12160Sstevel@tonic-gate (void) sprintf(t, " %s PR %s len %hu (%hu)", 12170Sstevel@tonic-gate HOSTNAME_V4(res, ipc->ip_dst), proto, 12180Sstevel@tonic-gate IP_HL(ipc) << 2, i); 12190Sstevel@tonic-gate t += strlen(t); 12200Sstevel@tonic-gate if (ipoff & IP_OFFMASK) { 1221*2393Syz155240 (void) sprintf(t, 1222*2393Syz155240 "(frag %d:%hu@%hu%s%s)", 1223*2393Syz155240 ntohs(ipc->ip_id), 1224*2393Syz155240 i - (IP_HL(ipc) << 2), 1225*2393Syz155240 (ipoff & IP_OFFMASK) << 3, 12260Sstevel@tonic-gate ipoff & IP_MF ? "+" : "", 1227*2393Syz155240 ipoff & IP_DF ? "-" : ""); 12280Sstevel@tonic-gate } 12290Sstevel@tonic-gate } 12300Sstevel@tonic-gate 12310Sstevel@tonic-gate } 12320Sstevel@tonic-gate } else { 12330Sstevel@tonic-gate (void) sprintf(t, "%s -> ", hostname(res, v, s)); 12340Sstevel@tonic-gate t += strlen(t); 12350Sstevel@tonic-gate (void) sprintf(t, "%s PR %s len %hu (%hu)", 12360Sstevel@tonic-gate hostname(res, v, d), proto, hl, plen); 12370Sstevel@tonic-gate t += strlen(t); 12380Sstevel@tonic-gate if (off & IP_OFFMASK) 1239*2393Syz155240 (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", 1240*2393Syz155240 ntohs(ip->ip_id), 1241*2393Syz155240 plen - hl, (off & IP_OFFMASK) << 3, 12420Sstevel@tonic-gate ipoff & IP_MF ? "+" : "", 1243*2393Syz155240 ipoff & IP_DF ? "-" : ""); 12440Sstevel@tonic-gate } 12450Sstevel@tonic-gate t += strlen(t); 12460Sstevel@tonic-gate 1247*2393Syz155240 printipflog: 12480Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPSTATE) { 12490Sstevel@tonic-gate (void) strcpy(t, " K-S"); 12500Sstevel@tonic-gate t += strlen(t); 12510Sstevel@tonic-gate } 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate if (ipf->fl_flags & FR_KEEPFRAG) { 12540Sstevel@tonic-gate (void) strcpy(t, " K-F"); 12550Sstevel@tonic-gate t += strlen(t); 12560Sstevel@tonic-gate } 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate if (ipf->fl_dir == 0) 12590Sstevel@tonic-gate strcpy(t, " IN"); 12600Sstevel@tonic-gate else if (ipf->fl_dir == 1) 12610Sstevel@tonic-gate strcpy(t, " OUT"); 12620Sstevel@tonic-gate t += strlen(t); 1263*2393Syz155240 if (ipf->fl_logtag != 0) { 1264*2393Syz155240 sprintf(t, " log-tag %d", ipf->fl_logtag); 1265*2393Syz155240 t += strlen(t); 1266*2393Syz155240 } 1267*2393Syz155240 if (ipf->fl_nattag.ipt_num[0] != 0) { 1268*2393Syz155240 strcpy(t, " nat-tag "); 1269*2393Syz155240 t += strlen(t); 1270*2393Syz155240 strncpy(t, ipf->fl_nattag.ipt_tag, sizeof(ipf->fl_nattag)); 12710Sstevel@tonic-gate t += strlen(t); 12720Sstevel@tonic-gate } 1273*2393Syz155240 if ((ipf->fl_lflags & FI_LOWTTL) != 0) { 1274*2393Syz155240 strcpy(t, " low-ttl"); 1275*2393Syz155240 t += 8; 1276*2393Syz155240 } 1277*2393Syz155240 if ((ipf->fl_lflags & FI_OOW) != 0) { 1278*2393Syz155240 strcpy(t, " OOW"); 1279*2393Syz155240 t += 4; 1280*2393Syz155240 } 1281*2393Syz155240 if ((ipf->fl_lflags & FI_BAD) != 0) { 1282*2393Syz155240 strcpy(t, " bad"); 1283*2393Syz155240 t += 4; 1284*2393Syz155240 } 1285*2393Syz155240 if ((ipf->fl_lflags & FI_NATED) != 0) { 1286*2393Syz155240 strcpy(t, " NAT"); 1287*2393Syz155240 t += 4; 1288*2393Syz155240 } 1289*2393Syz155240 if ((ipf->fl_lflags & FI_BADNAT) != 0) { 1290*2393Syz155240 strcpy(t, " bad-NAT"); 1291*2393Syz155240 t += 8; 1292*2393Syz155240 } 1293*2393Syz155240 if ((ipf->fl_lflags & FI_BADSRC) != 0) { 1294*2393Syz155240 strcpy(t, " bad-src"); 1295*2393Syz155240 t += 8; 1296*2393Syz155240 } 1297*2393Syz155240 if ((ipf->fl_lflags & FI_MULTICAST) != 0) { 1298*2393Syz155240 strcpy(t, " multicast"); 1299*2393Syz155240 t += 10; 1300*2393Syz155240 } 1301*2393Syz155240 if ((ipf->fl_lflags & FI_BROADCAST) != 0) { 1302*2393Syz155240 strcpy(t, " broadcast"); 1303*2393Syz155240 t += 10; 1304*2393Syz155240 } 1305*2393Syz155240 if ((ipf->fl_lflags & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST)) == 1306*2393Syz155240 FI_MBCAST) { 1307*2393Syz155240 strcpy(t, " mbcast"); 1308*2393Syz155240 t += 7; 1309*2393Syz155240 } 13100Sstevel@tonic-gate *t++ = '\n'; 13110Sstevel@tonic-gate *t++ = '\0'; 1312*2393Syz155240 defaction = 0; 1313*2393Syz155240 if (conf_file != NULL) 1314*2393Syz155240 defaction = check_action(buf, line, opts, lvl); 1315*2393Syz155240 if (defaction == 0) { 1316*2393Syz155240 if (opts & OPT_SYSLOG) 1317*2393Syz155240 syslog(lvl, "%s", line); 1318*2393Syz155240 else 1319*2393Syz155240 (void) fprintf(log, "%s", line); 1320*2393Syz155240 if (opts & OPT_HEXHDR) 1321*2393Syz155240 dumphex(log, opts, buf, 1322*2393Syz155240 sizeof(iplog_t) + sizeof(*ipf)); 1323*2393Syz155240 if (opts & OPT_HEXBODY) 1324*2393Syz155240 dumphex(log, opts, (char *)ip, 1325*2393Syz155240 ipf->fl_plen + ipf->fl_hlen); 1326*2393Syz155240 else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) 1327*2393Syz155240 dumphex(log, opts, (char *)ip + ipf->fl_hlen, 1328*2393Syz155240 ipf->fl_plen); 1329*2393Syz155240 } 13300Sstevel@tonic-gate } 13310Sstevel@tonic-gate 13320Sstevel@tonic-gate 13330Sstevel@tonic-gate static void usage(prog) 13340Sstevel@tonic-gate char *prog; 13350Sstevel@tonic-gate { 13360Sstevel@tonic-gate fprintf(stderr, "%s: [-abDFhnpstvxX] %s %s %s %s %s %s\n", 13370Sstevel@tonic-gate prog, "[-N device]", "[ [-o [NSI]] [-O [NSI]]", 13380Sstevel@tonic-gate "[-P pidfile]", "[-S device]", "[-f device]", 13390Sstevel@tonic-gate "filename"); 13400Sstevel@tonic-gate exit(1); 13410Sstevel@tonic-gate } 13420Sstevel@tonic-gate 13430Sstevel@tonic-gate 13440Sstevel@tonic-gate static void write_pid(file) 13450Sstevel@tonic-gate char *file; 13460Sstevel@tonic-gate { 13470Sstevel@tonic-gate FILE *fp = NULL; 13480Sstevel@tonic-gate int fd; 13490Sstevel@tonic-gate 13500Sstevel@tonic-gate if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) { 13510Sstevel@tonic-gate fp = fdopen(fd, "w"); 13520Sstevel@tonic-gate if (fp == NULL) { 13530Sstevel@tonic-gate close(fd); 13540Sstevel@tonic-gate fprintf(stderr, 13550Sstevel@tonic-gate "unable to open/create pid file: %s\n", file); 13560Sstevel@tonic-gate return; 13570Sstevel@tonic-gate } 13580Sstevel@tonic-gate fprintf(fp, "%d", getpid()); 13590Sstevel@tonic-gate fclose(fp); 13600Sstevel@tonic-gate } 13610Sstevel@tonic-gate } 13620Sstevel@tonic-gate 13630Sstevel@tonic-gate 13640Sstevel@tonic-gate static void flushlogs(file, log) 13650Sstevel@tonic-gate char *file; 13660Sstevel@tonic-gate FILE *log; 13670Sstevel@tonic-gate { 13680Sstevel@tonic-gate int fd, flushed = 0; 13690Sstevel@tonic-gate 13700Sstevel@tonic-gate if ((fd = open(file, O_RDWR)) == -1) { 13710Sstevel@tonic-gate (void) fprintf(stderr, "%s: open: %s\n", 13720Sstevel@tonic-gate file, STRERROR(errno)); 13730Sstevel@tonic-gate exit(1); 13740Sstevel@tonic-gate } 13750Sstevel@tonic-gate 13760Sstevel@tonic-gate if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { 13770Sstevel@tonic-gate printf("%d bytes flushed from log buffer\n", 13780Sstevel@tonic-gate flushed); 13790Sstevel@tonic-gate fflush(stdout); 13800Sstevel@tonic-gate } else 13810Sstevel@tonic-gate perror("SIOCIPFFB"); 13820Sstevel@tonic-gate (void) close(fd); 13830Sstevel@tonic-gate 13840Sstevel@tonic-gate if (flushed) { 13850Sstevel@tonic-gate if (opts & OPT_SYSLOG) 13860Sstevel@tonic-gate syslog(LOG_INFO, "%d bytes flushed from log\n", 13870Sstevel@tonic-gate flushed); 13880Sstevel@tonic-gate else if (log != stdout) 13890Sstevel@tonic-gate fprintf(log, "%d bytes flushed from log\n", flushed); 13900Sstevel@tonic-gate } 13910Sstevel@tonic-gate } 13920Sstevel@tonic-gate 13930Sstevel@tonic-gate 13940Sstevel@tonic-gate static void logopts(turnon, options) 13950Sstevel@tonic-gate int turnon; 13960Sstevel@tonic-gate char *options; 13970Sstevel@tonic-gate { 13980Sstevel@tonic-gate int flags = 0; 13990Sstevel@tonic-gate char *s; 14000Sstevel@tonic-gate 14010Sstevel@tonic-gate for (s = options; *s; s++) 14020Sstevel@tonic-gate { 14030Sstevel@tonic-gate switch (*s) 14040Sstevel@tonic-gate { 14050Sstevel@tonic-gate case 'N' : 14060Sstevel@tonic-gate flags |= OPT_NAT; 14070Sstevel@tonic-gate break; 14080Sstevel@tonic-gate case 'S' : 14090Sstevel@tonic-gate flags |= OPT_STATE; 14100Sstevel@tonic-gate break; 14110Sstevel@tonic-gate case 'I' : 14120Sstevel@tonic-gate flags |= OPT_FILTER; 14130Sstevel@tonic-gate break; 14140Sstevel@tonic-gate default : 14150Sstevel@tonic-gate fprintf(stderr, "Unknown log option %c\n", *s); 14160Sstevel@tonic-gate exit(1); 14170Sstevel@tonic-gate } 14180Sstevel@tonic-gate } 14190Sstevel@tonic-gate 14200Sstevel@tonic-gate if (turnon) 14210Sstevel@tonic-gate opts |= flags; 14220Sstevel@tonic-gate else 14230Sstevel@tonic-gate opts &= ~(flags); 14240Sstevel@tonic-gate } 14250Sstevel@tonic-gate 14260Sstevel@tonic-gate 14270Sstevel@tonic-gate int main(argc, argv) 14280Sstevel@tonic-gate int argc; 14290Sstevel@tonic-gate char *argv[]; 14300Sstevel@tonic-gate { 14310Sstevel@tonic-gate struct stat sb; 14320Sstevel@tonic-gate FILE *log = stdout; 1433*2393Syz155240 FILE *fp; 14340Sstevel@tonic-gate int fd[3], doread, n, i; 14350Sstevel@tonic-gate int tr, nr, regular[3], c; 14360Sstevel@tonic-gate int fdt[3], devices = 0, make_daemon = 0; 14370Sstevel@tonic-gate char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s; 14380Sstevel@tonic-gate extern int optind; 14390Sstevel@tonic-gate extern char *optarg; 14400Sstevel@tonic-gate 14410Sstevel@tonic-gate fd[0] = fd[1] = fd[2] = -1; 14420Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 14430Sstevel@tonic-gate iplfile[0] = IPL_NAME; 14440Sstevel@tonic-gate iplfile[1] = IPNAT_NAME; 14450Sstevel@tonic-gate iplfile[2] = IPSTATE_NAME; 14460Sstevel@tonic-gate 14470Sstevel@tonic-gate while ((c = getopt(argc, argv, "?abB:C:Df:FhnN:o:O:pP:sS:tvxX")) != -1) 14480Sstevel@tonic-gate switch (c) 14490Sstevel@tonic-gate { 14500Sstevel@tonic-gate case 'a' : 14510Sstevel@tonic-gate opts |= OPT_LOGALL; 14520Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 14530Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 14540Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 14550Sstevel@tonic-gate break; 14560Sstevel@tonic-gate case 'b' : 14570Sstevel@tonic-gate opts |= OPT_LOGBODY; 14580Sstevel@tonic-gate break; 14590Sstevel@tonic-gate case 'B' : 14600Sstevel@tonic-gate binarylogfile = optarg; 14610Sstevel@tonic-gate binarylog = fopen(optarg, "a"); 14620Sstevel@tonic-gate break; 14630Sstevel@tonic-gate case 'C' : 14640Sstevel@tonic-gate conf_file = optarg; 14650Sstevel@tonic-gate break; 14660Sstevel@tonic-gate case 'D' : 14670Sstevel@tonic-gate make_daemon = 1; 14680Sstevel@tonic-gate break; 14690Sstevel@tonic-gate case 'f' : case 'I' : 14700Sstevel@tonic-gate opts |= OPT_FILTER; 14710Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 14720Sstevel@tonic-gate iplfile[0] = optarg; 14730Sstevel@tonic-gate break; 14740Sstevel@tonic-gate case 'F' : 14750Sstevel@tonic-gate flushlogs(iplfile[0], log); 14760Sstevel@tonic-gate flushlogs(iplfile[1], log); 14770Sstevel@tonic-gate flushlogs(iplfile[2], log); 14780Sstevel@tonic-gate break; 14790Sstevel@tonic-gate case 'n' : 14800Sstevel@tonic-gate opts |= OPT_RESOLVE; 14810Sstevel@tonic-gate break; 14820Sstevel@tonic-gate case 'N' : 14830Sstevel@tonic-gate opts |= OPT_NAT; 14840Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 14850Sstevel@tonic-gate iplfile[1] = optarg; 14860Sstevel@tonic-gate break; 14870Sstevel@tonic-gate case 'o' : case 'O' : 14880Sstevel@tonic-gate logopts(c == 'o', optarg); 14890Sstevel@tonic-gate fdt[0] = fdt[1] = fdt[2] = -1; 14900Sstevel@tonic-gate if (opts & OPT_FILTER) 14910Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 14920Sstevel@tonic-gate if (opts & OPT_NAT) 14930Sstevel@tonic-gate fdt[1] = IPL_LOGNAT; 14940Sstevel@tonic-gate if (opts & OPT_STATE) 14950Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 14960Sstevel@tonic-gate break; 14970Sstevel@tonic-gate case 'p' : 14980Sstevel@tonic-gate opts |= OPT_PORTNUM; 14990Sstevel@tonic-gate break; 15000Sstevel@tonic-gate case 'P' : 15010Sstevel@tonic-gate pidfile = optarg; 15020Sstevel@tonic-gate break; 15030Sstevel@tonic-gate case 's' : 15040Sstevel@tonic-gate s = strrchr(argv[0], '/'); 15050Sstevel@tonic-gate if (s == NULL) 15060Sstevel@tonic-gate s = argv[0]; 15070Sstevel@tonic-gate else 15080Sstevel@tonic-gate s++; 15090Sstevel@tonic-gate openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); 15100Sstevel@tonic-gate s = NULL; 15110Sstevel@tonic-gate opts |= OPT_SYSLOG; 15120Sstevel@tonic-gate log = NULL; 15130Sstevel@tonic-gate break; 15140Sstevel@tonic-gate case 'S' : 15150Sstevel@tonic-gate opts |= OPT_STATE; 15160Sstevel@tonic-gate fdt[2] = IPL_LOGSTATE; 15170Sstevel@tonic-gate iplfile[2] = optarg; 15180Sstevel@tonic-gate break; 15190Sstevel@tonic-gate case 't' : 15200Sstevel@tonic-gate opts |= OPT_TAIL; 15210Sstevel@tonic-gate break; 15220Sstevel@tonic-gate case 'v' : 15230Sstevel@tonic-gate opts |= OPT_VERBOSE; 15240Sstevel@tonic-gate break; 15250Sstevel@tonic-gate case 'x' : 15260Sstevel@tonic-gate opts |= OPT_HEXBODY; 15270Sstevel@tonic-gate break; 15280Sstevel@tonic-gate case 'X' : 15290Sstevel@tonic-gate opts |= OPT_HEXHDR; 15300Sstevel@tonic-gate break; 15310Sstevel@tonic-gate default : 15320Sstevel@tonic-gate case 'h' : 15330Sstevel@tonic-gate case '?' : 15340Sstevel@tonic-gate usage(argv[0]); 15350Sstevel@tonic-gate } 15360Sstevel@tonic-gate 15370Sstevel@tonic-gate init_tabs(); 15380Sstevel@tonic-gate if (conf_file) 15390Sstevel@tonic-gate if (load_config(conf_file) == -1) 15400Sstevel@tonic-gate exit(1); 15410Sstevel@tonic-gate 15420Sstevel@tonic-gate /* 15430Sstevel@tonic-gate * Default action is to only open the filter log file. 15440Sstevel@tonic-gate */ 15450Sstevel@tonic-gate if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) 15460Sstevel@tonic-gate fdt[0] = IPL_LOGIPF; 15470Sstevel@tonic-gate 15480Sstevel@tonic-gate for (i = 0; i < 3; i++) { 15490Sstevel@tonic-gate if (fdt[i] == -1) 15500Sstevel@tonic-gate continue; 15510Sstevel@tonic-gate if (!strcmp(iplfile[i], "-")) 15520Sstevel@tonic-gate fd[i] = 0; 15530Sstevel@tonic-gate else { 15540Sstevel@tonic-gate if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { 15550Sstevel@tonic-gate (void) fprintf(stderr, 15560Sstevel@tonic-gate "%s: open: %s\n", iplfile[i], 15570Sstevel@tonic-gate STRERROR(errno)); 15580Sstevel@tonic-gate exit(1); 15590Sstevel@tonic-gate /* NOTREACHED */ 15600Sstevel@tonic-gate } 15610Sstevel@tonic-gate if (fstat(fd[i], &sb) == -1) { 15620Sstevel@tonic-gate (void) fprintf(stderr, "%d: fstat: %s\n", 15630Sstevel@tonic-gate fd[i], STRERROR(errno)); 15640Sstevel@tonic-gate exit(1); 15650Sstevel@tonic-gate /* NOTREACHED */ 15660Sstevel@tonic-gate } 15670Sstevel@tonic-gate if (!(regular[i] = !S_ISCHR(sb.st_mode))) 15680Sstevel@tonic-gate devices++; 15690Sstevel@tonic-gate } 15700Sstevel@tonic-gate } 15710Sstevel@tonic-gate 15720Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) { 15730Sstevel@tonic-gate logfile = argv[optind]; 15740Sstevel@tonic-gate log = logfile ? fopen(logfile, "a") : stdout; 15750Sstevel@tonic-gate if (log == NULL) { 15760Sstevel@tonic-gate (void) fprintf(stderr, "%s: fopen: %s\n", 15770Sstevel@tonic-gate argv[optind], STRERROR(errno)); 15780Sstevel@tonic-gate exit(1); 15790Sstevel@tonic-gate /* NOTREACHED */ 15800Sstevel@tonic-gate } 15810Sstevel@tonic-gate setvbuf(log, NULL, _IONBF, 0); 15820Sstevel@tonic-gate } else 15830Sstevel@tonic-gate log = NULL; 15840Sstevel@tonic-gate 15850Sstevel@tonic-gate if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { 15860Sstevel@tonic-gate #if BSD >= 199306 15870Sstevel@tonic-gate daemon(0, !(opts & OPT_SYSLOG)); 15880Sstevel@tonic-gate #else 15890Sstevel@tonic-gate int pid; 15900Sstevel@tonic-gate if ((pid = fork()) > 0) 15910Sstevel@tonic-gate exit(0); 15920Sstevel@tonic-gate if (pid < 0) { 15930Sstevel@tonic-gate (void) fprintf(stderr, "%s: fork() failed: %s\n", 15940Sstevel@tonic-gate argv[0], STRERROR(errno)); 15950Sstevel@tonic-gate exit(1); 15960Sstevel@tonic-gate /* NOTREACHED */ 15970Sstevel@tonic-gate } 15980Sstevel@tonic-gate setsid(); 15990Sstevel@tonic-gate if ((opts & OPT_SYSLOG)) 16000Sstevel@tonic-gate close(2); 16010Sstevel@tonic-gate #endif /* !BSD */ 16020Sstevel@tonic-gate close(0); 16030Sstevel@tonic-gate close(1); 16040Sstevel@tonic-gate } 16050Sstevel@tonic-gate write_pid(pidfile); 16060Sstevel@tonic-gate 16070Sstevel@tonic-gate signal(SIGHUP, handlehup); 16080Sstevel@tonic-gate 16090Sstevel@tonic-gate for (doread = 1; doread; ) { 16100Sstevel@tonic-gate nr = 0; 16110Sstevel@tonic-gate 16120Sstevel@tonic-gate for (i = 0; i < 3; i++) { 16130Sstevel@tonic-gate tr = 0; 16140Sstevel@tonic-gate if (fdt[i] == -1) 16150Sstevel@tonic-gate continue; 16160Sstevel@tonic-gate if (!regular[i]) { 16170Sstevel@tonic-gate if (ioctl(fd[i], FIONREAD, &tr) == -1) { 16180Sstevel@tonic-gate if (opts & OPT_SYSLOG) 16190Sstevel@tonic-gate syslog(LOG_CRIT, 16200Sstevel@tonic-gate "ioctl(FIONREAD): %m"); 16210Sstevel@tonic-gate else 16220Sstevel@tonic-gate perror("ioctl(FIONREAD)"); 16230Sstevel@tonic-gate exit(1); 16240Sstevel@tonic-gate /* NOTREACHED */ 16250Sstevel@tonic-gate } 16260Sstevel@tonic-gate } else { 16270Sstevel@tonic-gate tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); 16280Sstevel@tonic-gate if (!tr && !(opts & OPT_TAIL)) 16290Sstevel@tonic-gate doread = 0; 16300Sstevel@tonic-gate } 16310Sstevel@tonic-gate if (!tr) 16320Sstevel@tonic-gate continue; 16330Sstevel@tonic-gate nr += tr; 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate tr = read_log(fd[i], &n, buf, sizeof(buf)); 16360Sstevel@tonic-gate if (donehup) { 1637*2393Syz155240 if (logfile && (fp = fopen(logfile, "a"))) { 16380Sstevel@tonic-gate fclose(log); 1639*2393Syz155240 log = fp; 16400Sstevel@tonic-gate } 1641*2393Syz155240 if (binarylogfile && (fp = fopen(binarylogfile, "a"))) { 16420Sstevel@tonic-gate fclose(binarylog); 1643*2393Syz155240 binarylog = fp; 16440Sstevel@tonic-gate } 1645*2393Syz155240 init_tabs(); 1646*2393Syz155240 if (conf_file != NULL) 1647*2393Syz155240 load_config(conf_file); 1648*2393Syz155240 donehup = 0; 16490Sstevel@tonic-gate } 16500Sstevel@tonic-gate 16510Sstevel@tonic-gate switch (tr) 16520Sstevel@tonic-gate { 16530Sstevel@tonic-gate case -1 : 16540Sstevel@tonic-gate if (opts & OPT_SYSLOG) 16550Sstevel@tonic-gate syslog(LOG_CRIT, "read: %m\n"); 16560Sstevel@tonic-gate else 16570Sstevel@tonic-gate perror("read"); 16580Sstevel@tonic-gate doread = 0; 16590Sstevel@tonic-gate break; 16600Sstevel@tonic-gate case 1 : 16610Sstevel@tonic-gate if (opts & OPT_SYSLOG) 16620Sstevel@tonic-gate syslog(LOG_CRIT, "aborting logging\n"); 16630Sstevel@tonic-gate else 16640Sstevel@tonic-gate fprintf(log, "aborting logging\n"); 16650Sstevel@tonic-gate doread = 0; 16660Sstevel@tonic-gate break; 16670Sstevel@tonic-gate case 2 : 16680Sstevel@tonic-gate break; 16690Sstevel@tonic-gate case 0 : 16700Sstevel@tonic-gate if (n > 0) { 16710Sstevel@tonic-gate print_log(fdt[i], log, buf, n); 16720Sstevel@tonic-gate if (!(opts & OPT_SYSLOG)) 16730Sstevel@tonic-gate fflush(log); 16740Sstevel@tonic-gate } 16750Sstevel@tonic-gate break; 16760Sstevel@tonic-gate } 16770Sstevel@tonic-gate } 16780Sstevel@tonic-gate if (!nr && ((opts & OPT_TAIL) || devices)) 16790Sstevel@tonic-gate sleep(1); 16800Sstevel@tonic-gate } 16810Sstevel@tonic-gate return(0); 16820Sstevel@tonic-gate /* NOTREACHED */ 16830Sstevel@tonic-gate } 1684