/* 
 * $Id: idrp.c,v 1.3 1995/08/01 20:25:21 sjr Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#include "include.h"
#include "iso.h"
#include "idrp.h"
#include <stdio.h>
#include "md4global.h"	/* RSAREF globals and constants */
#include "md4.h"	/* md4-specific includes */

/* idrp.c 
 *
 * miscellaneous functions.  It may be appropriate to move some to other
 * locations.
 *	drop_packet - drop transmit packet for testing
 *	idrp_trace  - idrp trace function
 *	log_nm_event - log network management event 
 *	free_buffer - only for buffers allocated from task
 *		not for receive buffer, but I'm not sure about this
 * 	path_up(peer) - send all routes to new neighbor
 *	proto_to_family(proto) - ???
 * family_to_nlri_id    - family to nlri id conversion (pull later to idrp.c)
 *	idrp_send_dest_set(peer) - ??? I have NO idea!
 * 	set_rib_id(p_qos) -- now:  rib_id = idrp_mask; later - ???
 */ 
  
 
/*
 * Decide whether to drop a transmitted packet for fun. %%
 */
int 
drop_packet()
{
	int dropit = ((rand() % 10) == 0);
	if (dropit)
		trace_tf(idrp_trace_options, TR_NORMAL, 0, ("IDRP xmit packet dropped"));
	return(dropit);
}


/*
 * Trace an IDRP packet
 */
static void
idrp_trace(peer, comment, send_flag, pdu, length)
idrpPeer *peer;
char *comment;
int send_flag;
idrpPdu *pdu;
int length;
{
	trace_tf (idrp_trace_options, TR_NORMAL, 0, ("idrp_trace called"));
}



void log_nm_event(peer, type, value)
idrpPeer *peer;
int type;
int value;
{
	trace_tf(idrp_trace_options, TR_NORMAL, 0, 
		 ("IDRP mgmt event %s, peer %s, value %d",
		idrpManagementEvents[type], peer->name, value)); /* %% */
};


/*
 * Free a buffer
 */
void free_buffer(buf)
idrpBuffer *buf;
{
	idrp_mem_fit_free((void **) &buf->pdu_proto, buf->buf_len);
	IDRP_MEM_FIT_FREE(buf);
}


u_int
proto_to_nlri_id(type,len,proto)
char *type;
int  len;
u_char *proto;
{
int	i;

	NLRI_FAMILY_LOOP(i)
		{
		/* Note the NLRI protocol must be in 
		 * the same order as the NLRI family loop
		 * --- skh fix these two structures as one
	 	 * --- skh - also to get multi-length protocol
	 	 * ---- skh - value this will have to change 
		 * --- skh (3/15/93) 
	 	 */
 
		if (!bcmp((caddr_t) &idrp_nlri_proto_id[i].proto_type,(caddr_t)type,1))
			{
			if (!bcmp((caddr_t)&idrp_nlri_proto_id[i].proto_val,(caddr_t)proto,len))
				{
				return(i);
				}
			}
		} NLRI_FAMILY_LOOP_END;
	
	return(0);
}
	
u_int
proto_to_socktype(type,len,proto)
char *type;
int  len;
u_char *proto;
{
int i;
	NLRI_FAMILY_LOOP(i)
		{
		/* Note the NLRI protocol must be in 
		 * the same order as the NLRI family loop
		 * --- skh fix these two structures as one
	 	 * --- skh - also to get multi-length protocol
	 	 * ---- skh - value this will have to change 
		 * --- skh (3/15/93) 
	 	 */
 
		if (!bcmp((caddr_t) &idrp_nlri_proto_id[i].proto_type,(caddr_t)type,1))
			{
			if (!bcmp((caddr_t)&idrp_nlri_proto_id[i].proto_val,(caddr_t)proto,len))
				{
				return(nlri_family[i].family);
				}
			}
		} NLRI_FAMILY_LOOP_END;
	
	return(0);
}
	
u_int
family_to_nlri_id(family)
int	family;
{
int     i;

        NLRI_FAMILY_LOOP(i)
                {
                if (family == nlri_family[i].family)
                        {
                        return (nlri_family[i].nlri_id);
                        }
		} NLRI_FAMILY_LOOP_END

	return(0);
}

sockaddr_un *idrp_send_dest_set(peer)
idrpPeer *peer;
{
sockaddr_un	*p_dst;

	switch(peer->proto_sock)
		{
		case IDRP_PDU_PROTO_UDP:
		case IDRP_PDU_PROTO_IP_RAW:
			p_dst = peer->gw.gw_addr;
			break;

		case IDRP_PDU_PROTO_IDRP:
		case IDRP_PDU_PROTO_CLNP:
			p_dst = (sockaddr_un *) &peer->neighbor;
			break;
		}
	return(p_dst);
}
			
int
my_bis_peer(gw)
gw_entry *gw;
{
idrpPeer	*peer;

	IDRP_LIST(peer, idrp_peers)
		{
		if (&peer->gw == gw)
			{
			return(TRUE);
			}
		} IDRP_LIST_END;
	return(FALSE);
}	

/* 
 * Function: md4
 * Summary: Compute the 16-byte md4 digest of the buffer.
 * Author: jgs
 * Date: Mon Dec 07 12:47:00 1992
 * Notes:
 *   The md4 code can probably be tuned to be faster.  The code as included
 * is almost exactly the RFC 1320 code, which is said to sacrifice speed for
 * portability.  I have made few attempts to speed it up.
 */

u_char * 
md4 __PF3(buffer, u_char *,	/* buffer to be md4-digested */
	  length, u_int,	/* length of buffer in bytes */
	  digest, u_char *)	/* 16 bytes for md4 digest */
{
	MD4_CTX context;

	/* These all call functions in md4c.c, almost straight from RFC 1320 */
	MD4Init (&context);
	MD4Update(&context, buffer, length);
	MD4Final(digest, &context);

	return(digest);
}

/* set the RIB id; initially, use idrp_mask--later, use ??? */
int 
set_rib_id(p_qos)
idrp_distinguish_att *p_qos;
{
	p_qos->rib_id = (int) p_qos->idrp_mask;
	return(p_qos->rib_id);
}
