Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Apr 95 12:04:36 MDT
From:      terry@cs.weber.edu (Terry Lambert)
To:        timb@thud.cdrom.com (Tim Bach)
Cc:        freebsd-questions@FreeBSD.org
Subject:   Re: your mail
Message-ID:  <9504041804.AA15199@cs.weber.edu>
In-Reply-To: <199504040630.XAA23432@thud.cdrom.com> from "Tim Bach" at Apr 3, 95 11:30:16 pm

next in thread | previous in thread | raw e-mail | index | archive | help
-----
---
THE FOLLOWING IS EVERYTHING YOU NEVER WANTED TO KNOW ABOUT MODEM LOGINS
---
-----

> I am using FreeBSD 2.0 and mgetty..
> Problem is when somebody loses carrier the modem doesnt answer
> anymore because it doesnt know anybody logged off.All the person's
> proccesses are still there to.
>
> Please email me any suggestions and this get's pretty frustrating
> having to kill people's proccesses when i discover they aren't
> online anymore.
>
> Could it be how my modem is initialized or a problem with mgetty..
> ?????

It could be either or both.

The modem should "follow remote carrier".  This means that it should
not assert DCD to the computer unless carrier is present on the line.

On modern Hayes modems, this is AT&C1.

The modem should "reset as if powered of and turned on on an on-to-off
transition of DTR from the computer".

On modern Hayes modems, this is AT&D2.

Neither one of these are the default for most modems (which are set up
for unidirectional dialing by DOS weenies, so everything is forced
high so that it will "just work" for most unidirectional uses).



Hopefully, this provides enough information that you will be able
to isolate where your problem is occuring and rectify it.  I need
to appologize in advance for the length, but the login/getty/tty
state transitions don't seem to be documented fully anywhere, and
because you are not using the system supplied "getty" program,
you will have to diagnose where in the state table the "mgetty"
you are using instead is failing.

------------

The modem cable should not have any pins crossed in it to force signals
high.  Make sure you have a "straight through" cable.


You should be using a calling unit device instead of a tty device.
This should be part of a MAKEDEV in the /dev directory, done as root.

The practical effect of the /dev/cua0/cua1 device will be the setting
of the terminal modes HUPCL and -CLOCAL; you should log in through the
modem and type "stty -a" to make sure these settings are present.

In incorrectly configured program (ie: mgetty) could result in the
flags being set incorrectly after login.


The use of "mgetty" is a problem.  The "mgetty" program differs from
the "getty" program in that it opens the port and hangs on a read
waiting for the modem to announce a baud rate so that it can set
line speed.  The ability to open without DCD present is a real
problem, in that it defeats the purpose of a calling unit device
and thereby thwarts the normal modem login sequence.


A normal UNIX login sequence operates as follows:


STATE TRANSITIONS IN THE MODEM/COMPUTER STATE MACHINE DURING LOGIN:


[ The modem is set up to track DCD ]
[ The modem is set up to react to DTR ]
[ The computer is set up to use modem control on the port ]

1)	The modem comes on; the computer is not in multiuser
	mode, so DTR is not asserted.  The mode will not
	answer the phone until DTR is asserted.

2)	The computer goes to multiuser mode.  A "getty" is
	started on the port.

3)	The "getty" performs an open.  Because the modem has
	not asserted DCD because it does not have a connection
	the "getty" hangs in the open.

4)	The act of entering the open but not completing it
	means that the port is "partially open".  The port
	asserts DTR to the modem.

5)	Because DTR is asserted, the modem can now answer
	the phone if it rings.

6)	Input prior to the open completing is not queued.

7)	Someone calls.

8)	The modem says "RING" to the computer.  It also raises
	The RI (Ring Indicate) signal line if that is connected.

9)	The RI line is ignored by the driver; more on this later.

10)	Because DCD is not yet asserted by the modem, the "RING"
	strings are simply not queued as input.

11)	The modem answers the phone.  Its first act is to report
	its "CONNECT <baud rate>" message to the computer.

12)	Like other input prior to DCD being present, this data
	is ignored.

13)	As the final act in establishing the connection, the modem
	asserts DCD.

14)	When DCD is asserted, the driver allows the open to
	complete.

15)	The next statement in the "getty" causes the system banner
	(usually the contents of the file "/etc/issue") to be
	printed, followed by "<System name> login:".

16)	If the user does not see this, they send "break" signals;
	the "getty" changes the baud rate and reissues the prompt
	for each break signal received.  The baud rates for a
	particular line, as well as the default line settings for
	each are stored in the /etc/gettytab file.

17)	The user types their name followed by <return>.

18)	The "getty" program exec's the "/bin/login" program, passing
	the user's name.

19)	The "/bin/login" program prompts for a "password:" and then
	uses the library routine getpass() to read the password
	without echo.

20)	A password entered is encrypted with the salt for the
	password file entry for the user name passed to login; the
	encryption is performed iteratively, the net effect being
	a hash.  The encrypted password is compared to the entry
	from the password file.

21)	If the name was not in the password file, or the password
	did not match, then an error is printed.  The "/bin/login"
	program reissues a "login:" prompt for the name (this is
	why subsequent logins don't have the same banner as the
	initial login attempt).  A sufficient number of failures
	will cause the "/bin/login" program to exit in most
	security conscious implementations.  The result of this is
	the same as a successfully logged in user who has logged
	out (see below).  Typically, a security conscious login
	program will delay between failed attempts as well to slow
	down potential crackers.

