📄 rsvp_netio.c
字号:
if (FAILED(send_pkt(udp_addr(to,encap_portp),src,data,len, mc,vif,encap_ttl,FALSE))) log(LOG_ERR,errno,"send_pkt"); return(mode + 1); } return(mode);}staticintsend_pkt(net_addr *to,net_addr *from,void *msg,int len, int mc,int infn,int hops,int ra){ net_addr src; net_if inf; if (from != NULL) { switch (NET_GET_TYPE(from)) { case NET_ADDR_IPv4: if (NET_GET_TYPE(to) == NET_ADDR_UDP_IPv4) { NET_SET_ADDR3_UDP_IPv4(&src, NET_GET_ADDR_IPv4(from), encap_port); from = &src; } break;#ifdef USE_IPV6 case NET_ADDR_IPv6: if (NET_GET_TYPE(to) == NET_ADDR_UDP_IPv6) { NET_SET_ADDR3_UDP_IPv6(&src, NET_GET_ADDR_IPv6(from), encap_port); from = &src; } break;#endif /* USE_IPV6 */ default: break; } } if (l_debug >= LOG_HEXD) { log(LOG_DEBUG, 0, "Output to %s\n", net_addr_print(to)); hexf(stderr, msg, len); } if (infn < 0) return(net_send(to,from,msg,len,NULL,hops,ra)); if (mc) inf = if_vec[infn].if_addr; else inf = if_vec[IF_UNICAST(infn)].if_addr; return(net_send(to,from,msg,len,&inf,hops,ra));}staticintIsLocal(net_addr *addr,int *mc){ int i,j; net_addr *x,*y; net_if *inf; struct in_addr a,b;#ifdef USE_IPV6 struct in6_addr c,d;#endif /* USE_IPV6 */ x = net_addr_ip(addr); *mc = FALSE; switch (NET_GET_TYPE(x)) { case NET_ADDR_IPv4: a = NET_GET_ADDR_IPv4(x); if (IN_IS_ADDR_MULTICAST(&a)) { *mc = TRUE; return(TRUE); } for (i = 0; i < if_num; i++) { if (IsNumAPI(i)) continue; if (IF_DOWN(i)) continue; inf = &GET_IF(i); if (NET_GET_TYPE(inf) != NET_IF_PHY) continue; y = &NET_GET_IF_PHY_ADDR(inf); if (NET_UNEQUAL_TYPE(x,y)) continue; b = NET_GET_ADDR_IPv4(y); for (j = if_vec[i].prefix;j < NBITS(a);j++) { BSET_CLR(j,&a); BSET_CLR(j,&b); } if (IN_ARE_ADDR_EQUAL(&a,&b)) return(TRUE); } break;#ifdef USE_IPV6 case NET_ADDR_IPv6: c = NET_GET_ADDR_IPv6(x); if (IN6_IS_ADDR_MULTICAST(&c)) { *mc = TRUE; return(TRUE); } for (i = 0; i < if_num; i++) { if (IsNumAPI(i)) continue; if (IF_DOWN(i)) continue; inf = &GET_IF(i); if (NET_GET_TYPE(inf) != NET_IF_PHY) continue; y = &NET_GET_IF_PHY_ADDR(inf); if (NET_UNEQUAL_TYPE(x,y)) continue; d = NET_GET_ADDR_IPv6(y); for (j = if_vec[i].prefix;j < NBITS(c);j++) { BSET_CLR(j,&c); BSET_CLR(j,&d); } if (IN6_ARE_ADDR_EQUAL(&c,&d)) return(TRUE); } break;#endif /* USE_IPV6 */ default: break; } return(FALSE);}staticnet_addr *encap_addr(net_addr *to){ switch (NET_GET_TYPE(to)) { case NET_ADDR_IPv4: case NET_ADDR_UDP_IPv4: return(&encap_mc_addr);#ifdef USE_IPV6 case NET_ADDR_IPv6: case NET_ADDR_UDP_IPv6: return(&encap_mc_addr6);#endif /* USE_IPV6 */ default: return(NULL); }}staticnet_addr *udp_addr(net_addr *to,int port){ static net_addr addr; switch (NET_GET_TYPE(to)) { case NET_ADDR_IPv4: NET_SET_ADDR3_UDP_IPv4(&addr, NET_GET_ADDR_IPv4(to),port); return(&addr); case NET_ADDR_UDP_IPv4: NET_SET_ADDR3_UDP_IPv4(&addr, NET_GET_ADDR_UDP_IPv4(to).sin_addr,port); return(&addr);#ifdef USE_IPV6 case NET_ADDR_IPv6: NET_SET_ADDR3_UDP_IPv6(&addr, NET_GET_ADDR_IPv6(to),port); return(&addr); case NET_ADDR_UDP_IPv6: NET_SET_ADDR3_UDP_IPv6(&addr, NET_GET_ADDR_UDP_IPv6(to).sin6_addr,port); return(&addr);#endif /* USE_IPV6 */ default: return(NULL); }}intrsvp_input(int fd){ int n; char msg[MAX_PKT + sizeof(struct ip)]; net_addr from; net_if inf; n = net_recv(&from,msg,sizeof(msg),&inf); if (n == 0) return(FALSE); if (FAILED(n)) { log(LOG_ERR,errno,"net_recv"); return(FALSE); } switch(NET_GET_TYPE(&from)) { case NET_ADDR_IPv4: raw_input_ipv4(&from,msg,n,&inf); break; case NET_ADDR_UDP_IPv4: case NET_ADDR_UDP_IPv6: udp_input(&from,msg,n,&inf); break;#ifdef USE_IPV6 case NET_ADDR_IPv6: raw_input_ipv6(&from,msg,n,&inf); break;#endif /* USE_IPV6 */ default: log(LOG_ERR,errno,"net_recv"); return(FALSE); } return(TRUE);}/* * raw_input(): receive an RSVP protocol message (protocol 46) */staticintraw_input_ipv4(net_addr *from,char *msg,int len,net_if *inf){ net_addr dst,src; struct ip *ip = (struct ip *) msg; int iphdrlen, ipdatalen; struct packet packet; struct { packet_map raw_map_base; union { SenderDesc Sender_list; /* For Path-like messages */ FlowDesc Resv_list; /* For Resv-like messages */ } raw_map_ext[MAX_FLWDS-1]; } map; #ifdef __alpha__ iphdrlen = (ip->ip_vhl & 0xf) << 2;#else iphdrlen = ip->ip_hl << 2;#endif#ifdef linux ipdatalen = ntoh16(ip->ip_len) - iphdrlen;#else /* linux */ ipdatalen = ip->ip_len;#endif /* linux */ if (iphdrlen + ipdatalen != len) { log(LOG_ERR, 0, "Packet length wrong", 0); return(-1); } packet.pkt_order = BO_NET; packet.pkt_len = ipdatalen; packet.pkt_data = (common_header *) &msg[iphdrlen]; packet.pkt_offset = 0; packet.pkt_map = (packet_map *) ↦ packet.pkt_flags = 0; packet.pkt_ttl = ip->ip_ttl; /* * If dest addr is multicast group, test for and drop the * packet if we sent it ourselves. This "accidental" loopback * can only happen if there is an application running on this * (router) node, which has joined this multicast group; then * multicast Path, etc messages send to vifs will be * received on socket using RSVP_ON. */ NET_SET_ADDR_IPv4(&dst,ip->ip_dst); if (IN_IS_ADDR_MULTICAST(&ip->ip_dst)) { NET_SET_ADDR_IPv4(&src,ip->ip_src); if (map_if_addr(&src) != -1) return(SYS_NOERROR); } /* Unicast dest in IP header: map into apparent local * interface number, to be sure it was for me. */ else if (map_if_addr(&dst) < 0) { /* * If the message type is not Path or PathTear or ResvConf and if * IP destination address does not match any of the * addresses of the local interfaces, then forward the * message to IP destination address and return. */ if (packet.pkt_data->rsvp_type != RSVP_PATH && packet.pkt_data->rsvp_type != RSVP_CONFIRM && packet.pkt_data->rsvp_type != RSVP_PATH_TEAR) { if (FAILED(net_send(&dst,NULL,&msg[iphdrlen],ipdatalen, NULL,ip->ip_ttl,FALSE))) { log(LOG_ERR,errno,"net_send"); return(SYS_ERROR); } return(SYS_NOERROR); } } /* * Call common routine to do initial processing of RSVP packet. */ return(consume_input(&packet, from, inf));}#ifdef USE_IPV6staticintraw_input_ipv6(net_addr *from,char *msg,int len,net_if *inf){ net_addr dst,src; struct ip6_hdr *ip = (struct ip6_hdr *) msg; int ipdatalen; int iphdrlen = sizeof(struct ip6_hdr); struct packet packet; struct { packet_map raw_map_base; union { SenderDesc Sender_list; /* For Path-like messages */ FlowDesc Resv_list; /* For Resv-like messages */ } raw_map_ext[MAX_FLWDS-1]; } map; ipdatalen = ip->ip6_plen; if (iphdrlen + ipdatalen != len) { log(LOG_ERR, 0, "Packet length wrong", 0); return(-1); } packet.pkt_order = BO_NET; packet.pkt_len = ipdatalen; packet.pkt_data = (common_header *) &msg[iphdrlen]; packet.pkt_offset = 0; packet.pkt_map = (packet_map *) ↦ packet.pkt_flags = 0; packet.pkt_ttl = ip->ip6_hlim; /* * If dest addr is multicast group, test for and drop the * packet if we sent it ourselves. This "accidental" loopback * can only happen if there is an application running on this * (router) node, which has joined this multicast group; then * multicast Path, etc messages send to vifs will be * received on socket using RSVP_ON. */ NET_SET_ADDR_IPv6(&dst,ip->ip6_dst); if (IN6_IS_ADDR_MULTICAST(&ip->ip6_dst)) { NET_SET_ADDR_IPv6(&src,ip->ip6_src); if (map_if_addr(&src) != -1) return(SYS_NOERROR); } /* Unicast dest in IP header: map into apparent local * interface number, to be sure it was for me. */ else if (map_if_addr(&dst) < 0) { /* * If the message type is not Path or PathTear or ResvConf and if * IP destination address does not match any of the * addresses of the local interfaces, then forward the * message to IP destination address and return. */ if (packet.pkt_data->rsvp_type != RSVP_PATH && packet.pkt_data->rsvp_type != RSVP_CONFIRM && packet.pkt_data->rsvp_type != RSVP_PATH_TEAR) { if (FAILED(net_send(&dst,NULL,&msg[iphdrlen],ipdatalen, NULL,ip->ip6_hlim,FALSE))) { log(LOG_ERR,errno,"net_send"); return(SYS_ERROR); } return(SYS_NOERROR); } } /* * Call common routine to do initial processing of RSVP packet. */ return(consume_input(&packet, from, inf));}#endif /* USE_IPV6 *//* * udp_input(): receive a UDP-encapsulated RSVP protocol message */staticintudp_input(net_addr *from,char *msg,int len,net_if *inf){ struct packet packet; struct { packet_map raw_map_base; union { SenderDesc Sender_list; /* For Path-like messages */ FlowDesc Resv_list; /* For Resv-like messages */ } raw_map_ext[MAX_FLWDS-1]; } map; packet.pkt_order = BO_NET; packet.pkt_len = len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -