+

Last commit for cisco-acl-to-iptables: 04b5ee1f02837c3174d3f2d030f7d33b120fb55b

Fix 'add to iptables command' parameter

Benjamin Renard [2014-01-13 17:09:02]
Fix 'add to iptables command' parameter
#!/bin/bash

DEBUG=0
ADD_COMMENT=1
PERMIT='ACCEPT'
DENY='DROP'

IN=$1
[ ! -f "$IN" ] && echo "Usage : $0 [rule file] [add to iptables command] [-d]" && exit 1

ADD_TO_IPTABLES_CMD=$2

[ "$2" == "-d" -o "$3" == "-d" ] && DEBUG=1

function get_word() {
	echo "$1"|awk "{print \$$2}"
}

function is_valid_ip() {
	ip="$1"
	if [ "$( echo "$ip"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
	then
		for i in $( seq 1 4 )
		do
			O=$( echo "$ip"|cut -d '.' -f $i )
			[ $O -lt 0 -o $O -gt 254 ] && echo $i && return $i
		done
		echo 0
		return 0
	fi
	echo 1
	return 1
}

function convert_mask() {
	mask="$1"
	if [ "$( echo "$mask"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
	then
		NETMASK=""
		for i in $( seq 1 4 )
		do
			O=$( echo "$mask"|cut -d '.' -f $i )
			[ $O -lt 0 -o $O -gt 255 ] && echo "" && return $i
			let o=255-O
			NETMASK="$NETMASK.$o"
		done
		echo $NETMASK|sed 's/^\.//'
		return 0
	fi
	echo ""
	return 1
}

function convert_netmask_to_cidr() {
	mask="$1"
	if [ "$( echo "$mask"| egrep -c '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' )" == "1" ]
	then
		CIDR=0
		for i in $( seq 1 4 )
		do
			O=$( echo "$mask"|cut -d '.' -f $i )
			if [ "$O" == "0" ]
			then
				continue
			elif [ "$O" == "128" ]
			then
				let CIDR=CIDR+1
			elif [ "$O" == "192" ]
			then
				let CIDR=CIDR+2
			elif [ "$O" == "224" ]
			then
				let CIDR=CIDR+3
			elif [ "$O" == "240" ]
			then
				let CIDR=CIDR+4
			elif [ "$O" == "248" ]
			then
				let CIDR=CIDR+5
			elif [ "$O" == "252" ]
			then
				let CIDR=CIDR+6
			elif [ "$O" == "254" ]
			then
				let CIDR=CIDR+7
			elif [ "$O" == "255" ]
			then
				let CIDR=CIDR+8
			else
				echo ""
				return $i
			fi
		done
		echo $CIDR
		return 0
	fi
	echo ""
	return 1
}

function convert_ip_mask_to_arg() {
	IP="$1"
	MASK="$2"
	CIDR="$( convert_netmask_to_cidr "$MASK" )"
	if [ "$CIDR" == "" ]
	then
		echo "Error converting netmask $MASK to CIDR (Result : $CIDR | Code : $?). Stop." > /dev/stderr
		echo ""
		return 1
	elif [ "$CIDR" == "32" ]
	then
		echo "$IP"
	elif [ "$CIDR" == "0" -a "$IP" == "0.0.0.0" ]
	then
		echo "0/0"
	else
		echo "$IP/$CIDR"
	fi
}

function print_acl_details() {
	echo "ACL : $line
Action : $ACL_ACTION
Protocole : $ACL_PROTO
Groupe : $ACL_GROUP
Source : $ACL_SRC_NET/$ACL_SRC_MASK
Source services : '$ACL_SRC_PORTS'
Destination : $ACL_DST_NET/$ACL_DST_MASK
Destination services : '$ACL_DST_PORTS'"
}

function convert_2_iptables_cmd() {
	MULTIPORTS=0
	CMD="iptables -I FORWARD $ADD_TO_IPTABLES_CMD"
	[ "$ACL_PROTO" != 'ip' ] && CMD="$CMD -p $ACL_PROTO"

	SRC="$( convert_ip_mask_to_arg "$ACL_SRC_NET" "$ACL_SRC_MASK" )"
	[ "$SRC" == "" ] && echo "ERROR : Fail to convert source" > /dev/stderr && return 1
	[ "$SRC" != "0/0" ] && CMD="$CMD -s $SRC"

	if [ "$ACL_SRC_PORTS" != "any" ]
	then
		if [ $( echo "$ACL_SRC_PORTS"|sed 's/ /\n/'|wc -l ) -gt 1 ]
		then
			MULTIPORTS=1
			PORTS=""
			for p in $ACL_SRC_PORTS
			do
				PORTS=",$PORTS"
			done
			CMD="$CMD -m multiport --sports $( echo "$PORTS"|sed 's/^,//' )"
		else
			CMD="$CMD --sport $ACL_SRC_PORTS"
		fi
	fi

	DST="$( convert_ip_mask_to_arg "$ACL_DST_NET" "$ACL_DST_MASK" )"
	[ "$DST" == "" ] && echo "ERROR : Fail to convert destination" > /dev/stderr && return 1
	[ "$DST" != "0/0" ] && CMD="$CMD -d $DST"

	if [ "$ACL_DST_PORTS" != "any" ]
	then
		if [ $( echo "$ACL_DST_PORTS"|sed 's/ /\n/'|wc -l ) -gt 1 ]
		then
			PORTS=""
			for p in $ACL_DST_PORTS
			do
				PORTS=",$PORTS"
			done
			[ $MULTIPORTS -eq 0 ] && CMD="$CMD -m multiport"
			CMD="$CMD --dports $( echo "$PORTS"|sed 's/^,//' )"
		else
			CMD="$CMD --dport $ACL_DST_PORTS"
		fi
	fi

	if [ "$ACL_ACTION" == "permit" ]
	then
		CMD="$CMD -j $PERMIT"
	elif [ "$ACL_ACTION" == "deny" ]
	then
		CMD="$CMD -j $DENY"
	else
		echo "ERROR : Action '$ACL_ACTION' not recognized" > /dev/stderr
		return 1
	fi

	echo $CMD
}

IFS="
"
for line in $( cat "$IN"|egrep "^access-list " )
do
	# Reset
	word=""
	ACL_ACTION=""
	ACL_PROTO=""
	ACL_GROUP=""
	ACL_SRC_NET=""
	ACL_SRC_MASK=""
	ACL_SRC_PORTS=""
	ACL_DST_NET=""
	ACL_DST_MASK=""
	ACL_DST_PORTS=""

	field=2
	ACL_GROUP="$( get_word "$line" $field )"

	field=3
	ACL_ACTION="$( get_word "$line" $field )"
	if [ "$ACL_ACTION" != "permit" -a "$ACL_ACTION" != "deny" ]
	then
		echo "ERROR : Action not recognized in $( print_acl_details )"
		continue
	fi

	field=4
	ACL_PROTO="$( get_word "$line" $field )"

	field=5
	ACL_SRC_NET="$( get_word "$line" $field )"

	if [ "$ACL_SRC_NET" == "any" ]
	then
		ACL_SRC_NET="0.0.0.0"
		ACL_SRC_MASK="0.0.0.0"
	elif [ "$ACL_SRC_NET" == "host" ]
	then
		let field=field+1
		ACL_SRC_NET="$( get_word "$line" $field )"
		[ $( is_valid_ip "$ACL_SRC_NET" ) -ne 0 ] && echo "ERROR : Source host IP address not recognized in $( print_acl_details )" && continue
		ACL_SRC_MASK="255.255.255.255"
	elif [ "$( is_valid_ip "$ACL_SRC_NET" )" == "0" ]
	then
		let field=field+1
		ACL_SRC_MASK="$( get_word "$line" $field )"
		ACL_SRC_MASK=$( convert_mask "$ACL_SRC_MASK" )
		[ "$ACL_SRC_MASK" == "" ] && echo "ERROR : Source mask not recognized in $( print_acl_details )" && continue
	else
		echo "ERROR : Source net not recognized in ACL, pass : $line"
		continue
	fi

	let field=field+1
	word="$( get_word "$line" $field )"
	if [ "$word" == "eq" ]
	then
		ACL_SRC_PORTS=""
		while [ true ]
		do
			let field=field+1
			word="$( get_word "$line" $field )"
			[ "$word" == "" -o "$word" == "host" -o "$word" == "any" -o "$( is_valid_ip "$word" )" == "0" ] && break
			ACL_SRC_PORTS="$ACL_SRC_PORTS $word"
		done
		if [ "$ACL_SRC_PORTS" == " " ]
		then
			ACL_SRC_PORTS="any"
		else
			ACL_SRC_PORTS=$( echo "$ACL_SRC_PORTS"|sed 's/^ //' )
		fi
	else
		ACL_SRC_PORTS="any"
	fi

	if [ "$word" == "any" ]
	then
		ACL_DST_NET="0.0.0.0"
		ACL_DST_MASK="0.0.0.0"
	elif [ "$word" == "host" ]
	then
		let field=field+1
		ACL_DST_NET="$( get_word "$line" $field )"
		[ $( is_valid_ip "$ACL_DST_NET" ) -ne 0 ] && echo "ERROR : Destination host IP address not recognized in $( print_acl_details )" && continue
		ACL_DST_MASK="255.255.255.255"
	elif [ "$( is_valid_ip "$word" )" == "0" ]
	then
		ACL_DST_NET="$word"
		let field=field+1
		ACL_DST_MASK="$( get_word "$line" $field )"
		if [ "$ACL_DST_MASK" == "" ]
		then
			ACL_DST_MASK="255.255.255.255"
		else
			ACL_DST_MASK=$( convert_mask "$ACL_DST_MASK" )
			[ "$ACL_DST_MASK" == "" ] && echo "ERROR : Destination mask not recognized in $( print_acl_details )" && continue
		fi
	fi

	let field=field+1
	word="$( get_word "$line" $field )"
	if [ "$word" == "" ]
	then
		ACL_DST_PORTS="any"
	elif [ "$word" == "eq" ]
	then
		ACL_DST_PORTS=""
		while [ true ]
		do
			let field=field+1
			word="$( get_word "$line" $field )"
			[ "$word" == "" ] && break
			ACL_DST_PORTS="$ACL_DST_PORTS $word"
		done
		ACL_DST_PORTS=$( echo "$ACL_DST_PORTS"|sed 's/^ //' )
	else
		echo "ERROR : Destination port(s) specification not recognized (word = $word) in $( print_acl_details )"
		continue
	fi

	[ $DEBUG -eq 1 ] && print_acl_details
	[ $ADD_COMMENT -eq 1 ] && echo "# ACL : $line"
	convert_2_iptables_cmd
	echo
done
ViewGit