xref: /freebsd/usr.sbin/ppp/physical.c (revision 1fa75dc10776c57d2bb473c9a672f7de8cf172bb)
163b73463SBrian Somers /*
263b73463SBrian Somers  * Written by Eivind Eklund <eivind@yes.no>
363b73463SBrian Somers  *    for Yes Interactive
463b73463SBrian Somers  *
563b73463SBrian Somers  * Copyright (C) 1998, Yes Interactive.  All rights reserved.
663b73463SBrian Somers  *
763b73463SBrian Somers  * Redistribution and use in any form is permitted.  Redistribution in
863b73463SBrian Somers  * source form should include the above copyright and this set of
963b73463SBrian Somers  * conditions, because large sections american law seems to have been
1063b73463SBrian Somers  * created by a bunch of jerks on drugs that are now illegal, forcing
1163b73463SBrian Somers  * me to include this copyright-stuff instead of placing this in the
1263b73463SBrian Somers  * public domain.  The name of of 'Yes Interactive' or 'Eivind Eklund'
1363b73463SBrian Somers  * may not be used to endorse or promote products derived from this
1463b73463SBrian Somers  * software without specific prior written permission.
1563b73463SBrian Somers  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1663b73463SBrian Somers  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1763b73463SBrian Somers  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1863b73463SBrian Somers  *
191fa75dc1SBrian Somers  *  $Id: physical.c,v 1.1.2.33 1998/05/15 23:58:25 brian Exp $
2063b73463SBrian Somers  *
2163b73463SBrian Somers  */
2263b73463SBrian Somers 
232764b86aSBrian Somers #include <sys/types.h>
2463b73463SBrian Somers 
2563b73463SBrian Somers #include <stdio.h>
266f384573SBrian Somers #include <stdlib.h>
2763b73463SBrian Somers #include <string.h>
28fc1141b2SBrian Somers #include <time.h>
2963b73463SBrian Somers #include <unistd.h>
30fc1141b2SBrian Somers #include <utmp.h>
316f384573SBrian Somers #include <sys/tty.h>
3263b73463SBrian Somers 
3363b73463SBrian Somers #include "defs.h"
3463b73463SBrian Somers #include "mbuf.h"
3563b73463SBrian Somers #include "timer.h"
36879ed6faSBrian Somers #include "lqr.h"
3763258dccSBrian Somers #include "hdlc.h"
3863b73463SBrian Somers #include "throughput.h"
396140ba11SBrian Somers #include "fsm.h"
406140ba11SBrian Somers #include "lcp.h"
416140ba11SBrian Somers #include "async.h"
423b0f8d2eSBrian Somers #include "ccp.h"
438c07a7b2SBrian Somers #include "link.h"
4442d4d396SBrian Somers #include "descriptor.h"
4563b73463SBrian Somers #include "physical.h"
4642d4d396SBrian Somers #include "log.h"
47fc1141b2SBrian Somers #include "id.h"
4863b73463SBrian Somers 
4963b73463SBrian Somers /* External calls - should possibly be moved inline */
5063b73463SBrian Somers extern int IntToSpeed(int);
5163b73463SBrian Somers 
5263b73463SBrian Somers 
5363b73463SBrian Somers int
54dd7e2610SBrian Somers physical_GetFD(struct physical *phys) {
5563b73463SBrian Somers    return phys->fd;
5663b73463SBrian Somers }
5763b73463SBrian Somers 
5863b73463SBrian Somers int
59dd7e2610SBrian Somers physical_IsATTY(struct physical *phys) {
6063b73463SBrian Somers    return isatty(phys->fd);
6163b73463SBrian Somers }
6263b73463SBrian Somers 
6363b73463SBrian Somers int
64dd7e2610SBrian Somers physical_IsSync(struct physical *phys) {
65d585f8f5SBrian Somers    return phys->cfg.speed == 0;
6663b73463SBrian Somers }
6763b73463SBrian Somers 
68dd7e2610SBrian Somers const char *physical_GetDevice(struct physical *phys)
693bf710a4SBrian Somers {
703bf710a4SBrian Somers    return phys->name.full;
7163b73463SBrian Somers }
7263b73463SBrian Somers 
7363b73463SBrian Somers void
74dd7e2610SBrian Somers physical_SetDeviceList(struct physical *p, int argc, const char *const *argv)
7599294c8bSBrian Somers {
7699294c8bSBrian Somers   int f, pos;
7799294c8bSBrian Somers 
7899294c8bSBrian Somers   p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0';
7999294c8bSBrian Somers   for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) {
8099294c8bSBrian Somers     if (pos)
8199294c8bSBrian Somers       p->cfg.devlist[pos++] = ' ';
8299294c8bSBrian Somers     strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1);
8399294c8bSBrian Somers     pos += strlen(p->cfg.devlist + pos);
8499294c8bSBrian Somers   }
8563b73463SBrian Somers }
8663b73463SBrian Somers 
8763b73463SBrian Somers 
8863b73463SBrian Somers int
89dd7e2610SBrian Somers physical_SetSpeed(struct physical *phys, int speed) {
9063b73463SBrian Somers    if (IntToSpeed(speed) != B0) {
91d585f8f5SBrian Somers       phys->cfg.speed = speed;
9263b73463SBrian Somers       return 1;
9363b73463SBrian Somers    } else {
9463b73463SBrian Somers       return 0;
9563b73463SBrian Somers    }
9663b73463SBrian Somers }
9763b73463SBrian Somers 
9863b73463SBrian Somers void
99dd7e2610SBrian Somers physical_SetSync(struct physical *phys) {
100d585f8f5SBrian Somers    phys->cfg.speed = 0;
10163b73463SBrian Somers }
10263b73463SBrian Somers 
10363b73463SBrian Somers 
10463b73463SBrian Somers int
105dd7e2610SBrian Somers physical_SetRtsCts(struct physical *phys, int enable) {
106b762af4fSBrian Somers    phys->cfg.rts_cts = enable ? 1 : 0;
10763b73463SBrian Somers    return 1;
10863b73463SBrian Somers }
10963b73463SBrian Somers 
11063b73463SBrian Somers /* Encapsulation for a read on the FD.  Avoids some exposure, and
11163b73463SBrian Somers    concentrates control. */
11263b73463SBrian Somers ssize_t
113dd7e2610SBrian Somers physical_Read(struct physical *phys, void *buf, size_t nbytes) {
11463b73463SBrian Somers    return read(phys->fd, buf, nbytes);
11563b73463SBrian Somers }
11663b73463SBrian Somers 
11763b73463SBrian Somers ssize_t
118dd7e2610SBrian Somers physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
11963b73463SBrian Somers    return write(phys->fd, buf, nbytes);
12063b73463SBrian Somers }
121ecd5172aSBrian Somers 
122ecd5172aSBrian Somers int
123dd7e2610SBrian Somers physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
124b6dec9f0SBrian Somers                    int *n, int force)
12542d4d396SBrian Somers {
12642d4d396SBrian Somers   struct physical *p = descriptor2physical(d);
12742d4d396SBrian Somers   int sets;
12842d4d396SBrian Somers 
12942d4d396SBrian Somers   sets = 0;
130b6dec9f0SBrian Somers   if (p->fd >= 0) {
131b6dec9f0SBrian Somers     if (r) {
132b6dec9f0SBrian Somers       FD_SET(p->fd, r);
13324989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd);
134b6dec9f0SBrian Somers       sets++;
135b6dec9f0SBrian Somers     }
136b6dec9f0SBrian Somers     if (e) {
137b6dec9f0SBrian Somers       FD_SET(p->fd, e);
13824989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd);
139b6dec9f0SBrian Somers       sets++;
140b6dec9f0SBrian Somers     }
141b6dec9f0SBrian Somers     if (w && (force || link_QueueLen(&p->link))) {
142b6dec9f0SBrian Somers       FD_SET(p->fd, w);
14324989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd);
144b6dec9f0SBrian Somers       sets++;
145b6dec9f0SBrian Somers     }
146b6dec9f0SBrian Somers     if (sets && *n < p->fd + 1)
147b6dec9f0SBrian Somers       *n = p->fd + 1;
148b6dec9f0SBrian Somers   }
14942d4d396SBrian Somers 
15042d4d396SBrian Somers   return sets;
15142d4d396SBrian Somers }
15242d4d396SBrian Somers 
15342d4d396SBrian Somers int
154ea722969SBrian Somers physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e)
155ea722969SBrian Somers {
156ea722969SBrian Somers   int sets;
157ea722969SBrian Somers 
158ea722969SBrian Somers   sets = 0;
159ea722969SBrian Somers   if (p->fd >= 0) {
160ea722969SBrian Somers     if (r && FD_ISSET(p->fd, r)) {
161ea722969SBrian Somers       FD_CLR(p->fd, r);
162ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd);
163ea722969SBrian Somers       sets++;
164ea722969SBrian Somers     }
165ea722969SBrian Somers     if (e && FD_ISSET(p->fd, e)) {
166ea722969SBrian Somers       FD_CLR(p->fd, e);
167ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd);
168ea722969SBrian Somers       sets++;
169ea722969SBrian Somers     }
170ea722969SBrian Somers     if (w && FD_ISSET(p->fd, w)) {
171ea722969SBrian Somers       FD_CLR(p->fd, w);
172ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd);
173ea722969SBrian Somers       sets++;
174ea722969SBrian Somers     }
175ea722969SBrian Somers   }
176ea722969SBrian Somers 
177ea722969SBrian Somers   return sets;
178ea722969SBrian Somers }
179ea722969SBrian Somers 
180ea722969SBrian Somers int
181dd7e2610SBrian Somers physical_IsSet(struct descriptor *d, const fd_set *fdset)
18242d4d396SBrian Somers {
18342d4d396SBrian Somers   struct physical *p = descriptor2physical(d);
18442d4d396SBrian Somers   return p->fd >= 0 && FD_ISSET(p->fd, fdset);
18542d4d396SBrian Somers }
18642d4d396SBrian Somers 
18742d4d396SBrian Somers void
188dd7e2610SBrian Somers physical_Login(struct physical *phys, const char *name)
189fc1141b2SBrian Somers {
190dd7e2610SBrian Somers   if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) {
191fc1141b2SBrian Somers     if (phys->Utmp)
192dd7e2610SBrian Somers       log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base);
193fc1141b2SBrian Somers     else {
194fc1141b2SBrian Somers       struct utmp ut;
1951fa75dc1SBrian Somers       const char *connstr;
196fc1141b2SBrian Somers 
197fc1141b2SBrian Somers       memset(&ut, 0, sizeof ut);
198fc1141b2SBrian Somers       time(&ut.ut_time);
199fc1141b2SBrian Somers       strncpy(ut.ut_name, name, sizeof ut.ut_name);
2001fa75dc1SBrian Somers       strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line);
2011fa75dc1SBrian Somers       if ((connstr = getenv("CONNECT")))
2021fa75dc1SBrian Somers         /* mgetty sets this to the connection speed */
2031fa75dc1SBrian Somers         strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
204fc1141b2SBrian Somers       ID0login(&ut);
205fc1141b2SBrian Somers       phys->Utmp = 1;
206fc1141b2SBrian Somers     }
207fc1141b2SBrian Somers   }
208e43ebac1SBrian Somers }
209fc1141b2SBrian Somers 
210fc1141b2SBrian Somers void
211dd7e2610SBrian Somers physical_Logout(struct physical *phys)
212fc1141b2SBrian Somers {
213fc1141b2SBrian Somers   if (phys->Utmp) {
214fc1141b2SBrian Somers     ID0logout(phys->name.base);
215fc1141b2SBrian Somers     phys->Utmp = 0;
216fc1141b2SBrian Somers   }
217fc1141b2SBrian Somers }
218dd0645c5SBrian Somers 
219dd0645c5SBrian Somers int
220dd0645c5SBrian Somers physical_SetMode(struct physical *p, int mode)
221dd0645c5SBrian Somers {
222dd0645c5SBrian Somers   if (p->type & (PHYS_DIRECT|PHYS_DEDICATED)
223dd0645c5SBrian Somers       || mode & (PHYS_DIRECT|PHYS_DEDICATED)) {
224dd0645c5SBrian Somers     log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name,
225dd0645c5SBrian Somers                mode2Nam(p->type), mode2Nam(mode));
226dd0645c5SBrian Somers     return 0;
227dd0645c5SBrian Somers   }
228dd0645c5SBrian Somers   p->type = mode;
229dd0645c5SBrian Somers   return 1;
230dd0645c5SBrian Somers }
231