Re: Bash script to see if PPP link is up...

From: Lew Pitcher (lpitcher_at_sympatico.ca)
Date: 08/23/03


Date: Fri, 22 Aug 2003 21:11:52 -0400

Alan Connor wrote:
> On Fri, 22 Aug 2003 03:53:41 +0000 (UTC), David Efflandt <efflandt@xnet.com> wrote:
>
>>
>>On Thu, 21 Aug 2003 21:28:57 GMT, Alan Connor <xxxxxx@xxxx.xxx> wrote:
>>
>>>On Thu, 21 Aug 2003 21:54:51 +0100, JRH <john.nntp@yoredale2003.uklinux.net> wrote:
>>
>>ifconfig may be able to tell if it is up, but can it tell if it is
>>connected or not? For example when you use demand pppd, the ppp0
>>interface appears in ifconfig, but it is not connected until there is
>>traffic routed to it. Likewise if an idle time is set for a demand
>>connection and it disconnects, ifconfig would still show it up. That is
>>why I use ip-up & ip-down scripts (which are reliable even for demand and
>>idle).
>>
>
>
> To repeat:
>
> If my ppp connection is not up, /sbin/ifconfig ppp0 exits with an error
> message and the exit code reads 1
>
> If the connection is up, then I get the full info and the exit code is 0.

The keys to this are the words "my" and "I", as in "my ppp connection" and "I get".
Your experience is not the be-all and end-all of Linux, and ifconfig is not a reliable
way to determine if pppd has established an internet connection.

[snip]

> It seems that some folks have the mistaken notion that all programs and
> utilities with the same name behave just the same, even on differently
> configured OSs.

Including you. You seem to think that ifconfig is a reliable indicator, and /we/
have experience that it is not.

[snip]

So, instead of debating who's right and who's wrong, lets /see/ what happens.
On /my/ system, I'll try /your/ suggestion and JRH's script, and we'll see if
either of you have a solution that will work for me.

I run Slackware Linux 9.0 (I've run Slackware Linux since it's 3.0 release),
with current levels of all relevant packages and the 2.4.21 kernel. I have
pppd running in "dial-on-demand" mode so that any off-lan activity from my
lan gets routed through the ppp interface to the internet.

/I/ say that your ifconfig trick doesn't reliably indicate when this config
is "on the internet" and when it is "off". /I/ say that JRH's script suffers
from the same unreliability, although his script gives a little better info
than technique does. /I/ say that the only reliable way /I've/ found to
determine the state of my internet connection is to use the features of
the /etc/ppp/ip-up and /etc/ppp/ip-down scripts.

So, here's my demonstration...

Linux Kernel 2.4.21 compiled for Pentium processor

   root@merlin:~# uname -a
   Linux merlin 2.4.21 #17 Sat Jun 21 21:34:23 EDT 2003 i586 unknown

Slackware Linux 9.0 installation (all packages updated)

   root@merlin:~# cat /etc/slackware-version
   Slackware 9.0.0

The ppp-2.4.1-i386-2 package from slackware.com

   root@merlin:~# ls /var/adm/packages/ppp*
   /var/adm/packages/ppp-2.4.1-i386-2

Verify that...

   root@merlin:~# head -16 /var/adm/packages/ppp-2.4.1-i386-2
   PACKAGE NAME: ppp-2.4.1-i386-2
   COMPRESSED PACKAGE SIZE: 186 K
   UNCOMPRESSED PACKAGE SIZE: 480 K
   PACKAGE LOCATION: slackware/n/ppp-2.4.1-i386-2.tgz
   PACKAGE DESCRIPTION:
   ppp: ppp (Point-to-Point Protocol)
   ppp:
   ppp: The Point-to-Point Protocol (PPP) provides a method for transmitting
   ppp: data over serial links. It's commonly used for connecting to the
   ppp: Internet using a modem. This package includes the PPP daemon (pppd),
   ppp: which negotiates with the peer to establish the link and sets up the
   ppp: ppp network interface, and pppsetup, an easy-to-use utility for
   ppp: setting up your PPP daemon.
   ppp:
   ppp:
   ppp:

