/* * Update the MTU on all routes for the given interface */ void route_UpdateMTU(struct bundle *bundle) { struct rt_msghdr *rtm; struct sockaddr *sa[RTAX_MAX]; struct ncprange dst; size_t needed; char *sp, *cp, *ep; int mib[6]; log_Printf(LogDEBUG, "route_UpdateMTU (%d)\n", bundle->iface->index); mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { log_Printf(LogERROR, "route_IfDelete: sysctl: estimate: %s\n", strerror(errno)); return; } sp = malloc(needed); if (sp == NULL) return; if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { log_Printf(LogERROR, "route_IfDelete: sysctl: getroute: %s\n", strerror(errno)); free(sp); return; } ep = sp + needed; for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)cp; route_ParseHdr(rtm, sa); if (sa[RTAX_DST] && (sa[RTAX_DST]->sa_family == AF_INET #ifndef NOINET6 || sa[RTAX_DST]->sa_family == AF_INET6 #endif ) && sa[RTAX_GATEWAY] && rtm->rtm_index == bundle->iface->index) { if (log_IsKept(LogTCPIP)) { ncprange_setsa(&dst, sa[RTAX_DST], sa[RTAX_NETMASK]); log_Printf(LogTCPIP, "route_UpdateMTU: Netif: %d (%s), dst %s," " mtu %lu\n", rtm->rtm_index, Index2Nam(rtm->rtm_index), ncprange_ntoa(&dst), bundle->iface->mtu); } rt_Update(bundle, sa[RTAX_DST], sa[RTAX_GATEWAY], sa[RTAX_NETMASK], sa[RTAX_IFP], sa[RTAX_IFA]); } } free(sp); }
static const char * addrstr(struct ncprange *addr, unsigned type) { switch (type) { case T_MYADDR: return "MYADDR"; case T_HISADDR: return "HISADDR"; case T_DNS0: return "DNS0"; case T_DNS1: return "DNS1"; } return ncprange_ntoa(addr); }
void route_ShowSticky(struct prompt *p, struct sticky_route *r, const char *tag, int indent) { int tlen = strlen(tag); if (tlen + 2 > indent) prompt_Printf(p, "%s:\n%*s", tag, indent, ""); else prompt_Printf(p, "%s:%*s", tag, indent - tlen - 1, ""); for (; r; r = r->next) { prompt_Printf(p, "%*sadd ", tlen ? 0 : indent, ""); tlen = 0; if (r->type & ROUTE_DSTMYADDR) prompt_Printf(p, "MYADDR"); else if (r->type & ROUTE_DSTMYADDR6) prompt_Printf(p, "MYADDR6"); else if (r->type & ROUTE_DSTHISADDR) prompt_Printf(p, "HISADDR"); else if (r->type & ROUTE_DSTHISADDR6) prompt_Printf(p, "HISADDR6"); else if (r->type & ROUTE_DSTDNS0) prompt_Printf(p, "DNS0"); else if (r->type & ROUTE_DSTDNS1) prompt_Printf(p, "DNS1"); else if (ncprange_isdefault(&r->dst)) prompt_Printf(p, "default"); else prompt_Printf(p, "%s", ncprange_ntoa(&r->dst)); if (r->type & ROUTE_GWHISADDR) prompt_Printf(p, " HISADDR\n"); else if (r->type & ROUTE_GWHISADDR6) prompt_Printf(p, " HISADDR6\n"); else prompt_Printf(p, " %s\n", ncpaddr_ntoa(&r->gw)); } }
void rt_Update(struct bundle *bundle, const struct sockaddr *dst, const struct sockaddr *gw, const struct sockaddr *mask) { struct ncprange ncpdst; struct rtmsg rtmes; char *p; int s, wb; s = ID0socket(PF_ROUTE, SOCK_RAW, 0); if (s < 0) { log_Printf(LogERROR, "rt_Update: socket(): %s\n", strerror(errno)); return; } memset(&rtmes, '\0', sizeof rtmes); rtmes.m_rtm.rtm_version = RTM_VERSION; rtmes.m_rtm.rtm_type = RTM_CHANGE; rtmes.m_rtm.rtm_addrs = 0; rtmes.m_rtm.rtm_seq = ++bundle->routing_seq; rtmes.m_rtm.rtm_pid = getpid(); rtmes.m_rtm.rtm_flags = RTF_UP | RTF_STATIC; if (bundle->ncp.cfg.sendpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe; rtmes.m_rtm.rtm_inits |= RTV_SPIPE; } if (bundle->ncp.cfg.recvpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.cfg.recvpipe; rtmes.m_rtm.rtm_inits |= RTV_RPIPE; } rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->iface->mtu; rtmes.m_rtm.rtm_inits |= RTV_MTU; p = rtmes.m_space; if (dst) { rtmes.m_rtm.rtm_addrs |= RTA_DST; p += memcpy_roundup(p, dst, dst->sa_len); } rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; p += memcpy_roundup(p, gw, gw->sa_len); if (mask) { rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; p += memcpy_roundup(p, mask, mask->sa_len); } rtmes.m_rtm.rtm_msglen = p - (char *)&rtmes; wb = ID0write(s, &rtmes, rtmes.m_rtm.rtm_msglen); if (wb < 0) { ncprange_setsa(&ncpdst, dst, mask); log_Printf(LogTCPIP, "rt_Update failure:\n"); log_Printf(LogTCPIP, "rt_Update: Dst = %s\n", ncprange_ntoa(&ncpdst)); if (rtmes.m_rtm.rtm_errno == 0) log_Printf(LogWARN, "%s: Change route failed: errno: %s\n", ncprange_ntoa(&ncpdst), strerror(errno)); else log_Printf(LogWARN, "%s: Change route failed: %s\n", ncprange_ntoa(&ncpdst), strerror(rtmes.m_rtm.rtm_errno)); } close(s); }
static void p_sockaddr(struct prompt *prompt, struct sockaddr *phost, struct sockaddr *pmask, int width) { struct ncprange range; char buf[29]; struct sockaddr_dl *dl = (struct sockaddr_dl *)phost; if (log_IsKept(LogDEBUG)) { char tmp[50]; log_Printf(LogDEBUG, "Found the following sockaddr:\n"); log_Printf(LogDEBUG, " Family %d, len %d\n", (int)phost->sa_family, (int)phost->sa_len); inet_ntop(phost->sa_family, phost->sa_data, tmp, sizeof tmp); log_Printf(LogDEBUG, " Addr %s\n", tmp); if (pmask) { inet_ntop(pmask->sa_family, pmask->sa_data, tmp, sizeof tmp); log_Printf(LogDEBUG, " Mask %s\n", tmp); } } switch (phost->sa_family) { case AF_INET: #ifndef NOINET6 case AF_INET6: #endif ncprange_setsa(&range, phost, pmask); if (ncprange_isdefault(&range)) prompt_Printf(prompt, "%-*s ", width - 1, "default"); else prompt_Printf(prompt, "%-*s ", width - 1, ncprange_ntoa(&range)); return; case AF_LINK: if (dl->sdl_nlen) snprintf(buf, sizeof buf, "%.*s", dl->sdl_nlen, dl->sdl_data); else if (dl->sdl_alen) { if (dl->sdl_type == IFT_ETHER) { if (dl->sdl_alen < sizeof buf / 3) { int f; u_char *MAC; MAC = (u_char *)dl->sdl_data + dl->sdl_nlen; for (f = 0; f < dl->sdl_alen; f++) sprintf(buf+f*3, "%02x:", MAC[f]); buf[f*3-1] = '\0'; } else strcpy(buf, "??:??:??:??:??:??"); } else sprintf(buf, "<IFT type %d>", dl->sdl_type); } else if (dl->sdl_slen) sprintf(buf, "<slen %d?>", dl->sdl_slen); else sprintf(buf, "link#%d", dl->sdl_index); break; default: sprintf(buf, "<AF type %d>", phost->sa_family); break; } prompt_Printf(prompt, "%-*s ", width-1, buf); }
int rt_Set(struct bundle *bundle, int cmd, const struct ncprange *dst, const struct ncpaddr *gw, int bang, int quiet) { struct rtmsg rtmes; int s, nb, wb; char *cp; const char *cmdstr; struct sockaddr_storage sadst, samask, sagw; int result = 1; if (bang) cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!"); else cmdstr = (cmd == RTM_ADD ? "Add" : "Delete"); s = ID0socket(PF_ROUTE, SOCK_RAW, 0); if (s < 0) { log_Printf(LogERROR, "rt_Set: socket(): %s\n", strerror(errno)); return result; } memset(&rtmes, '\0', sizeof rtmes); rtmes.m_rtm.rtm_version = RTM_VERSION; rtmes.m_rtm.rtm_type = cmd; rtmes.m_rtm.rtm_addrs = RTA_DST; rtmes.m_rtm.rtm_seq = ++bundle->routing_seq; rtmes.m_rtm.rtm_pid = getpid(); rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; if (cmd == RTM_ADD) { if (bundle->ncp.cfg.sendpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe; rtmes.m_rtm.rtm_inits |= RTV_SPIPE; } if (bundle->ncp.cfg.recvpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.cfg.recvpipe; rtmes.m_rtm.rtm_inits |= RTV_RPIPE; } } ncprange_getsa(dst, &sadst, &samask); #if defined(__KAME__) && !defined(NOINET6) add_scope((struct sockaddr *)&sadst, bundle->iface->index); #endif cp = rtmes.m_space; cp += memcpy_roundup(cp, &sadst, sadst.ss_len); if (cmd == RTM_ADD) { if (gw == NULL) { log_Printf(LogERROR, "rt_Set: Program error\n"); close(s); return result; } ncpaddr_getsa(gw, &sagw); #if defined(__KAME__) && !defined(NOINET6) add_scope((struct sockaddr *)&sagw, bundle->iface->index); #endif if (ncpaddr_isdefault(gw)) { if (!quiet) log_Printf(LogERROR, "rt_Set: Cannot add a route with" " gateway 0.0.0.0\n"); close(s); return result; } else { cp += memcpy_roundup(cp, &sagw, sagw.ss_len); rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; } } if (!ncprange_ishost(dst)) { cp += memcpy_roundup(cp, &samask, samask.ss_len); rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; } nb = cp - (char *)&rtmes; rtmes.m_rtm.rtm_msglen = nb; wb = ID0write(s, &rtmes, nb); if (wb < 0) { log_Printf(LogTCPIP, "rt_Set failure:\n"); log_Printf(LogTCPIP, "rt_Set: Cmd = %s\n", cmdstr); log_Printf(LogTCPIP, "rt_Set: Dst = %s\n", ncprange_ntoa(dst)); if (gw != NULL) log_Printf(LogTCPIP, "rt_Set: Gateway = %s\n", ncpaddr_ntoa(gw)); failed: if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST || (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) { if (!bang) { log_Printf(LogWARN, "Add route failed: %s already exists\n", ncprange_ntoa(dst)); result = 0; /* Don't add to our dynamic list */ } else { rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE; if ((wb = ID0write(s, &rtmes, nb)) < 0) goto failed; } } else if (cmd == RTM_DELETE && (rtmes.m_rtm.rtm_errno == ESRCH || (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) { if (!bang) log_Printf(LogWARN, "Del route failed: %s: Non-existent\n", ncprange_ntoa(dst)); } else if (rtmes.m_rtm.rtm_errno == 0) { if (!quiet || errno != ENETUNREACH) log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr, ncprange_ntoa(dst), strerror(errno)); } else log_Printf(LogWARN, "%s route failed: %s: %s\n", cmdstr, ncprange_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno)); } if (log_IsKept(LogDEBUG)) { char gwstr[40]; if (gw) snprintf(gwstr, sizeof gwstr, "%s", ncpaddr_ntoa(gw)); else snprintf(gwstr, sizeof gwstr, "<none>"); log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %s, gateway = %s\n", wb, cmdstr, ncprange_ntoa(dst), gwstr); } close(s); return result; }
/* * Delete routes associated with our interface */ void route_IfDelete(struct bundle *bundle, int all) { struct rt_msghdr *rtm; struct sockaddr *sa[RTAX_MAX]; struct ncprange range; int pass; size_t needed; char *sp, *cp, *ep; int mib[6]; log_Printf(LogDEBUG, "route_IfDelete (%d)\n", bundle->iface->index); mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { log_Printf(LogERROR, "route_IfDelete: sysctl: estimate: %s\n", strerror(errno)); return; } sp = malloc(needed); if (sp == NULL) return; if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) { log_Printf(LogERROR, "route_IfDelete: sysctl: getroute: %s\n", strerror(errno)); free(sp); return; } ep = sp + needed; for (pass = 0; pass < 2; pass++) { /* * We do 2 passes. The first deletes all cloned routes. The second * deletes all non-cloned routes. This is done to avoid * potential errors from trying to delete route X after route Y where * route X was cloned from route Y (and is no longer there 'cos it * may have gone with route Y). */ if (RTF_WASCLONED == 0 && pass == 0) /* So we can't tell ! */ continue; for (cp = sp; cp < ep; cp += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)cp; route_ParseHdr(rtm, sa); if (rtm->rtm_index == bundle->iface->index && sa[RTAX_DST] && sa[RTAX_GATEWAY] && (sa[RTAX_DST]->sa_family == AF_INET #ifndef NOINET6 || sa[RTAX_DST]->sa_family == AF_INET6 #endif ) && (all || (rtm->rtm_flags & RTF_GATEWAY))) { if (log_IsKept(LogDEBUG)) { char gwstr[41]; struct ncpaddr gw; ncprange_setsa(&range, sa[RTAX_DST], sa[RTAX_NETMASK]); ncpaddr_setsa(&gw, sa[RTAX_GATEWAY]); snprintf(gwstr, sizeof gwstr, "%s", ncpaddr_ntoa(&gw)); log_Printf(LogDEBUG, "Found %s %s\n", ncprange_ntoa(&range), gwstr); } if (sa[RTAX_GATEWAY]->sa_family == AF_INET || #ifndef NOINET6 sa[RTAX_GATEWAY]->sa_family == AF_INET6 || #endif sa[RTAX_GATEWAY]->sa_family == AF_LINK) { if ((pass == 0 && (rtm->rtm_flags & RTF_WASCLONED)) || (pass == 1 && !(rtm->rtm_flags & RTF_WASCLONED))) { ncprange_setsa(&range, sa[RTAX_DST], sa[RTAX_NETMASK]); rt_Set(bundle, RTM_DELETE, &range, NULL, 0, 0); } else log_Printf(LogDEBUG, "route_IfDelete: Skip it (pass %d)\n", pass); } else log_Printf(LogDEBUG, "route_IfDelete: Can't remove routes for family %d\n", sa[RTAX_GATEWAY]->sa_family); } } } free(sp); }
static int iface_addr_Add(const char *name, struct iface_addr *addr, int s) { struct ifaliasreq ifra; #ifndef NOINET6 struct in6_aliasreq ifra6; #endif struct sockaddr_in *me4, *msk4, *peer4; struct sockaddr_storage ssme, sspeer, ssmsk; int res; ncprange_getsa(&addr->ifa, &ssme, &ssmsk); ncpaddr_getsa(&addr->peer, &sspeer); res = 0; switch (ncprange_family(&addr->ifa)) { case AF_INET: memset(&ifra, '\0', sizeof ifra); strncpy(ifra.ifra_name, name, sizeof ifra.ifra_name - 1); me4 = (struct sockaddr_in *)&ifra.ifra_addr; memcpy(me4, &ssme, sizeof *me4); msk4 = (struct sockaddr_in *)&ifra.ifra_mask; memcpy(msk4, &ssmsk, sizeof *msk4); peer4 = (struct sockaddr_in *)&ifra.ifra_broadaddr; if (ncpaddr_family(&addr->peer) == AF_UNSPEC) { peer4->sin_family = AF_INET; peer4->sin_len = sizeof(*peer4); peer4->sin_addr.s_addr = INADDR_NONE; } else memcpy(peer4, &sspeer, sizeof *peer4); res = ID0ioctl(s, SIOCAIFADDR, &ifra); if (log_IsKept(LogDEBUG)) { char buf[100]; snprintf(buf, sizeof buf, "%s", ncprange_ntoa(&addr->ifa)); log_Printf(LogWARN, "%s: AIFADDR %s -> %s returns %d\n", ifra.ifra_name, buf, ncpaddr_ntoa(&addr->peer), res); } break; #ifndef NOINET6 case AF_INET6: memset(&ifra6, '\0', sizeof ifra6); strncpy(ifra6.ifra_name, name, sizeof ifra6.ifra_name - 1); memcpy(&ifra6.ifra_addr, &ssme, sizeof ifra6.ifra_addr); memcpy(&ifra6.ifra_prefixmask, &ssmsk, sizeof ifra6.ifra_prefixmask); if (ncpaddr_family(&addr->peer) == AF_UNSPEC) ifra6.ifra_dstaddr.sin6_family = AF_UNSPEC; else if (memcmp(&((struct sockaddr_in6 *)&ssmsk)->sin6_addr, &in6mask128, sizeof in6mask128) == 0) memcpy(&ifra6.ifra_dstaddr, &sspeer, sizeof ifra6.ifra_dstaddr); ifra6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; ifra6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; res = ID0ioctl(s, SIOCAIFADDR_IN6, &ifra6); break; #endif } if (res == -1) { char dst[40]; const char *end = #ifndef NOINET6 ncprange_family(&addr->ifa) == AF_INET6 ? "_IN6" : #endif ""; if (ncpaddr_family(&addr->peer) == AF_UNSPEC) log_Printf(LogWARN, "iface add: ioctl(SIOCAIFADDR%s, %s): %s\n", end, ncprange_ntoa(&addr->ifa), strerror(errno)); else { snprintf(dst, sizeof dst, "%s", ncpaddr_ntoa(&addr->peer)); log_Printf(LogWARN, "iface add: ioctl(SIOCAIFADDR%s, %s -> %s): %s\n", end, ncprange_ntoa(&addr->ifa), dst, strerror(errno)); } } return res != -1; }
static int filter_Parse(struct ncp *ncp, int argc, char const *const *argv, struct filterent *ofp) { struct filterent fe; struct protoent *pe; char *wp; int action, family, ruleno, val, width; ruleno = strtol(*argv, &wp, 0); if (*argv == wp || ruleno >= MAXFILTERS) { log_Printf(LogWARN, "Parse: invalid filter number.\n"); return 0; } if (ruleno < 0) { for (ruleno = 0; ruleno < MAXFILTERS; ruleno++) { ofp->f_action = A_NONE; ofp++; } log_Printf(LogWARN, "Parse: filter cleared.\n"); return 1; } ofp += ruleno; if (--argc == 0) { log_Printf(LogWARN, "Parse: missing action.\n"); return 0; } argv++; memset(&fe, '\0', sizeof fe); val = strtol(*argv, &wp, 0); if (!*wp && val >= 0 && val < MAXFILTERS) { if (val <= ruleno) { log_Printf(LogWARN, "Parse: Can only jump forward from rule %d\n", ruleno); return 0; } action = val; } else if (!strcmp(*argv, "permit")) { action = A_PERMIT; } else if (!strcmp(*argv, "deny")) { action = A_DENY; } else if (!strcmp(*argv, "clear")) { ofp->f_action = A_NONE; return 1; } else { log_Printf(LogWARN, "Parse: %s: bad action\n", *argv); return 0; } fe.f_action = action; argc--; argv++; if (argc && argv[0][0] == '!' && !argv[0][1]) { fe.f_invert = 1; argc--; argv++; } ncprange_init(&fe.f_src); ncprange_init(&fe.f_dst); if (argc == 0) pe = NULL; else if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { if (argc < 2) { log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); return 0; } else if (strcasecmp(*argv, "any") == 0 || ncprange_aton(&fe.f_src, ncp, *argv)) { family = ncprange_family(&fe.f_src); if (!ncprange_getwidth(&fe.f_src, &width)) width = 0; if (width == 0) ncprange_init(&fe.f_src); fe.f_srctype = addrtype(*argv); argc--; argv++; if (strcasecmp(*argv, "any") == 0 || ncprange_aton(&fe.f_dst, ncp, *argv)) { if (ncprange_family(&fe.f_dst) != AF_UNSPEC && ncprange_family(&fe.f_src) != AF_UNSPEC && family != ncprange_family(&fe.f_dst)) { log_Printf(LogWARN, "Parse: src and dst address families differ\n"); return 0; } if (!ncprange_getwidth(&fe.f_dst, &width)) width = 0; if (width == 0) ncprange_init(&fe.f_dst); fe.f_dsttype = addrtype(*argv); argc--; argv++; } else { log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); return 0; } if (argc) { if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { log_Printf(LogWARN, "Parse: %s: Protocol expected\n", *argv); return 0; } else { argc--; argv++; } } } else { log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); return 0; } } else { argc--; argv++; } if (argc >= 2 && strcmp(*argv, "timeout") == 0) { fe.timeout = strtoul(argv[1], NULL, 10); argc -= 2; argv += 2; } val = 1; fe.f_proto = (pe == NULL) ? 0 : pe->p_proto; switch (fe.f_proto) { case IPPROTO_TCP: case IPPROTO_UDP: case IPPROTO_IPIP: #ifndef NOINET6 case IPPROTO_IPV6: #endif val = ParseUdpOrTcp(argc, argv, pe, &fe); break; case IPPROTO_ICMP: #ifndef NOINET6 case IPPROTO_ICMPV6: #endif val = ParseIcmp(argc, argv, &fe); break; default: val = ParseGeneric(argc, &fe); break; } log_Printf(LogDEBUG, "Parse: Src: %s\n", ncprange_ntoa(&fe.f_src)); log_Printf(LogDEBUG, "Parse: Dst: %s\n", ncprange_ntoa(&fe.f_dst)); log_Printf(LogDEBUG, "Parse: Proto: %d\n", fe.f_proto); log_Printf(LogDEBUG, "Parse: src: %s (%d)\n", filter_Op2Nam(fe.f_srcop), fe.f_srcport); log_Printf(LogDEBUG, "Parse: dst: %s (%d)\n", filter_Op2Nam(fe.f_dstop), fe.f_dstport); log_Printf(LogDEBUG, "Parse: estab: %u\n", fe.f_estab); log_Printf(LogDEBUG, "Parse: syn: %u\n", fe.f_syn); log_Printf(LogDEBUG, "Parse: finrst: %u\n", fe.f_finrst); if (val) *ofp = fe; return val; }