aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/mrouted/rsrr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/mrouted/rsrr.c')
-rw-r--r--usr.sbin/mrouted/rsrr.c485
1 files changed, 0 insertions, 485 deletions
diff --git a/usr.sbin/mrouted/rsrr.c b/usr.sbin/mrouted/rsrr.c
deleted file mode 100644
index 86d6e6eaf438..000000000000
--- a/usr.sbin/mrouted/rsrr.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (c) 1993 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 non-commercial purposes
- * and without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both the copyright notice and
- * this permission notice appear in supporting documentation. and that
- * any documentation, advertising materials, and other materials related
- * to such distribution and use acknowledge that the software was
- * developed 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.
- */
-
-/* RSRR code written by Daniel Zappala, USC Information Sciences Institute,
- * April 1995.
- */
-
-/* May 1995 -- Added support for Route Change Notification */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#ifdef RSRR
-
-#include "defs.h"
-#include <sys/param.h>
-#ifdef HAVE_SA_LEN
-#include <stddef.h> /* for offsetof */
-#endif
-
-/*
- * Exported variables.
- */
-int rsrr_socket; /* interface to reservation protocol */
-
-/*
- * Global RSRR variables.
- */
-char rsrr_recv_buf[RSRR_MAX_LEN]; /* RSRR receive buffer */
-char rsrr_send_buf[RSRR_MAX_LEN]; /* RSRR send buffer */
-
-struct sockaddr_un client_addr;
-int client_length = sizeof(client_addr);
-
-
-/*
- * Procedure definitions needed internally.
- */
-static void rsrr_accept __P((int recvlen));
-static void rsrr_accept_iq __P((void));
-static int rsrr_accept_rq __P((struct rsrr_rq *route_query, int flags,
- struct gtable *gt_notify));
-static void rsrr_read __P((int, fd_set *));
-static int rsrr_send __P((int sendlen));
-static void rsrr_cache __P((struct gtable *gt,
- struct rsrr_rq *route_query));
-
-/* Initialize RSRR socket */
-void
-rsrr_init()
-{
- int servlen;
- struct sockaddr_un serv_addr;
-
- if ((rsrr_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
- log(LOG_ERR, errno, "Can't create RSRR socket");
-
- unlink(RSRR_SERV_PATH);
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sun_family = AF_UNIX;
- strcpy(serv_addr.sun_path, RSRR_SERV_PATH);
-#ifdef HAVE_SA_LEN
- servlen = offsetof(struct sockaddr_un, sun_path) +
- strlen(serv_addr.sun_path);
- serv_addr.sun_len = servlen;
-#else
- servlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
-#endif
-
- if (bind(rsrr_socket, (struct sockaddr *) &serv_addr, servlen) < 0)
- log(LOG_ERR, errno, "Can't bind RSRR socket");
-
- if (register_input_handler(rsrr_socket, rsrr_read) < 0)
- log(LOG_WARNING, 0, "Couldn't register RSRR as an input handler");
-}
-
-/* Read a message from the RSRR socket */
-static void
-rsrr_read(f, rfd)
- int f;
- fd_set *rfd;
-{
- register int rsrr_recvlen;
-
- bzero((char *) &client_addr, sizeof(client_addr));
- rsrr_recvlen = recvfrom(rsrr_socket, rsrr_recv_buf, sizeof(rsrr_recv_buf),
- 0, (struct sockaddr *)&client_addr, &client_length);
- if (rsrr_recvlen < 0) {
- if (errno != EINTR)
- log(LOG_ERR, errno, "RSRR recvfrom");
- return;
- }
- rsrr_accept(rsrr_recvlen);
-}
-
-/* Accept a message from the reservation protocol and take
- * appropriate action.
- */
-static void
-rsrr_accept(recvlen)
- int recvlen;
-{
- struct rsrr_header *rsrr;
- struct rsrr_rq *route_query;
-
- if (recvlen < RSRR_HEADER_LEN) {
- log(LOG_WARNING, 0,
- "Received RSRR packet of %d bytes, which is less than min size",
- recvlen);
- return;
- }
-
- rsrr = (struct rsrr_header *) rsrr_recv_buf;
-
- if (rsrr->version > RSRR_MAX_VERSION) {
- log(LOG_WARNING, 0,
- "Received RSRR packet version %d, which I don't understand",
- rsrr->version);
- return;
- }
-
- switch (rsrr->version) {
- case 1:
- switch (rsrr->type) {
- case RSRR_INITIAL_QUERY:
- /* Send Initial Reply to client */
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "Received Initial Query\n");
- rsrr_accept_iq();
- break;
- case RSRR_ROUTE_QUERY:
- /* Check size */
- if (recvlen < RSRR_RQ_LEN) {
- log(LOG_WARNING, 0,
- "Received Route Query of %d bytes, which is too small",
- recvlen);
- break;
- }
- /* Get the query */
- route_query = (struct rsrr_rq *) (rsrr_recv_buf + RSRR_HEADER_LEN);
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0,
- "Received Route Query for src %s grp %s notification %d",
- inet_fmt(route_query->source_addr.s_addr, s1),
- inet_fmt(route_query->dest_addr.s_addr,s2),
- BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));
- /* Send Route Reply to client */
- rsrr_accept_rq(route_query,rsrr->flags,NULL);
- break;
- default:
- log(LOG_WARNING, 0,
- "Received RSRR packet type %d, which I don't handle",
- rsrr->type);
- break;
- }
- break;
-
- default:
- log(LOG_WARNING, 0,
- "Received RSRR packet version %d, which I don't understand",
- rsrr->version);
- break;
- }
-}
-
-/* Send an Initial Reply to the reservation protocol. */
-static void
-rsrr_accept_iq()
-{
- struct rsrr_header *rsrr;
- struct rsrr_vif *vif_list;
- struct uvif *v;
- int vifi, sendlen;
-
- /* Check for space. There should be room for plenty of vifs,
- * but we should check anyway.
- */
- if (numvifs > RSRR_MAX_VIFS) {
- log(LOG_WARNING, 0,
- "Can't send RSRR Route Reply because %d is too many vifs",
- numvifs);
- return;
- }
-
- /* Set up message */
- rsrr = (struct rsrr_header *) rsrr_send_buf;
- rsrr->version = 1;
- rsrr->type = RSRR_INITIAL_REPLY;
- rsrr->flags = 0;
- rsrr->num = numvifs;
-
- vif_list = (struct rsrr_vif *) (rsrr_send_buf + RSRR_HEADER_LEN);
-
- /* Include the vif list. */
- for (vifi=0, v = uvifs; vifi < numvifs; vifi++, v++) {
- vif_list[vifi].id = vifi;
- vif_list[vifi].status = 0;
- if (v->uv_flags & VIFF_DISABLED)
- BIT_SET(vif_list[vifi].status,RSRR_DISABLED_BIT);
- vif_list[vifi].threshold = v->uv_threshold;
- vif_list[vifi].local_addr.s_addr = v->uv_lcl_addr;
- }
-
- /* Get the size. */
- sendlen = RSRR_HEADER_LEN + numvifs*RSRR_VIF_LEN;
-
- /* Send it. */
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "Send RSRR Initial Reply");
- rsrr_send(sendlen);
-}
-
-/* Send a Route Reply to the reservation protocol. The Route Query
- * contains the query to which we are responding. The flags contain
- * the incoming flags from the query or, for route change
- * notification, the flags that should be set for the reply. The
- * kernel table entry contains the routing info to use for a route
- * change notification.
- */
-static int
-rsrr_accept_rq(route_query,flags,gt_notify)
- struct rsrr_rq *route_query;
- int flags;
- struct gtable *gt_notify;
-{
- struct rsrr_header *rsrr;
- struct rsrr_rr *route_reply;
- struct gtable *gt,local_g;
- struct rtentry *r;
- int sendlen;
- u_long mcastgrp;
-
- /* Set up message */
- rsrr = (struct rsrr_header *) rsrr_send_buf;
- rsrr->version = 1;
- rsrr->type = RSRR_ROUTE_REPLY;
- rsrr->flags = 0;
- rsrr->num = 0;
-
- route_reply = (struct rsrr_rr *) (rsrr_send_buf + RSRR_HEADER_LEN);
- route_reply->dest_addr.s_addr = route_query->dest_addr.s_addr;
- route_reply->source_addr.s_addr = route_query->source_addr.s_addr;
- route_reply->query_id = route_query->query_id;
-
- /* Blank routing entry for error. */
- route_reply->in_vif = 0;
- route_reply->reserved = 0;
- route_reply->out_vif_bm = 0;
-
- /* Get the size. */
- sendlen = RSRR_RR_LEN;
-
- /* If kernel table entry is defined, then we are sending a Route Reply
- * due to a Route Change Notification event. Use the kernel table entry
- * to supply the routing info.
- */
- if (gt_notify) {
- /* Set flags */
- rsrr->flags = flags;
- /* Include the routing entry. */
- route_reply->in_vif = gt_notify->gt_route->rt_parent;
- if (BIT_TST(flags,RSRR_NOTIFICATION_BIT))
- route_reply->out_vif_bm = gt_notify->gt_grpmems;
- else
- route_reply->out_vif_bm = 0;
- } else if (find_src_grp(route_query->source_addr.s_addr, 0,
- route_query->dest_addr.s_addr)) {
-
- /* Found kernel entry. Code taken from add_table_entry() */
- gt = gtp ? gtp->gt_gnext : kernel_table;
-
- /* Include the routing entry. */
- route_reply->in_vif = gt->gt_route->rt_parent;
- route_reply->out_vif_bm = gt->gt_grpmems;
-
- /* Cache reply if using route change notification. */
- if BIT_TST(flags,RSRR_NOTIFICATION_BIT) {
- rsrr_cache(gt,route_query);
- BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT);
- }
-
- } else {
- /* No kernel entry; use routing table. */
- r = determine_route(route_query->source_addr.s_addr);
-
- if (r != NULL) {
- /* We need to mimic what will happen if a data packet
- * is forwarded by multicast routing -- the kernel will
- * make an upcall and mrouted will install a route in the kernel.
- * Our outgoing vif bitmap should reflect what that table
- * will look like. Grab code from add_table_entry().
- * This is gross, but it's probably better to be accurate.
- */
-
- gt = &local_g;
- mcastgrp = route_query->dest_addr.s_addr;
-
- gt->gt_mcastgrp = mcastgrp;
- gt->gt_grpmems = 0;
- gt->gt_scope = 0;
- gt->gt_route = r;
-
- /* obtain the multicast group membership list */
- determine_forwvifs(gt);
-
- /* Include the routing entry. */
- route_reply->in_vif = gt->gt_route->rt_parent;
- route_reply->out_vif_bm = gt->gt_grpmems;
-
- } else {
- /* Set error bit. */
- BIT_SET(rsrr->flags,RSRR_ERROR_BIT);
- }
- }
-
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "%sSend RSRR Route Reply for src %s dst %s in vif %d out vif %d\n",
- gt_notify ? "Route Change: " : "",
- inet_fmt(route_reply->source_addr.s_addr,s1),
- inet_fmt(route_reply->dest_addr.s_addr,s2),
- route_reply->in_vif,route_reply->out_vif_bm);
-
- /* Send it. */
- return rsrr_send(sendlen);
-}
-
-/* Send an RSRR message. */
-static int
-rsrr_send(sendlen)
- int sendlen;
-{
- int error;
-
- /* Send it. */
- error = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0,
- (struct sockaddr *)&client_addr, client_length);
-
- /* Check for errors. */
- if (error < 0) {
- log(LOG_WARNING, errno, "Failed send on RSRR socket");
- } else if (error != sendlen) {
- log(LOG_WARNING, 0,
- "Sent only %d out of %d bytes on RSRR socket\n", error, sendlen);
- }
- return error;
-}
-
-/* Cache a message being sent to a client. Currently only used for
- * caching Route Reply messages for route change notification.
- */
-static void
-rsrr_cache(gt,route_query)
- struct gtable *gt;
- struct rsrr_rq *route_query;
-{
- struct rsrr_cache *rc, **rcnp;
- struct rsrr_header *rsrr;
-
- rsrr = (struct rsrr_header *) rsrr_send_buf;
-
- rcnp = &gt->gt_rsrr_cache;
- while ((rc = *rcnp) != NULL) {
- if ((rc->route_query.source_addr.s_addr ==
- route_query->source_addr.s_addr) &&
- (rc->route_query.dest_addr.s_addr ==
- route_query->dest_addr.s_addr) &&
- (!strcmp(rc->client_addr.sun_path,client_addr.sun_path))) {
- /* Cache entry already exists.
- * Check if route notification bit has been cleared.
- */
- if (!BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) {
- /* Delete cache entry. */
- *rcnp = rc->next;
- free(rc);
- } else {
- /* Update */
- rc->route_query.query_id = route_query->query_id;
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0,
- "Update cached query id %ld from client %s\n",
- rc->route_query.query_id, rc->client_addr.sun_path);
- }
- return;
- }
- rcnp = &rc->next;
- }
-
- /* Cache entry doesn't already exist. Create one and insert at
- * front of list.
- */
- rc = (struct rsrr_cache *) malloc(sizeof(struct rsrr_cache));
- if (rc == NULL)
- log(LOG_ERR, 0, "ran out of memory");
- rc->route_query.source_addr.s_addr = route_query->source_addr.s_addr;
- rc->route_query.dest_addr.s_addr = route_query->dest_addr.s_addr;
- rc->route_query.query_id = route_query->query_id;
- strcpy(rc->client_addr.sun_path, client_addr.sun_path);
- rc->client_length = client_length;
- rc->next = gt->gt_rsrr_cache;
- gt->gt_rsrr_cache = rc;
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "Cached query id %ld from client %s\n",
- rc->route_query.query_id,rc->client_addr.sun_path);
-}
-
-/* Send all the messages in the cache. Currently this is used to send
- * all the cached Route Reply messages for route change notification.
- */
-void
-rsrr_cache_send(gt,notify)
- struct gtable *gt;
- int notify;
-{
- struct rsrr_cache *rc, **rcnp;
- int flags = 0;
-
- if (notify)
- BIT_SET(flags,RSRR_NOTIFICATION_BIT);
-
- rcnp = &gt->gt_rsrr_cache;
- while ((rc = *rcnp) != NULL) {
- if (rsrr_accept_rq(&rc->route_query,flags,gt) < 0) {
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "Deleting cached query id %ld from client %s\n",
- rc->route_query.query_id,rc->client_addr.sun_path);
- /* Delete cache entry. */
- *rcnp = rc->next;
- free(rc);
- } else {
- rcnp = &rc->next;
- }
- }
-}
-
-/* Clean the cache by deleting all entries. */
-void
-rsrr_cache_clean(gt)
- struct gtable *gt;
-{
- struct rsrr_cache *rc,*rc_next;
-
- IF_DEBUG(DEBUG_RSRR)
- log(LOG_DEBUG, 0, "cleaning cache for group %s\n",
- inet_fmt(gt->gt_mcastgrp, s1));
- rc = gt->gt_rsrr_cache;
- while (rc) {
- rc_next = rc->next;
- free(rc);
- rc = rc_next;
- }
- gt->gt_rsrr_cache = NULL;
-}
-
-void
-rsrr_clean()
-{
- unlink(RSRR_SERV_PATH);
-}
-
-#endif /* RSRR */