#line 1026 "../../src/builtin/snarf.m4"
/* -*- buffer-read-only: t -*- vi: set ro:
   THIS FILE IS GENERATED AUTOMATICALLY.  PLEASE DO NOT EDIT.
*/
#line 1026
#ifdef HAVE_CONFIG_H
#line 1026
# include <config.h>
#line 1026
#endif
#line 1026
#include <sys/types.h>
#line 1026

#line 1026
#include "mailfromd.h"
#line 1026
#include "prog.h"
#line 1026
#include "builtin.h"
#line 1026

#line 1026

#line 1066 "../../src/builtin/snarf.m4"

/* End of snarf.m4 */
#line 1 "ipaddr.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2007-2025 Sergey Poznyakoff

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */



#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void
#line 23
bi_ntohl(eval_environ_t env)
#line 23

#line 23

#line 23 "ipaddr.bi"
{
#line 23
	
#line 23

#line 23
        long  n;
#line 23
        
#line 23

#line 23
        get_numeric_arg(env, 0, &n);
#line 23
        
#line 23
        adjust_stack(env, 1);
#line 23

#line 23

#line 23
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 23
		prog_trace(env, "ntohl %lu",n);;
#line 23

{
	
#line 25
do {
#line 25
  push(env, (STKVAL)(mft_number)(ntohl((uint32_t) n)));
#line 25
  goto endlab;
#line 25
} while (0);
}
endlab:
#line 27
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 27
	return;
#line 27
}

void
#line 29
bi_htonl(eval_environ_t env)
#line 29

#line 29

#line 29 "ipaddr.bi"
{
#line 29
	
#line 29

#line 29
        long  n;
#line 29
        
#line 29

#line 29
        get_numeric_arg(env, 0, &n);
#line 29
        
#line 29
        adjust_stack(env, 1);
#line 29

#line 29

#line 29
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 29
		prog_trace(env, "htonl %lu",n);;
#line 29

{
	
#line 31
do {
#line 31
  push(env, (STKVAL)(mft_number)(htonl((uint32_t) n)));
#line 31
  goto endlab;
#line 31
} while (0);
}
endlab:
#line 33
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 33
	return;
#line 33
}

/* FIXME: The following functions assume binary complement arithmetic.
   This is hardly a limitation, the similar approach works in GNU Radius
   for years. Nevertheless, this assumption should be noted. */

void
#line 39
bi_ntohs(eval_environ_t env)
#line 39

#line 39

#line 39 "ipaddr.bi"
{
#line 39
	
#line 39

#line 39
        long  n;
#line 39
        
#line 39

#line 39
        get_numeric_arg(env, 0, &n);
#line 39
        
#line 39
        adjust_stack(env, 1);
#line 39

#line 39

#line 39
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 39
		prog_trace(env, "ntohs %lu",n);;
#line 39

{
	
#line 41
do {
#line 41
  push(env, (STKVAL)(mft_number)((uint32_t) ntohs(((uint16_t) n) & 0xffff)));
#line 41
  goto endlab;
#line 41
} while (0);
}
endlab:
#line 43
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 43
	return;
#line 43
}

void
#line 45
bi_htons(eval_environ_t env)
#line 45

#line 45

#line 45 "ipaddr.bi"
{
#line 45
	
#line 45

#line 45
        long  n;
#line 45
        
#line 45

#line 45
        get_numeric_arg(env, 0, &n);
#line 45
        
#line 45
        adjust_stack(env, 1);
#line 45

#line 45

#line 45
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 45
		prog_trace(env, "htons %lu",n);;
#line 45

{
	
#line 47
do {
#line 47
  push(env, (STKVAL)(mft_number)((uint32_t) htons(((uint16_t) n) & 0xffff)));
#line 47
  goto endlab;
#line 47
} while (0);
}
endlab:
#line 49
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 49
	return;
#line 49
}

void
#line 51
bi_inet_aton(eval_environ_t env)
#line 51

#line 51

#line 51 "ipaddr.bi"
{
#line 51
	
#line 51

#line 51
        char *  s;
#line 51
        
#line 51

#line 51
        get_string_arg(env, 0, &s);
#line 51
        
#line 51
        adjust_stack(env, 1);
#line 51

#line 51

#line 51
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 51
		prog_trace(env, "inet_aton %s",s);;
#line 51

{
	struct in_addr addr;

		if (!(inet_aton(s, &addr)))
#line 55
		(
#line 55
	env_throw_bi(env, mfe_invip, "inet_aton", _("invalid IP address (%s)"),s)
#line 55
)
#line 58
;
	
#line 59
do {
#line 59
  push(env, (STKVAL)(mft_number)(ntohl(addr.s_addr)));
#line 59
  goto endlab;
#line 59
} while (0);
}
endlab:
#line 61
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 61
	return;
#line 61
}

void
#line 63
bi_inet_ntoa(eval_environ_t env)
#line 63

#line 63

#line 63 "ipaddr.bi"
{
#line 63
	
#line 63

#line 63
        long  ip;
#line 63
        
#line 63

#line 63
        get_numeric_arg(env, 0, &ip);
#line 63
        
#line 63
        adjust_stack(env, 1);
#line 63

#line 63

#line 63
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 63
		prog_trace(env, "inet_ntoa %lu",ip);;
#line 63

{
	struct in_addr addr;

	addr.s_addr = htonl(ip);
	
#line 68
do {
#line 68
  pushs(env, inet_ntoa(addr));
#line 68
  goto endlab;
#line 68
} while (0);
}
endlab:
#line 70
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 70
	return;
#line 70
}

void
#line 72
bi_len_to_netmask(eval_environ_t env)
#line 72

#line 72

#line 72 "ipaddr.bi"
{
#line 72
	
#line 72

#line 72
        long  x;
#line 72
        
#line 72

#line 72
        get_numeric_arg(env, 0, &x);
#line 72
        
#line 72
        adjust_stack(env, 1);
#line 72

#line 72

#line 72
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 72
		prog_trace(env, "len_to_netmask %lu",x);;
#line 72

{
	unsigned long n = (unsigned long) x;
	unsigned long netmask;

		if (!(n <= 32))
#line 77
		(
#line 77
	env_throw_bi(env, mfe_range, "len_to_netmask", _("invalid netmask: %lu"),n)
#line 77
)
;
	n = 32 - n;
	if (n == 32)
		netmask = 0;
	else
		netmask = (0xfffffffful >> n) << n;
	
#line 84
do {
#line 84
  push(env, (STKVAL)(mft_number)(netmask));
#line 84
  goto endlab;
#line 84
} while (0);
}
endlab:
#line 86
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 86
	return;
#line 86
}

void
#line 88
bi_netmask_to_len(eval_environ_t env)
#line 88

#line 88

#line 88 "ipaddr.bi"
{
#line 88
	
#line 88

#line 88
        long  x;
#line 88
        
#line 88

#line 88
        get_numeric_arg(env, 0, &x);
#line 88
        
#line 88
        adjust_stack(env, 1);
#line 88

#line 88

#line 88
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 88
		prog_trace(env, "netmask_to_len %lu",x);;
#line 88

{
	unsigned long n = (unsigned long) x;
	unsigned long i;

	for (i = 32; i > 0; i--) {
		if (n & 1)
			break;
		n >>= 1;
	}
	
#line 98
do {
#line 98
  push(env, (STKVAL)(mft_number)(i));
#line 98
  goto endlab;
#line 98
} while (0);
}
endlab:
#line 100
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 100
	return;
#line 100
}

void
#line 102
bi_reverse_ipstr(eval_environ_t env)
#line 102

#line 102

#line 102 "ipaddr.bi"
{
#line 102
	
#line 102

#line 102
        char * MFL_DATASEG ipstr;
#line 102
        
#line 102

#line 102
        get_string_arg(env, 0, &ipstr);
#line 102
        
#line 102
        adjust_stack(env, 1);
#line 102

#line 102

#line 102
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 102
		prog_trace(env, "reverse_ipstr %s",ipstr);;
#line 102

{
	char revip[IPMAX_DOTTED_BUFSIZE];
	int n = dns_reverse_ipstr(ipstr, revip, sizeof(revip));
		if (!(n > 0))
#line 106
		(
#line 106
	env_throw_bi(env, mfe_invip, "reverse_ipstr", _("invalid IP address: %s"),ipstr)
#line 106
)
#line 108
;
	revip[n-1] = 0;
	
#line 110
do {
#line 110
  pushs(env, revip);
#line 110
  goto endlab;
#line 110
} while (0);
}
endlab:
#line 112
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 112
	return;
#line 112
}

void
#line 114
bi_is_ipstr(eval_environ_t env)
#line 114

#line 114

#line 114 "ipaddr.bi"
{
#line 114
	
#line 114

#line 114
        char *  ipstr;
#line 114
        
#line 114

#line 114
        get_string_arg(env, 0, &ipstr);
#line 114
        
#line 114
        adjust_stack(env, 1);
#line 114

#line 114

#line 114
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 114
		prog_trace(env, "is_ipstr %s",ipstr);;
#line 114

{
	
#line 116
do {
#line 116
  push(env, (STKVAL)(mft_number)(dns_str_is_ipv4(ipstr) || dns_str_is_ipv6(ipstr)));
#line 116
  goto endlab;
#line 116
} while (0);
}
endlab:
#line 118
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 118
	return;
#line 118
}

