1#include <sys/types.h> 2#include <sys/param.h> 3#include <sys/socket.h> 4#include <sys/cmn_err.h> 5#include <sys/kmem.h> 6#include <net/route.h> 7#include <netatalk/at.h> 8#include <errno.h> 9 10#include "rt.h" 11 12struct rtab { 13 struct rtab *r_next, *r_prev; 14 struct sockaddr_at r_dst; 15 struct sockaddr_at r_gate; 16}; 17 18static struct rtab *rt_net = NULL; 19static struct rtab *rt_host = NULL; 20 21 int 22rt_add( struct sockaddr_at *dst, struct sockaddr_at *gate, int flags ) 23{ 24 struct rtab *r; 25 struct rtab *rtab; 26 27 if ( flags & RTF_HOST ) { 28 rtab = rt_host; 29 } else { 30 rtab = rt_net; 31 } 32 for ( r = rtab; r != NULL; r = r->r_next ) { 33 if (( r->r_dst.sat_addr.s_net == dst->sat_addr.s_net ) && 34 (( flags & RTF_HOST ) ? 35 r->r_dst.sat_addr.s_node == dst->sat_addr.s_node : 1 )) { 36 return( EEXIST ); 37 } 38 } 39 40 if (( r = kmem_alloc( sizeof( struct rtab ), KM_NOSLEEP )) == NULL ) { 41 return( ENOMEM ); 42 } 43 r->r_dst = *dst; 44 r->r_gate = *gate; 45 46 r->r_prev = NULL; 47 r->r_next = rtab; 48 if ( rtab != NULL ) { 49 rtab->r_prev = r; 50 } 51 if ( flags & RTF_HOST ) { 52 rt_host = r; 53 } else { 54 rt_net = r; 55 } 56 return( 0 ); 57} 58 59 int 60rt_del( struct sockaddr_at *dst, struct sockaddr_at *gate, int flags ) 61{ 62 struct rtab *r; 63 struct rtab *rtab; 64 65 if ( flags & RTF_HOST ) { 66 rtab = rt_host; 67 } else { 68 rtab = rt_net; 69 } 70 for ( r = rtab; r != NULL; r = r->r_next ) { 71 if (( r->r_dst.sat_addr.s_net == dst->sat_addr.s_net ) && 72 (( flags & RTF_HOST ) ? 73 r->r_dst.sat_addr.s_node == dst->sat_addr.s_node : 1 )) { 74 break; 75 } 76 } 77 if ( r == NULL ) { 78 return( ESRCH ); 79 } 80 81 if ( r == rtab ) { 82 if ( flags & RTF_HOST ) { 83 rt_host = r->r_next; 84 } else { 85 rt_net = r->r_next; 86 } 87 } 88 if ( r->r_next != NULL ) { 89 r->r_next->r_prev = r->r_prev; 90 } 91 if ( r->r_prev != NULL ) { 92 r->r_prev->r_next = r->r_next; 93 } 94 kmem_free( r, sizeof( struct rtab )); 95 return( 0 ); 96} 97 98 int 99rt_gate( struct sockaddr_at *dst, struct sockaddr_at *gate ) 100{ 101 struct rtab *r; 102 103 for ( r = rt_host; r != NULL; r = r->r_next ) { 104 if ( r->r_dst.sat_addr.s_net == dst->sat_addr.s_net && 105 r->r_dst.sat_addr.s_node == dst->sat_addr.s_node ) { 106 break; 107 } 108 } 109 if ( r != NULL ) { 110 *gate = r->r_gate; 111 return( 0 ); 112 } 113 114 for ( r = rt_net; r != NULL; r = r->r_next ) { 115 if ( r->r_dst.sat_addr.s_net == dst->sat_addr.s_net ) { 116 break; 117 } 118 } 119 if ( r == NULL ) { 120 return( -1 ); 121 } 122 123 *gate = r->r_gate; 124 return( 0 ); 125} 126