nfs-ganesha 1.4
|
00001 /* 00002 * Various comparison functions 00003 */ 00004 #ifdef HAVE_CONFIG_H 00005 #include "config.h" 00006 #endif 00007 00008 #include <errno.h> 00009 #include <stdio.h> /* For NULL */ 00010 00011 #include "../include/cidr.h" 00012 00013 00014 /* Is one block entirely contained in another? */ 00015 int 00016 cidr_contains(const CIDR *big, const CIDR *little) 00017 { 00018 int i, oct, bit; 00019 int pflen; 00020 00021 /* Sanity */ 00022 if(big==NULL || little==NULL) 00023 { 00024 errno = EFAULT; 00025 return(-1); 00026 } 00027 00028 /* First off, they better be the same type */ 00029 if(big->proto != little->proto) 00030 { 00031 errno = EPROTO; 00032 return(-1); 00033 } 00034 00035 /* We better understand the protocol, too */ 00036 if(big->proto!=CIDR_IPV4 && big->proto!=CIDR_IPV6) 00037 { 00038 errno = EINVAL; 00039 return(-1); 00040 } 00041 00042 /* 00043 * little better be SMALL enough to fit in big. Note: The prefix 00044 * lengths CAN be the same, and little could still 'fit' in big if 00045 * the network bits are all the same. No need to special-case it, as 00046 * the normal tests below will DTRT. Save big's pflen for the test 00047 * loop. 00048 */ 00049 if(cidr_get_pflen(little) < (pflen = cidr_get_pflen(big))) 00050 { 00051 errno = 0; 00052 return(-1); 00053 } 00054 00055 /* 00056 * Now let's compare. Note that for IPv4 addresses, the first 12 00057 * octets are irrelevant. We take care throughout to keep them 00058 * zero'd out, so we don't _need_ to explicitly ignore them. But, 00059 * it's wasteful; it quadrules the amount of work needed to be done 00060 * to compare to v4 blocks, and this function may be useful in fairly 00061 * performance-sensitive parts of the application. Sure, an extra 12 00062 * uint8_t compares better not be the make-or-break perforamnce point 00063 * for anything real, but why make it harder unnecessarily? 00064 */ 00065 if(big->proto==CIDR_IPV4) 00066 { 00067 i = 96; 00068 pflen += 96; 00069 } 00070 else if(big->proto==CIDR_IPV6) 00071 i = 0; 00072 else 00073 { 00074 /* Shouldn't happen */ 00075 errno = ENOENT; /* This is a really bad choice of errno */ 00076 return(-1); 00077 } 00078 00079 /* Start comparing */ 00080 for( /* i */ ; i < pflen ; i++ ) 00081 { 00082 /* For convenience, set temp. vars to the octet/bit */ 00083 oct = i/8; 00084 bit = 7-(i%8); 00085 00086 if((big->addr[oct] & (1<<bit)) != (little->addr[oct] & (1<<bit))) 00087 { 00088 errno = 0; 00089 return(-1); 00090 } 00091 } 00092 00093 /* If we get here, all their network bits are the same */ 00094 return(0); 00095 } 00096 00097 00098 /* Are two CIDR's the same? */ 00099 int 00100 cidr_equals(const CIDR *one, const CIDR *two) 00101 { 00102 int i; 00103 00104 /* Check protocols */ 00105 if(one->proto != two->proto) 00106 return(-1); 00107 00108 /* Check addresses/masks */ 00109 if(one->proto==CIDR_IPV4) 00110 i = 12; 00111 else 00112 i = 0; 00113 for(/* i */ ; i<=15 ; i++) 00114 { 00115 if(one->addr[i] != two->addr[i]) 00116 return(-1); 00117 if(one->mask[i] != two->mask[i]) 00118 return(-1); 00119 } 00120 00121 /* If we make it here, they're the same */ 00122 return(0); 00123 }