From owner-freebsd-ipfw Wed Mar 28 21: 9:46 2001 Delivered-To: freebsd-ipfw@freebsd.org Received: from mail.noos.fr (verlaine.noos.net [212.198.2.73]) by hub.freebsd.org (Postfix) with ESMTP id 6769737B71C for ; Wed, 28 Mar 2001 21:09:22 -0800 (PST) (envelope-from clefevre@poboxes.com) Received: (qmail 3309868 invoked by uid 0); 29 Mar 2001 06:09:23 -0000 Received: from d165.dhcp212-198-231.noos.fr (HELO gits.dyndns.org) ([212.198.231.165]) (envelope-sender ) by verlaine.noos.net (qmail-ldap-1.03) with DES-CBC3-SHA encrypted SMTP for ; 29 Mar 2001 06:09:23 -0000 Received: (from root@localhost) by gits.dyndns.org (8.11.3/8.11.3) id f2T58xo13172; Thu, 29 Mar 2001 07:09:00 +0200 (CEST) (envelope-from clefevre@poboxes.com) To: "Rodney W. Grimes" Cc: mikel@ocsinternet.com (Mikel), johnny.dang@johnnydang.net (Johnny Dang), FREEBSD-IPFW@FreeBSD.ORG (FreeBSD IpFW) Subject: [LONG] Re: Scripting with IPFW References: <200103270821.AAA90749@gndrsh.dnsmgr.net> X-Face: V|+c;4!|B?E%BE^{E6);aI.[<97Zd*>^#%Y5Cxv;%Y[PT-LW3;A:fRrJ8+^k"e7@+30g0YD0*^^3jgyShN7o?a]C la*Zv'5NA,=963bM%J^o]C Reply-To: Cyrille Lefevre In-Reply-To: <200103270821.AAA90749@gndrsh.dnsmgr.net> From: Cyrille Lefevre Mail-Copies-To: never Date: 29 Mar 2001 07:08:54 +0200 Message-ID: Lines: 81 User-Agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.1 (Cuyahoga Valley) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Sender: owner-freebsd-ipfw@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --=-=-= "Rodney W. Grimes" 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