📄 rsrr_rsrr.c
字号:
/* * @(#) $Id: rsrr_rsrr.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsrr_rsrr.c **************************** * * * RSRR: Routing Support for Resource Reservations * * * *****************************************************************//**************************************************************************** RSVPD -- ReSerVation Protocol Daemon USC Information Sciences Institute Marina del Rey, California RSRR written by: Daniel Zappala, April 1995 RSRR modified by: Jeff Kann, Oct 1997 Copyright (c) 1996 by the University of Southern California All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation in source and binary forms for any purpose and without fee is hereby granted, provided that both the above copyright notice and this permission notice appear in all copies. and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed in part by the University of Southern California, Information Sciences Institute. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about the suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Other copyrights might apply to parts of this software and are so noted when applicable.********************************************************************/#include "rsvp_daemon.h"#include <sys/stat.h>#include <errno.h>#define Clear_LL_Vector(n) memset(&if_vec[n].if_LLifv, 0, sizeof(LLDAL_calls_t))extern int errno;#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux)#include <net/if.h>#include <net/if.h>#include <net/if_dl.h>#include <net/route.h>#include <netinet/in.h>#endif /* PF_ROUTE */extern int rsrr_route_reply(u_long, net_addr *, net_addr *, u_short, bitmap *, int, u_char);/* * External Declarations */extern int unicast_init();extern char *bm_expand();extern PSB *Find_fPSB(Session *, SENDER_TEMPLATE *);extern int locate_LIH(unsigned int, net_addr *);extern int lnum;extern bitmap bmp_unicast;#ifndef HOST_ONLY/* * No RSRR code for HOST_ONLY */int seq;int shift; /* value to shift the vif returned by mrouted to inum in the if_vec[] *//* * RSRR definitions */struct rsrr_vif vif_list[RSRR_MAX_VIFS_V2]; /* RSVP vif list */int gated_to_rsvpd[RSRR_MAX_VIFS_V2]; /* table to convert interface from gated to the interface in rsvpd */int rsrr_socket; /* interface to reservation protocol */int rsrr_use_v1_ipv4 = -1; /* RSRR v1 being used for IPv4 */int rsrr_use_v2_ipv4 = -1; /* RSRR v2 being used for IPv4 */#ifdef USE_IPV6int rsrr_socket_v6; /* interface to reservation protocol */int rsrr_use_v1_ipv6 = 0; /* RSRR v1 never used for IPv6 */int rsrr_use_v2_ipv6 = 1; /* RSRR v2 should be used for IPv6 */#endif /* USE_IPV6 */#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux)extern int rskt; /* Routing socket */#endif /* PF_ROUTE */char rsrr_recv_buf[RSRR_MAX_LEN]; /* RSRR receive buffer */char rsrr_send_buf[RSRR_MAX_LEN]; /* RSRR send buffer */struct sockaddr_un serv_addr_v4; /* V4 Server address */struct sockaddr_un cli_addr_v4; /* V4 Client address */#ifdef USE_IPV6struct sockaddr_un serv_addr_v6; /* V6 Server address */struct sockaddr_un cli_addr_v6; /* V6 Client address */#endif /* USE_IPV6 */int clilen, servlen; /* Lengths *//* * External debugging definitions. */extern char *inet_fmt();#ifdef USE_IPV6extern char *ip6_sprintf();extern u_long ds_tobmp();extern unsigned int addr_toidx();#endifextern char s1[];extern char s2[];extern char s3[];extern char s4[];/* * Internal RSRR global variables. */struct rsrr_query_table *rsrr_qt[RSRR_QT_SIZE]; /* Query table */char s[2*RSRR_MAX_VIFS_V2];/* * Forward Declarations */void rsrr_init();int rsrr_read();int rsrr_send_iq();int rsrr_send_rq();int rsrr_send();int rsrr_send0();int rsrr_accept_ux();int rsrr_accept_rt();int rsrr_accept_ir_ux();int rsrr_accept_ir_rt();int rsrr_accept_rr_ux();int rsrr_accept_rr_rt();void rsrr_qt_init();u_long rsrr_qt_getid();void rsrr_qt_cache();struct rsrr_query_table *rsrr_qt_lookup();void rsrr_qt_delete();int resv_exist();void SetNotifyBit();rsrr_bmp * convert(rsrr_bmp *, rsrr_bmp *);#ifdef SOLARIS/* * Routing socket indicies */#define RTAX_DST 0#define RTAX_GATEWAY 1#define RTAX_NETMASK 2#define RTAX_GENMASK 3#define RTAX_IFP 4#define RTAX_IFA 5#define RTAX_AUTHOR 6#define RTAX_BRD 7#define RTAX_MAX 8#endif/* * Initialize RSRR socket */voidrsrr_init(){ struct stat sb; const char *check_v4 = RSRR_SERV_PATH;#ifdef USE_IPV6 const char *check_v6 = RSRR_SRV6_PATH;#endif /* USE_IPV6 */#ifdef __FreeBSD__ const char *mrd_v4 = "/var/run/mrouted.pid";#ifdef USE_IPV6 const char *mrd_v6 = "/var/run/gated.pid";#endif /* USE_IPV6 */#else const char *mrd_v4 = "/etc/mrouted.pid";#ifdef USE_IPV6 const char *mrd_v6 = "/var/run/gated.pid";#endif /* USE_IPV6 */#endif /* __FreeBSD__ */ /* * Routing sockets are initiated inside unicast_init() */ unicast_init(); /* * UNIX domain socket to talk to IPv4 mrouted */ if ((rsrr_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { log(LOG_ERR, errno, "Can't create RSRR V4 socket", 0); return; }#ifdef USE_IPV6 /* * UNIX domain socket to talk to IPv6 gated */ if ((rsrr_socket_v6 = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { log(LOG_ERR, errno, "Can't create RSRR V6 socket", 0); return; }#endif /* USE_IPV6 */ /* * Server's address. */ memset((char *) &serv_addr_v4, 0, sizeof(serv_addr_v4)); serv_addr_v4.sun_family = AF_UNIX; strcpy(serv_addr_v4.sun_path, RSRR_SERV_PATH);#ifdef USE_IPV6 memset((char *) &serv_addr_v6, 0, sizeof(serv_addr_v6)); serv_addr_v6.sun_family = AF_UNIX; strcpy(serv_addr_v6.sun_path, RSRR_SRV6_PATH);#endif /* USE_IPV6 *//* * Here we assume the path for v4 and v6 are of the same lengths */#ifdef STANDARD_C_LIBRARY servlen = (offsetof(struct sockaddr_un, sun_path) + strlen(serv_addr_v4.sun_path));#else servlen = sizeof(serv_addr_v4.sun_family)+strlen(serv_addr_v4.sun_path);#endif#ifdef SOCKADDR_LEN serv_addr_v4.sun_len = servlen;#ifdef USE_IPV6 serv_addr_v6.sun_len = servlen;#endif /* USE_IPV6 */#endif /* * Client's address. */ memset((char *) &cli_addr_v4, 0, sizeof(cli_addr_v4)); cli_addr_v4.sun_family = AF_UNIX; strcpy(cli_addr_v4.sun_path, RSRR_CLI_PATH);#ifdef USE_IPV6 memset((char *) &cli_addr_v6, 0, sizeof(cli_addr_v6)); cli_addr_v6.sun_family = AF_UNIX; strcpy(cli_addr_v6.sun_path, RSRR_CL6_PATH);#endif /* USE_IPV6 */#ifdef STANDARD_C_LIBRARY clilen = (offsetof(struct sockaddr_un, sun_path) + strlen(cli_addr_v4.sun_path));#else clilen = sizeof(cli_addr_v4.sun_family) + strlen(cli_addr_v4.sun_path);#endif#ifdef SOCKADDR_LEN cli_addr_v4.sun_len = clilen;#ifdef USE_IPV6 cli_addr_v6.sun_len = clilen;#endif /* USE_IPV6 */#endif /* * Remove on the off-chance that it was left around. */ unlink(cli_addr_v4.sun_path);#ifdef USE_IPV6 unlink(cli_addr_v6.sun_path);#endif /* USE_IPV6 */ /* * bind this socket to our address */ if (bind(rsrr_socket, (struct sockaddr *)&cli_addr_v4, clilen) < 0) { log(LOG_ERR, errno, "Can't bind RSRR V4 socket", 0); return; }#ifdef USE_IPV6 if (bind(rsrr_socket_v6, (struct sockaddr *)&cli_addr_v6, clilen) < 0) { log(LOG_ERR, errno, "Can't bind RSRR V6 socket", 0); return; }#endif /* USE_IPV6 */ /* * check if the mulitcast routing daemon is running or it * has support for rsrr */ if (stat(check_v4, &sb) == -1 && errno == ENOENT) { /* * error = No such file or directory * this means either IPv4 mrouted is not running or * it is running but it wasn't compiled with RSRR * support */ NoV4Mroute = 1; if (stat(mrd_v4, &sb) == -1) { /* * no pid info for mrouted pid, it's not running */ log(LOG_ERR,0,"IPv4 Multicast Daemon is not running\n"); } else { /* * it may be running without RSRR support or the * pid file was left around without being removed */ log(LOG_ERR,0,"IPv4 Multicast Daemon was killed or " "it does not support RSRR\n"); } } else NoV4Mroute = 0;#ifdef USE_IPV6 if (stat(check_v6, &sb) == -1 && errno == ENOENT) { /* * error = No such file or directory * this means either IPv6 gated is not running or * it is running but it wasn't compiled with RSRR * support */ NoV6Mroute = 1; if (stat(mrd_v6, &sb) == -1) { /* * no pid info for gated pid, it's not running */ log(LOG_ERR,0,"IPv6 Multicast Daemon is not running\n"); } else { /* * it may be running without RSRR support or the * pid file was left around without being removed */ log(LOG_ERR,0,"IPv6 Multicast Daemon was killed or " "it does not support RSRR\n"); } } else NoV6Mroute = 0;#endif /* USE_IPV6 */ /* * initialize the query table */ rsrr_qt_init();}/* * Read a message from the RSRR socket, and call rsrr_accept_xx to * process it. Return an error if the message is not of the type * specified. */intrsrr_read(sock_type, expected_type) u_char sock_type; u_char expected_type;{ int skt = -1; switch(sock_type) { case RSRR_SOCK_V4UX: /* * it's from IPv4 Unix domain socket */ skt = rsrr_socket; return rsrr_accept_ux(sock_type, skt, expected_type); break;#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux) case RSRR_SOCK_RT: /* * it's from Unix routing socket */ skt = rskt; return 0; break;#endif /* PF_ROUTE */#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * it's from IPv6 Unix domain socket */ skt = rsrr_socket_v6; return rsrr_accept_ux(sock_type, skt, expected_type);#endif /* USE_IPV6 */ default: log(LOG_ERR, errno, "Unknown socket to RSRR", 0); return(-1); }}/* * Send initial RSRR Interface Query message */intrsrr_send0(int sendlen) { int rv = 0; int error_v4 = 0;#ifdef USE_IPV6 int error_v6 = 0;#endif /* USE_IPV6 */ if (!NoV4Mroute) { /* * IPv4 mrouted is running, send it */ error_v4 = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0, (struct sockaddr *)&serv_addr_v4, servlen); }#ifdef USE_IPV6 if (!NoV6Mroute) { /* * IPv6 gated is running, send it */ error_v6 = sendto(rsrr_socket_v6, rsrr_send_buf, sendlen, 0, (struct sockaddr *)&serv_addr_v6, servlen); }#endif /* USE_IPV6 */ if (!NoV4Mroute) { if (error_v4 == ECONNREFUSED) { /* * IPv4 mrouted is running, but the connection was refused * reset NoV4Mroute to be true */ log(LOG_ERR,errno,"Connection refused on RSRR V4 socket",0); NoV4Mroute = 1; rv = -1; } else if (error_v4 < 0) { /* * other errors */ log(LOG_ERR,errno,"Sending initially on RSRR V4 socket",0); NoV4Mroute = 1; rv = -1; } }#ifdef USE_IPV6 if (!NoV6Mroute) { if (error_v6 == ECONNREFUSED) { /* * IPv6 gated is running, but the connection was refused * reset NoV6Mroute to be true */ log(LOG_ERR,errno,"Connection refused on RSRR V6 socket",0); NoV6Mroute = 1; rv = -1; } else if (error_v6 < 0) { /* * other errors */ log(LOG_ERR,errno,"Sending initially on RSRR V6 socket",0); NoV6Mroute = 1; rv = -1; } }#endif /* USE_IPV6 */ return rv;}/* * Send a RSRR message */intrsrr_send(type, sendlen) u_char type; int sendlen;{ int error; switch (type) { case RSRR_SOCK_V4UX: /* * send the message through IPv4 UNIX domain socket */ error = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0, (struct sockaddr *)&serv_addr_v4, servlen); if (error < 0) { log(LOG_ERR, errno, "Sending on RSRR V4 socket", 0); return -1; } if (error != sendlen) { log(LOG_ERR,0,"Sent only %d out of %d bytes on RSRR V4 socket\n", error, sendlen); return -1; } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: /* * send the message through IPv6 UNIX domain socket */ error = sendto(rsrr_socket_v6, rsrr_send_buf, sendlen, 0, (struct sockaddr *)&serv_addr_v6, servlen); if (error < 0) { log(LOG_ERR, errno, "Sending on RSRR V6 socket", 0); return -1; } if (error != sendlen) { log(LOG_ERR, 0, "Sent only %d out of %d bytes on RSRR V6 socket\n", error, sendlen); return -1; } break;#endif /* USE_IPV6 */ default: return -1; } return 0;}/* * Handling incoming packet from specific Unix domain socket * The packet should conform to RSRR message types (v1 or v2) */intrsrr_accept_ux(sock_type,skt,expected_type) u_char sock_type; int skt; u_char expected_type;{ register int rsrr_recvlen; int dummy = 0; struct rsrr_header *rsrr; /* * receive from socket */ rsrr_recvlen = recvfrom(skt, rsrr_recv_buf, sizeof(rsrr_recv_buf), 0, (struct sockaddr *) 0, &dummy); if (rsrr_recvlen < 0) { log(LOG_ERR, errno, "recvfrom", 0); return -1; } if (rsrr_recvlen < RSRR_HEADER_LEN) { /* * truncated packet */ log(LOG_ERR, 0, "Received RSRR packet of %d bytes, which is less than min size", rsrr_recvlen); return -1; } rsrr = (struct rsrr_header *) rsrr_recv_buf; /* * replied version beyond our max supported version * This shouldn't happen if application do as the draft specified */ if (rsrr->version > RSRR_MAX_VERSION) { log(LOG_ERR, 0, "Received RSRR packet version %d, which I don't understand", rsrr->version); return -1; } /* * Check if expected type is specified and force match if it is. */ if (expected_type != RSRR_ALL_TYPES && rsrr->type != expected_type) { log(LOG_ERR, 0, "Received RSRR packet of type %d, but I'm expecting type %d\n", rsrr->type, expected_type); return -1; } switch (rsrr->version) { case 1: /* * RSRR version 1 */ switch (rsrr->type) { case RSRR_INTERFACE_REPLY: /* * Interface Reply message type */ if (rsrr_recvlen < (RSRR_HEADER_LEN + rsrr->num * RSRRV1_VIF_LEN)) { log(LOG_ERR, 0, "Received Interface Reply of %d bytes, which is too small\n", rsrr_recvlen); break; } switch (sock_type) { case RSRR_SOCK_V4UX: /* * from IPv4 socket */ if (rsrr->version < RSRR_MAX_VERSION) { /* * we can handle this packet * since it's within the max * version we declared */ rsrr_use_v1_ipv4 = 1; rsrr_use_v2_ipv4 = 0; } else { /* * we can use our max supported * version */ rsrr_use_v1_ipv4 = 0; rsrr_use_v2_ipv4 = 1; } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -