Friday, June 5, 2009

Protecting from ARP attack – Dynamic ARP Inspection (DAI)

My environment: Cisco Catalyst 3560E
IOS: c3560e-universal-mz.122-35.SE5.bin

Before a PC can talk to another PC, it must do an ARP request to map the IP address to a MAC address.

For example:

Client A (ARP Request Broadcast): Who is

Client B (ARP Reply): I am, mac address B

A client can send out unsolicited reply (gratuitous ARP) according to the ARP RFC.  That means anyone can claim to be the owner of any IP-MAC address pair.  ARP attack is using this to poison the ARP cache on switch and redirect the traffic.

Dynamic ARP inspection is a security feature to protect from ARP attack based on DHCP snooping binding database. 

! Global Command
ip arp inspection vlan 168,201

! Interface that you want to trust
ip arp inspection trust

! Default untrust
no ip arp inspection trust

For those host with static IP address (not get address from DHCP server), their information will not be stored in the DHCP binding table therefore you will get reject message on the console.

Jun  5 12:31:40.734 HKT: %SW_DAI-4-DHCP_SNOOPING_DENY: 1 Invalid ARPs (Req) on Gi0/4, vlan 201.([000c.29f2.6a88/ HKT Fri Jun 5 2009])

In that case you’ll need to create an ARP access-list to allow static address hosts:

! Define ARP ACL
pandaeatsbamboo-sw01(config)#arp access-list allow-arp
pandaeatsbamboo-sw01(config-arp-nacl)#permit ip host mac any

! Apply ARP ACL to DAI
pandaeatsbamboo-sw01(config)#ip arp inspection filter allow-arp vlan 201

Protecting from Rogue DHCP server attacks – DHCP Snooping

My environment: Cisco Catalyst 3560E
IOS: c3560e-universal-mz.122-35.SE5.bin

One of the common DHCP server attack is rogue dhcp server attack, the potential problem is the attacker will become the hosts’ default gateway or DNS server.  DHCP snooping can prevent it from happening by untrusting the switchport that are not connecting to the DHCP server.

! Global Command

! which vlan you would like to snoop
ip dhcp snooping vlan 168,201

! this is important otherwise this feature is not enabled
ip dhcp snooping

! Switchport configuration for DHCP server
int gi0/4
ip dhcp snooping trust

! User-facing switchport configuration, default untrust
int gi0/5
no ip dhcp snooping trust

To showing the DHCP snooping binding:

pandaeatsbamboo-sw01#sh ip dhcp snooping binding
MacAddress IpAddress Lease(sec) Type VLAN Interface
------------------ --------------- ---------- ------------- ---- --------------------
00:16:C8:FF:C4:6D 80179 dhcp-snooping 201 GigabitEthernet0/6
00:17:E0:1C:AB:1A 79680 dhcp-snooping 201 GigabitEthernet0/8
Total number of bindings: 2

DHCP Snooping table can be written to flash or external storage.  Very importantly if you want to get the DHCP snooping database agent working, you MUST synchronize your switch with NTP, you can verify it with the command “sh ntp status”, make sure the clock is synchronized.

ip dhcp snooping database tftp://


Then you can show ip dhcp snooping database to verify:

pandaeatsbamboo-sw01#sh ip dhcp snooping database
Agent URL : tftp://
Write delay Timer : 15 seconds
Abort Timer : 300 seconds

Agent Running : No
Delay Timer Expiry : Not Running
Abort Timer Expiry : Not Running

Last Succeded Time : 10:29:01 HKT Fri Jun 5 2009
Last Failed Time : 18:35:29 HKT Wed Jun 3 2009
Last Failed Reason : Unable to access URL.

Total Attempts : 1206 Startup Failures : 0
Successful Transfers : 1205 Failed Transfers : 1
Successful Reads : 2 Failed Reads : 0
Successful Writes : 1203 Failed Writes : 1
Media Failures : 0

