/* * Read the initial info for all members of a bridge interface. * Returns the number of ports, 0 - if none, otherwise * -1 if some other error occured. */ int bridge_getinfo_bif_ports(struct bridge_if *bif) { uint32_t i; int32_t buf_len; struct ifbreq *b_req_buf, *b_req; struct ifbpstpreq *bs_req_buf, *bs_req; struct bridge_port *bp; struct mibif *m_if; if ((buf_len = bridge_port_get_iflist(bif, &b_req_buf)) < 0) return (-1); for (i = 0; i < buf_len / sizeof(struct ifbreq); i++) { b_req = b_req_buf + i; if ((m_if = mib_find_if_sys(b_req->ifbr_portno)) != NULL) { /* Hopefully we will not fail here. */ if ((bp = bridge_new_port(m_if, bif)) != NULL) { bp->status = RowStatus_active; bridge_port_getinfo_conf(b_req, bp); bridge_port_getinfo_mibif(m_if, bp); } } else { syslog(LOG_ERR, "bridge member %s not present " "in mibII ifTable", b_req->ifbr_ifsname); } } free(b_req_buf); if ((buf_len = bridge_port_get_ifstplist(bif, &bs_req_buf)) < 0) return (-1); for (bp = bridge_port_bif_first(bif); bp != NULL; bp = bridge_port_bif_next(bp)) { if ((bs_req = bridge_port_find_ifstplist(bp->port_no, bs_req_buf, buf_len)) == NULL) bridge_port_clearinfo_opstp(bp); else bridge_port_getinfo_opstp(bs_req, bp); } free(bs_req_buf); return (i); }
/* * Update the information for the bridge interface members. */ int bridge_update_memif(struct bridge_if *bif) { int added, updated; uint32_t i; int32_t buf_len; struct ifbreq *b_req_buf, *b_req; struct ifbpstpreq *bs_req_buf, *bs_req; struct bridge_port *bp, *bp_next; struct mibif *m_if; if ((buf_len = bridge_port_get_iflist(bif, &b_req_buf)) < 0) return (-1); added = updated = 0; #define BP_FOUND 0x01 for (i = 0; i < buf_len / sizeof(struct ifbreq); i++) { b_req = b_req_buf + i; if ((m_if = mib_find_if_sys(b_req->ifbr_portno)) == NULL) { syslog(LOG_ERR, "bridge member %s not present " "in mibII ifTable", b_req->ifbr_ifsname); continue; } if ((bp = bridge_port_find(m_if->index, bif)) == NULL && (bp = bridge_new_port(m_if, bif)) != NULL) { bp->status = RowStatus_active; added++; } if (bp != NULL) { updated++; bridge_port_getinfo_conf(b_req, bp); bridge_port_getinfo_mibif(m_if, bp); bp->flags |= BP_FOUND; } } free(b_req_buf); /* Clean up list. */ for (bp = bridge_port_bif_first(bif); bp != NULL; bp = bp_next) { bp_next = bridge_port_bif_next(bp); if ((bp->flags & BP_FOUND) == 0 && bp->status == RowStatus_active) bridge_port_remove(bp, bif); else bp->flags |= ~BP_FOUND; } #undef BP_FOUND if ((buf_len = bridge_port_get_ifstplist(bif, &bs_req_buf)) < 0) return (-1); for (bp = bridge_port_bif_first(bif); bp != NULL; bp = bridge_port_bif_next(bp)) { if ((bs_req = bridge_port_find_ifstplist(bp->port_no, bs_req_buf, buf_len)) == NULL) bridge_port_clearinfo_opstp(bp); else bridge_port_getinfo_opstp(bs_req, bp); } free(bs_req_buf); bif->ports_age = time(NULL); return (updated); }
/* * process routing message */ void mib_sroute_process(struct rt_msghdr *rtm, struct sockaddr *gw, struct sockaddr *dst, struct sockaddr *mask) { struct sockaddr_in *in_dst, *in_gw; struct in_addr in_mask; struct mibif *ifp; struct sroute key; struct sroute *r, *r1; in_addr_t ha; if (dst == NULL || gw == NULL || dst->sa_family != AF_INET || gw->sa_family != AF_INET) return; in_dst = (struct sockaddr_in *)(void *)dst; in_gw = (struct sockaddr_in *)(void *)gw; if (rtm->rtm_flags & RTF_HOST) in_mask.s_addr = 0xffffffff; else if (mask == NULL || mask->sa_len == 0) in_mask.s_addr = 0; else in_mask = ((struct sockaddr_in *)(void *)mask)->sin_addr; /* build the index */ ha = ntohl(in_dst->sin_addr.s_addr); key.index[0] = (ha >> 24) & 0xff; key.index[1] = (ha >> 16) & 0xff; key.index[2] = (ha >> 8) & 0xff; key.index[3] = (ha >> 0) & 0xff; ha = ntohl(in_mask.s_addr); key.index[4] = (ha >> 24) & 0xff; key.index[5] = (ha >> 16) & 0xff; key.index[6] = (ha >> 8) & 0xff; key.index[7] = (ha >> 0) & 0xff; /* ToS */ key.index[8] = 0; ha = ntohl(in_gw->sin_addr.s_addr); key.index[9] = (ha >> 24) & 0xff; key.index[10] = (ha >> 16) & 0xff; key.index[11] = (ha >> 8) & 0xff; key.index[12] = (ha >> 0) & 0xff; if (rtm->rtm_type == RTM_DELETE) { r = RB_FIND(sroutes, &sroutes, &key); if (r == 0) { #ifdef DEBUG_ROUTE syslog(LOG_WARNING, "%s: DELETE: %u.%u.%u.%u " "%u.%u.%u.%u %u %u.%u.%u.%u not found", __func__, key.index[0], key.index[1], key.index[2], key.index[3], key.index[4], key.index[5], key.index[6], key.index[7], key.index[8], key.index[9], key.index[10], key.index[11], key.index[12]); #endif return; } RB_REMOVE(sroutes, &sroutes, r); free(r); route_total--; #ifdef DEBUG_ROUTE printf("%s: DELETE: %u.%u.%u.%u " "%u.%u.%u.%u %u %u.%u.%u.%u\n", __func__, key.index[0], key.index[1], key.index[2], key.index[3], key.index[4], key.index[5], key.index[6], key.index[7], key.index[8], key.index[9], key.index[10], key.index[11], key.index[12]); #endif return; } /* GET or ADD */ ifp = NULL; if ((ifp = mib_find_if_sys(rtm->rtm_index)) == NULL) { if (rtm->rtm_type == RTM_ADD) { /* make it a get so the kernel fills the index */ mib_send_rtmsg(rtm, gw, dst, mask); return; } mib_iflist_bad = 1; } if ((r = malloc(sizeof(*r))) == NULL) { syslog(LOG_ERR, "%m"); return; } memcpy(r->index, key.index, sizeof(r->index)); r->ifindex = (ifp == NULL) ? 0 : ifp->index; r->type = (rtm->rtm_flags & RTF_REJECT) ? 2 : 4; /* cannot really know, what protocol it runs */ r->proto = (rtm->rtm_flags & RTF_LOCAL) ? 2 : (rtm->rtm_flags & RTF_STATIC) ? 3 : (rtm->rtm_flags & RTF_DYNAMIC) ? 4 : 10; r1 = RB_INSERT(sroutes, &sroutes, r); if (r1 != NULL) { #ifdef DEBUG_ROUTE syslog(LOG_WARNING, "%s: %u.%u.%u.%u " "%u.%u.%u.%u %u %u.%u.%u.%u duplicate route", __func__, key.index[0], key.index[1], key.index[2], key.index[3], key.index[4], key.index[5], key.index[6], key.index[7], key.index[8], key.index[9], key.index[10], key.index[11], key.index[12]); #endif r1->ifindex = r->ifindex; r1->type = r->type; r1->proto = r->proto; free(r); return; } route_total++; #ifdef DEBUG_ROUTE printf("%s: ADD/GET: %u.%u.%u.%u " "%u.%u.%u.%u %u %u.%u.%u.%u\n", __func__, key.index[0], key.index[1], key.index[2], key.index[3], key.index[4], key.index[5], key.index[6], key.index[7], key.index[8], key.index[9], key.index[10], key.index[11], key.index[12]); #endif }