nfs-ganesha 1.4
|
00001 /* 00002 * Functions to generate various addresses based on a CIDR 00003 */ 00004 #ifdef HAVE_CONFIG_H 00005 #include "config.h" 00006 #endif 00007 00008 #include <errno.h> 00009 #include <string.h> 00010 #include "../include/cidr.h" 00011 00012 00013 /* Create a network address */ 00014 CIDR * 00015 cidr_addr_network(const CIDR *addr) 00016 { 00017 int i, j; 00018 CIDR *toret; 00019 00020 /* Quick check */ 00021 if(addr==NULL) 00022 { 00023 errno = EFAULT; 00024 return(NULL); 00025 } 00026 00027 toret = cidr_alloc(); 00028 if(toret==NULL) 00029 return(NULL); /* Preserve errno */ 00030 toret->proto = addr->proto; 00031 00032 /* The netmask is the same */ 00033 memcpy(toret->mask, addr->mask, (16 * sizeof(toret->mask[0])) ); 00034 00035 /* Now just figure out the network address and spit it out */ 00036 for(i=0 ; i<=15 ; i++) 00037 { 00038 for(j=7 ; j>=0 ; j--) 00039 { 00040 /* If we're into host bits, hop out */ 00041 if( (addr->mask[i] & 1<<j) == 0) 00042 return(toret); 00043 00044 /* Else, copy this network bit */ 00045 toret->addr[i] |= (addr->addr[i] & 1<<j); 00046 } 00047 } 00048 00049 /* 00050 * We only get here on host (/32 or /128) addresses; shorter masks 00051 * return earlier. But it's as correct as can be to just say the 00052 * same here, so... 00053 */ 00054 return(toret); 00055 } 00056 00057 00058 /* And a broadcast */ 00059 CIDR * 00060 cidr_addr_broadcast(const CIDR *addr) 00061 { 00062 int i, j; 00063 CIDR *toret; 00064 00065 /* Quick check */ 00066 if(addr==NULL) 00067 { 00068 errno = EFAULT; 00069 return(NULL); 00070 } 00071 00072 toret = cidr_alloc(); 00073 if(toret==NULL) 00074 return(NULL); /* Preserve errno */ 00075 toret->proto = addr->proto; 00076 00077 /* The netmask is the same */ 00078 memcpy(toret->mask, addr->mask, (16 * sizeof(toret->mask[0])) ); 00079 00080 /* Copy all the network bits */ 00081 for(i=0 ; i<=15 ; i++) 00082 { 00083 for(j=7 ; j>=0 ; j--) 00084 { 00085 /* If we're into host bits, hop out */ 00086 if( (addr->mask[i] & 1<<j) == 0) 00087 goto post; 00088 00089 /* Else, copy this network bit */ 00090 toret->addr[i] |= (addr->addr[i] & 1<<j); 00091 00092 } 00093 } 00094 00095 post: 00096 /* Now set the remaining bits to 1 */ 00097 for( /* i */ ; i<=15 ; i++) 00098 { 00099 for( /* j */ ; j>=0 ; j--) 00100 toret->addr[i] |= (1<<j); 00101 00102 j=7; 00103 } 00104 00105 /* And send it back */ 00106 return(toret); 00107 } 00108 00109 00110 /* Get the first host in a CIDR block */ 00111 CIDR * 00112 cidr_addr_hostmin(const CIDR *addr) 00113 { 00114 CIDR *toret; 00115 00116 toret = cidr_addr_network(addr); 00117 if(toret==NULL) 00118 return(NULL); /* Preserve errno */ 00119 00120 toret->addr[15] |= 1; 00121 00122 return(toret); 00123 } 00124 00125 00126 /* Get the last host in a CIDR block */ 00127 CIDR * 00128 cidr_addr_hostmax(const CIDR *addr) 00129 { 00130 CIDR *toret; 00131 00132 toret = cidr_addr_broadcast(addr); 00133 if(toret==NULL) 00134 return(NULL); /* Preserve errno */ 00135 00136 toret->addr[15] &= 0xfe; 00137 00138 return(toret); 00139 }