Subject: Re: How to make pppd dial out... FAQ
To: Peter Galbavy <peter@wonderland.org>
From: Simon J. Gerraty <sjg@zen.void.oz.au>
List: current-users
Date: 06/28/1995 09:46:02
> I am getting back to the wonderful world of serial coms after my portable
> Compaq has aquired enough memory and disk to run NetBSD. kermit (from 190
> sources) works fine, but damed if I can get pppd/chat to open the /dev/tty00
> device.

I've added current-users to the cc as the scripts below may be of
general interst... 

> Any offers people ? (Real modem, i386, NetBSD-current as of May
> binary snapshot)

I've been running dial-up PPP on NetBSD sparc and i386 without
problems.

ttys line looks like:

tty02   "/local/bin/mgetty -s 19200 -n 4 -x 3"  dialup on local rtscts

I don't believe mgetty is relevant, on the sparc the line was marked
off. 

The only changes I've made to ppp is to run ip-up as root, so that
routes can be fiddled.  I've made no changes to chat.  My sources are
of May 8 vintage.  Modems used vary.

The shell archive below contains the scripts I've been using for quite
a while to setup my PPP link to my ISP (and before that to a couple of
work sites).  The ipfwall script is run from rc.local.

Hope you find these useful.

--sjg

#!/bin/sh
# This is a shell archive.
# remove everything above the "#!/bin/sh" line
# and feed to /bin/sh
# Use -c option to overwrite existing files
#
# Contents: 
#	ppp/doppp.sh
#	ppp/ip-up
#	ppp/options
#	ppp/ppplogin
#	ppp/ipfwall
#
# packed by: <sjg@zen.void.oz.au> on Wed Jun 28 09:32:39 EST 1995
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: making path "ppp"
test -d ppp || mkdir ppp
if test -f ppp/doppp.sh -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"ppp/doppp.sh\"
else
  echo shar: Extracting \"ppp/doppp.sh\" \(4709 characters\)
  sed 's/^X//' >ppp/doppp.sh << '!EOF'