Even pppd agrees.

   root@merlin:~# pppd -h
   pppd version 2.4.1
   Usage: pppd [ options ], where options are:
           <device> Communicate over the named device
           <speed> Set the baud rate to <speed>
           <loc>:<rem> Set the local and/or remote interface IP
                           addresses. Either one may be omitted.
           asyncmap <n> Set the desired async map to hex <n>
           auth Require authentication from peer
           connect <p> Invoke shell command <p> to set up the serial line
           crtscts Use hardware RTS/CTS flow control
           defaultroute Add default route through interface
           file <f> Take options from file <f>
           modem Use modem control lines
           mru <n> Set MRU value to <n> for negotiation
   See pppd(8) for more options.

Right now, ppp dial-on-demand is down, so no ppp0 shows up in ifconfig

   root@merlin:~# /sbin/ifconfig
   eth0 Link encap:Ethernet HWaddr 00:C0:F0:37:C2:80
             inet addr:192.168.11.1 Bcast:192.168.11.255 Mask:255.255.255.0
             UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
             RX packets:7306 errors:38 dropped:0 overruns:0 frame:38
             TX packets:57475 errors:0 dropped:0 overruns:0 carrier:0
             collisions:847 txqueuelen:100
             RX bytes:758130 (740.3 Kb) TX bytes:6155617 (5.8 Mb)
             Interrupt:10 Base address:0x6000

   lo Link encap:Local Loopback
             inet addr:127.0.0.1 Mask:255.0.0.0
             UP LOOPBACK RUNNING MTU:16436 Metric:1
             RX packets:6329 errors:0 dropped:0 overruns:0 frame:0
             TX packets:6329 errors:0 dropped:0 overruns:0 carrier:0
             collisions:0 txqueuelen:0
             RX bytes:3116710 (2.9 Mb) TX bytes:3116710 (2.9 Mb)

We try your trick of checking the returncode from ifconfig,
and find that ifconfig returns 1 when no PPP daemon is running

   root@merlin:~# /sbin/ifconfig ppp0
   ppp0: error fetching interface information: Device not found
   root@merlin:~# echo $?
   1

Now, I start up the ppp0 dial-on-demand daemon (by hand, although
I usually use the equivalent ppp-go script).

   root@merlin:~# rm -f /var/LCK* /var/run/ppp*.pid
   root@merlin:~# /usr/sbin/pppd file "/etc/ppp/options.demand" &
   [1] 3333

Now, ifconfig shows that ppp0 is up, connecting local IP address 10.64.64.64
to remote IP address 10.10.10.10, and ifconfig returns a zero returncode.

   root@merlin:~# /sbin/ifconfig ppp0
   ppp0 Link encap:Point-to-Point Protocol
             inet addr:10.64.64.64 P-t-P:10.10.10.10 Mask:255.255.255.255
             UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
             RX packets:0 errors:0 dropped:0 overruns:0 frame:0
             TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
             collisions:0 txqueuelen:3
             RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
   root@merlin:~# echo $?
   0

However,
1) My wife is using our one and only phone line at the moment, so
    ppp0 *is not* connected to the internet. For that matter, chat
    hasn't even picked up the phone, let alone tried to dial out.
