Skip site navigation (1)Skip section navigation (2)
Date:      29 Mar 2001 07:08:54 +0200
From:      Cyrille Lefevre <clefevre@poboxes.com>
To:        "Rodney W. Grimes" <freebsd@gndrsh.dnsmgr.net>
Cc:        mikel@ocsinternet.com (Mikel), johnny.dang@johnnydang.net (Johnny Dang), FREEBSD-IPFW@FreeBSD.ORG (FreeBSD IpFW)
Subject:   [LONG] Re: Scripting with IPFW
Message-ID:  <n1a517rt.fsf@gits.dyndns.org>
In-Reply-To: <200103270821.AAA90749@gndrsh.dnsmgr.net>
References:  <200103270821.AAA90749@gndrsh.dnsmgr.net>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=

"Rodney W. Grimes" <freebsd@gndrsh.dnsmgr.net> writes:

> oif=fxp0
> iif=rl0
> oip=`ifconfig ${oif} | awk '/inet/ {print $2; exit}'`
                                   ^ /inet /

I would suggest you to match on inet followed by a space or
you'll match inet6 which is probably you don't want.

# ifconfig -a | awk '/inet/{print $0;exit}'
	inet6 fe80::260:8ff:fe1a:9a37%ep0 prefixlen 64 scopeid 0x1 
# ifconfig -a | awk '/inet /{print $0;exit}'
	inet 212.198.231.165 netmask 0xffffff00 broadcast 212.198.231.255

> omask=`ifconfig ${oif} | awk '/inet/ {print $4; exit}'`
> iip=`ifconfig ${iif} | awk '/inet/ {print $2; exit}'`
> imask=`ifconfig ${iif} | awk '/inet/ {print $4; exit}'`

also, these 4 lines may be rewritten as :

        eval `ifconfig -a | awk -v oif="${oif}:" -v iif="${iif}:"  '
        $1 == oif { status = 1 ; next } # I/O interfaces
        $1 == iif { status = 3 ; next } # use odd numbers here
        $1 ~ /:/ { status = 0; next }   # other interfaces
        !status { next }                # are skipped
        /inet / { status++ }            # match on first IPv4 address
        status == 2 {                   # and use even numbers there
                printf "omask=%s oip=%s\n", $4, $2
                status = 0; next        # skip IPv4 aliases
        }
        status == 4 {
                printf "imask=%s iip=%s\n", $4, $2
                status = 0; next
        }
        '`

which is what I use for months. (well, not exactly true since I have
only one interface for input/ouput due to an old BIOS and IRQ
conflicts which prevent me from having to network cards :)

> onet=`cidr -q ${oif} -h ${omask} | awk '/network/ {print $3}'`
                  ^^^ should be oip.                       ^^ $NF is safer.

> inet=`cidr -q ${iif} -h ${imask} | awk '/network/ {print $3}'`

the following first two files are the dhclient's hooks I use for
months.  the *dhclient-enter-hooks* was essentially used for debugging
purpose.  recently, I added the multiple aliases hack which is not
handled by dhclient right now. it can handle only one alias by
interface.  the *dhclient-exit-hooks* redo the aliases if needed,
restart the firewall, update the dynamic dns and my private dns. the
dhclient.conf is provided as a sample for multiple aliases.  the
*start_if.ep0* is use at boot time to avoid restarting the firewall
which is just started before by the rc.network script.  since I use
many private variables, I also supply the *rc.conf* file.  FYI, I'm
using and maintaining the *isc-dhcp3* port for months, also, since the
dhclient-v2 is too buggy if you are using the /prepend/ tag in
*dhclient.conf.

hope this help and have fun :)


--=-=-=
Content-Disposition: attachment; filename=dhclient-enter-hooks
Content-Description: /etc/dhclient-enter-hooks

#!/bin/sh

