static void print_rts(struct rt_spare *rts, int force_metric, /* -1=suppress, 0=default */ int force_ifp, /* -1=suppress, 0=default */ int force_router, /* -1=suppress, 0=default, 1=display */ int force_tag, /* -1=suppress, 0=default, 1=display */ int force_time) /* 0=suppress, 1=display */ { int i; if (force_metric >= 0) fprintf(ftrace, "metric=%-2d ", rts->rts_metric); if (force_ifp >= 0) fprintf(ftrace, "%s ", (rts->rts_ifp == 0 ? "if?" : rts->rts_ifp->int_name)); if (force_router > 0 || (force_router == 0 && rts->rts_router != rts->rts_gate)) fprintf(ftrace, "router=%s ", naddr_ntoa(rts->rts_router)); if (force_time > 0) fprintf(ftrace, "%s ", ts(rts->rts_time)); if (force_tag > 0 || (force_tag == 0 && rts->rts_tag != 0)) fprintf(ftrace, "tag=%#x ", ntohs(rts->rts_tag)); if (rts->rts_de_ag != 0) { for (i = 1; (u_int)(1 << i) <= rts->rts_de_ag; i++) continue; fprintf(ftrace, "de_ag=%d ", i); } }
/* Send the buffer */ static void supply_write(struct ws_buf *wb) { /* Output multicast only if legal. * If we would multicast and it would be illegal, then discard the * packet. */ switch (wb->type) { case NO_OUT_MULTICAST: trace_pkt("skip multicast to %s because impossible", naddr_ntoa(ws.to.sin_addr.s_addr)); break; case NO_OUT_RIPV2: break; default: if (ws.a != NULL && ws.a->type == RIP_AUTH_MD5) end_md5_auth(wb,ws.a); if (output(wb->type, &ws.to, ws.ifp, wb->buf, ((char *)wb->n - (char*)wb->buf)) < 0 && ws.ifp != NULL) if_sick(ws.ifp); ws.npackets++; break; } clr_ws_buf(wb,ws.a); }
/* display an address */ char * addrname(naddr addr, /* in network byte order */ naddr mask, int force) /* 0=show mask if nonstandard, */ { /* 1=always show mask, 2=never */ #define NUM_BUFS 4 static int bufno; static struct { char str[15+20]; } bufs[NUM_BUFS]; char *s, *sp; naddr dmask; int i; s = strcpy(bufs[bufno].str, naddr_ntoa(addr)); bufno = (bufno+1) % NUM_BUFS; if (force == 1 || (force == 0 && mask != std_mask(addr))) { sp = &s[strlen(s)]; dmask = mask & -mask; if (mask + dmask == 0) { for (i = 0; i != 32 && ((1<<i) & mask) == 0; i++) continue; sprintf(sp, "/%d", 32-i); } else { sprintf(sp, " (mask %#x)", (u_int)mask); } } return s; #undef NUM_BUFS }
void trace_if(const char *act, struct interface *ifp) { if (!TRACEACTIONS || ftrace == 0) return; lastlog(); (void)fprintf(ftrace, "%-3s interface %-4s ", act, ifp->int_name); (void)fprintf(ftrace, "%-15s-->%-15s ", naddr_ntoa(ifp->int_addr), addrname(((ifp->int_if_flags & IFF_POINTOPOINT) ? ifp->int_dstaddr : htonl(ifp->int_net)), ifp->int_mask, 1)); if (ifp->int_metric != 0) (void)fprintf(ftrace, "metric=%d ", ifp->int_metric); if (ifp->int_adj_inmetric != 0) (void)fprintf(ftrace, "adj_inmetric=%u ", ifp->int_adj_inmetric); if (ifp->int_adj_outmetric != 0) (void)fprintf(ftrace, "adj_outmetric=%u ", ifp->int_adj_outmetric); if (!IS_RIP_OUT_OFF(ifp->int_state) && ifp->int_d_metric != 0) (void)fprintf(ftrace, "fake_default=%u ", ifp->int_d_metric); trace_bits(if_bits, ifp->int_if_flags, 0); trace_bits(is_bits, ifp->int_state, 0); (void)fputc('\n',ftrace); }
char * rtname(naddr dst, naddr mask, naddr gate) { static char buf[3*4+3+1+2+3 /* "xxx.xxx.xxx.xxx/xx-->" */ +3*4+3+1]; /* "xxx.xxx.xxx.xxx" */ int i; i = sprintf(buf, "%-16s-->", addrname(dst, mask, 0)); sprintf(&buf[i], "%-*s", 15+20-MAX(20,i), naddr_ntoa(gate)); return buf; }
void trace_dr(const struct dr *drp) { if (ftrace == NULL) return; lastlog(); (void) fprintf(ftrace, " %-4s %-15s %s ", drp->dr_ifp != NULL ? drp->dr_ifp->int_name : "?", naddr_ntoa(drp->dr_gate), ts(drp->dr_ts)); (void) fprintf(ftrace, "%s %d %u\n", ts(drp->dr_life), SIGN_PREF(drp->dr_recv_pref), drp->dr_pref); }
char * rtname(in_addr_t dst, in_addr_t mask, in_addr_t gate) { static char buf[sizeof ("xxx.xxx.xxx.xxx/xx-->xxx.xxx.xxx.xxx")]; int i; (void) snprintf(buf, sizeof (buf), "%-16s-->", addrname(dst, mask, 0)); i = strlen(buf); (void) snprintf(&buf[i], (sizeof (buf) -i), "%-*s", 15+24-MAX(24, i), naddr_ntoa(gate)); return (buf); }
/* display an address */ char * addrname(in_addr_t addr, /* in network byte order */ in_addr_t mask, int force) /* 0=show mask if nonstandard, */ { /* 1=always show mask, 2=never */ #define NUM_BUFS 4 static int bufno; static struct { /* * this array can hold either of the following strings terminated * by a null character: * "xxx.xxx.xxx.xxx/xx" * "xxx.xxx.xxx.xxx (mask xxx.xxx.xxx.xxx)" * */ char str[2*INET_ADDRSTRLEN + sizeof (" (mask )")]; } bufs[NUM_BUFS]; char *s, *sp; in_addr_t dmask; int i, len; struct in_addr tmp_addr; tmp_addr.s_addr = addr; len = strlcpy(bufs[bufno].str, inet_ntoa(tmp_addr), sizeof (bufs[bufno].str)); s = bufs[bufno].str; bufno = (bufno+1) % NUM_BUFS; if (force == 1 || (force == 0 && mask != std_mask(addr))) { sp = &s[strlen(s)]; dmask = mask & -mask; if (mask + dmask == 0) { i = ffs(mask); (void) snprintf(sp, (sizeof (bufs[bufno].str) - len), "/%d", (NBBY * sizeof (in_addr_t) + 1) - i); } else { (void) snprintf(sp, (sizeof (bufs[bufno].str) - len), " (mask %s)", naddr_ntoa(htonl(mask))); } } return (s); #undef NUM_BUFS }
void trace_khash(const struct khash *krt) { if (ftrace == NULL) return; lastlog(); (void) fprintf(ftrace, " %-15s-->%-15s metric=%d ", addrname(krt->k_dst, krt->k_mask, 0), naddr_ntoa(krt->k_gate), krt->k_metric); if (krt->k_ifp != NULL) (void) fprintf(ftrace, "ifp %s ", krt->k_ifp->int_name); else (void) fprintf(ftrace, "ifp NULL "); (void) fprintf(ftrace, "%s ", ts(krt->k_keep)); (void) fprintf(ftrace, "%s ", ts(krt->k_redirect_time)); trace_bits(ks_bits, krt->k_state, _B_TRUE); (void) fputc('\n', ftrace); }
/* put an entry into the packet */ static void supply_out(struct ag_info *ag) { int i; naddr mask, v1_mask, dst_h, ddst_h = 0; struct ws_buf *wb; /* Skip this route if doing a flash update and it and the routes * it aggregates have not changed recently. */ if (ag->ag_seqno < update_seqno && (ws.state & WS_ST_FLASH)) return; dst_h = ag->ag_dst_h; mask = ag->ag_mask; v1_mask = ripv1_mask_host(htonl(dst_h), (ws.state & WS_ST_TO_ON_NET) ? ws.ifp : 0); i = 0; /* If we are sending RIPv2 packets that cannot (or must not) be * heard by RIPv1 listeners, do not worry about sub- or supernets. * Subnets (from other networks) can only be sent via multicast. * A pair of subnet routes might have been promoted so that they * are legal to send by RIPv1. * If RIPv1 is off, use the multicast buffer. */ if ((ws.state & WS_ST_RIP2_ALL) || ((ag->ag_state & AGS_RIPV2) && v1_mask != mask)) { /* use the RIPv2-only buffer */ wb = &v2buf; } else { /* use the RIPv1-or-RIPv2 buffer */ wb = &v12buf; /* Convert supernet route into corresponding set of network * routes for RIPv1, but leave non-contiguous netmasks * to ag_check(). */ if (v1_mask > mask && mask + (mask & -mask) == 0) { ddst_h = v1_mask & -v1_mask; i = (v1_mask & ~mask)/ddst_h; if (i > ws.gen_limit) { /* Punt if we would have to generate an * unreasonable number of routes. */ if (TRACECONTENTS) trace_misc("sending %s-->%s as 1" " instead of %d routes", addrname(htonl(dst_h), mask, 1), naddr_ntoa(ws.to.sin_addr .s_addr), i+1); i = 0; } else { mask = v1_mask; ws.gen_limit -= i; } } } do { wb->n->n_family = RIP_AF_INET; wb->n->n_dst = htonl(dst_h); /* If the route is from router-discovery or we are * shutting down, admit only a bad metric. */ wb->n->n_metric = ((stopint || ag->ag_metric < 1) ? HOPCNT_INFINITY : ag->ag_metric); wb->n->n_metric = htonl(wb->n->n_metric); /* Any non-zero bits in the supposedly unused RIPv1 fields * cause the old `routed` to ignore the route. * That means the mask and so forth cannot be sent * in the hybrid RIPv1/RIPv2 mode. */ if (ws.state & WS_ST_RIP2_ALL) { if (ag->ag_nhop != 0 && ((ws.state & WS_ST_QUERY) || (ag->ag_nhop != ws.ifp->int_addr && on_net(ag->ag_nhop, ws.ifp->int_net, ws.ifp->int_mask)))) wb->n->n_nhop = ag->ag_nhop; wb->n->n_mask = htonl(mask); wb->n->n_tag = ag->ag_tag; } dst_h += ddst_h; if (++wb->n >= wb->lim) supply_write(wb); } while (i-- != 0); }
const char * saddr_ntoa(struct sockaddr *sa) { return (sa == NULL) ? "?" : naddr_ntoa(S_ADDR(sa)); }
const char * saddr_ntoa(struct sockaddr_storage *ss) { return (ss == NULL) ? "?" : naddr_ntoa(S_ADDR(ss)); }