#include <sys_defs.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef IN_CLASSD_NET
#define IN_CLASSD_NET 0xf0000000
#define IN_CLASSD_NSHIFT 28
#endif
#define BITS_PER_ADDR 32
#include <msg.h>
#include <vstring.h>
#include <inet_addr_list.h>
#include <name_mask.h>
#include <own_inet_addr.h>
#include <mail_params.h>
#include <mynetworks.h>
#define MASK_STYLE_CLASS (1 << 0)
#define MASK_STYLE_SUBNET (1 << 1)
#define MASK_STYLE_HOST (1 << 2)
static NAME_MASK mask_styles[] = {
MYNETWORKS_STYLE_CLASS, MASK_STYLE_CLASS,
MYNETWORKS_STYLE_SUBNET, MASK_STYLE_SUBNET,
MYNETWORKS_STYLE_HOST, MASK_STYLE_HOST,
0,
};
const char *mynetworks(void)
{
static VSTRING *result;
if (result == 0) {
char *myname = "mynetworks";
INET_ADDR_LIST *my_addr_list;
INET_ADDR_LIST *my_mask_list;
unsigned long addr;
unsigned long mask;
struct in_addr net;
int shift;
int junk;
int i;
int mask_style;
mask_style = name_mask("mynetworks mask style", mask_styles,
var_mynetworks_style);
for (i = 0, junk = mask_style; junk != 0; junk >>= 1)
i += (junk & 1);
if (i != 1)
msg_fatal("bad %s value: %s; specify exactly one value",
VAR_MYNETWORKS_STYLE, var_mynetworks_style);
result = vstring_alloc(20);
my_addr_list = own_inet_addr_list();
my_mask_list = own_inet_mask_list();
for (i = 0; i < my_addr_list->used; i++) {
addr = ntohl(my_addr_list->addrs[i].s_addr);
mask = ntohl(my_mask_list->addrs[i].s_addr);
switch (mask_style) {
case MASK_STYLE_CLASS:
if (IN_CLASSA(addr)) {
mask = IN_CLASSA_NET;
shift = IN_CLASSA_NSHIFT;
} else if (IN_CLASSB(addr)) {
mask = IN_CLASSB_NET;
shift = IN_CLASSB_NSHIFT;
} else if (IN_CLASSC(addr)) {
mask = IN_CLASSC_NET;
shift = IN_CLASSC_NSHIFT;
} else if (IN_CLASSD(addr)) {
mask = IN_CLASSD_NET;
shift = IN_CLASSD_NSHIFT;
} else {
msg_fatal("%s: bad address class: %s",
myname, inet_ntoa(my_addr_list->addrs[i]));
}
break;
case MASK_STYLE_SUBNET:
for (junk = mask, shift = BITS_PER_ADDR; junk != 0; shift--, (junk <<= 1))
;
break;
case MASK_STYLE_HOST:
mask = ~0;
shift = 0;
break;
default:
msg_panic("unknown mynetworks mask style: %s",
var_mynetworks_style);
}
net.s_addr = htonl(addr & mask);
vstring_sprintf_append(result, "%s/%d ",
inet_ntoa(net), BITS_PER_ADDR - shift);
}
if (msg_verbose)
msg_info("%s: %s", myname, vstring_str(result));
}
return (vstring_str(result));
}
#ifdef TEST
char *var_inet_interfaces;
char *var_mynetworks_style;
int main(int argc, char **argv)
{
if (argc != 3)
msg_fatal("usage: %s mask_style interface_list", argv[0]);
msg_verbose = 10;
var_inet_interfaces = argv[2];
var_mynetworks_style = argv[1];
mynetworks();
}
#endif