xref: /freebsd/usr.sbin/ppp/physical.c (revision 6f8e9f0a8a6fa4e9dd0ad9ada1caecef634c90a2)
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  *
196f8e9f0aSBrian Somers  *  $Id: physical.c,v 1.5 1998/08/07 18:42:50 brian Exp $
2063b73463SBrian Somers  *
2163b73463SBrian Somers  */
2263b73463SBrian Somers 
2363b73463SBrian Somers #include <stdio.h>
246f384573SBrian Somers #include <stdlib.h>
2563b73463SBrian Somers #include <string.h>
26fc1141b2SBrian Somers #include <time.h>
2763b73463SBrian Somers #include <unistd.h>
28fc1141b2SBrian Somers #include <utmp.h>
296f384573SBrian Somers #include <sys/tty.h>
3063b73463SBrian Somers 
3163b73463SBrian Somers #include "defs.h"
3263b73463SBrian Somers #include "mbuf.h"
3363b73463SBrian Somers #include "timer.h"
34879ed6faSBrian Somers #include "lqr.h"
3563258dccSBrian Somers #include "hdlc.h"
3663b73463SBrian Somers #include "throughput.h"
376140ba11SBrian Somers #include "fsm.h"
386140ba11SBrian Somers #include "lcp.h"
396140ba11SBrian Somers #include "async.h"
403b0f8d2eSBrian Somers #include "ccp.h"
418c07a7b2SBrian Somers #include "link.h"
4242d4d396SBrian Somers #include "descriptor.h"
4363b73463SBrian Somers #include "physical.h"
4442d4d396SBrian Somers #include "log.h"
45fc1141b2SBrian Somers #include "id.h"
4663b73463SBrian Somers 
4763b73463SBrian Somers /* External calls - should possibly be moved inline */
4863b73463SBrian Somers extern int IntToSpeed(int);
4963b73463SBrian Somers 
5063b73463SBrian Somers 
5163b73463SBrian Somers int
52dd7e2610SBrian Somers physical_GetFD(struct physical *phys) {
5363b73463SBrian Somers    return phys->fd;
5463b73463SBrian Somers }
5563b73463SBrian Somers 
5663b73463SBrian Somers int
57dd7e2610SBrian Somers physical_IsATTY(struct physical *phys) {
5863b73463SBrian Somers    return isatty(phys->fd);
5963b73463SBrian Somers }
6063b73463SBrian Somers 
6163b73463SBrian Somers int
62dd7e2610SBrian Somers physical_IsSync(struct physical *phys) {
63d585f8f5SBrian Somers    return phys->cfg.speed == 0;
6463b73463SBrian Somers }
6563b73463SBrian Somers 
66dd7e2610SBrian Somers const char *physical_GetDevice(struct physical *phys)
673bf710a4SBrian Somers {
683bf710a4SBrian Somers    return phys->name.full;
6963b73463SBrian Somers }
7063b73463SBrian Somers 
7163b73463SBrian Somers void
72dd7e2610SBrian Somers physical_SetDeviceList(struct physical *p, int argc, const char *const *argv)
7399294c8bSBrian Somers {
7499294c8bSBrian Somers   int f, pos;
7599294c8bSBrian Somers 
7699294c8bSBrian Somers   p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0';
7799294c8bSBrian Somers   for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) {
7899294c8bSBrian Somers     if (pos)
7999294c8bSBrian Somers       p->cfg.devlist[pos++] = ' ';
8099294c8bSBrian Somers     strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1);
8199294c8bSBrian Somers     pos += strlen(p->cfg.devlist + pos);
8299294c8bSBrian Somers   }
8363b73463SBrian Somers }
8463b73463SBrian Somers 
8563b73463SBrian Somers 
8663b73463SBrian Somers int
87dd7e2610SBrian Somers physical_SetSpeed(struct physical *phys, int speed) {
8863b73463SBrian Somers    if (IntToSpeed(speed) != B0) {
89d585f8f5SBrian Somers       phys->cfg.speed = speed;
9063b73463SBrian Somers       return 1;
9163b73463SBrian Somers    } else {
9263b73463SBrian Somers       return 0;
9363b73463SBrian Somers    }
9463b73463SBrian Somers }
9563b73463SBrian Somers 
9663b73463SBrian Somers void
97dd7e2610SBrian Somers physical_SetSync(struct physical *phys) {
98d585f8f5SBrian Somers    phys->cfg.speed = 0;
9963b73463SBrian Somers }
10063b73463SBrian Somers 
10163b73463SBrian Somers 
10263b73463SBrian Somers int
103dd7e2610SBrian Somers physical_SetRtsCts(struct physical *phys, int enable) {
104b762af4fSBrian Somers    phys->cfg.rts_cts = enable ? 1 : 0;
10563b73463SBrian Somers    return 1;
10663b73463SBrian Somers }
10763b73463SBrian Somers 
10863b73463SBrian Somers /* Encapsulation for a read on the FD.  Avoids some exposure, and
10963b73463SBrian Somers    concentrates control. */
11063b73463SBrian Somers ssize_t
111dd7e2610SBrian Somers physical_Read(struct physical *phys, void *buf, size_t nbytes) {
11263b73463SBrian Somers    return read(phys->fd, buf, nbytes);
11363b73463SBrian Somers }
11463b73463SBrian Somers 
11563b73463SBrian Somers ssize_t
116dd7e2610SBrian Somers physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
11763b73463SBrian Somers    return write(phys->fd, buf, nbytes);
11863b73463SBrian Somers }
119ecd5172aSBrian Somers 
120ecd5172aSBrian Somers int
121dd7e2610SBrian Somers physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
122b6dec9f0SBrian Somers                    int *n, int force)
12342d4d396SBrian Somers {
12442d4d396SBrian Somers   struct physical *p = descriptor2physical(d);
12542d4d396SBrian Somers   int sets;
12642d4d396SBrian Somers 
12742d4d396SBrian Somers   sets = 0;
128b6dec9f0SBrian Somers   if (p->fd >= 0) {
129b6dec9f0SBrian Somers     if (r) {
130b6dec9f0SBrian Somers       FD_SET(p->fd, r);
13124989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd);
132b6dec9f0SBrian Somers       sets++;
133b6dec9f0SBrian Somers     }
134b6dec9f0SBrian Somers     if (e) {
135b6dec9f0SBrian Somers       FD_SET(p->fd, e);
13624989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd);
137b6dec9f0SBrian Somers       sets++;
138b6dec9f0SBrian Somers     }
1390f2f3eb3SBrian Somers     if (w && (force || link_QueueLen(&p->link) || p->out)) {
140b6dec9f0SBrian Somers       FD_SET(p->fd, w);
14124989c68SBrian Somers       log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd);
142b6dec9f0SBrian Somers       sets++;
143b6dec9f0SBrian Somers     }
144b6dec9f0SBrian Somers     if (sets && *n < p->fd + 1)
145b6dec9f0SBrian Somers       *n = p->fd + 1;
146b6dec9f0SBrian Somers   }
14742d4d396SBrian Somers 
14842d4d396SBrian Somers   return sets;
14942d4d396SBrian Somers }
15042d4d396SBrian Somers 
15142d4d396SBrian Somers int
152ea722969SBrian Somers physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e)
153ea722969SBrian Somers {
154ea722969SBrian Somers   int sets;
155ea722969SBrian Somers 
156ea722969SBrian Somers   sets = 0;
157ea722969SBrian Somers   if (p->fd >= 0) {
158ea722969SBrian Somers     if (r && FD_ISSET(p->fd, r)) {
159ea722969SBrian Somers       FD_CLR(p->fd, r);
160ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd);
161ea722969SBrian Somers       sets++;
162ea722969SBrian Somers     }
163ea722969SBrian Somers     if (e && FD_ISSET(p->fd, e)) {
164ea722969SBrian Somers       FD_CLR(p->fd, e);
165ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd);
166ea722969SBrian Somers       sets++;
167ea722969SBrian Somers     }
168ea722969SBrian Somers     if (w && FD_ISSET(p->fd, w)) {
169ea722969SBrian Somers       FD_CLR(p->fd, w);
170ea722969SBrian Somers       log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd);
171ea722969SBrian Somers       sets++;
172ea722969SBrian Somers     }
173ea722969SBrian Somers   }
174ea722969SBrian Somers 
175ea722969SBrian Somers   return sets;
176ea722969SBrian Somers }
177ea722969SBrian Somers 
178ea722969SBrian Somers int
179dd7e2610SBrian Somers physical_IsSet(struct descriptor *d, const fd_set *fdset)
18042d4d396SBrian Somers {
18142d4d396SBrian Somers   struct physical *p = descriptor2physical(d);
18242d4d396SBrian Somers   return p->fd >= 0 && FD_ISSET(p->fd, fdset);
18342d4d396SBrian Somers }
18442d4d396SBrian Somers 
18542d4d396SBrian Somers void
186dd7e2610SBrian Somers physical_Login(struct physical *phys, const char *name)
187fc1141b2SBrian Somers {
188dd7e2610SBrian Somers   if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) {
189fc1141b2SBrian Somers     if (phys->Utmp)
190dd7e2610SBrian Somers       log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base);
191fc1141b2SBrian Somers     else {
192fc1141b2SBrian Somers       struct utmp ut;
1931fa75dc1SBrian Somers       const char *connstr;
194fc1141b2SBrian Somers 
195fc1141b2SBrian Somers       memset(&ut, 0, sizeof ut);
196fc1141b2SBrian Somers       time(&ut.ut_time);
197fc1141b2SBrian Somers       strncpy(ut.ut_name, name, sizeof ut.ut_name);
1981fa75dc1SBrian Somers       strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line);
1991fa75dc1SBrian Somers       if ((connstr = getenv("CONNECT")))
2001fa75dc1SBrian Somers         /* mgetty sets this to the connection speed */
2011fa75dc1SBrian Somers         strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
202fc1141b2SBrian Somers       ID0login(&ut);
203fc1141b2SBrian Somers       phys->Utmp = 1;
204fc1141b2SBrian Somers     }
205fc1141b2SBrian Somers   }
206e43ebac1SBrian Somers }
207fc1141b2SBrian Somers 
208fc1141b2SBrian Somers void
209dd7e2610SBrian Somers physical_Logout(struct physical *phys)
210fc1141b2SBrian Somers {
211fc1141b2SBrian Somers   if (phys->Utmp) {
212fc1141b2SBrian Somers     ID0logout(phys->name.base);
213fc1141b2SBrian Somers     phys->Utmp = 0;
214fc1141b2SBrian Somers   }
215fc1141b2SBrian Somers }
216dd0645c5SBrian Somers 
217dd0645c5SBrian Somers int
218dd0645c5SBrian Somers physical_SetMode(struct physical *p, int mode)
219dd0645c5SBrian Somers {
22092b09558SBrian Somers   if ((p->type & (PHYS_DIRECT|PHYS_DEDICATED) ||
22192b09558SBrian Somers        mode & (PHYS_DIRECT|PHYS_DEDICATED)) &&
22292b09558SBrian Somers       (!(p->type & PHYS_DIRECT) || !(mode & PHYS_BACKGROUND))) {
223dd0645c5SBrian Somers     log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name,
224dd0645c5SBrian Somers                mode2Nam(p->type), mode2Nam(mode));
225dd0645c5SBrian Somers     return 0;
226dd0645c5SBrian Somers   }
227dd0645c5SBrian Somers   p->type = mode;
228dd0645c5SBrian Somers   return 1;
229dd0645c5SBrian Somers }
2306f8e9f0aSBrian Somers 
2316f8e9f0aSBrian Somers void
2326f8e9f0aSBrian Somers physical_DeleteQueue(struct physical *p)
2336f8e9f0aSBrian Somers {
2346f8e9f0aSBrian Somers   if (p->out) {
2356f8e9f0aSBrian Somers     mbuf_Free(p->out);
2366f8e9f0aSBrian Somers     p->out = NULL;
2376f8e9f0aSBrian Somers   }
2386f8e9f0aSBrian Somers   link_DeleteQueue(&p->link);
2396f8e9f0aSBrian Somers }
240