void
#line 120
bi_is_ip4str(eval_environ_t env)
#line 120

#line 120

#line 120 "ipaddr.bi"
{
#line 120
	
#line 120

#line 120
        char *  ipstr;
#line 120
        
#line 120

#line 120
        get_string_arg(env, 0, &ipstr);
#line 120
        
#line 120
        adjust_stack(env, 1);
#line 120

#line 120

#line 120
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 120
		prog_trace(env, "is_ip4str %s",ipstr);;
#line 120

{
	
#line 122
do {
#line 122
  push(env, (STKVAL)(mft_number)(dns_str_is_ipv4(ipstr)));
#line 122
  goto endlab;
#line 122
} while (0);
}
endlab:
#line 124
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 124
	return;
#line 124
}

void
#line 126
bi_is_ip6str(eval_environ_t env)
#line 126

#line 126

#line 126 "ipaddr.bi"
{
#line 126
	
#line 126

#line 126
        char *  ipstr;
#line 126
        
#line 126

#line 126
        get_string_arg(env, 0, &ipstr);
#line 126
        
#line 126
        adjust_stack(env, 1);
#line 126

#line 126

#line 126
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 126
		prog_trace(env, "is_ip6str %s",ipstr);;
#line 126

{
	
#line 128
do {
#line 128
  push(env, (STKVAL)(mft_number)(dns_str_is_ipv6(ipstr)));
#line 128
  goto endlab;
#line 128
} while (0);
}
endlab:
#line 130
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 130
	return;
#line 130
}

void
#line 132
bi_match_cidr(eval_environ_t env)
#line 132

#line 132

#line 132 "ipaddr.bi"
{
#line 132
	
#line 132

#line 132
        char *  ipstr;
#line 132
        char *  cidrstr;
#line 132
        
#line 132

#line 132
        get_string_arg(env, 0, &ipstr);
#line 132
        get_string_arg(env, 1, &cidrstr);
#line 132
        
#line 132
        adjust_stack(env, 2);
#line 132

#line 132

#line 132
	if (builtin_module_trace(BUILTIN_IDX_ipaddr))
#line 132
		prog_trace(env, "match_cidr %s %s",ipstr, cidrstr);;
#line 132

{
	struct mu_cidr ip, cidr;

		if (!(mu_cidr_from_string(&ip, ipstr) == 0))
#line 136
		(
#line 136
	env_throw_bi(env, mfe_invip, "match_cidr", _("not a valid IP or CIDR: %s"),ipstr)
#line 136
)
#line 138
;
		if (!(mu_cidr_from_string(&cidr, cidrstr) == 0))
#line 139
		(
#line 139
	env_throw_bi(env, mfe_invcidr, "match_cidr", _("not a valid IP or CIDR: %s"),cidrstr)
#line 139
)
#line 141
;
	
#line 142
do {
#line 142
  push(env, (STKVAL)(mft_number)(mu_cidr_match(&cidr, &ip) == 0));
#line 142
  goto endlab;
#line 142
} while (0);
}
endlab:
#line 144
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 144
	return;
#line 144
}
#line 1026 "../../src/builtin/snarf.m4"

#line 1026

#line 1026

#line 1026
void
#line 1026
ipaddr_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 23 "ipaddr.bi"
va_builtin_install_ex("ntohl", bi_ntohl, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 29 "ipaddr.bi"
va_builtin_install_ex("htonl", bi_htonl, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 39 "ipaddr.bi"
va_builtin_install_ex("ntohs", bi_ntohs, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 45 "ipaddr.bi"
va_builtin_install_ex("htons", bi_htons, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 51 "ipaddr.bi"
va_builtin_install_ex("inet_aton", bi_inet_aton, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 63 "ipaddr.bi"
va_builtin_install_ex("inet_ntoa", bi_inet_ntoa, 0, dtype_string, 1, 0, 0|0, dtype_number);
#line 72 "ipaddr.bi"
va_builtin_install_ex("len_to_netmask", bi_len_to_netmask, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 88 "ipaddr.bi"
va_builtin_install_ex("netmask_to_len", bi_netmask_to_len, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 102 "ipaddr.bi"
va_builtin_install_ex("reverse_ipstr", bi_reverse_ipstr, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 114 "ipaddr.bi"
va_builtin_install_ex("is_ipstr", bi_is_ipstr, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 120 "ipaddr.bi"
va_builtin_install_ex("is_ip4str", bi_is_ip4str, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 126 "ipaddr.bi"
va_builtin_install_ex("is_ip6str", bi_is_ip6str, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 132 "ipaddr.bi"
va_builtin_install_ex("match_cidr", bi_match_cidr, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_string);

#line 1026 "../../src/builtin/snarf.m4"
	
#line 1026
}
#line 1026 "../../src/builtin/snarf.m4"