dhclient_conf=/usr/local/etc/dhclient.conf
dhclient_boot=/var/run/dhclient.boot
dhclient_log=/var/run/dhclient.$reason.log
dhclient_tmp=/var/run/dhclient.$$
dhclient_var=/var/run/dhclient.var

if [ -f $dhclient_boot ]; then
	exec > $dhclient_log 2>&1 ; set -x
else
	exec >> $dhclient_log 2>&1 ; set -x
fi

trap "rm -f ${dhclient_tmp}" 0

# initialization

LOGGER="logger -s -p local1.notice -t dhclient"

# logging

if [ "x$reason" != x ]; then
	$LOGGER Reason for $interface: $reason
fi
if [ "x$medium" != x ]; then
	$LOGGER Medium for $interface: $medium
fi

case ${reason} in
BOUND|RENEW|REBIND|REBOOT)

	if [ -f $dhclient_boot ]; then
		rm -f $dhclient_var
	fi

	if [ -f $dhclient_var ]; then
		: . $dhclient_var
	fi

	cp /dev/null $dhclient_var

	;;
esac

for new_var in \
	new_host_name \
	new_ip_address \
	new_subnet_mask \
	new_broadcast_address  \
	new_network_number \
	new_routers  \
	new_static_routes \
	new_domain_name \
	new_domain_name_servers \
	alias_ip_address \
	alias_subnet_mask \
	new_dhcp_server_identifier \
	new_dhcp_message_type \
	new_dhcp_lease_time \
	new_dhcp_renewal_time \
	new_dhcp_rebinding_time \
	new_expiry
do
        new_lab= spc=
        for elem in `echo $new_var | sed "s/_/ /g"`; do
                caps=`expr $elem : "\(.\).*" | tr a-z A-Z`
                rest=`expr $elem : ".\(.*\)"`
                new_lab="$new_lab$spc$caps$rest"
                spc=" "
        done
	new_lab=`echo $new_lab | sed 's/Ip/IP/;s/Dhcp/DHCP/'`
        eval new_val=\$$new_var

        old_var=`echo $new_var | sed "s/new/old/"`
        old_lab=`echo $new_lab | sed "s/New/Old/"`
        eval old_val=\$$old_var

	case $old_var in
	old_domain_name*) old_val=`echo $old_val | \
			  sed -e :l -e 's/\(.*\) \1 \(.*\)/\1 \2/;t l'` ;;
	esac

        if [ "x$old_val" != x ] && [ "x$new_val" != "x$old_val" ]; then
                $LOGGER "$old_lab: $old_val"
        fi
        if [ "x$new_val" != x ]; then
                $LOGGER "$new_lab: $new_val"
        fi

	case ${reason} in
	BOUND|RENEW|REBIND|REBOOT)
	    if echo $old_var | grep -q old
	    then
		    eval old_val=\$$new_var
		    echo $old_var=\${$old_var:-\"$old_val\"} export $old_var >> $dhclient_var
	    fi
	    ;;
	esac
done

case ${reason} in
PREINIT)

	awk -v interface=$interface '
		/[ 	]*#[ 	]*alias/ && $3 == interface { print $4 }
	' $dhclient_conf |
	while read alias_ip_address; do
		ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
		route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
	done

	;;
BOUND|RENEW|REBIND|REBOOT|EXPIRE|FAIL|TIMEOUT)

	awk -v interface=$interface '
		/[ 	]*#[ 	]*alias/ && $3 == interface { print $4 }
	' $dhclient_conf |
	while read alias_ip_address; do
		if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
		   [ x$alias_ip_address != x$old_ip_address ]; then
			ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
			route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
		fi
	done

	;;
esac

# eof

--=-=-=
Content-Disposition: attachment; filename=dhclient-exit-hooks
Content-Description: /etc/dhclient-exit-hooks

#!/bin/sh

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/rc.conf ]; then
	. /etc/defaults/rc.conf
	source_rc_confs
elif [ -r /etc/rc.conf ]; then
	. /etc/rc.conf
fi

# for var in \
# 	firewall_enable firewall_script firewall_type dhcp_bootfile \
# 	dyndns_enable dyndns_program dyndns_flags \
# 	dyndns_database dyndns_hostname dyndns_domainname \
# 	named_enable named_zone domainname \
# do;
# 	eval echo ${var}=\"\$${var}\"
# done


case ${reason} in
BOUND|RENEW|REBIND|REBOOT|EXPIRE|FAIL|TIMEOUT)
	awk -v interface=$interface '
		/[ 	]*#[ 	]*alias/ && $3 == interface { print $4, $5 }
	' $dhclient_conf |
	while read alias_ip_address alias_subnet_mask; do
		alias_subnet_arg="netmask $alias_subnet_mask"
		if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ]; then
			ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
			route add $alias_ip_address 127.0.0.1
		fi
	done
	;;
esac

case ${reason} in
BOUND|RENEW|REBIND|REBOOT|EXPIRE|TIMEOUT)

# reset the firewall rules, if any

case ${firewall_enable} in
[Yy][Ee][Ss])
	if /sbin/ipfw -q flush > /dev/null 2>&1; then
		firewall_in_kernel=1
	else
		firewall_in_kernel=0
	fi

	if [ ${firewall_in_kernel} -eq 1 ]; then
		if [ -z "${firewall_script}" ]; then
			firewall_script=/etc/rc.firewall
		fi

		if [ -f "${dhcp_bootfile}" ]; then
			rm -f ${dhcp_bootfile}

			firewall_type="OPEN"
		fi

		sh ${firewall_script} ${firewall_type}
	fi
esac

;; esac # reason


case ${reason} in BOUND|REBIND|REBOOT|RENEW)

# echo domain ${domainname} >> /etc/resolv.conf

# record the new ip address, if needed

date2julian () # day month year
{
# Tapani Tarvainen July 1998, May 2000 - Julian Day Number from calendar date
	day=$1 month=$2 year=$3
	tmpmonth=$(( 12 * ${year} + ${month} - 3 ))
	tmpyear=$(( ${tmpmonth} / 12 ))
	echo $(( (734 * ${tmpmonth} + 15) / 24 -  2 * ${tmpyear} + \
	${tmpyear}/4 - ${tmpyear}/100 + ${tmpyear}/400 + ${day} + 1721119 ))
}

days_lapsed () { # file
	file=$1
	cday=$(date +%d) cmonth=$(date +%m) cyear=$(date +%Y)
	cdate="${cday} ${cmonth} ${cyear}"
	fdate=$(ls -l ${file} | awk -v cmonth=$cmonth -v cyear=$cyear '
	BEGIN {
		month["Jan"]=1; month["Feb"]=2; month["Mar"]=3
		month["Apr"]=4; month["May"]=5; month["Jun"]=6
		month["Jul"]=7; month["Aug"]=8; month["Sep"]=9
		month["Oct"]=10; month["Nov"]=11; month["Dec"]=12
	}
	{ print $7, month[$6], $8 ~ /:/ ? cyear - (month[$6] > cmonth) : $8 }')
	echo $(( $(date2julian ${cdate} ) - $(date2julian ${fdate}) ))
}

case ${dyndns_enable} in
[Yy][Ee][Ss])
	if [ -n "${new_ip_address}" ]; then
		dyndns_fqdn=${dyndns_hostname}.${dyndns_domainname}
		dyndns_file=${dyndns_database}/${dyndns_fqdn}
		sedipre="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
		days_lapsed=0

		if [ -f ${dyndns_file} ]; then
			dyndns_ip_address=$(cat ${dyndns_file})
			days_lapsed=$(days_lapsed ${dyndns_file})
		fi

		if [ "${dyndns_ip_address}" != "${new_ip_address}" ] ||
		   [ "${days_lapsed}" -ge ${dyndns_interval} ]; then
			if [ "${dyndns_ip_address}" != "${new_ip_address}" ]; then
				if [ -n "${dyndns_ip_address}" ]; then
					$LOGGER "Old DynDNS IP Address: ${dyndns_ip_address}"
				fi
				$LOGGER New DynDNS IP Address: ${new_ip_address}
			else
				$LOGGER ReNew DynDNS IP Address: ${new_ip_address}
			fi

			if [ -x "${dyndns_program}" ]; then
				cmd=${dyndns_program} args=
				args="${args} --host ${dyndns_fqdn}"
				args="${args} --ip ${new_ip_address}"
				args="${args} ${dyndns_flags}"
				succeeded="Update of ${dyndns_fqdn} succeeded"
				notchanged="Host ${dyndns_fqdn} not changed"
				re="${succeeded}|${notchanged}" email=root

				${cmd} ${args} > ${dhclient_tmp} 2>&1; rc=$?

				if egrep -q "${re}" ${dhclient_tmp}; then
					echo ${new_ip_address} > ${dyndns_file}
				else
					cat - ${dhclient_tmp} <<- EOF |
					${cmd} ${args}
					echo ${new_ip_address} > ${dyndns_file}
					echo
