238 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
ip_lib.c
 | 
						|
 | 
						|
Copyright 1995 Philip Homburg
 | 
						|
*/
 | 
						|
 | 
						|
#include "inet.h"
 | 
						|
#include "buf.h"
 | 
						|
#include "event.h"
 | 
						|
#include "type.h"
 | 
						|
 | 
						|
#include "assert.h"
 | 
						|
#include "io.h"
 | 
						|
#include "ip_int.h"
 | 
						|
 | 
						|
THIS_FILE
 | 
						|
 | 
						|
PUBLIC ipaddr_t ip_get_netmask (hostaddr)
 | 
						|
ipaddr_t hostaddr;
 | 
						|
{
 | 
						|
	return ip_netmask(ip_nettype(hostaddr));
 | 
						|
}
 | 
						|
 | 
						|
PUBLIC int ip_chk_hdropt (opt, optlen)
 | 
						|
u8_t *opt;
 | 
						|
int optlen;
 | 
						|
{
 | 
						|
	int i, security_present= FALSE, lose_source_present= FALSE,
 | 
						|
		strict_source_present= FALSE, record_route_present= FALSE,
 | 
						|
		timestamp_present= FALSE;
 | 
						|
 | 
						|
	assert (!(optlen & 3));
 | 
						|
	i= 0;
 | 
						|
	while (i<optlen)
 | 
						|
	{
 | 
						|
		DBLOCK(2, printf("*opt= %d\n", *opt));
 | 
						|
 | 
						|
		switch (*opt)
 | 
						|
		{
 | 
						|
		case IP_OPT_EOL:	/* End of Option list */
 | 
						|
			return NW_OK;
 | 
						|
		case IP_OPT_NOP:	/* No Operation */
 | 
						|
			i++;
 | 
						|
			opt++;
 | 
						|
			break;
 | 
						|
		case IP_OPT_SEC:	/* Security */
 | 
						|
			if (security_present)
 | 
						|
				return EINVAL;
 | 
						|
			security_present= TRUE;
 | 
						|
			if (opt[1] != 11)
 | 
						|
				return EINVAL;
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		case IP_OPT_LSRR:	/* Lose Source and Record Route */
 | 
						|
			if (lose_source_present)
 | 
						|
			{
 | 
						|
				DBLOCK(1, printf("2nd lose soruce route\n"));
 | 
						|
				return EINVAL;
 | 
						|
			}
 | 
						|
			lose_source_present= TRUE;
 | 
						|
			if (opt[1]<3)
 | 
						|
			{
 | 
						|
				DBLOCK(1,
 | 
						|
				printf("wrong length in source route\n"));
 | 
						|
				return EINVAL;
 | 
						|
			}
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		case IP_OPT_SSRR:	/* Strict Source and Record Route */
 | 
						|
			if (strict_source_present)
 | 
						|
				return EINVAL;
 | 
						|
			strict_source_present= TRUE;
 | 
						|
			if (opt[1]<3)
 | 
						|
				return EINVAL;
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		case IP_OPT_RR:		/* Record Route */
 | 
						|
			if (record_route_present)
 | 
						|
				return EINVAL;
 | 
						|
			record_route_present= TRUE;
 | 
						|
			if (opt[1]<3)
 | 
						|
				return EINVAL;
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		case IP_OPT_TS:		/* Timestamp */
 | 
						|
			if (timestamp_present)
 | 
						|
				return EINVAL;
 | 
						|
			timestamp_present= TRUE;
 | 
						|
			if (opt[1] != 4)
 | 
						|
				return EINVAL;
 | 
						|
			switch (opt[3] & 0xff)
 | 
						|
			{
 | 
						|
			case 0:
 | 
						|
			case 1:
 | 
						|
			case 3:
 | 
						|
				break;
 | 
						|
			default:
 | 
						|
				return EINVAL;
 | 
						|
			}
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		case IP_OPT_RTRALT:
 | 
						|
			if (opt[1] != 4)
 | 
						|
				return EINVAL;
 | 
						|
			i += opt[1];
 | 
						|
			opt += opt[1];
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			return EINVAL;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (i > optlen)
 | 
						|
	{
 | 
						|
		DBLOCK(1, printf("option of wrong length\n"));
 | 
						|
		return EINVAL;
 | 
						|
	}
 | 
						|
	return NW_OK;
 | 
						|
}
 | 
						|
 | 
						|
PUBLIC void ip_print_frags(acc)
 | 
						|
acc_t *acc;
 | 
						|
{
 | 
						|
#if DEBUG
 | 
						|
	ip_hdr_t *ip_hdr;
 | 
						|
	int first;
 | 
						|
 | 
						|
	if (!acc)
 | 
						|
		printf("(null)");
 | 
						|
 | 
						|
	for (first= 1; acc; acc= acc->acc_ext_link, first= 0)
 | 
						|
	{
 | 
						|
assert (acc->acc_length >= IP_MIN_HDR_SIZE);
 | 
						|
		ip_hdr= (ip_hdr_t *)ptr2acc_data(acc);
 | 
						|
		if (first)
 | 
						|
		{
 | 
						|
			writeIpAddr(ip_hdr->ih_src);
 | 
						|
			printf(" > ");
 | 
						|
			writeIpAddr(ip_hdr->ih_dst);
 | 
						|
		}
 | 
						|
		printf(" {%x:%d@%d%c}", ntohs(ip_hdr->ih_id),
 | 
						|
			ntohs(ip_hdr->ih_length), 
 | 
						|
			(ntohs(ip_hdr->ih_flags_fragoff) & IH_FRAGOFF_MASK)*8,
 | 
						|
			(ntohs(ip_hdr->ih_flags_fragoff) & IH_MORE_FRAGS) ?
 | 
						|
			'+' : '\0');
 | 
						|
	}
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
PUBLIC ipaddr_t ip_get_ifaddr(port_nr)
 | 
						|
int port_nr;
 | 
						|
{
 | 
						|
	assert(port_nr >= 0 && port_nr < ip_conf_nr);
 | 
						|
 | 
						|
	return ip_port_table[port_nr].ip_ipaddr;
 | 
						|
}
 | 
						|
 | 
						|
PUBLIC nettype_t ip_nettype(ipaddr)
 | 
						|
ipaddr_t ipaddr;
 | 
						|
{
 | 
						|
	u8_t highbyte;
 | 
						|
	nettype_t nettype;
 | 
						|
 | 
						|
	ipaddr= ntohl(ipaddr);
 | 
						|
	highbyte= (ipaddr >> 24) & 0xff;
 | 
						|
	if (highbyte == 0)
 | 
						|
	{
 | 
						|
		if (ipaddr == 0)
 | 
						|
			nettype= IPNT_ZERO;
 | 
						|
		else
 | 
						|
			nettype= IPNT_MARTIAN;
 | 
						|
	}
 | 
						|
	else if (highbyte < 127)
 | 
						|
		nettype= IPNT_CLASS_A;
 | 
						|
	else if (highbyte == 127)
 | 
						|
		nettype= IPNT_LOCAL;
 | 
						|
	else if (highbyte < 192)
 | 
						|
		nettype= IPNT_CLASS_B;
 | 
						|
	else if (highbyte < 224)
 | 
						|
		nettype= IPNT_CLASS_C;
 | 
						|
	else if (highbyte < 240)
 | 
						|
		nettype= IPNT_CLASS_D;
 | 
						|
	else if (highbyte < 248)
 | 
						|
		nettype= IPNT_CLASS_E;
 | 
						|
	else if (highbyte < 255)
 | 
						|
		nettype= IPNT_MARTIAN;
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (ipaddr == (ipaddr_t)-1)
 | 
						|
			nettype= IPNT_BROADCAST;
 | 
						|
		else
 | 
						|
			nettype= IPNT_MARTIAN;
 | 
						|
	}
 | 
						|
	return nettype;
 | 
						|
}
 | 
						|
 | 
						|
PUBLIC ipaddr_t ip_netmask(nettype)
 | 
						|
nettype_t nettype;
 | 
						|
{
 | 
						|
	switch(nettype)
 | 
						|
	{
 | 
						|
	case IPNT_ZERO:		return HTONL(0x00000000);
 | 
						|
	case IPNT_CLASS_A:
 | 
						|
	case IPNT_LOCAL:	return HTONL(0xff000000);
 | 
						|
	case IPNT_CLASS_B:	return HTONL(0xffff0000);
 | 
						|
	case IPNT_CLASS_C:	return HTONL(0xffffff00);
 | 
						|
	default:		return HTONL(0xffffffff);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#if 0
 | 
						|
PUBLIC char *ip_nettoa(nettype)
 | 
						|
nettype_t nettype;
 | 
						|
{
 | 
						|
	switch(nettype)
 | 
						|
	{
 | 
						|
	case IPNT_ZERO:		return "zero";
 | 
						|
	case IPNT_CLASS_A:	return "class A";
 | 
						|
	case IPNT_LOCAL:	return "local";
 | 
						|
	case IPNT_CLASS_B:	return "class B";
 | 
						|
	case IPNT_CLASS_C:	return "class C";
 | 
						|
	case IPNT_CLASS_D:	return "class D";
 | 
						|
	case IPNT_CLASS_E:	return "class E";
 | 
						|
	case IPNT_MARTIAN:	return "martian";
 | 
						|
	case IPNT_BROADCAST:	return "broadcast";
 | 
						|
	default:		return "<unknown>";
 | 
						|
	}
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * $PchId: ip_lib.c,v 1.10 2002/06/08 21:35:52 philip Exp $
 | 
						|
 */
 |