Thursday, June 4, 2009

Pktgen – a tool to generate packets at very high speed in the kernel

My environment: RedHat Fedora Core 8 x86_64

Firstly check if your pktgen is running:

[root@pandaeatsbamboo pktgen]# ps -e | grep pktgen
8913 ?        00:01:55 kpktgend_0
8914 ?        00:01:55 kpktgend_1
8915 ?        00:00:01 kpktgend_2
8916 ?        00:00:01 kpktgend_3

I have a quad-core AMD CPU therefore you will see 4 processes there.  Pktgen creates 1 thread per CPU.

If you can’t see that, try to:
modprobe pktgen

I have 2 NIC card, eth0 and eth1, here is my sample shell script to kick start the pktgen:

#! /bin/sh


#modprobe pktgen



function pgset() {

    local result


    echo $1 > $PGDEV


    result=`cat $PGDEV | fgrep "Result: OK:"`

    if [ "$result" = "" ]; then

         cat $PGDEV | fgrep Result:




function pg() {

    echo inject > $PGDEV

    cat $PGDEV



# Config Start Here -----------------------------------------------------------



# thread config

# Each CPU has own thread. Two CPU exammple. We add eth1, eth2 respectivly.



  echo "Removing all devices"

 pgset "rem_device_all"

  echo "Adding eth0"

 pgset "add_device eth0"

  echo "Setting max_before_softirq 10000"

 pgset "max_before_softirq 10000"



  echo "Removing all devices"

 pgset "rem_device_all"

  echo "Adding eth1"

 pgset "add_device eth1"

  echo "Setting max_before_softirq 10000"

 pgset "max_before_softirq 10000"



# device config

# delay 0 means maximum speed.


CLONE_SKB="clone_skb 1000000"

# NIC adds 4 bytes CRC

PKT_SIZE="pkt_size 60"


# COUNT 0 means forever

#COUNT="count 0"

COUNT="count 10000000"

DELAY="delay 0"



  echo "Configuring $PGDEV"

 pgset "$COUNT"

 pgset "$CLONE_SKB"

 pgset "$PKT_SIZE"

 pgset "$DELAY"

 pgset "dst"

 pgset "dst_mac  00:24:51:13:06:41"



  echo "Configuring $PGDEV"

 pgset "$COUNT"

 pgset "$CLONE_SKB"

 pgset "$PKT_SIZE"

 pgset "$DELAY"

 pgset "dst"

 pgset "dst_mac  00:24:51:13:06:43"


# Time to run



 echo "Running... ctrl^C to stop"

 pgset "start"

 echo "Done"

To view the statistics, check the files in /proc/net/pktgen/ethX

[root@pandaeatsbamboo pktgen]# less /proc/net/pktgen/eth0

Params: count 10000000  min_pkt_size: 60  max_pkt_size: 60

     frags: 0  delay: 0  clone_skb: 1000000  ifname: eth0

     flows: 0 flowlen: 0

     queue_map_min: 0  queue_map_max: 0

     dst_min:  dst_max:

     src_min:   src_max:

     src_mac: 00:1f:d0:50:19:6d dst_mac: 00:24:51:13:06:41

     udp_src_min: 9  udp_src_max: 9  udp_dst_min: 9  udp_dst_max: 9

     src_mac_count: 0  dst_mac_count: 0



     pkts-sofar: 10000000  errors: 0

     started: 1244025262231283us  stopped: 1244025310237392us idle: 11640574us

     seq_num: 10000001  cur_dst_mac_offset: 0  cur_src_mac_offset: 0

     cur_saddr: 0xfa016aa8  cur_daddr: 0xf8016aa8

     cur_udp_dst: 9  cur_udp_src: 9

     cur_queue_map: 0

     flows: 0

Result: OK: 48006109(c36365535+d11640574) usec, 10000000 (60byte,0frags)

  208306pps 99Mb/sec (99986880bps) errors: 0

To learn more you can visit here: