2
* minor utilities for subnet-mask manipulation
3
* Copyright (C) 1998, 1999 Henry Spencer.
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>.
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.
15
* RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
20
#define ABITS 32 /* bits in an IPv4 address */
24
- goodmask - is this a good (^1*0*$) subnet mask?
25
* You are not expected to understand this. See Henry S. Warren Jr,
26
* "Functions realizable with word-parallel logical and two's-complement
27
* addition instructions", CACM 20.6 (June 1977), p.439.
33
unsigned long x = ntohl(mask.s_addr);
34
/* clear rightmost contiguous string of 1-bits */
35
# define CRCS1B(x) (((x|(x-1))+1)&x)
36
# define TOPBIT (1UL << 31)
38
/* either zero, or has one string of 1-bits which is left-justified */
39
if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
45
- masktobits - how many bits in this mask?
46
* The algorithm is essentially a binary search, but highly optimized
47
* for this particular task.
49
int /* -1 means !goodmask() */
53
unsigned long m = ntohl(mask.s_addr);
62
if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
66
if (m&(0x00ff0000UL<<1)) {
70
if (m&(0x0f000000UL<<1)) {
74
if (m&(0x30000000UL<<1)) {
78
if (m&(0x40000000UL<<1))
85
- bitstomask - return a mask with this many high bits on
91
struct in_addr result;
93
if (n > 0 && n <= ABITS)
94
result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
98
result.s_addr = 0; /* best error report we can do */