Here is a file I typed up to help a friend who is a new Linux user get
started with networking. Maybe it is of use to someone else too...
Note this necessarily simplifies things by assuming you have a Redhat-like
distribution and a basic familiarity with root shell access to the system.
I thought the HOWTOs on the subject are far too in-depth for an impatient
user who just got the network hookup and is itching to get online.
Markus's Short & Sweet Networking Guide
To be able to send and receive IP traffic, you need to have an interface
to send it through. You can list all your currently defined interfaces
with the "ifconfig" command...
eth0 Link encap:Ethernet HWaddr 00:50:04:B1:CF:EC
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1492 Metric:1
RX packets:217197 errors:0 dropped:0 overruns:0 frame:0
TX packets:245484 errors:0 dropped:0 overruns:0 carrier:0
Interrupt:11 Base address:0xe800
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:3924 Metric:1
RX packets:24444 errors:0 dropped:0 overruns:0 frame:0
TX packets:24444 errors:0 dropped:0 overruns:0 carrier:0
Here we have an ethernet interface and the local loopback interface.
To be able to send packets by IP address, we need a routing table. You
can dump the current routing table with "route" or "netstat -r" (equivalent
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.1 * 255.255.255.255 UH 0 0 0 eth0
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
default getafix 0.0.0.0 UG 0 0 0 eth0
What this tells us is that the path to 192.168.0.1 (ourselves) is through
eth0, the path to anything on our class C subnet (192.168.0.x) is through
eth0, the path to the local loopback address 127.x.x.x is through the loopback
interface lo, and the default path to anything else is through node "getafix"
which is reachable through interface eth0.
How does the machine know what IP address "getafix" translates to? In this
case it knows because there is a hard mapping in /etc/hosts...
% cat /etc/hosts
127.0.0.1 localhost localhost.localdomain
192.168.0.1 asterix asterix.localdomain
192.168.0.2 obelix obelix.localdomain
192.168.0.3 getafix getafix.localdomain
192.168.0.4 dogmatix dogmatix.localdomain
192.168.0.6 frankenstein frankenstein.localdomain
What if I want to reach some random node on the internet, that there is no
entry for in /etc/hosts? This is where the DNS (Domain Naming System)
comes in. It's extremely complicated, but fortunately all we have to be
able to do is point to a name server and we're in business
% cat /etc/resolv.conf
In this case, the name server is a node on our own LAN, but it could just
as well be one on the wide open internet somewhere.
How do you set this up?
Here is the hard way. Suppose you have an NE2000 ethernet card set to
I/O address 340, IRQ 11.
1. Tell the system about the card. In /etc/conf.modules, enter the following
alias eth0 ne
options ne io=0x340 irq=11
2. Configure the interface
# ifconfig eth0 192.168.0.7/24 up
Because of the alias in /etc/conf.modules the system knows that to load
the driver for "eth0" it should really load the NE2000 driver "ne".
3. Route all otherwise unrouted traffic to this interface
# route add default gw 192.168.0.3
4. Set the name server in /etc/resolv.conf as shown earlier
5. Map any hosts on the local network that the name server doesn't know
about by adding entries to /etc/hosts. Also in /etc/hosts ensure that
the "localhost" line and the line for the own machine are as shown,
otherwise you'll get a 1-minute timeout during boot.
That's it. You're on the internet. In the above example
IP address = 192.168.0.7
Netmask = 255.255.255.0 (the /24 at the end of the IP address)
Gateway = 192.168.0.3
DNS server = 192.168.0.3
Substitute whatever values are true for your own internet connection.
Redhat Linux can do all this for you automatically at boot if you configure
it through the "netconf" command. This is supposed to be the easy way.
Dial-up networking uses the PPP protocol. The way it works is
1. A modem connection is established
2. The program "pppd" negotiates an IP connection
3. pppd creates an interface named "ppp0" (or ppp1 ... if more than one)
4. The rest is the same as for ethernet
A PPP connection requires a user name and a password. The remote end
may ask for PAP (Password Authentication Protocol) or CHAP (Challenge /
Response Authentication Protocol.) You make the required information
available to pppd in these files
# cat /etc/ppp/pap-secrets
username * password
# cat /etc/ppp/chap-secrets
username * password
This way it will be ready for either kind of authentication request.
Note that "username" may need to be in the form "user@domain"
Next it is good practice that /dev/modem refers to the serial port your
modem is hooked up to.
# ls -l /dev/modem
lrwxrwxrwx 1 root tty 10 Sep 29 19:44 /dev/modem -> /dev/ttyS0
The pppd program takes a lot of options. In a multiuser system with
unprivileged users, you can force certain options on everybody by setting
them in this file:
# cat /etc/ppp/options
In this case, only the "lock" option is globally set. Now to actually run
pppd, you execute a "ppp-on" script which you must write, or at least
# cat ppp-on
exec /usr/sbin/pppd debug /dev/modem 115200 nodetach noipdefault crtscts\
hide-password user _____ defaultroute connect ./ppp-on-dialer
Here you would substitute your user name (same as in the *-secrets files)
for the _____ part. You can look up all the options. pppd will invoke
the script "ppp-on-dialer" to make the phone call, so we need that too:
# cat ppp-on-dialer
/usr/sbin/chat -v \
TIMEOUT 3 \
ABORT '\nBUSY\r' \
ABORT '\nNO ANSWER\r' \
ABORT '\nRINGING\r\n\r\nRINGING\r' \
'' \rATZ \
'OK-+++\c-OK' ATM1 \
TIMEOUT 60 \
OK ATDT520-1135 \
The "chat" command will be run, connected to the serial port, to "chat"
with the modem to achieve the desired result. Then it will exit and pppd
will start talking ppp to the other end. Some phone numbers will talk
ppp right away, others (like the Freenet one above) may give a menu where
one of whose options is "go into PPP mode". In that case you would extend
the chat script to navigate that too, like
CONNECT '' \
'Unsure? Enter 1' '2'
In this case, Freenet prints a menu that ends with "Unsure? Enter 1" and
when chat sees that it sends 2 which causes a drop into PPP mode. Some
online services may prompt for a userid/password before they let you get
that far; you can make the chat script take care of that too.
Note that the chat script is one command! The \ at the end of the lines
mean "continue on the next line".
If the connection is successful, pppd will configure the ppp0 interface
with an IP address given to it by the other end, and set the default route
too (because we told it to.) We must still set up /etc/resolv.conf to
point to a name server; whoever provides the PPP service should also provide
the addresses of several (use a separate "nameserver" line for each.)
What, it didn't work? First look in /var/log/messages...
Feb 5 22:06:48 asterix pppd: Serial connection established.
Feb 5 22:06:48 asterix pppd: Using interface ppp0
Feb 5 22:06:48 asterix pppd: Connect: ppp0 <--> /dev/ttyS0
Feb 5 22:06:50 asterix pppd: local IP address 220.127.116.11
Feb 5 22:06:50 asterix pppd: remote IP address 18.104.22.168
(You will also see a log of your chat script, thanks to the -v option to chat).
If you got as far as the "Connect:" part and then it failed, you want to
see the debug output generated by the "debug" argument to pppd. To do this
you need to configure your system logger by adding this line to
Now anything sent through the system log facility in the "debug" category
will be put in the file /var/log/messages.debug. You have to kick the system
logger to get it to reread the file, with
# killall -HUP syslogd
Now retry the dialup attempt and monitor the messages.debug file...
Serial connection established.
Using interface ppp0
ppp0 <--> /dev/ttyS0
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xc87a1913> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0x0> <auth pap> <magic 0xce79be2e>
sent [LCP ConfNak id=0x1 <asyncmap 0xa0000>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xc87a1913> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x2 <asyncmap 0xa0000> <auth pap> <magic 0xce79be2e>
sent [LCP ConfAck id=0x2 <asyncmap 0xa0000> <auth pap> <magic 0xce79be2e>
sent [PAP AuthReq id=0x1 user="username" password=<hidden>]
rcvd [PAP AuthAck id=0x1 ""]
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <compress VJ 0f 01>]
sent [CCP ConfReq id=0x1 <deflate 15> <deflate(old#) 15> <bsd v1 15>]
rcvd [IPCP ConfReq id=0x3 <compress VJ 0f 01> <addr 22.214.171.124>]
sent [IPCP ConfAck id=0x3 <compress VJ 0f 01> <addr 126.96.36.199>]
rcvd [IPCP ConfNak id=0x1 <addr 188.8.131.52>]
sent [IPCP ConfReq id=0x2 <addr 184.108.40.206> <compress VJ 0f 01>]
rcvd [LCP ProtRej id=0x4 80 fd 01 01 00 0f 1a 04 78 00 18 04 78 00 15 03 2f]
rcvd [IPCP ConfAck id=0x2 <addr 220.127.116.11> <compress VJ 0f 01>]
local IP address 18.104.22.168
remote IP address 22.214.171.124
Here you can see the conversation that the local ppp daemon is having with
the remote one, first via LCP (Link Configuration Protocol), then via PAP
to authenticate who is calling, then CCP (I forget what that is) then IPCP
to set up IP connectivity, most importantly to give you an IP address to use.
When you are done with the link you can shut it down cleanly by sending a
TERM signal to pppd...
# killall pppd
Easy Dial-Up Networking
There are assorted GUI dialup clients that run under X and do all the
above for you and make it look like Microsoft Dialup Networking. I quite
like the one that comes with KDE, called "kppp". But there is simply no
substitute for knowing what goes on "under the hood".
Note that the NET-3-HOWTO may have another name depending on what version
of the OS you are running (I think it's up to NET-4 now.)
Also the man pages for ifconfig, pppd, route, netstat.
To find the driver name and parameters for your ethernet card, in a Redhat
type distribution at least, you can consult the file /boot/module-info.
For the NE2000 you would find:
"NE1000, NE2000, and compatible"
io "Base I/O address" "0x[0-9a-fA-F]+"
irq "IRQ level" "[0-9]+"
Of course if you use a GUI tool like "netconf" it will probably prompt you
for the information.