static int ether_Slot(struct physical *p) { struct etherdevice *dev = device2ether(p->handler); return dev->slot; }
static ssize_t ether_Write(struct physical *p, const void *v, size_t n) { struct etherdevice *dev = device2ether(p->handler); return NgSendData(p->fd, dev->hook, v, n) == -1 ? -1 : (ssize_t)n; }
static void ether_Free(struct physical *p) { struct etherdevice *dev = device2ether(p->handler); physical_SetDescriptor(p); if (dev->cs != -1) close(dev->cs); free(dev); }
static int ether_IsSet(struct fdescriptor *d, const fd_set *fdset) { struct physical *p = descriptor2physical(d); struct etherdevice *dev = device2ether(p->handler); int result; result = dev->cs >= 0 && FD_ISSET(dev->cs, fdset); result += physical_IsSet(d, fdset); return result; }
static int ether_AwaitCarrier(struct physical *p) { struct etherdevice *dev = device2ether(p->handler); if (dev->connected != CARRIER_OK && !dev->timeout--) dev->connected = CARRIER_LOST; else if (dev->connected == CARRIER_PENDING) ether_MessageIn(dev); return dev->connected; }
static const char * ether_OpenInfo(struct physical *p) { struct etherdevice *dev = device2ether(p->handler); switch (dev->connected) { case CARRIER_PENDING: return "negotiating"; case CARRIER_OK: return "established"; } return "disconnected"; }
static int ether_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct physical *p = descriptor2physical(d); struct etherdevice *dev = device2ether(p->handler); int result; if (r && dev->cs >= 0) { FD_SET(dev->cs, r); log_Printf(LogTIMER, "%s(ctrl): fdset(r) %d\n", p->link.name, dev->cs); result = 1; } else result = 0; result += physical_doUpdateSet(d, r, w, e, n, 0); return result; }
static void ether_DescriptorRead(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) { struct physical *p = descriptor2physical(d); struct etherdevice *dev = device2ether(p->handler); if (dev->cs >= 0 && FD_ISSET(dev->cs, fdset)) { ether_MessageIn(dev); if (dev->connected == CARRIER_LOST) { log_Printf(LogPHASE, "%s: Device disconnected\n", p->link.name); datalink_Down(p->dl, CLOSE_NORMAL); return; } } if (physical_IsSet(d, fdset)) physical_DescriptorRead(d, bundle, fdset); }
static void ether_device2iov(struct device *d, struct iovec *iov, int *niov, int maxiov, int *auxfd, int *nauxfd) { struct etherdevice *dev = device2ether(d); int sz = physical_MaxDeviceSize(); iov[*niov].iov_base = realloc(d, sz); if (iov[*niov].iov_base == NULL) { log_Printf(LogALERT, "Failed to allocate memory: %d\n", sz); AbortProgram(EX_OSERR); } iov[*niov].iov_len = sz; (*niov)++; if (dev->cs >= 0) { *auxfd = dev->cs; (*nauxfd)++; } }
static int ether_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) { struct etherdevice *dev = device2ether(p->handler); int result; if (r && dev->cs >= 0 && FD_ISSET(dev->cs, r)) { FD_CLR(dev->cs, r); log_Printf(LogTIMER, "%s: fdunset(ctrl) %d\n", p->link.name, dev->cs); result = 1; } else result = 0; /* Careful... physical_RemoveFromSet() called us ! */ p->handler->removefromset = NULL; result += physical_RemoveFromSet(p, r, w, e); p->handler->removefromset = ether_RemoveFromSet; return result; }