#
#
# Copyright (c) 1995-2000 by Sun Microsystems, Inc.
# All rights reserved.
#
# This software is provided by Sun ``AS IS'' and any express or implied
# warranties, including, but not limited to, the implied warranties of
# merchantability and fitness for a particular purpose are disclaimed.
# In no event shall Sun Microsystems be liable for any direct, indirect,
# incidental, special, exemplary, or consequential damages.
#
# This software is not a product, and is provided for evaluation purposes
# only.
#
# This software may not be resold without the express permission of
# Sun Microsystems.
#
# Feedback on this tool may be sent to packet-shell-owner@sunroof.eng.sun.com.
#
# Packet Shell
#
#
#pragma ident	"@(#)Makefile	1.82	00/07/14 SMI"

CC = cc
#
#
# CONFIGURATION OPTIONS
#
#


# Directory for Tcl/Tk Package (defaults to /opt/tcltk)
TCLTKDIR= /opt/tcltk

# Solaris:
TCLLIBNAME= tcl7.6
TKLIBNAME= tk4.2

# FreeBSD:
# TCLLIBNAME= tcl76
# TKLIBNAME= tk42

# Base for X11:
# XXX.sparker

# Solaris:
X11BASE=/usr/openwin

# FreeBSD:
# X11BASE=/usr/X11R6

# OS
# Current choices: SOLARIS, FREEBSD
#

# Some systems also require extra fiddling here.  Currently:
#	For Solaris 2.5.1 and earlier, add -DNEED_FIXED_SIZED_TYPES
#	For Solaris 2.5.1 and earlier, add -DNO_SNPRINTF

# Solaris:
OS=-DSOLARIS

# FreeBSD:
# OS=-DFREEBSD

#
# different flags for shared objects on different OSes:
#

# Solaris:
SHARED_OBJ=-G

# FreeBSD:
# SHARED_OBJ=-Bshareable

# Include directories
# Make sure you cover:
#	X11, Tcl/Tk, libpcap

INCLUDES= -I$(TCLTKDIR)/include -I$(X11BASE)/include -I$(LIBPCAPDIR_INC)


# Library directories
# Must be enough to find libraries to link against for:
#	X11, Tcl/Tk, libpcap

LIBDIRS= -L$(TCLTKDIR)/lib -L$(X11BASE)/lib

# Special Libraries to link against
# Default collection

# Solaris:
OSLIBS= -lm -ldl -lsocket -lnsl 

# FreeBSD:
# OSLIBS= -lm

#
# Which protocols are actually supported are different on different OSes.
# Uncomment ONE of the following lines to select which set you have,
# and customize if necessary
#

# Solaris:
PSH_PROTOS=	data dhcp ether file hopopt icmp ip ipv6 ipv6-frag ipv6-icmp \
	ipv6-opts ipv6-route skeleton socket syscall tcp tli

# FreeBSD:
# PSH_PROTOS= 	data dhcp ether file ip socket tcp

#
# Built-in filter technology
#
# The packet shell tries to provide access to some packet filter language
# and filters, but different systems use different ones.  For now we have
# a configurable.  Eventually we punt and use libpcap on all systems.

# Solaris:
PKTFILT= snoop_pf.o

# FreeBSD:
# PKTFILT= -lpcap

#
# Install command takes different flags on Solaris and BSD
#

# Solaris:
INSTALL=	/usr/ucb/install -c

# FreeBSD:
# INSTALL=	install -c

#
# END CONFIGURATION SECTION
#


# Begin standard boiler-plate Makefile


# Directory for Relocatable Libraries in the Tcl/Tk 
# Package (defaults to /opt/tcltk/lib)
TCLTKDIR_LINK=/opt/tcltk/lib

#
# Though libpcap can be normally fetched from ftp.ee.lbl.gov, it's
# included in the tcltk package so that you don't need to get it and
# build it.  The directory you set LIBPCAPDIR_LIB contains libpcap.a,
# and LIBPCAPDIR_INC contains the pcap.h, pcap-namedb.h, and net/bpf.h
# files.
#
LIBPCAPDIR_LIB=$(TCLTKDIR)/lib
LIBPCAPDIR_INC=$(TCLTKDIR)/include

CFLAGS=	$(OS) $(INCLUDES)
LIBS= -l$(TCLLIBNAME)  $(OSLIBS)

PSH_OBJS=	name2int.o psh_compat.o psh_utils.o $(PKTFILT)
PSH_PROTOS_STR=	streams
DHCP_ALIASES=	bootpc bootps

