#compdef ifconfig

local curcontext="$curcontext" state line ret=1
local -a opts args alias debug updownlist

alias=( '(-alias alias)'{,-}'alias[remove or establish alternate address for if]' )
debug=( '(-debug debug)'{,-}'debug[disable or enable debugging code]' )
updownlist=(
  '(-a -d -C)-u[restrict to interfaces which are up]'
  '(-a -u -C)-d[restrict to interfaces which are down]'
  '(-a -C -m -L 1 *)-l[list interfaces]'
)

case $OSTYPE in
  darwin*)
    args=( -s $updownlist )
    opts=(
      $alias $debug delete dest_address ipdst nsellength
      {,-}trailers {,-}link{0,1,2}
    )
  ;;
  freebsd*)
    args=( -s $updown
      '(-a -l -u -d -m -L 1 *)-C[list interface cloners]'
      '(-l -C)-m[list supported media]'
      '(-l -C)-L[show address lifetime as time offset]'
    )
    opts=( $alias $debug
      anycast lladdr media {,-}mediaopt {,delete}tunnel create destroy
      {,un}plumb vlan {,-}vlandev metric prefixlen range phase ssid muid
      stationname channel authmode {,-}powersave powersavesleep wepmode
      {,-}wep {,-}nwkey add delete ether {,-}link{0,1,2}
    )
  ;;
  irix5*) opts=( $debug ) ;;
  irix6*)
    opts=( $debug {-,}highbw {,-}link{0,1,2} primary rspace sspace  )
    args=( '-w[display additional information]' )
  ;;
  linux*)
    opts=(
      '(-promisc promisc)'{,-}'promisc[disable or enable promiscuous mode]'
      '(-allmulti allmulti)'{,-}'allmulti[disable or enable all-multicast]'
      'media[set physical port type]' 'hw[set hardware class]'
      add del dstaddr io_addr irq mem_start multicast pointopoint
      tunnel txqueuelen
    )
  ;;
  solaris*)
    args=(
      '-ad[apply to all down interfaces]'
      '-adD[apply to all down interfaces not controlled by DHCP]'
      '-au[apply to all up interfaces]'
      '-auD[apply to all up interfaces not controlled by DHCP]'
    )
    opts=(
      'auto-revarp[use RARP to acquire address]'
      {,-}trailers {,-}private {,un}plumb
      '(dhcp auto-dhcp)'{,auto-}'dhcp[use dhcp]'
      primary wait drop extend ping release start status
    )
  ;;
esac

_arguments -C "$args[@]" \
  '-a[apply to all interfaces]' \
  '1:network interface:_net_interfaces' \
  '::address family:(atalk ether inet inet6 ax25 ddp ipx netrom)' \
  '*:option:->options' && ret=0
  
[[ -n "$state" ]] && _values -S ' ' 'option' "$opts[@]" \
  '(down)up[activate interface]' \
  '(up)down[shut down interface]' \
  '(-arp arp)'{,-}'arp[disable or enable address resolution protocol]' \
  'metric[set routing metric for interface]' \
  'mtu[set maximum transfer unit]' \
  'netmask[specify network mask]' \
  'broadcast[specify broadcast address]' \
  'address[specify IP address of interface]' && ret=0

return ret