EOF
					mail -s "dyndns@${hostname} (rc=$rc)" ${email}
				fi
			fi

			case ${named_enable} in
			[Yy][Ee][Ss])
				named_file=${named_database}/${domainname}

				if [ -f ${named_file} ]; then
					ed - ${named_file} <<- EOF &&
g/; ${dyndns_fqdn}/s/${ipre}/${new_ip_address}/
w
q
EOF
					killall -1 named 2>/dev/null
				fi
			esac
		fi
	fi
esac

ifconfig -a > /var/run/ifconfig.log
netstat -rna > /var/run/netstat.log

;; esac # reason


# eof

--=-=-=
Content-Disposition: attachment; filename=dhclient.conf
Content-Description: /etc/dhclient.conf

# $FreeBSD: src/etc/dhclient.conf,v 1.2 1999/08/27 23:23:41 peter Exp $
#
#	This file is required by the ISC DHCP client.
#	See ``man 5 dhclient.conf'' for details.
#
#	In most cases an empty file is suffient for most people as the
#	defaults are usually fine.
#

timeout 60;
retry 60;
select-timeout 5;
reboot 10;
initial-interval 5;

interface "ep0" {
	request subnet-mask, broadcast-address, time-offset, routers,
		domain-name, domain-name-servers, host-name;
	require subnet-mask, domain-name-servers;

	prepend domain-name "gits.fr.invalid "; # the final space is required
	prepend domain-name-servers 127.0.0.1;

	# media "link2";
}

alias {
	interface "ep0";
	fixed-address 192.168.144.96;
	option subnet-mask 255.255.255.0;
	# alias ep0 192.168.144.97 255.255.255.0
}

--=-=-=
Content-Disposition: attachment; filename=start_if.ep0
Content-Description: /etc/start_if.ep0

#!/bin/sh

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/rc.conf ]; then
	. /etc/defaults/rc.conf
	source_rc_confs
elif [ -r /etc/rc.conf ]; then
	. /etc/rc.conf
fi

if [ "x$dhcp_bootfile" != x ]; then
	touch $dhcp_bootfile
fi

--=-=-=
Content-Disposition: attachment; filename=rc.conf
Content-Description: /etc/rc.conf

#!/bin/sh
#
# This file now contains just the overrides from /etc/defaults/rc.conf
# please make all changes to this file.

# -- sysinstall generated deltas -- #

##############################################################
### Important initial Boot-time options  #####################
##############################################################

#
# apm
#
apm_enable="YES"
hlt_enable="YES"		#add-on#
apmd_enable="YES"

##############################################################
###  Network configuration sub-section  ######################
##############################################################

