OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / initsubnet.c
1 /*
2  * initialize subnet structure
3  * Copyright (C) 2000, 2002  Henry Spencer.
4  * 
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Library General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9  * 
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13  * License for more details.
14  *
15  * RCSID $Id: initsubnet.c,v 1.6 2002/03/12 16:50:46 henry Exp $
16  */
17 #include "internal.h"
18 #include "freeswan.h"
19
20 /*
21  - initsubnet - initialize ip_subnet from address and count
22  *
23  * The only hard part is checking for host-part bits turned on.
24  */
25 err_t                           /* NULL for success, else string literal */
26 initsubnet(addr, count, clash, dst)
27 const ip_address *addr;
28 int count;
29 int clash;                      /* '0' zero host-part bits, 'x' die on them */
30 ip_subnet *dst;
31 {
32         unsigned char *p;
33         int n;
34         int c;
35         unsigned m;
36         int die;
37
38         dst->addr = *addr;
39         n = addrbytesptr(&dst->addr, (const unsigned char **)&p);
40         if (n == 0)
41                 return "unknown address family";
42
43         switch (clash) {
44         case '0':
45                 die = 0;
46                 break;
47         case 'x':
48                 die = 1;
49                 break;
50         default:
51                 return "unknown clash-control value in initsubnet";
52                 break;
53         }
54
55         c = count / 8;
56         if (c > n)
57                 return "impossible mask count";
58         p += c;
59         n -= c;
60
61         m = 0xff;
62         c = count % 8;
63         if (n > 0 && c != 0)    /* partial byte */
64                 m >>= c;
65         for (; n > 0; n--) {
66                 if ((*p & m) != 0) {
67                         if (die)
68                                 return "improper subnet, host-part bits on";
69                         *p &= ~m;
70                 }
71                 m = 0xff;
72                 p++;
73         }
74
75         dst->maskbits = count;
76         return NULL;
77 }
78
79 /*
80  - addrtosubnet - initialize ip_subnet from a single address
81  */
82 err_t                           /* NULL for success, else string literal */
83 addrtosubnet(addr, dst)
84 const ip_address *addr;
85 ip_subnet *dst;
86 {
87         int n;
88
89         dst->addr = *addr;
90         n = addrbytesptr(&dst->addr, (const unsigned char **)NULL);
91         if (n == 0)
92                 return "unknown address family";
93         dst->maskbits = n*8;
94         return NULL;
95 }