X:
X# NAME:
X#	doppp - set up a PPP session
X#
X# SYNOPSIS:
X#	doppp [options]
X#
X# DESCRIPTION:
X#	Builds a chat script for 'chat' to use.  We build it each time
X#	because we have to handle a time based one time password.
X#	We also have to handle calling via X.25 PAD :-)
X#	There are _lots_ of options, but most should be just set in
X#	.doppprc and left alone.
X#
X# AUTHOR:
X#	Simon J. Gerraty <sjg@zen.void.oz.au>
X#
X
X# RCSid:
X#	$Id: doppp.sh,v 1.1 1995/06/27 23:29:13 sjg Exp $
X#
X#	@(#) Copyright (c) 1994 Simon J. Gerraty
X#
X#	This file is provided in the hope that it will
X#	be of use.  There is absolutely NO WARRANTY.
X#	Permission to copy, redistribute or otherwise
X#	use this file is hereby granted provided that 
X#	the above copyright notice and this notice are
X#	left intact. 
X#      
X#	Please send copies of changes and bug-fixes to:
X#	sjg@zen.void.oz.au
X#
X
Xopt_str=I:X:S:U:t:s:T:P:N:L:R:u:p:c:f:raM:C:D:
X
X# most options are listed here for documentation only,
X# the blank ones would have been initialized below anyway.
X
X# these options are for access via X.25
Xopt_I=				# fixed part of NUI
Xopt_X=				# X.121 dest address
Xopt_S=				# sub address 24
Xopt_U=				# user data
X
Xopt_C=CONNECT			# call connected
Xopt_M=OK			# modem prompt
Xopt_D=ATD			# modem dial command
Xopt_Z=ATZ			# modem initialization
Xopt_t=/dev/tty02		# device to use
Xopt_s=19200			# speed
Xopt_T=60			# initial timeout
Xopt_P=131400			# phone number - public PAD
Xopt_N=192.168.42		# ppp net number
Xopt_L=2				# our host number on $opt_N
Xopt_R=1				# other end
Xopt_u=ppp			# user id
Xopt_p=				# password
Xopt_c=				# post login commands
Xopt_f=				# file of post login commands
X				# or fixed chat script
Xopt_r=1				# send \r after connect?
X
Xconnected=SunOS			# string to spot when connected
X
X# override the above defaults in say $HOME/.doppprc
XMyname=`basename $0 .sh`
XMydir=`dirname $0`
Xrc=.${Myname}rc
Xfor d in $HOME $Mydir; do
X  test -s $d/$rc && { . $d/$rc; break; }
Xdone
X
Xcase `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac
X
X# this sets default values of 0 for booleans, and "" for strings
X# unless they do not already have values.
Xeval `echo $opt_str | sed -e 's/\([^:]\)$/\1!/' -e 's/\([^:!]\)\([^:!]\)/\1!\2/g' -e 's/\(.\):/opt_\1=$opt_\1; /g'  -e 's/\(.\)!/opt_\1=${opt_\1-0}; /g'`
X
Xset -- `getopt $opt_str $*`
X
Xwhile [ $# -gt 0 ]
Xdo
X  case "$1" in
X  --)	shift; break;;
X  -*)
X    # Most shells give you ' ' in IFS whether you want it or not.
X    # but at least one, doesn't.  So the following gives us
X    # consistency.
X    o=`IFS=" -"; set -- $1; echo $*`	# lose the '-'
X    case .$opt_str. in
X    *${o}:*)
X      eval opt_$o=\"$2\"; shift 2;;
X    *${o}*)
X      eval opt_$o=1; shift;;
X    esac
X    ;;
X    *)	break;;			# should not happen
X  esac
Xdone
X
Xcase "$opt_L" in
X*.*.*.*) ;;
X"") ;;
X*)	opt_L=$opt_N.$opt_L;;
Xesac
Xcase "$opt_R" in
X*.*.*.*) ;;
X"") ;;
X*)	opt_R=$opt_N.$opt_R;;
Xesac
X
Xtest "$opt_L$opt_R" && addrs=${opt_L}:$opt_R || addrs=
X
Xask () { echo $N "${2:-$1?} "$C; read $1; }
X
X# now start building the chat script
XCS=/tmp/$Myname.chat.$$
X
X> $CS
Xchmod 600 $CS
X
X# dial
Xtest "$opt_P" && cat <<! >> $CS
XTIMEOUT ${opt_T:-60}
XABORT "NO CARRIER" ABORT BUSY
X"" $opt_Z
X"$opt_M" $opt_D$opt_P
X"$opt_C" "\\d\\c"
X!
X
X# doing X.25 ?
Xcase "$opt_X$opt_S" in
X"") ;;
X*)
X  ask key
X  # this just lets us have an alternate X.121 address in rc file
X  XS=${XS:-$opt_X}
X  case "$opt_S" in
X  "")	dest=N${key}${opt_I}-${opt_X};;
X  *)	dest=N${key}${opt_I}-${XS}${opt_S};;
X  esac
X  test "$opt_U" && dest="${dest}D$opt_U"
X  # this profile works ok, change it at your peril
X  profile="1:0,2:0,3:0,4:2,5:0,6:0,7:0,8:0,9:0,10:0,12:0,13:0,14:0,15:0"
X  cat <<! >>$CS
XPAC "\\dset $profile"
X"" "\\d$dest"
XTIMEOUT 120
X"$connected" "\\c"
X!
X  ;;
Xesac 
X
X# now the login section
X
Xtest "$opt_r" = 0 || echo '"" ""' >> $CS
X
Xtest "$opt_u" && cat <<! >>$CS
Xogin:--ogin: $opt_u
Xssword: "\\q$opt_p"
X!
X# if all the other options are blank then opt_f may name
X# the entire chat script :-)
Xtest -f "$opt_f" && cat $opt_f >> $CS
Xtest "$opt_c" && echo "$opt_c" >> $CS
X
Xis_up () {
X  case `ifconfig $1` in
X  *UP*)	: ;;			# true
X  *)	false;;
X  esac
X}
X
X# work out which ppp device we will be getting:
Xfor i in 0 1 2 3 4 5 6 7 8 9
Xdo
X  is_up ppp$i || { ppp_dev=ppp$i; break; }
Xdone
X
X${NICE} ${pppd:-pppd} lock connect "${chat:-chat} -v -f $CS" debug $opt_t $opt_s $pppopts $addrs
X
Xsleep 10
X# we can't use pid file, because it does not get written until
X# after chat finishes which is too late.
Xppp_pid=`ps | grep -v grep | grep "pppd.*$CS" | awk '{ print $1 }'`
X  
X# ok, wait for ppp_dev to be UP
Xwhile :; do
X  is_up $ppp_dev && { sleep 10; break; }
X  # but it may be down because chat failed.
X  kill -0 $ppp_pid >/dev/null 2>&1 || exit 1
X  sleep 20			# wait a while
Xdone
X
Xrm -f $CS
!EOF
  if test 4709 -ne `wc -c < ppp/doppp.sh`; then
    echo shar: \"ppp/doppp.sh\" unpacked with wrong size!
  fi
  chmod +x ppp/doppp.sh
fi
if test -f ppp/ip-up -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"ppp/ip-up\"
else
  echo shar: Extracting \"ppp/ip-up\" \(2764 characters\)
  sed 's/^X//' >ppp/ip-up << '!EOF'
X#!/bin/sh
X# NAME:
X#	ip-up - commands to execute when ppp link comes up/down
X#
X# SYNOPSIS:
X#	ip-up "iface" "tty" "speed" "local_addr" "remote_addr"
X#	ip-down "iface" "tty" "speed" "local_addr" "remote_addr"
X#
X# DESCRIPTION:
X#	This script is invoked by pppd when "iface" comes up or down.
X#
X# SEE ALSO:
X#	pppd(8).
X#
X# AUTHOR:
X#	Simon J. Gerraty <sjg@zen.void.oz.au>
X#
X
X# RCSid:
X#	$Id: ip-up,v 1.1 1995/06/27 23:29:14 sjg Exp $
X#
X#	@(#) Copyright (c) 1995 Simon J. Gerraty
X#
X#	This file is provided in the hope that it will
X#	be of use.  There is absolutely NO WARRANTY.
X#	Permission to copy, redistribute or otherwise
X#	use this file is hereby granted provided that 
X#	the above copyright notice and this notice are
X#	left intact. 
X#      
X#	Please send copies of changes and bug-fixes to:
X#	sjg@zen.void.oz.au
X#
X
X  
X# this is for debug
X#DOIT=echo
X
XMyname=`basename $0 .sh`
XMydir=`dirname $0`
X
Xif [ -f $Mydir/ip-debug ]; then
X  exec > /tmp/$Myname.$$ 2>&1
X  set -x
Xfi
X
Xiface=$1
Xtty=$2
Xspeed=$3
Xlocal_addr=$4
Xremote_addr=$5
X
X
Xremote=$iface
Xif [ -f $Mydir/nets ]; then
X  # nets contains lines like
X  # 192.9.200 sun
X  remote=`grep $remote_addr $Mydir/nets | cut -d: -f2`
X  case "$remote" in
X  "")	rnet=`IFS=.; set -- $remote_addr; echo "$1.$2.$3"`
X	remote=`grep $rnet $Mydir/nets | cut -d: -f2`
X	;;
X  esac
Xfi
X
XOS=`uname`
Xcase $OS in
XNetBSD) 
X        PATH=$PATH:/sbin:/usr/sbin
X        psopts=-ax; metric0=; metric1=;;
XSunOS)
X	PATH=$PATH:/usr/etc
X        psopts=-ax; metric0=0; metric1=1;;
Xesac
Xexport PATH
X
X# routes...
Xcase $0 in
X*up)
X  case $OS in
X  NetBSD)
X    test -f $Mydir/default.$remote && $DOIT route delete default
X    $DOIT route delete $remote_addr
X    ;;
X  esac
X  $DOIT route add $local_addr 127.0.0.1 $metric0 
X  $DOIT route add $remote_addr $local_addr $metric1
X  test -f $Mydir/default.$remote && $DOIT route add default $remote_addr $metric1
X  netstat -rn
X  ;;
X*down)
X  test -f $Mydir/default.$remote && route delete default $remote_addr $metric1
X  route delete $remote_addr $local_addr $metric1
X  route delete $local_addr 127.0.0.1 $metric0
X;;
Xesac
X
X# redirect sendmail?
Xmailertable=/usr/local/mail/lib/mailertable.db
X
Xif test -f $mailertable; then
X  ( cd `dirname $mailertable`
X    case $0 in
X    *up)
X      if [ -s mailertable.$remote ]; then
X        $DOIT cp mailertable.$remote mailertable
X        $DOIT make
X      fi
X      ;;
X    *down)
X      if [ -s mailertable.default ]; then
X        $DOIT cp mailertable.default mailertable
X        $DOIT make
X      fi
X      ;;
X    esac
X  )
Xfi
X
X# run inetd for this interface?
Xif [ -f /etc/inetd.$iface ]; then
X  inetd_pid=`ps $psopts | grep -v grep | grep "inetd.*$iface" | awk '{ print $1 }'`
X  test "$inetd_pid" && kill $inetd_pid
X  case $0 in
X  *up)
X    inetd -a $local_addr /etc/inetd.$iface;;
X  esac
Xfi
!EOF
  if test 2764 -ne `wc -c < ppp/ip-up`; then
    echo shar: \"ppp/ip-up\" unpacked with wrong size!
  fi
  chmod +x ppp/ip-up
  ln ppp/ip-up ppp/ip-down
fi
if test -f ppp/options -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"ppp/options\"
else
  echo shar: Extracting \"ppp/options\" \(114 characters\)
  sed 's/^X//' >ppp/options << '!EOF'
Xmtu 552
Xmru 552
Xmodem
Xcrtscts
X#lcp-echo-interval 120
X#lcp-echo-failure 10
Xnetmask 255.255.255.192
Xdebug 
Xkdebug 1
!EOF
  if test 114 -ne `wc -c < ppp/options`; then
    echo shar: \"ppp/options\" unpacked with wrong size!
  fi
  chmod +x ppp/options
fi
if test -f ppp/ppplogin -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"ppp/ppplogin\"
else
  echo shar: Extracting \"ppp/ppplogin\" \(70 characters\)
  sed 's/^X//' >ppp/ppplogin << '!EOF'
X:
Xstty cs8 -parenb -opost -istrip
Xsleep 2
Xexec /usr/sbin/pppd debug 
X
!EOF
  if test 70 -ne `wc -c < ppp/ppplogin`; then
    echo shar: \"ppp/ppplogin\" unpacked with wrong size!
  fi
  chmod +x ppp/ppplogin
fi
if test -f ppp/ipfwall -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"ppp/ipfwall\"
else
  echo shar: Extracting \"ppp/ipfwall\" \(2219 characters\)
  sed 's/^X//' >ppp/ipfwall << '!EOF'
X:
X# ipfirewall filters for internet connection
X
X# generally we would want to ensure that no spoofed addresses
X# or packets with options are let in.
X# since the kernel on gate does not forward packets
X# or accept source routing
X# or accept packets addressed to interfaces other than that which
X# they arrived on... the filters here can be quite simple.
X#
X# basically we want to stop folk talking to portmap, nfs, X and other
X# vulnerable apps.  Everything else can take care of itself.
X
X# start clean
X
Xipfirewall flush
XUDP_REJECT="111 2049 514 449"
XTCP_REJECT="111 2049 6000 449"
X
X# are we being paranoid?
XDEFAULT_DENY=no
X# if yes then need these
XUDP_ALLOW="echo domain"
XTCP_ALLOW=""
X
X# nets we should not see...
XMYNETS=203.12.250.0/24
X
X
X# basically, we want to only filter on the ppp interface(s)
X
X# behaviour of ipfirewall...
X# default action if no filter matches is opposite of first filter.
X# ie. if first is reject, then default is to accept...
X
X# adding an explicit global reject at the end is the best solution.
X
X# note that we do not accept based on src port as it is untrust worthy
X
Xfor IF in ${*:-""}
Xdo
X	# first don't allow spoofing...
X	ipfirewall addb $IF reject all from 127.0.0.0/8 to 0/0
X	for NET in $MYNETS
X	do 
X		ipfirewall addb $IF reject all from $NET to 0/0
X	done
X
X	# ok, allow some things
X	test "$UDP_REJECT" && ipfirewall addb $IF reject udp from 0/0 to 0/0 $UDP_REJECT
X	test "$TCP_REJECT" && ipfirewall addb $IF reject tcp from 0/0 to 0/0 $TCP_REJECT
X        case "$DEFAULT_DENY" in
X	""|no) ;;
X	*)
X	  # accept some specific activities
X	  ipfirewall addb $IF accept tcp from 0/0 to 0/0 $TCP_ALLOW
X	  ipfirewall addb $IF accept udp from 0/0 to 0/0 $UDP_ALLOW
X          ;;
X	esac
Xdone
X
X# Block the 'dangerous' IP options.
Xipfirewall addb reject all ip_misc_option from 0/0 to 0/0
X
Xcase "$DEFAULT_DENY" in
X""|no) ;;
X*) # we will deny all else on each interface
X  # but icmp not already rejected is ok
X  ipfirewall addb accept icmp from 0/0 to 0/0
X  # Allow tail fragments.
X  ipfirewall addb accept all ip_tail_fragment from 0/0 to 0/0
X
X  for IF in ${*:-""}
X  do
X	# default is to deny anything not specifically allowed...
X	ipfirewall addb $IF reject all from 0/0 to 0/0
X  done
X  ;;
Xesac
Xipfirewall list
!EOF
  if test 2219 -ne `wc -c < ppp/ipfwall`; then
    echo shar: \"ppp/ipfwall\" unpacked with wrong size!
  fi
  chmod +x ppp/ipfwall
fi
exit 0