PSH_ROOT=	/opt/psh
PSH_EXES=	xpsh psh $(PSH_PROTOS) xplot
PSH_EXES_STR=	$(PSH_PROTOS_STR) strsim 
PSH_CLEAN=	xpsh psh $(PSH_PROTOS) $(PSH_PROTOS_STR) strsim
PSH_BIN=	$(PSH_ROOT)/bin
PSH_PROTODIR=	$(PSH_ROOT)/lib
PSH_MAN=	$(PSH_ROOT)/man
PSH_STR=	$(PSH_ROOT)/streams
PSH_TCLLIB=	$(PSH_ROOT)/tcllib
PSH_SCRIPTS=	$(PSH_ROOT)/scripts
PSH_LLIB_CFILES= psh.c name2int.c psh_compat.c psh_utils.c 
LFLAGS	=	-u -v -x -errtags -erroff=E_BAD_PTR_CAST_ALIGN $(CFLAGS) -L .
LINTOPTS=	$(LFLAGS) $(LIBDIRS) $(LIBS)

all:	$(PSH_EXES)

xpsh.o:	psh.c psh.h proto.h
	$(CC) -DWINDOWS -c -o $@ $(CFLAGS) psh.c

xpsh:	$(PSH_OBJS) xpsh.o
	$(CC) -o $@ xpsh.o $(PSH_OBJS) $(LIBDIRS) -l$(TKLIBNAME) -lBLT $(LIBS) -lX11 -R/usr/lib:$(X11BASE)/lib:$(TCLTKDIR_LINK)

llib-lxpsh.ln:	llib-ltcl7.6.ln NEVER
	$(LINT) -o xpsh -DWINDOWS $(LINTOPTS) psh.c $(PSH_OBJS:.o=.c)

psh.o:	psh.c psh.h proto.h
	$(CC) -c -o $@ $(CFLAGS) psh.c

psh:	$(PSH_OBJS) psh.o
	$(CC) -g -o $@ psh.o $(PSH_OBJS) $(LIBDIRS) $(LIBS)
	sync

llib-lpsh.ln:	llib-ltcl7.6.ln NEVER
	$(LINT) -o psh $(LINTOPTS) psh.c $(PSH_OBJS:.o=.c)

llib-ltcl7.6.ln:	llib-ltcl7.6.c
	$(LINT) $(LFLAGS) -c $?

purify:
	$(MAKE) CC="/net/suntools/export/tools/`uname -p`/bin/purify cc"

psh_utils.o psh.o:	psh.h

ether:	ether.o psh.h $(LIBPCAPDIR_LIB)/libpcap.a
	$(LD) $(SHARED_OBJ) -o $@ ether.o $(LIBPCAPDIR_LIB)/libpcap.a

ip:	ip.o dlprims.o
	$(LD) $(SHARED_OBJ) -o $@ ip.o dlprims.o

ipv6:	ipv6.o dlprims.o
	$(LD) $(SHARED_OBJ) -o $@ ipv6.o dlprims.o

#
# PSH protocol libraries rely on dependencies between the various libraries.
# This means a given link order is required.  -N<dependency> is how you tell
# 2.6 and later linkers this.  If you don't have 2.6, delete -Nfoo, but
# know that you should clean all objects and then re-install them all to 
# ensure correct linkage.
#

skeleton:	skeleton.o
	$(LD) $(SHARED_OBJ) -o $@ skeleton.o

ipv6-icmp:	ipv6-icmp.o
	$(LD)  $(SHARED_OBJ) -o $@ ipv6-icmp.o

icmp:	icmp.o
	$(LD)  $(SHARED_OBJ) -o $@ icmp.o

ipv6-frag:	ipv6-frag.o
	$(LD) $(SHARED_OBJ) -o $@ ipv6-frag.o

ipv6-route:	ipv6-route.o
	$(LD) $(SHARED_OBJ) -o $@ ipv6-route.o

file:	file.o file_tcpdump.o
	$(LD) $(SHARED_OBJ) -o $@ file.o file_tcpdump.o

dhcp:	dhcp.o dhcp_util.o
	$(LD) $(SHARED_OBJ) -o $@ dhcp.o dhcp_util.o

data:	data.o dlprims.o
	$(LD) $(SHARED_OBJ) -o $@ data.o

mip:	mip.o miputils.o mipmd5.o dlprims.o
	$(LD) $(SHARED_OBJ) -o $@ mip.o miputils.o mipmd5.o

socket:	socket.o
	$(LD) $(SHARED_OBJ) -o $@ socket.o

hopopt: ipv6-opts.o
	$(LD) $(SHARED_OBJ) -o $@ ipv6-opts.o

ipv6-opts: ipv6-opts.o  ipv6.h
	$(LD) $(SHARED_OBJ) -o $@ ipv6-opts.o

syscall:	syscall.o
	$(LD) $(SHARED_OBJ) -o $@ syscall.o

tli:	tli.o
	$(LD) $(SHARED_OBJ) -o $@ tli.o