### Basic network options: ###
#
# hostname & domainnames
#
hostname="gits"
domainname="gits.fr.invalid"		#add-on#
# nisdomainname="gits.fr.invalid"
ip_address="192.168.144.96"		#add-on#
ip_netmask="255.255.255.0"		#add-on#
ip_bitmask="24"				#add-on#
#
# dhcp
#
dhcp_program="/usr/local/sbin/dhclient"
dhcp_flags="-1 -q" # -D
dhcp_bootfile="/var/run/dhclient.boot"	#add-on#
#
# bridge
#
# bridge_enable="YES"			#add-on#
# bridge_cfg="ep0:1,ep1:1"		#add-on#
# bridge_ipfw="YES"			#add-on#
#
# firewall
#
firewall_enable="YES"
firewall_quiet="YES"
firewall_type="CUSTOM_STATIC"
firewall_interface="ep0"		#add-on#
firewall_logging="YES"
#
# ipfilter_enable="YES"
# ipfilter_program="/sbin/ipf -Fa -f"
# ipfilter_flags="=E"
# ipfilter_rules="/etc/ipf.rules"
#
# ipmon_enable="YES"
# ipmon_flags="-Dsn"
#
# natd
#
natd_enable="YES"
natd_interface="ep0"
natd_conf="/etc/natd.conf"		#add-on#
natd_flags="-f $natd_conf"
#
# ipnat_enable="YES"
# ipnat_program="/sbin/ipnat -CF -f"
# ipnat_rules="/etc/ipnat.rules"
#
# routing options
#
tcp_extensions="YES"
log_in_vain="YES"
tcp_drop_synfin="YES"
tcp_restrict_rst="YES"
icmp_drop_redirect="YES"
icmp_log_redirect="YES"
ip_stealth="YES"			#add-on#
tcp_blackhole="YES"			#add-on#
udp_blackhole="YES"			#add-on#
#
# network interfaces
#
network_interfaces="lo0 ep0"		# auto
ifconfig_ep0="DHCP"
# ifconfig_ep0="inet $hostname netmask $ip_netmask"
#
# ppp
#
# ppp_enable="YES"
# ppp_profile="freesurf"
# ppp_nat="YES"

### Network daemon (miscellaneous) & NFS options: ###
#
# syslogd
#
syslogd_flags="-a $ip_address/$ip_bitmask -vv" # -a *$domainname
#
# inetd
#
inetd_flags="-wW -l"
#
# named
#
named_enable="YES"
named_flags="-u bind -g bind"
named_database="/etc/namedb/zone"	#add-on#
#
# automounter
#
# amd_enable="YES"
# amd_flags="-F /etc/amd.conf"
#
# rarpd
#
# rarpd_enable="YES"			#add-on#
rarpd_interface="-a"			#add-on#
rarpd_flags="-v -s $rarpd_interface"	#add-on#
#
# bootparamd
#
# bootparamd_enable="YES"		#add-on#
bootparamd_flags="-s"			#add-on#
#
# nfs
#
# nfs_client_enable="YES"
# nfs_server_enable="YES"
nfs_interface="-a"			#add-on# -h $hostname
nfs_server_flags="-u -t -n 4 $nfs_interface"
# nfs_reserved_port_only="YES"
#
# mountd
#
mountd_flags="-l -r -2"
#
# portmap (used by: rstatd rusersd walld pcnfsd rquotad sprayd)
#
portmap_enable="NO"
portmap_flags="-v"
#
# sshd
#
sshd_enable="YES"
sshd_flags="-4"

### Network Time Services options: ###
#
# ntpdate
#
ntpdate_enable="YES"
ntpdate_flags="-bs ntp.obspm.fr ntp.univ-lyon1.fr canon.inria.fr ntp-sop.inria.fr"
#
# xntpd
#
xntpd_enable="YES"

# Network Information Services (NIS) options: ###
# nis_client_enable="YES"
# nis_server_enable="YES"
# nis_server_flags="-n"
# nis_yppasswdd_enable="YES"
# nis_yppasswdd_flags="-f"

