nfs-ganesha 1.4

cidr_addr.c

Go to the documentation of this file.
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 }