22)	On a successful match of name + password, "/bin/login" will
	exec the shell line from the users password entry.  Again,
	modern secure systems will ensure that the program to be
	run is in the file "/etc/shells".  A NULL entry is taken
	to mean "/bin/sh", although a more flexible implementation
	would get its default from the first entry in "/etc/shells".

23)	The user interacts with the computer until they decide to
	log out.  The log out can take two forms: a disconnect by
	the user, and an explicti command to the system to exit
	the top level shell by the user.

---

24a)	The user disconnects the connection from their end.

25a)	The modem deasserts DCD (because it is set up correctly).

26a)	The tty settings include -CLOCAL.  Because of this, the
	top level shell (the "process group leader") is sent a
	SIGHUP causing it to exit.

27a)	In a correct implementation, a signal delivered to the
	process group leader is delivered to the process group;
	there are some who would argue this on the basis of
	POSIX; they should read the forthcoming book "UNIX
	Internals: The New Frontier" (Prentice Hall).

28a)	When the final process has exited, since the tty settings
	include HUPCL, the DTR is dropped; the period of drop should
	be in excess of 250ms in a correct impelementation, and
	the device should block all requests until the time period
	has expired.

29a)	The modem resets as if powered off then on when the on-to-off
	DTR transition occurs (because it is set up correctly).

30a)	The "init" process is the parent of the top level shell; it
	gets the SIGCHLD, and reaps the process.  It restarts a
	"getty" on the port (but the open is blocked until the DTR
	toggle has had sufficient time to cause the modem to begin
	to reset).

31a)	The cycle starts over.

---

24b)	The user explicitly logs out.

25b)	The last process closes the port.

26b)	The tty settings include HUPCL.  Because of this, the DTR
	is dropped; the period of the drop should be in excess of
	250ms in a correct impelementation, and the device should
	block all requests until the time period has expired.

27b)	The modem resets as if powered off then on when the on-to-off
	DTR transition occurs (because it is set up correctly).  This
	act dumps the connection between the modem and the users
	modem, and the connection is lost ("NO CARRIER").

28b)	The "init" process is the parent of the top level shell; it
	gets the SIGCHLD, and reaps the process.  It restarts a
	"getty" on the port (but the open is blocked until the DTR
	toggle has had sufficient time to cause the modem to begin
	to reset).

29b)	The cycle starts over.


------------------------------------------------------------------

A COMMON PROBLEM AND ITS CHARACTERISTIC SYMPTOMS:


Note that an incorrect configuration involving DCD will typically
cause the very obvious symptom of you calling the machine, getting a
connection, and the machine hangs up on you.

This is because the modem state transition table is confused.  If
it gets input from the computer AFTER it has carrier but BEFORE
it has DCD, it thinks it is dialing out and that you are attempting
to cancel the call (I have disassembled Hayes and US Robotics ROMS
to diagnose this in the first place).

This is exactly the situation if the computer has an input present
before DCD is raised and echos the "RING" or "CONNECT" messages
back to the modem.

------------------------------------------------------------------

WHAT WILL CAUSE FAILURE:


If the mgetty incorrectly sets CLOCAL or -HUPCL in its effort to
open the port without DCD being present, this will prevent normal
operation.

If the modem is set up incorrectly, this will prevent normal operation.

If the cable between the modem and the computer is not a straight
cable, it could interfere in the ability of the modem and the computer
to correctly communicate DCD and DTR state information.

If the mgetty/getty is started on a tty device instead of a cua device,
the default port settings will not include -CLOCAL and HUPCL, and
the connection will not behave as expected.

If the signal settings in the /etc/gettytab file explicitly unset
HUPCL or explicitly set CLOCAL, the connection will behave eratically.

If the signal processing is not per BSD/SYSV instead of POSIX handling
with regard to the delivery of SIGHUP to the process group instead of
just the group leader (has to do with order of operation on delivery
vs. signal propagation to children), the connection will be left open
when following the "b" path, or processes will be left running and
still associated with the tty (and a getty will not act correctly)
following the "a" path.


EDITORIAL OPINION:


The "mgetty" program is bad.  It should not succeed in the open
without DCD present; this prevents the port for being used for
dialout without killing the "mgetty".

The correct way to open the port without DCD present is to use the
O_NDELAY flag; this has the side effect of setting no delay on reads,
when you probably do not want this, with no way to unset them.

The correct procedure is to: open with O_NDELAY, open a second time
without O_NDELAY (the second open will not block because there is
already an open on the port), and close the first open.  This is
called "the partial open hack", but in reality it is not a hack
(unless you consider the overloading of O_NDELAY in the first place
a hack).

The "mgetty" program should be rewritten to use an open flag that
causes the open to hang until a "ring indicate" signal is seen
instead od waiting for DCD.  The driver should be rewritten to
accomodate this.  Then the "mgetty" should do it's reads normally;
an alarm should be set so that if DCD (a "CONNECT" message) does
not occur within a set period of time, the mgetty closes the port
and reissues the open.  This will guard against false alarms that
are caused by a number of rings less than the guard rings that
the modem is set to wait for before answering.  Note that this
flag *must* be seperate from the O_NDELAY flag, and the partial
open hack could *not* be used to properly implement this approach.

The locking of port parameters in "/etc/rc.serial" is bad; the
serial driver should use bit fields in the device minor number
to flag values that can not be set in "/etc/gettydefs"; all
other values should be set in "/etc/gettydefs".  This last will
not preclude using the device, but it makes it messy.


					Regards,
					Terry Lambert
					terry@cs.weber.edu
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9504041804.AA15199>