static struct atmdevice * atm_CreateDevice(struct physical *p, const char *iface, unsigned vpi, unsigned vci) { struct atmdevice *dev; struct sockaddr_natm sock; if ((dev = calloc(1, sizeof *dev)) == NULL) { log_Printf(LogWARN, "%s: Cannot allocate an atm device: %s\n", p->link.name, strerror(errno)); return NULL; } sock.snatm_len = sizeof sock; sock.snatm_family = AF_NATM; strncpy(sock.snatm_if, iface, IFNAMSIZ); sock.snatm_vpi = vpi; sock.snatm_vci = vci; log_Printf(LogPHASE, "%s: Connecting to %s:%u.%u\n", p->link.name, iface, vpi, vci); p->fd = socket(PF_NATM, SOCK_DGRAM, PROTO_NATMAAL5); if (p->fd >= 0) { log_Printf(LogDEBUG, "%s: Opened atm socket %s\n", p->link.name, p->name.full); if (connect(p->fd, (struct sockaddr *)&sock, sizeof sock) == 0) return dev; else log_Printf(LogWARN, "%s: connect: %s\n", p->name.full, strerror(errno)); } else log_Printf(LogWARN, "%s: socket: %s\n", p->name.full, strerror(errno)); close(p->fd); p->fd = -1; free(dev); return NULL; }
struct mbuf * auth_ReadHeader(struct authinfo *authp, struct mbuf *bp) { size_t len; len = m_length(bp); if (len >= sizeof authp->in.hdr) { bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr); if (len >= ntohs(authp->in.hdr.length)) return bp; authp->in.hdr.length = htons(0); log_Printf(LogWARN, "auth_ReadHeader: Short packet (%u > %zu) !\n", ntohs(authp->in.hdr.length), len); } else { authp->in.hdr.length = htons(0); log_Printf(LogWARN, "auth_ReadHeader: Short packet header (%u > %zu) !\n", (int)(sizeof authp->in.hdr), len); } m_freem(bp); return NULL; }
struct mbuf * auth_ReadName(struct authinfo *authp, struct mbuf *bp, size_t len) { if (len > sizeof authp->in.name - 1) log_Printf(LogWARN, "auth_ReadName: Name too long (%zu) !\n", len); else { size_t mlen = m_length(bp); if (len > mlen) log_Printf(LogWARN, "auth_ReadName: Short packet (%zu > %zu) !\n", len, mlen); else { bp = mbuf_Read(bp, (u_char *)authp->in.name, len); authp->in.name[len] = '\0'; return bp; } } *authp->in.name = '\0'; m_freem(bp); return NULL; }
struct mbuf * lqr_RecvEcho(struct fsm *fp, struct mbuf *bp) { struct hdlc *hdlc = &link2physical(fp->link)->hdlc; struct lcp *lcp = fsm2lcp(fp); struct echolqr lqr; if (m_length(bp) >= sizeof lqr) { m_freem(mbuf_Read(bp, &lqr, sizeof lqr)); bp = NULL; lqr.magic = ntohl(lqr.magic); lqr.signature = ntohl(lqr.signature); lqr.sequence = ntohl(lqr.sequence); /* Tolerate echo replies with either magic number */ if (lqr.magic != 0 && lqr.magic != lcp->his_magic && lqr.magic != lcp->want_magic) { log_Printf(LogWARN, "%s: lqr_RecvEcho: Bad magic: expected 0x%08x," " got 0x%08x\n", fp->link->name, lcp->his_magic, lqr.magic); /* * XXX: We should send a terminate request. But poor implementations may * die as a result. */ } if (lqr.signature == SIGNATURE || lqr.signature == lcp->want_magic) { /* some implementations return the wrong magic */ /* careful not to update lqm.echo.seq_recv with older values */ if ((hdlc->lqm.echo.seq_recv > (u_int32_t)0 - 5 && lqr.sequence < 5) || (hdlc->lqm.echo.seq_recv <= (u_int32_t)0 - 5 && lqr.sequence > hdlc->lqm.echo.seq_recv)) hdlc->lqm.echo.seq_recv = lqr.sequence; } else log_Printf(LogWARN, "lqr_RecvEcho: Got sig 0x%08lx, not 0x%08lx !\n", (u_long)lqr.signature, (u_long)SIGNATURE); } else log_Printf(LogWARN, "lqr_RecvEcho: Got packet size %zd, expecting %ld !\n", m_length(bp), (long)sizeof(struct echolqr)); return bp; }
void m_enqueue(struct mqueue *queue, struct mbuf *bp) { if (bp != NULL) { if (queue->last) { queue->last->m_nextpkt = bp; queue->last = bp; } else queue->last = queue->top = bp; queue->len++; log_Printf(LogDEBUG, "m_enqueue: len = %lu\n", (unsigned long)queue->len); } }
void log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) { if (log_IsKept(lev)) { char buf[68]; char *b, *c; const u_char *ptr; int f; if (hdr && *hdr) log_Printf(lev, "%s\n", hdr); b = buf; c = b + 50; do { f = bp->m_len; ptr = CONST_MBUF_CTOP(bp); while (f--) { sprintf(b, " %02x", (int) *ptr); *c++ = isprint(*ptr) ? *ptr : '.'; ptr++; b += 3; if (b == buf + 48) { memset(b, ' ', 2); *c = '\0'; log_Printf(lev, "%s\n", buf); b = buf; c = b + 50; } } } while ((bp = bp->m_next) != NULL); if (b > buf) { memset(b, ' ', 50 - (b - buf)); *c = '\0'; log_Printf(lev, "%s\n", buf); } } }
void log_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n) { if (log_IsKept(lev)) { char buf[68]; char *b, *c; if (hdr && *hdr) log_Printf(lev, "%s\n", hdr); while (n > 0) { b = buf; c = b + 50; for (b = buf; b != buf + 48 && n--; b += 3, ptr++) { sprintf(b, " %02x", (int) *ptr); *c++ = isprint(*ptr) ? *ptr : '.'; } memset(b, ' ', 50 - (b - buf)); *c = '\0'; log_Printf(lev, "%s\n", buf); } } }
void AbortProgram(int excode) { if (SignalBundle) server_Close(SignalBundle); log_Printf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode)); if (SignalBundle) { bundle_Close(SignalBundle, NULL, CLOSE_STAYDOWN); bundle_Destroy(SignalBundle); } log_Close(); exit(excode); }
static void datalink_LoginDone(struct datalink *dl) { chat_Finish(&dl->chat); if (!dl->script.packetmode) { dl->dial.tries = -1; dl->dial.incs = 0; datalink_NewState(dl, DATALINK_READY); } else if (!physical_Raw(dl->physical)) { dl->dial.tries = 0; log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n"); if (dl->script.run) { datalink_NewState(dl, DATALINK_LOGOUT); if (!chat_Setup(&dl->chat, dl->cfg.script.logout, NULL)) log_Printf(LogWARN, "Invalid logout script\n"); } else { physical_StopDeviceTimer(dl->physical); if (dl->physical->type == PHYS_DEDICATED) /* force a redial timeout */ physical_Close(dl->physical); datalink_HangupDone(dl); } } else { dl->dial.tries = -1; dl->dial.incs = 0; hdlc_Init(&dl->physical->hdlc, &dl->physical->link.lcp); async_Setup(&dl->physical->async); lcp_Setup(&dl->physical->link.lcp, dl->state == DATALINK_READY ? 0 : dl->physical->link.lcp.cfg.openmode); ccp_Setup(&dl->physical->link.ccp); datalink_NewState(dl, DATALINK_LCP); fsm_Up(&dl->physical->link.lcp.fsm); fsm_Open(&dl->physical->link.lcp.fsm); } }
static int do_inet_aton(const char *start, const char *end, struct in_addr *ip) { char ipstr[16]; if (end - start > 15) { log_Printf(LogWARN, "%.*s: Invalid IP address\n", (int)(end-start), start); return 0; } strncpy(ipstr, start, end-start); ipstr[end-start] = '\0'; return inet_aton(ipstr, ip); }
int auth_Validate(struct bundle *bundle, const char *name, const char *key, struct physical *physical) { /* Used by PAP routines */ FILE *fp; int n, lineno; char *vector[5], buff[LINE_LEN]; const char *slash; fp = OpenSecret(SECRETFILE); again: lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') continue; buff[strcspn(buff, "\n")] = '\0'; memset(vector, '\0', sizeof vector); if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strcmp(vector[0], name) == 0) { CloseSecret(fp); return auth_CheckPasswd(name, vector[1], key); } } } if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { /* Look for the name without the leading domain */ name = slash + 1; if (fp != NULL) { rewind(fp); goto again; } } if (fp != NULL) CloseSecret(fp); #ifndef NOPASSWDAUTH if (Enabled(bundle, OPT_PASSWDAUTH)) return auth_CheckPasswd(name, "*", key); #endif return 0; /* Invalid */ }
static void ipv6cp_LayerDown(struct fsm *fp) { /* About to come down */ struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); static int recursing; char addr[40]; if (!recursing++) { snprintf(addr, sizeof addr, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); log_Printf(LogIPV6CP, "%s: LayerDown: %s\n", fp->link->name, addr); #ifndef NORADIUS radius_Flush(&fp->bundle->radius); radius_Account(&fp->bundle->radius, &fp->bundle->radacct6, fp->bundle->links, RAD_STOP, &ipv6cp->throughput); /* * XXX: Avoid duplicate evaluation of filterid between IPCP and * IPV6CP. When IPCP is enabled and rejected, filterid is not * evaluated. */ if (!Enabled(fp->bundle, OPT_IPCP)) { if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, NULL, NULL); } #endif /* * XXX this stuff should really live in the FSM. Our config should * associate executable sections in files with events. */ if (system_Select(fp->bundle, addr, LINKDOWNFILE, NULL, NULL) < 0) { /* * XXX: Avoid duplicate evaluation of label between IPCP and * IPV6CP. When IPCP is enabled and rejected, label is not * evaluated. */ if (bundle_GetLabel(fp->bundle) && !Enabled(fp->bundle, OPT_IPCP)) { if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), LINKDOWNFILE, NULL, NULL) < 0) system_Select(fp->bundle, "MYADDR6", LINKDOWNFILE, NULL, NULL); } else system_Select(fp->bundle, "MYADDR6", LINKDOWNFILE, NULL, NULL); } ipv6cp_Setup(ipv6cp); } recursing--; }
int ncpaddr_aton(struct ncpaddr *addr, struct ncp *ncp, const char *data) { struct ncprange range; if (!ncprange_aton(&range, ncp, data)) return 0; if (range.ncprange_family == AF_INET && range.ncprange_ip4width != 32 && range.ncprange_ip4addr.s_addr != INADDR_ANY) { log_Printf(LogWARN, "ncpaddr_aton: %s: Only 32 bits allowed\n", data); return 0; } #ifndef NOINET6 if (range.ncprange_family == AF_INET6 && range.ncprange_ip6width != 128 && !IN6_IS_ADDR_UNSPECIFIED(&range.ncprange_ip6addr)) { log_Printf(LogWARN, "ncpaddr_aton: %s: Only 128 bits allowed\n", data); return 0; } #endif switch (range.ncprange_family) { case AF_INET: addr->ncpaddr_family = range.ncprange_family; addr->ncpaddr_ip4addr = range.ncprange_ip4addr; return 1; #ifndef NOINET6 case AF_INET6: addr->ncpaddr_family = range.ncprange_family; addr->ncpaddr_ip6addr = range.ncprange_ip6addr; return 1; #endif } return 0; }
static void SendLqrReport(void *v) { struct lcp *lcp = (struct lcp *)v; struct physical *p = link2physical(lcp->fsm.link); timer_Stop(&p->hdlc.lqm.timer); if (p->hdlc.lqm.method & LQM_LQR) { if (p->hdlc.lqm.lqr.resent > 5) { /* XXX: Should implement LQM strategy */ log_Printf(LogPHASE, "%s: ** Too many LQR packets lost **\n", lcp->fsm.link->name); log_Printf(LogLQM, "%s: Too many LQR packets lost\n", lcp->fsm.link->name); p->hdlc.lqm.method = 0; datalink_Down(p->dl, CLOSE_NORMAL); } else { SendLqrData(lcp); p->hdlc.lqm.lqr.resent++; } } else if (p->hdlc.lqm.method & LQM_ECHO) { if ((p->hdlc.lqm.echo.seq_sent > 5 && p->hdlc.lqm.echo.seq_sent - 5 > p->hdlc.lqm.echo.seq_recv) || (p->hdlc.lqm.echo.seq_sent <= 5 && p->hdlc.lqm.echo.seq_sent > p->hdlc.lqm.echo.seq_recv + 5)) { log_Printf(LogPHASE, "%s: ** Too many LCP ECHO packets lost **\n", lcp->fsm.link->name); log_Printf(LogLQM, "%s: Too many LCP ECHO packets lost\n", lcp->fsm.link->name); p->hdlc.lqm.method = 0; datalink_Down(p->dl, CLOSE_NORMAL); } else SendEchoReq(lcp); } if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load) timer_Start(&p->hdlc.lqm.timer); }
static int i4b_Raw(struct physical *p) { int oldflag; log_Printf(LogDEBUG, "%s: Entering i4b_Raw\n", p->link.name); oldflag = fcntl(p->fd, F_GETFL, 0); if (oldflag < 0) return 0; fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK); return 1; }
static void i4b_StartTimer(struct physical *p) { struct i4bdevice *dev = device2i4b(p->handler); timer_Stop(&dev->Timer); dev->Timer.load = SECTICKS; dev->Timer.func = i4b_Timeout; dev->Timer.name = "i4b CD"; dev->Timer.arg = p; log_Printf(LogDEBUG, "%s: Using i4b_Timeout [%p]\n", p->link.name, i4b_Timeout); timer_Start(&dev->Timer); }
static int DecodeCtrlCommand(char *line, char *arg) { const char *end; if (!strncasecmp(line, "include", 7) && issep(line[7])) { end = InterpretArg(line+8, arg); if (*end && *end != '#') log_Printf(LogWARN, "usage: !include filename\n"); else return CTRL_INCLUDE; } return CTRL_UNKNOWN; }
static ssize_t ng_Read(struct physical *p, void *v, size_t n) { char hook[NG_HOOKSIZ]; log_Printf(LogDEBUG, "ng_Read\n"); switch (p->dl->state) { case DATALINK_DIAL: case DATALINK_LOGIN: return ng_MessageIn(p, v, n); } return NgRecvData(p->fd, v, n, hook); }
static void udp_device2iov(struct device *d, struct iovec *iov, int *niov, int maxiov, int *auxfd, int *nauxfd) { 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)++; }
static void CheckLabel(const char *label, struct prompt *prompt, int mode) { const char *err; if ((err = system_IsValid(label, prompt, mode)) != NULL) { fprintf(stderr, "%s: %s\n", label, err); if (mode == PHYS_DIRECT) log_Printf(LogWARN, "Label %s rejected -direct connection: %s\n", label, err); log_Close(); exit(1); } }
int physical_SetMode(struct physical *p, int mode) { if ((p->type & (PHYS_DIRECT|PHYS_DEDICATED) || mode & (PHYS_DIRECT|PHYS_DEDICATED)) && (!(p->type & PHYS_DIRECT) || !(mode & PHYS_BACKGROUND))) { /* Note: The -direct -> -background is for callback ! */ log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name, mode2Nam(p->type), mode2Nam(mode)); return 0; } p->type = mode; return 1; }
int ID0open(const char *path, int flags, ...) { int ret; va_list ap; va_start(ap, flags); ID0set0(); ret = open(path, flags, va_arg(ap, int)); log_Printf(LogID0, "%d = open(\"%s\", %d)\n", ret, path, flags); ID0setuser(); va_end(ap); return ret; }
static int iface_ChangeFlags(const char *ifname, int flags, int how) { struct ifreq ifrq; int s; s = ID0socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { log_Printf(LogERROR, "iface_ChangeFlags: socket: %s\n", strerror(errno)); return 0; } memset(&ifrq, '\0', sizeof ifrq); strncpy(ifrq.ifr_name, ifname, sizeof ifrq.ifr_name - 1); ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { log_Printf(LogERROR, "iface_ChangeFlags: ioctl(SIOCGIFFLAGS): %s\n", strerror(errno)); close(s); return 0; } if (how == IFACE_ADDFLAGS) ifrq.ifr_flags |= flags; else ifrq.ifr_flags &= ~flags; if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) { log_Printf(LogERROR, "iface_ChangeFlags: ioctl(SIOCSIFFLAGS): %s\n", strerror(errno)); close(s); return 0; } close(s); return 1; /* Success */ }
void tun_configure(struct bundle *bundle) { #ifdef __NetBSD__ struct ifreq ifr; int s; s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { log_Printf(LogERROR, "tun_configure: socket(): %s\n", strerror(errno)); return; } sprintf(ifr.ifr_name, "tun%d", bundle->unit); ifr.ifr_mtu = bundle->iface->mtu; if (ioctl(s, SIOCSIFMTU, &ifr) < 0) log_Printf(LogERROR, "tun_configure: ioctl(SIOCSIFMTU): %s\n", strerror(errno)); close(s); #else struct tuninfo info; memset(&info, '\0', sizeof info); info.type = IFT_PPP; info.mtu = bundle->iface->mtu; info.baudrate = bundle->bandwidth; #ifdef __OpenBSD__ info.flags = IFF_UP|IFF_POINTOPOINT|IFF_MULTICAST; #endif if (ID0ioctl(bundle->dev.fd, TUNSIFINFO, &info) < 0) log_Printf(LogERROR, "tun_configure: ioctl(TUNSIFINFO): %s\n", strerror(errno)); #endif }
static struct udpdevice * udp_CreateDevice(struct physical *p, char *host, char *port) { struct udpdevice *dev; struct servent *sp; if ((dev = malloc(sizeof *dev)) == NULL) { log_Printf(LogWARN, "%s: Cannot allocate a udp device: %s\n", p->link.name, strerror(errno)); return NULL; } dev->sock.sin_family = AF_INET; dev->sock.sin_addr = GetIpAddr(host); if (dev->sock.sin_addr.s_addr == INADDR_NONE) { log_Printf(LogWARN, "%s: %s: unknown host\n", p->link.name, host); free(dev); return NULL; } dev->sock.sin_port = htons(atoi(port)); if (dev->sock.sin_port == 0) { sp = getservbyname(port, "udp"); if (sp) dev->sock.sin_port = sp->s_port; else { log_Printf(LogWARN, "%s: %s: unknown service\n", p->link.name, port); free(dev); return NULL; } } log_Printf(LogPHASE, "%s: Connecting to %s:%s/udp\n", p->link.name, host, port); p->fd = socket(PF_INET, SOCK_DGRAM, 0); if (p->fd >= 0) { log_Printf(LogDEBUG, "%s: Opened udp socket %s\n", p->link.name, p->name.full); if (connect(p->fd, (struct sockaddr *)&dev->sock, sizeof dev->sock) == 0) { dev->connected = UDP_CONNECTED; return dev; } else log_Printf(LogWARN, "%s: connect: %s\n", p->name.full, strerror(errno)); } else log_Printf(LogWARN, "%s: socket: %s\n", p->name.full, strerror(errno)); close(p->fd); p->fd = -1; free(dev); return NULL; }
static int tcp_OpenConnection(const char *name, char *host, char *port) { struct sockaddr_in dest; int sock; struct servent *sp; dest.sin_family = AF_INET; dest.sin_addr = GetIpAddr(host); if (dest.sin_addr.s_addr == INADDR_NONE) { log_Printf(LogWARN, "%s: %s: unknown host\n", name, host); return -2; } dest.sin_port = htons(atoi(port)); if (dest.sin_port == 0) { sp = getservbyname(port, "tcp"); if (sp) dest.sin_port = sp->s_port; else { log_Printf(LogWARN, "%s: %s: unknown service\n", name, port); return -2; } } log_Printf(LogPHASE, "%s: Connecting to %s:%s/tcp\n", name, host, port); sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) return -2; if (connect(sock, (struct sockaddr *)&dest, sizeof dest) < 0) { log_Printf(LogWARN, "%s: connect: %s\n", name, strerror(errno)); close(sock); return -2; } return sock; }
/* * arp_ClearProxy - Delete the proxy ARP entry for the peer. */ int arp_ClearProxy(struct bundle *bundle, struct in_addr addr, int s) { struct arpreq arpreq; memset(&arpreq, '\0', sizeof arpreq); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr = addr.s_addr; if (ID0ioctl(s, SIOCDARP, (caddr_t) & arpreq) < 0) { log_Printf(LogERROR, "arp_ClearProxy: ioctl(SIOCDARP): %s\n", strerror(errno)); return 0; } return 1; }
static void ChapOutput(struct physical *physical, u_int code, u_int id, const u_char *ptr, int count, const char *text) { int plen; struct fsmheader lh; struct mbuf *bp; plen = sizeof(struct fsmheader) + count; lh.code = code; lh.id = id; lh.length = htons(plen); bp = m_get(plen, MB_CHAPOUT); memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); if (count) memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); log_DumpBp(LogDEBUG, "ChapOutput", bp); if (text == NULL) log_Printf(LogPHASE, "Chap Output: %s\n", chapcodes[code]); else log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text); link_PushPacket(&physical->link, bp, physical->dl->bundle, LINK_QUEUES(&physical->link) - 1, PROTO_CHAP); }
static int chap_UpdateSet_old(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) { struct chap *chap = descriptor2chap(d); if (r && chap && chap->child.fd != -1) { FD_SET(chap->child.fd, r); if (*n < chap->child.fd + 1) *n = chap->child.fd + 1; log_Printf(LogTIMER, "Chap: fdset(r) %d\n", chap->child.fd); return 1; } return 0; }
static void physical_Found(struct physical *p) { FILE *lockfile; char fn[PATH_MAX]; if (*p->name.full == '/') { snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base); lockfile = ID0fopen(fn, "w"); if (lockfile != NULL) { fprintf(lockfile, "%s%d\n", TUN_NAME, p->dl->bundle->unit); fclose(lockfile); } else log_Printf(LogALERT, "%s: Can't create %s: %s\n", p->link.name, fn, strerror(errno)); } throughput_start(&p->link.stats.total, "physical throughput", Enabled(p->dl->bundle, OPT_THROUGHPUT)); p->connect_count++; p->input.sz = 0; log_Printf(LogPHASE, "%s: Connected!\n", p->link.name); }