dhcp.c: dhcp.h dhcp_util.h dhcp_types.h
ip.c: psh.h
ipv6.c: psh.h ipv6.h
ipv6-icmp.c: psh.h
icmp.c: psh.h
snoop_pf.o: snoop.h
ipv6-frag.c: psh.h ipv6.h
file.c: psh.h
socket.c: psh.h
ipv6-opts.c: psh.h ipv6.h
ipv6-route.c: psh.h ipv6.h
tli.c: psh.h
psh_utils.c: psh.h
syscall.c: psh.h

tcp:	tcp.o psh.h
	$(LD) $(SHARED_OBJ) -o $@ $@.o

streams_ddi.o:	streams_ddi.c streams.h
	$(CC) -c -Ikernel $(CFLAGS) streams_ddi.c 
mblk.o:	mblk.c streams.h
	$(CC) -c -Ikernel $(CFLAGS) mblk.c

streams:	streams.o proto.h psh.h
	$(LD) $(SHARED_OBJ) -o $@ streams.o

strsim:	streams_ddi.o mblk.o
	$(LD) $(SHARED_OBJ) -N/usr/lib/libdl.so.1 -N/usr/lib/libpthread.so.1 -o $@ streams_ddi.o mblk.o

streams-sim: $(PSH_EXES_STR) $(PSH_OBJS)
	$(CC) -c $(CFLAGS) psh.c
	$(CC) -g -o psh psh.o $(PSH_OBJS) $(PSH_OBJS_STR) $(LIBDIRS) \
		-lpthread $(LIBS)
	$(CC) -DWINDOWS -c $(CFLAGS) psh.c
	$(CC) -o xpsh psh.o $(PSH_OBJS) $(PSH_OBJS_STR) $(LIBDIRS) -lpthread \
		-l$(TKLIBNAME) $(LIBS) -lX11 -lBLT \
		-R/usr/lib:$(X11BASE)/lib:$(TCLTKDIR_LINK)

