summaryrefslogtreecommitdiffstats
path: root/src/util/mask_addr.c
blob: 5ddd0ca0660dbfd994309e51b8b6c024484cf06d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*++
/* NAME
/*	mask_addr 3
/* SUMMARY
/*	address bit banging
/* SYNOPSIS
/*	#include <mask_addr.h>
/*
/*	void	mask_addr(addr_bytes, addr_byte_count, network_bits)
/*	unsigned char *addr_bytes;
/*	unsigned addr_byte_count;
/*	unsigned network_bits;
/* DESCRIPTION
/*	mask_addr() clears all the host bits in the specified
/*	address.  The code can handle addresses of any length,
/*	and bytes of any width.
/*
/*	Arguments:
/* .IP addr_bytes
/*	The network address in network byte order.
/* .IP addr_byte_count
/*	The network address length in bytes.
/* .IP network_bits
/*	The number of initial bits that will not be cleared.
/* DIAGNOSTICS
/*	Fatal errors: the number of network bits exceeds the address size.
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include <sys_defs.h>
#include <limits.h>			/* CHAR_BIT */

/* Utility library. */

#include <msg.h>
#include <mask_addr.h>

/* mask_addr - mask off a variable-length address */

void    mask_addr(unsigned char *addr_bytes,
		          unsigned addr_byte_count,
		          unsigned network_bits)
{
    unsigned char *p;

    if (network_bits > addr_byte_count * CHAR_BIT)
	msg_panic("mask_addr: address byte count %d too small for bit count %d",
		  addr_byte_count, network_bits);

    p = addr_bytes + network_bits / CHAR_BIT;
    network_bits %= CHAR_BIT;

    if (network_bits != 0)
	*p++ &= ~0U << (CHAR_BIT - network_bits);

    while (p < addr_bytes + addr_byte_count)
	*p++ = 0;
}