2) Since ppp0 is not connected to the internet, neither the remote IP
    address nor the local IP address reported are valid (they are both
    placeholder addresses which will be discarded once I /do/ connect
    to the internet.

So, let's see how JRH's script works (posted in message <3f45318b@212.67.96.135> )
I cut'n'paste his script directly from his post into the terminal window and
execute it. I get...

   root@merlin:~# EXTIF="ppp0" # external interface, may be empty
   root@merlin:~# IFCONFIG=/sbin/ifconfig
   root@merlin:~# AWK=/bin/awk
   root@merlin:~#
   root@merlin:~# # get the external IP address - it returns empty string if it is not up
   root@merlin:~# if [ -n "$EXTIF" ]; then
> EXTIP="`$IFCONFIG $EXTIF 2>/dev/null | $AWK \
> /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
> fi
   root@merlin:~# echo " External IP: $EXTIP"
     External IP: 10.64.64.64

Again, this is wrong. I'm *not* connected to the internet, and, while the IP
address reported is the placeholder address assigned by pppd, it is *not* the
IP address used by my dial-on-demand pppd.

So, neither your technique nor JRH's technique properly reports the state of
my system's internet connection.

Now, the technique that /I/ use is to have the /etc/ppp/ip-up script create
a sentinal file when pppd establishes it's IP connection to the internet, and
have the /etc/ppp/ip-down script delete the sentinal file. This way, external
processes can check for the existance of the sentinal and determine indirectly
the state of the internet connection.

Take a look at the manpage for pppd...

   root@merlin:~# man pppd
   PPPD(8) PPPD(8)

   NAME
          pppd - Point to Point Protocol daemon

   SYNOPSIS
          pppd [ tty_name ] [ speed ] [ options ]

   DESCRIPTION
          The Point-to-Point Protocol (PPP) provides a method for transmit-
          ting datagrams over serial point-to-point links. PPP is composed
          of three parts: a method for encapsulating datagrams over serial
          links, an extensible Link Control Protocol (LCP), and a family of
          Network Control Protocols (NCP) for establishing and configuring
          different network-layer protocols.
   [snip]
   SCRIPTS
          Pppd invokes scripts at various stages in its processing which
          can be used to perform site-specific ancillary processing. These
          scripts are usually shell scripts, but could be executable code
          files instead. Pppd does not wait for the scripts to finish.
          The scripts are executed as root (with the real and effective
          user-id set to 0), so that they can do things such as update
          routing tables or run privileged daemons. Be careful that the
          contents of these scripts do not compromise your system's secu-
          rity. Pppd runs the scripts with standard input, output and
          error redirected to /dev/null, and with an environment that is
          empty except for some environment variables that give information
          about the link. The environment variables that pppd sets are:
   [snip]
          Pppd invokes the following scripts, if they exist. It is not an
          error if they don't exist.
   [snip]
          /etc/ppp/ip-up
                 A program or script which is executed when the link is
                 available for sending and receiving IP packets (that is,
                 IPCP has come up). It is executed with the parameters

                 interface-name tty-device speed local-IP-address remote-
                 IP-address ipparam

          /etc/ppp/ip-down
                 A program or script which is executed when the link is no
                 longer available for sending and receiving IP packets.
                 This script can be used for undoing the effects of the
                 /etc/ppp/ip-up script. It is invoked in the same manner
                 and with the same parameters as the ip-up script.

My /etc/ppp/ip-up script creates (or replaces) the /var/run/ppp0.ip file
when ppp0 comes up. The file contains the local IP address assigned by
my ISP, in textual form. This way, I can test for the existance of the
file to determine whether or not my internet connection is up, and /if/
it is up, I can determine the IP address without resorting to the
ifconfig/grep/awk awkwardness.

   root@merlin:~# cat /etc/ppp/ip-up
   #!/bin/sh
   #
   # ip-up interface-name tty-device speed local-IP remote-IP ipparm
   # $1 $2 $3 $4 $5 $6
   #
   # (NB: ipparm is string from ipparm parameter in pppd options)
   #
   # This file /etc/ppp/ip-up is run by pppd when there's a
   # successful ppp connection.
   #
   # The environment is cleared before executing this script
   # so the path must be reset.
   #
   PATH=/usr/bin:/usr/sbin:/usr/local/bin:/sbin:/bin
   export PATH
   #
   SCRIPT=`/usr/bin/basename $0`
   #
   echo $4 >/var/run/$1.ip

My /etc/ppp/ip-down script deletes the /var/run/ppp0.ip file, so that when I loose
my internet connection, the sentinal file disappears. Again, if an external process
looks for the file, and /does not/ find it, it can assume that /etc/ppp/ip-down
deleted it, and infer that the internet connection has been dropped.

   root@merlin:~# cat /etc/ppp/ip-down
   #!/bin/sh
   #
   # This script is run by pppd after the PPP connection is ended.
   #
   # ip-down interface-name tty-device speed local-IP remote-IP ipparm
   # $1 $2 $3 $4 $5 $6
   #
   # (NB: ipparm is string from ipparm parameter in pppd options)
   #
   PATH=/usr/sbin:/sbin:/usr/bin:/usr/local/bin:/bin
   export PATH
   #
   SCRIPT=`/usr/bin/basename $0`
   #
   rm /var/run/$1.ip

Finally, here's an example of a script that determines if my internet
connection is live or not.

   root@merlin:~# cat is_ppp_up
   #!/bin/bash
   if [ -f /var/run/ppp0.ip ]
   then
      echo "Yes, PPP0 is UP with IP address " `cat /var/run/ppp0.ip`
      exit 0
   else
      echo "No, PPP0 is DOWN"
      exit 1
   fi

When I run it while I'm "offline", I get

   root@merlin:~# ./is_ppp_up
   No, PPP0 is DOWN

However, if I do something that requires an internet connection
(like try to browse http://slashdot.net/ under Mozilla), I get

   root@merlin:~# ./is_ppp_up
   Yes, PPP0 is UP with IP address 64.228.63.114

If I try the ifconfig returncode trick, I get the same results as when my internet
connection is down.

   root@merlin:~# /sbin/ifconfig ppp0
   ppp0 Link encap:Point-to-Point Protocol
             inet addr:64.228.63.114 P-t-P:64.228.63.241 Mask:255.255.255.255
             UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
             RX packets:100 errors:1 dropped:0 overruns:0 frame:0
             TX packets:105 errors:0 dropped:10 overruns:0 carrier:0
             collisions:0 txqueuelen:3
             RX bytes:49724 (48.5 Kb) TX bytes:9794 (9.5 Kb)

   root@merlin:~# echo $?
   0

If I try JRH's script, I get marginally different results from when my internet
connection was down. At least this time JRH's script properly reports my IP address.

   root@merlin:~# EXTIF="ppp0" # external interface, may be empty
   root@merlin:~# IFCONFIG=/sbin/ifconfig
   root@merlin:~# AWK=/bin/awk
   root@merlin:~#
   root@merlin:~# # get the external IP address - it returns empty string if it is not up
   root@merlin:~# if [ -n "$EXTIF" ]; then
> EXTIP="`$IFCONFIG $EXTIF 2>/dev/null | $AWK \
> /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
> fi
   root@merlin:~# echo " External IP: $EXTIP"
     External IP: 64.228.63.114

And if I try it again after my internet connection comes down ("idle time out"),
I get /the same/ results. It appears that JRH's script thinks that my internet
connection is still up.

   root@merlin:~# ./is_ppp_up
   No, PPP0 is DOWN

   root@merlin:~# EXTIF="ppp0" # external interface, may be empty
   root@merlin:~# IFCONFIG=/sbin/ifconfig
   root@merlin:~# AWK=/bin/awk
   root@merlin:~#
   root@merlin:~# # get the external IP address - it returns empty string if it is not up
   root@merlin:~# if [ -n "$EXTIF" ]; then
> EXTIP="`$IFCONFIG $EXTIF 2>/dev/null | $AWK \
> /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
> fi
   root@merlin:~# echo " External IP: $EXTIP"
     External IP: 64.228.63.114

   root@merlin:~#

In all, ifconfig is not reliable in determining whether pppd has an internet
connection or not. The only reliable way so far seems to be to get the info
directly from pppd through one of it's exits (like /etc/ppp/ip-up).

-- 
Lew Pitcher
Master Codewright and JOAT-in-training
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.


Relevant Pages

  • Re: Internet connection
    ... > Check that your card is recognized with ifconfig. ... Windows IP Configuration ... Ethernet adapter Local Area Connection: ...
    (comp.unix.bsd.freebsd.misc)
  • Re: Bash script to see if PPP link is up...
    ... >>I have invited Alan Connor to resume the discussion on PPP link state ... > connection was established and would go down when connection was lost. ... Even if ifconfig shows the existance of ppp0, if IPCP negotiation fails, the ... > (whether connected due to demand, or disconnected due to idle timeout). ...
    (comp.os.linux.networking)
  • Re: [opensuse] Script to check interface & restart network service
    ... suffices and doesn't need bash. ... You can also check for the interface (with ifconfig or ip link show), ... connection. ...
    (SuSE)
  • Connecting the 50G to the internet
    ... I can connect my 50g to my computer using Usinagaz and pppd, ... can't get a connection to my network or the internet. ...
    (comp.sys.hp48)
  • RE: PPPoE Configuration problems
    ... Time to post your current rc.conf, ppp.conf, ifconfig -a, ... that your connection is not working. ... to my isp. ... To unsubscribe, ...
    (freebsd-questions)