install: all
	mkdir -p $(PSH_PROTODIR) $(PSH_BIN) $(PSH_TCLLIB)
	mkdir -p $(PSH_SCRIPTS) $(PSH_MAN)/man1 $(PSH_MAN)/man3
	mkdir -p $(PSH_TCLLIB)/pbuild
	if [ -f strsim ]; then mkdir -p $(PSH_STR); fi
	$(INSTALL) -m 755 psh $(PSH_BIN)
	$(INSTALL) -m 755 xpsh $(PSH_BIN)
	$(INSTALL) -m 755 harness $(PSH_BIN)
	$(INSTALL) -m 755 harness.seq $(PSH_BIN)
	$(INSTALL) -m 755 snoop2tcpdump $(PSH_BIN)
	$(INSTALL) -m 755 tcpdump2snoop $(PSH_BIN)
	$(INSTALL) -m 755 pbuild $(PSH_BIN)
	$(INSTALL) -m 755 ../scripts/tcp/tcp.analysis $(PSH_BIN)
	$(INSTALL) -m 755 ../scripts/tcp/tcp.graph $(PSH_BIN)
	cd ../scripts/tcpgraph; \
		$(MAKE) PSH_TCLLIB=$(PSH_TCLLIB) PSH_BIN=$(PSH_BIN) \
		INSTALL="$(INSTALL)" install
	if [ ! -f xplot/xplot ]; then cd xplot; $(MAKE) X11BASE=$(X11BASE); fi
	$(INSTALL) -m 755 xplot/xplot $(PSH_BIN)
	cp -f $(PSH_PROTOS) $(PSH_PROTODIR)
	for f in $(DHCP_ALIASES); do \
		rm -f $(PSH_PROTODIR)/$$f; \
		ln $(PSH_PROTODIR)/dhcp $(PSH_PROTODIR)/$$f; \
	done
	if [ -f strsim ]; then cp strsim $(PSH_STR); fi
	if [ -f streams ]; then cp -f $(PSH_PROTOS_STR) $(PSH_PROTODIR); fi
	cp -f ../doc/*.1 $(PSH_MAN)/man1
	cp -f ../doc/*.3 $(PSH_MAN)/man3
	cp -f ../tcllib/*.proto $(PSH_TCLLIB)
	cp -f ../tcllib/pshrc $(PSH_TCLLIB)
	cp -f ../tcllib/pinfo.tcl $(PSH_TCLLIB)
	cp -f ../tcllib/ioctl_array.tcl $(PSH_TCLLIB)
	cp -f ../tcllib/pbuild.tk $(PSH_TCLLIB)
	rm -f $(PSH_TCLLIB)/pbuild/*.tcl
	cp ../tcllib/pbuild/*.tcl $(PSH_TCLLIB)/pbuild
	cp -f ../README $(PSH_ROOT)
	cd ../scripts; find . -name SCCS -prune -o -print | \
	    cpio -pdu $(PSH_SCRIPTS);

PROTO=../proto
PROTOBIN=$(PROTO)/bin
PROTOLIB=$(PROTO)/lib
PROTOMAN=$(PROTO)/man
PROTOSTR=$(PROTO)/streams
PROTOTCLLIB=$(PROTO)/tcllib
PROTOSCRIPTS=$(PROTO)/scripts
install_proto: all
	rm -rf $(PROTO)/*
	mkdir -p $(PROTOBIN) $(PROTOLIB) $(PROTOMAN)/man1 $(PROTOMAN)/man3
	mkdir -p $(PROTOTCLLIB) $(PROTOSCRIPTS)
	mkdir -p $(PROTOTCLLIB)/pbuild
	if [ -f strsim ]; then mkdir -p $(PROTOSTR); fi
	$(INSTALL) -m 755 $(INS_F) psh $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) xpsh $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) harness $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) harness.seq $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) tcpdump2snoop $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) snoop2tcpdump $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) pbuild $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) ../scripts/tcp/tcp.analysis $(PROTOBIN)
	$(INSTALL) -m 755 $(INS_F) ../scripts/tcp/tcp.graph $(PROTOBIN)
	cd ../scripts/tcpgraph; \
		$(MAKE) PROTOTCLLIB=../$(PROTOTCLLIB) PROTOBIN=../$(PROTOBIN) install_proto
	if [ ! -f xplot/xplot ]; then cd xplot; $(MAKE) X11BASE=$(X11BASE); fi
	$(INSTALL) -m 755 $(INS_F) xplot/xplot $(PROTOBIN)
	cp -f $(PSH_PROTOS) $(PROTOLIB)
	if [ -f strsim ]; then cp -f strsim $(PROTOSTR); fi
	if [ -f streams ]; then cp -f $(PSH_PROTOS_STR) $(PROTOLIB); fi
	cp -f ../doc/*.1 $(PROTOMAN)/man1
	cp -f ../doc/*.3 $(PROTOMAN)/man3
	cp -f ../tcllib/*.proto $(PROTOTCLLIB)
	cp -f ../tcllib/pshrc $(PROTOTCLLIB)
	cp -f ../tcllib/pinfo.tcl $(PROTOTCLLIB)
	cp -f ../tcllib/ioctl_array.tcl $(PROTOTCLLIB)
	cp -f ../tcllib/pbuild.tk $(PROTOTCLLIB)
	cp -f ../tcllib/pbuild/*.tcl $(PROTOTCLLIB)/pbuild
	cp -f ../README $(PROTO)
	cd ../scripts; find . -name SCCS -prune -o -print | \
	    cpio -pdu $(PROTOSCRIPTS);
	if [ ! -f streams ]; then cd ../pkg; $(MAKE) package; else \
		cd ../pkg; $(MAKE) package-streams; fi

clean:
	rm -f *.o *.ln core $(PSH_CLEAN)
	cd xplot; $(MAKE) clean

tags:
	ctags -t *.[ch]

xplot:
	cd xplot; $(MAKE) X11BASE=$(X11BASE)

#
# Lint strategy is kind of complex.  We make a library of the core packet
# shell, and then we run it against each library's source as a series of
# separate wads.  This is done because dlsym() is used to call into each
# library at a series of fixed entry points, and this would yield lots of
# multiply defined diagnostics.
#

lint:	psh.lint xpsh.lint skeleton.lint data.lint mip.lint dhcp.lint  \
	ether.lint file.lint icmp.lint ip.lint ipv6.lint ipv6-frag.lint \
	ipv6-opts.lint ipv6-route.lint syscall.lint socket.lint tcp.lint \
	tli.lint

psh.lint:	llib-lpsh.ln

xpsh.lint:	llib-lxpsh.ln

skeleton.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) skeleton.c

data.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) data.c

dhcp.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) dhcp.c dhcp_util.c

ether.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ether.c

file.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) file.c

icmp.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) icmp.c

ip.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ip.c

ipv6.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ipv6.c

ipv6-frag.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ipv6-frag.c

ipv6-icmp.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ipv6-icmp.c

ipv6-opts.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ipv6-opts.c

ipv6-route.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) ipv6-route.c

mip.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) mip.c mipmd5.c miputils.c

syscall.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) syscall.c

socket.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) socket.c

tcp.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) tcp.c

tli.lint: llib-lpsh.ln
	$(LINT.c) $(LINTOPTS) tli.c

NEVER:

#
# cstyle check.  Note that we list files explicitly because a few files
# are not cstyle clean, nor expected to be.  They are:
#	file_tcpdump.c
cstyle:
	cstyle -p `echo *.c *.h | sed -e 's/file_tcpdump.c//' -e 's/streams_ddi.c//' -e 's/bpf.h//' -e 's/gnuc.h//'

