📄 rsrr_rsrr.c
字号:
/* * Should be error */ if (rsrr->flags == 1) log(LOG_ERR,errno,"RSRR_IR: Error in gated",0); else log(LOG_ERR,errno,"RSRR_IR: Wrong version",0); return(-1);#endif /* USE_IPV6 */ default: return(-1); } /* * accept this interface reply */ return rsrr_accept_ir_ux(sock_type, rsrr); case RSRR_ROUTE_REPLY: /* * Route Reply message type */ if (rsrr_recvlen < RSRRV1_RR_LEN) { log(LOG_ERR, 0, "Received Route Reply of %d bytes, which is too small\n", rsrr_recvlen); break; } switch (sock_type) { case RSRR_SOCK_V4UX: /* * from IPv4 socket */ if (!rsrr_use_v1_ipv4) { log(LOG_ERR,0,"RSRR_RR Version mismatched. Expecting 2"); return -1; } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * from IPv6 socket */ log(LOG_ERR,0,"RSRR v1 does not support IPv6"); return -1;#endif /* USE_IPV6 */ default: return -1; } /* * accept this route reply */ return rsrr_accept_rr_ux(sock_type, rsrr); default: log(LOG_ERR, 0, "Received RSRR packet type %d, which I don't handle", rsrr->type); break; } break; case 2: /* * RSRR version 2 */ switch (rsrr->type) { case RSRR_INTERFACE_REPLY: /* * Interface Reply message type */ if (rsrr_recvlen < (RSRR_HEADER_LEN + rsrr->num*RSRR_VIF_LEN)) { log(LOG_ERR, 0, "Received Interface Reply of %d bytes, which is too small\n", rsrr_recvlen); break; } if (rsrr->flags == 1) { log(LOG_ERR, 0, "Error occurred during interface query"); break; } switch (sock_type) { case RSRR_SOCK_V4UX: /* * from IPv4 socket */ if (rsrr->version < RSRR_MAX_VERSION) { rsrr_use_v1_ipv4 = 1; rsrr_use_v2_ipv4 = 0; } else { rsrr_use_v1_ipv4 = 0; rsrr_use_v2_ipv4 = 1; } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * from IPv6 socket */ if (rsrr->version < RSRR_MAX_VERSION) { /* * Impossible. Should be error */ log(LOG_ERR,errno,"Wrong version",0); return(-1); } else { rsrr_use_v2_ipv6 = 1; rsrr_use_v1_ipv6 = 0; } break;#endif /* USE_IPV6 */ default: return(-1); } /* * accept this interface reply */ return rsrr_accept_ir_ux(sock_type, rsrr); case RSRR_ROUTE_REPLY: /* * Route Reply message type */ if (rsrr_recvlen < RSRR_RR_LEN) { log(LOG_ERR, 0, "Received Route Reply of %d bytes, which is too small\n", rsrr_recvlen); break; } switch (sock_type) { case RSRR_SOCK_V4UX: /* * from IPv4 socket */ if (!rsrr_use_v2_ipv4) { log(LOG_ERR,0,"RSRR_RR Version mismatched. Expecting 1"); return -1; } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * from IPv6 socket */ if (!rsrr_use_v2_ipv6) { log(LOG_ERR,0,"someting is wrong"); return -1; } break;#endif /* USE_IPV6 */ default: return -1; } /* * accept this route reply */ return rsrr_accept_rr_ux(sock_type, rsrr); default: log(LOG_ERR, 0, "Received RSRR packet type %d, which I don't handle", rsrr->type); break; } break; default: log(LOG_ERR, 0, "Received RSRR packet version %d, which I don't understand", rsrr->version); break; } return 0;}/* * to accept message coming in from the routing socket * this is useful for asynchronous reply from the kernel, * but currently it's not used due to the fast response * from the kernel and the extra overhead of listening * to all the messages received from the routing socket * that are not related to rsvpd. */intrsrr_accept_rt(sock_type, skt, expected_type) u_char sock_type; int skt; u_char expected_type;{#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux) /* * the routing socket used by SGI is not supported */ struct sockaddr *sa;#ifdef SOLARIS caddr_t cp; struct sockaddr *rti_info[RTA_NUMBITS];#else struct sockaddr *rti_info[RTAX_MAX];#endif net_addr dst; net_addr naddr; struct rt_msghdr *mhp; char buf[RTM_BUFLEN]; struct sockaddr_dl *sdlp; char ifname[IFNAMSIZ]; struct sockaddr_in *iifa; int ifnum; int len; int rv; int i; unsigned int ifidx = 0;#ifdef USE_IPV6 struct sockaddr_in6 *iifa6;#endif /* USE_IPV6 */ memset(buf, 0, sizeof buf); mhp = (struct rt_msghdr *)buf; sa = (struct sockaddr *)(mhp + 1); /* * Read the reply */ len = read(skt, buf, sizeof(buf)); /* * not for this process */ if (mhp->rtm_pid != getpid()) return 0; /* * Here we assume no RTM_IFINFO */ if (len < 0 || mhp->rtm_errno) { if (IsDebug(DEBUG_ROUTE)) log(LOG_DEBUG, errno, "unicast route lookup failed"); return -1; } if (len == 0) { log(LOG_ERR, 0, "unicast route lookup is confused"); return -1; } /* * collect all the information from the message */#ifdef SOLARIS cp = (caddr_t)sa; for (i = 0; i < RTA_NUMBITS; i++) { switch (mhp->rtm_addrs & (1 << i)) { case RTA_DST: case RTA_GATEWAY: case RTA_NETMASK: case RTA_GENMASK: case RTA_AUTHOR: case RTA_IFA: rti_info[i] = (struct sockaddr *)cp; cp += sizeof (struct sockaddr_in); break; case RTA_IFP: rti_info[i] = (struct sockaddr *)cp; cp += sizeof (struct sockaddr_dl); break; } }#else for (i = 0; i < RTAX_MAX; i++) { if (mhp->rtm_addrs & (1 << i)) { rti_info[i] = sa; NEXT_SA(sa); } else rti_info[i] = NULL; }#endif /* * process the info */ if ((sa = rti_info[RTAX_IFP]) != NULL) { /* * outgoing data-link address for this unicast route */ sdlp = (struct sockaddr_dl *)sa; if (sdlp->sdl_family != AF_LINK || sdlp->sdl_nlen == 0) { if (IsDebug(DEBUG_ROUTE)) log(LOG_DEBUG, 0, "unicast route through weird ifp"); return -1; } strncpy(ifname, sdlp->sdl_data, sdlp->sdl_nlen); if (sdlp->sdl_nlen < IFNAMSIZ) ifname[sdlp->sdl_nlen] = '\0'; /* * get the outgoing interface index from the * interface name */ ifidx = if_nametoindex(ifname); } if ((sa = rti_info[RTAX_DST]) != NULL) { /* * destination address for this unicast route */ if (sa->sa_family == AF_INET) { NET_SET_ADDR_IPv4(&dst, ((struct sockaddr_in *)sa)->sin_addr); }#ifdef USE_IPV6 else if (sa->sa_family == AF_INET6) { NET_SET_ADDR_IPv6(&dst, ((struct sockaddr_in6 *)sa)->sin6_addr); }#endif /* USE_IPV6 */ } else return -1; if ((sa = rti_info[RTAX_IFA]) != NULL) { /* * get the outgoing interface address */ if (sa->sa_family == AF_INET) { iifa = (struct sockaddr_in *)sa; NET_SET_ADDR_IPv4(&naddr, iifa->sin_addr); }#ifdef USE_IPV6 else if (sa->sa_family == AF_INET6) { iifa6 = (struct sockaddr_in6 *)sa; NET_SET_ADDR_IPv6(&naddr, iifa6->sin6_addr); }#endif /* USE_IPV6 */ else return -1; /* * use the index and address to get the outgoing LIH * used within rsvpd for further processing */ ifnum = locate_LIH(ifidx, &naddr); if (ifnum == -1) /* * failed to locate the correct LIH */ return -1; else { /* * set up the outgoing bitmap and process it */ bmp_set(&bmp_unicast, ifnum); rv = rsrr_route_reply(seq,(net_addr *)0,&dst,(u_short)0, &bmp_unicast,1,0); return rv; } } else return -1;#endif /* PF_ROUTE */ return -1;}/* * Send an Interface Query to multicast routing */intrsrr_send_iq(int note){ struct rsrr_header *rsrr; int sendlen; int rv; /* * Set up Interface Query message */ rsrr = (struct rsrr_header *) rsrr_send_buf; /* * Hack version number here to enable automatic version negotiation */ rsrr->version = 1; /* compatibility hack */ rsrr->type = RSRR_INTERFACE_QUERY; rsrr->flags = note; /* notification bit */ rsrr->num = 2; /* maximum supported version */ /* * Get the size. */ sendlen = RSRR_HEADER_LEN; if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG, 0, "> Interface Query\n"); /* * Send it. */ rv = rsrr_send0(sendlen); return (rv);}/* * Accept an Interface Reply. The reply contains the vifs that routing * is using; initiatlize our own vif structure so RSVP can keep track * of them. */intrsrr_accept_ir_ux(sock_type,rsrr_in) u_char sock_type; struct rsrr_header *rsrr_in;{ int vf,i; int base; static int first = 1; base = vif_num; switch (sock_type) { case RSRR_SOCK_V4UX: /* * increase the total number of vif number used by RSRR * and set up the variable shift to be used later when * interpreting the bitmap from mrouted */ vif_num += rsrr_in->num; shift = if_num; if (NoV4Mroute) { /* * This is the interface reply from IPv4 mrouted */ NoV4Mroute = 0; } if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG, 0, "< IPv4 Mcast Daemon Interface Reply with %d vifs\n",rsrr_in->num); break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * we don't increase the vif number here because the * IPv6 mrouting daemon we use does not use any virtual * interfaces as IPv4 mrouted does, thus all the interfaces * used here are logical */ if (NoV6Mroute) { /* * the interface reply from IPv6 mrouting daemon */ NoV6Mroute = 0; } if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG, 0, "< IPv6 Mcast Daemon Interface Reply with %d vifs\n",rsrr_in->num); break;#endif /* USE_IPV6 */ default: return -1; } /* * Initialize permanent RSVP vif_list and gated_to_rsvpd * conversion table responsible for translating the interface * number used by gated to the one used by rsvpd. Gated has * different numbers and ordering of the interfaces, thus we * have to do one more step for conversion. */ if (first == 1) { /* * first time being called here, do the initialization, * so we don't do this again when rsrr_accept_ir_ux is * called for the second time. rsrr_accept_ir_ux would * be called twice if both IPv4 mrouted and IPv6 gated * are both running with RSRR support */ for (vf=0; vf< RSRR_MAX_VIFS_V2; vf++) { BIT_SET(vif_list[vf].status,RSRR_M_DISABLED_BIT); gated_to_rsvpd[vf] = -1; } first = 0; } switch (sock_type) { case RSRR_SOCK_V4UX: /* * IPv4 */ if (rsrr_use_v1_ipv4) { /* * RSRR v1 */ struct rsrrv1_vif *vifs; /* * skip over the RSRR header */ vifs = (struct rsrrv1_vif *)(rsrr_recv_buf+RSRR_HEADER_LEN); /* * loop through all the interfaces from the * interface reply */ for (vf = 0; vf < rsrr_in->num; vf++) { /* * loop through the if_vec[] table we kept */ for (i = 0; i < lnum; i++) { /* * Skip over API interface */ if (IsNumAPI(i)) continue; /* * Find a matching address from if_vec */ if (vifs[vf].local_addr.s_addr == NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&GET_IF(i))).s_addr) { /* * Build vif_list used by RSRR with * BobB's suggestion of correct value * for prefix */ vif_list[base+vf].id = vifs[vf].id; vif_list[base+vf].threshold = vifs[vf].threshold; vif_list[base+vf].prefix = 24; vif_list[base+vf].status = (u_char)vifs[vf].status; vif_list[base+vf].family = AF_INET; vif_list[base+vf].length = sizeof(struct in_addr); vif_list[base+vf].addr_v4.s_addr = vifs[vf].local_addr.s_addr; if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG, 0, "Configured vif %d with %s\n", vifs[vf].id, inet_fmt(vifs[vf].local_addr.s_addr,s1)); /* * append to end of if_vec[] */ strncpy(if_vec[if_num].if_name, if_vec[i].if_name, IFNAMSIZ); /* if_vec[if_num].if_index = if_vec[i].if_index; */ if_vec[if_num].if_index = vifs[vf].id; if_vec[if_num].if_unicast = i; if_vec[if_num].if_udpttl = if_vec[i].if_udpttl; if_vec[if_num].prefix = 24; if_vec[if_num].if_flags |= IF_FLAG_IFF_MC; if (BIT_TST(vifs[vf].status,RSRR_M_DISABLED_BIT)) if_vec[if_num].if_flags &= ~IF_FLAG_IFF_UP; else if_vec[if_num].if_flags |= IF_FLAG_IFF_UP; NET_SET_IF_VIF(&(if_vec[if_num].if_addr), NET_GET_IF_PHY_ADDR(&GET_IF(i)), vifs[vf].id); Clear_LL_Vector(if_num); if_num++; break; } } } if (i == if_num) { log(LOG_ERR, 0,"VIF config error\n"); return(-1); } } else { /* * Use RSRR v2 format */ struct rsrr_vif *vifs; /* * skip over the RSRR header */ vifs = (struct rsrr_vif *)(rsrr_recv_buf+RSRR_HEADER_LEN); /* * loop through all the interfaces from the * interface reply */ for (vf = 0; vf < rsrr_in->num; vf++) { /* * loop through the if_vec[] table we kept */ for (i = 0; i < lnum; i++) { /* * Skip over API interface */ if (IsNumAPI(i)) continue; if (vifs[vf].addr_v4.s_addr == NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&GET_IF(i))).s_addr) { vif_list[base+vf].id = vifs[vf].id; vif_list[base+vf].threshold = vifs[vf].threshold; vif_list[base+vf].prefix = vifs[vf].prefix; vif_list[base+vf].status = vifs[vf].status; vif_list[base+vf].family = vifs[vf].family; vif_list[base+vf].length = vifs[vf].length; vif_list[base+vf].addr_v4 = vifs[vf].addr_v4; if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG, 0, "Configured vif %d with %s\n", vifs[vf].id, inet_fmt(vifs[vf].addr_v4.s_addr,s1)); /* * append to end of if_vec */ strncpy(if_vec[if_num].if_name, if_vec[i].if_name, IFNAMSIZ); /* if_vec[if_num].if_index = if_vec[i].if_index; */ if_vec[if_num].if_index = vifs[vf].id; if_vec[if_num].if_unicast = i; if_vec[if_num].if_udpttl = if_vec[i].if_udpttl; if_vec[if_num].prefix = vifs[vf].prefix; if_vec[if_num].if_flags |= IF_FLAG_IFF_MC; if (BIT_TST(vifs[vf].status,RSRR_M_DISABLED_BIT)) if_vec[if_num].if_flags &= ~IF_FLAG_IFF_UP; else if_vec[if_num].if_flags |= IF_FLAG_IFF_UP; NET_SET_IF_VIF(&(if_vec[if_num].if_addr), NET_GET_IF_PHY_ADDR(&GET_IF(i)), vifs[vf].id); Clear_LL_Vector(if_num); if_num++; break; } } } } if (i == if_num) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -