diff options
Diffstat (limited to 'usr.sbin/ppp/physical.c')
-rw-r--r-- | usr.sbin/ppp/physical.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c index 7c36e4a0df18..8de5cc32b014 100644 --- a/usr.sbin/ppp/physical.c +++ b/usr.sbin/ppp/physical.c @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: physical.c,v 1.15 1999/06/01 19:08:58 brian Exp $ + * $Id: physical.c,v 1.16 1999/06/02 00:46:54 brian Exp $ * */ @@ -98,15 +98,22 @@ static int physical_DescriptorWrite(struct descriptor *, struct bundle *, static void physical_DescriptorRead(struct descriptor *, struct bundle *, const fd_set *); +static int +physical_DeviceSize(void) +{ + return sizeof(struct device); +} + struct { struct device *(*create)(struct physical *); struct device *(*iov2device)(int, struct physical *, struct iovec *iov, int *niov, int maxiov); + int (*DeviceSize)(void); } devices[] = { - { tty_Create, tty_iov2device }, - { tcp_Create, tcp_iov2device }, - { udp_Create, udp_iov2device }, - { exec_Create, exec_iov2device } + { tty_Create, tty_iov2device, tty_DeviceSize }, + { tcp_Create, tcp_iov2device, tcp_DeviceSize }, + { udp_Create, udp_iov2device, udp_DeviceSize }, + { exec_Create, exec_iov2device, exec_DeviceSize } }; #define NDEVICES (sizeof devices / sizeof devices[0]) @@ -559,6 +566,20 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, p->fd = fd; + type = (long)p->handler; + p->handler = NULL; + for (h = 0; h < NDEVICES && p->handler == NULL; h++) + p->handler = (*devices[h].iov2device)(type, p, iov, niov, maxiov); + + if (p->handler == NULL) { + log_Printf(LogPHASE, "%s: Device %s, unknown link type\n", + p->link.name, p->name.full); + free(iov[(*niov)++].iov_base); + physical_SetupStack(p, "unknown", PHYSICAL_NOFORCE); + } else + log_Printf(LogPHASE, "%s: Device %s, link type is %s\n", + p->link.name, p->name.full, p->handler->name); + if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load) lqr_reStart(&p->link.lcp); hdlc_StartTimer(&p->hdlc); @@ -566,20 +587,33 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, throughput_start(&p->link.throughput, "physical throughput", Enabled(dl->bundle, OPT_THROUGHPUT)); - type = (long)p->handler; - for (h = 0; h < NDEVICES && p->handler == NULL; h++) - p->handler = (*devices[h].iov2device)(type, p, iov, niov, maxiov); + return p; +} - if (p->handler == NULL) - physical_SetupStack(p, "unknown", PHYSICAL_NOFORCE); +int +physical_MaxDeviceSize() +{ + int biggest, sz, n; - return p; + biggest = sizeof(struct device); + for (sz = n = 0; n < NDEVICES; n++) + if (devices[n].DeviceSize) { + sz = (*devices[n].DeviceSize)(); + if (biggest < sz) + biggest = sz; + } + + return biggest; } int physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, pid_t newpid) { + struct device *h; + int sz; + + h = NULL; if (p) { hdlc_StopTimer(&p->hdlc); lqr_StopTimer(p); @@ -591,7 +625,7 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, timer_Stop(&p->link.ccp.fsm.StoppedTimer); if (p->handler) { if (p->handler->device2iov) - (*p->handler->device2iov)(p, iov, niov, maxiov, newpid); + h = p->handler; p->handler = (struct device *)(long)p->handler->type; } @@ -604,17 +638,34 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov, physical_ChangedPid(p, newpid); } - if (*niov >= maxiov) { - log_Printf(LogERROR, "physical2iov: No room for physical !\n"); + if (*niov + 1 >= maxiov) { + log_Printf(LogERROR, "physical2iov: No room for physical + device !\n"); if (p) free(p); return -1; } - iov[*niov].iov_base = p ? p : malloc(sizeof *p); + iov[*niov].iov_base = p ? (void *)p : malloc(sizeof *p); iov[*niov].iov_len = sizeof *p; (*niov)++; + sz = physical_MaxDeviceSize(); + if (p) { + if (h) + (*h->device2iov)(h, iov, niov, maxiov, newpid); + else { + iov[*niov].iov_base = malloc(sz); + if (p->handler) + memcpy(iov[*niov].iov_base, p->handler, sizeof *p->handler); + iov[*niov].iov_len = sz; + (*niov)++; + } + } else { + iov[*niov].iov_base = malloc(sz); + iov[*niov].iov_len = sz; + (*niov)++; + } + return p ? p->fd : 0; } |