### Network routing options: ###
#
# ip forwarding
#
gateway_enable="YES"
#
# routed
#
router_enable="YES"
router_flags="-s" # ou -q

##############################################################
###  System console options  #################################
##############################################################

#
# keyboard
#
# keymap="fr.iso.acc"
keymap="us.iso.acc"
keyrate="fast"
#
# cursor
#
cursor="destructive"
#
# fonts
#
# scrnmap="iso-8859-1_to_cp437"
font8x16="iso-8x16"
font8x14="iso-8x14"
font8x8="iso-8x8"
#
# blanktime
#
blanktime="600"
#
# screen saver
#
saver="green"
# saver="matrix"
#
# moused
#
moused_enable="YES"
moused_port="/dev/psm0"
#
# all screens options
#
# allscreens_flags="-m on" # 80x50
#
# mixer
#
mixer="vol 100:100 pcm 25:25 speaker 50:50 line 0:0"	#add-on#

##############################################################
###  Miscellaneous administrative options  ###################
##############################################################

#
# savecore
#
dumpdev="/dev/da0s1b"
#
# quotas
#
# check_quotas="YES"
# enable_quotas="YES"
#
# accounting
#
accounting_enable="YES"
#
# compatibility options
#
# ibcs2_enable="YES"
linux_enable="YES"
# svr4_enable="YES"
#
# cleaning
#
# clear_tmp_enable="YES"
#
# vi.recover
#
vi_recover="/var/preserve"		#add-on#
#
# ldconfig paths
#
ldconfig_extra_paths=
ldconfig_extra_paths="$ldconfig_extra_paths /usr/local/pilot/lib"
ast_arch=$(uname -msr | awk '{sub("-.*","",$2);print tolower($3"--"$1$2)}')
ldconfig_extra_paths="$ldconfig_extra_paths /usr/local/arch/$ast_arch/lib"
for ldconfig_path in $ldconfig_extra_paths; do
	case " $ldconfig_paths " in
	*" $ldconfig_path "*) ;;
	*) ldconfig_paths="$ldconfig_paths $ldconfig_path" ;;
	esac
done
ldconfig_extra_paths_aout=
# ldconfig_extra_paths_aout="$ldconfig_extra_paths_aout /usr/X11R6-4.0/lib/aout"
for ldconfig_path_aout in $ldconfig_extra_paths_aout; do
	case " $ldconfig_paths_aout " in
	*" $ldconfig_path_aout "*) ;;
	*) ldconfig_paths_aout="$ldconfig_paths_aout $ldconfig_path_aout" ;;
	esac
done
#
# security options
#
# kern_securelevel_enable="YES"
# kern_securelevel="0"			# implies 1 in multi-user level
#
# kernel options
#
kern_corefile=core			#add-on#
#
# dyndns
#
dyndns_program="/usr/local/sbin/ddup"	#add-on#
dyndns_enable="YES"			#add-on#
dyndns_flags="--wildcard"		#add-on#
dyndns_hostname="$hostname"		#add-on#
dyndns_domainname="dyndns.org"		#add-on#
dyndns_database="/var/db"		#add-on#
dyndns_interval="25"			#add-on#
#
# upsd
#
upsd_program="/usr/local/sbin/bkpupsd"	#add-on#
upsd_enable="YES"			#add-on#
upsd_flags="/dev/cuaa1"			#add-on#
#
# rc log/debug
#
rc_log_enable="YES"
rc_debug_enable="NO"

# -- sysinstall generated deltas -- #

noWarn="YES"

--=-=-=


Cyrille.
--
home: mailto:clefevre@poboxes.com   UNIX is user-friendly; it's just particular
work: mailto:Cyrille.Lefevre@edf.fr   about who it chooses to be friends with.

--=-=-=--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ipfw" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?n1a517rt.fsf>