LoginSignup
5
4

More than 5 years have passed since last update.

nl80211のmulticastに耳を傾けてみる

Posted at

nl80211 とは、netlink のうちの generic netlink の枠組みを使って作られているプロトコルです。libnl という標準的なライブラリが存在するのですが、内部で C の関数ポインタを使った callback が多用されていて、golang から扱いにくかったので pure golang でツールを書きました。ツールは go get github.com/hkwi/nlgo します。

まずは 802.11 でかつ nl80211 を使うドライバのデバイスを用意します(マシンに繋ぎます)。そして nl80211grp コマンド起動。

次で genl CTRL で nl80211 関連の multicast group id を調べています。nl80211 の中に config, scan, regulatory, mlme という multicast があることが分かります。

2015/02/16 11:52:32 "CTRL_ATTR(FAMILY_NAME: \"nl80211\\x00\", FAMILY_ID: 0x1e, VERSION: 0x1, HDRSIZE: 0x0, MAXATTR: 0xbf, OPS: [1: OP(ID: 0x1, FLAGS: 0xe), 2: OP(ID: 0x2, FLAGS: 0xb), 3: OP(ID: 0x5, FLAGS: 0xe), 4: OP(ID: 0x6, FLAGS: 0xb), 5: OP(ID: 0x7, FLAGS: 0xb), 6: OP(ID: 0x8, FLAGS: 0xb), 7: OP(ID: 0x9, FLAGS: 0xb), 8: OP(ID: 0xa, FLAGS: 0xb), 9: OP(ID: 0xb, FLAGS: 0xb), 10: OP(ID: 0xc, FLAGS: 0xb), 11: OP(ID: 0xe, FLAGS: 0xb), 12: OP(ID: 0xf, FLAGS: 0xb), 13: OP(ID: 0x10, FLAGS: 0xb), 14: OP(ID: 0x11, FLAGS: 0xe), 15: OP(ID: 0x12, FLAGS: 0xb), 16: OP(ID: 0x13, FLAGS: 0xb), 17: OP(ID: 0x14, FLAGS: 0xb), 18: OP(ID: 0x15, FLAGS: 0xf), 19: OP(ID: 0x16, FLAGS: 0xb), 20: OP(ID: 0x17, FLAGS: 0xb), 21: OP(ID: 0x18, FLAGS: 0xb), 22: OP(ID: 0x19, FLAGS: 0xb), 23: OP(ID: 0x1f, FLAGS: 0xa), 24: OP(ID: 0x1a, FLAGS: 0xb), 25: OP(ID: 0x1b, FLAGS: 0xb), 26: OP(ID: 0x1c, FLAGS: 0xa), 27: OP(ID: 0x1d, FLAGS: 0xb), 28: OP(ID: 0x21, FLAGS: 0xb), 29: OP(ID: 0x20, FLAGS: 0xc), 30: OP(ID: 0x4b, FLAGS: 0xb), 31: OP(ID: 0x4c, FLAGS: 0xb), 32: OP(ID: 0x25, FLAGS: 0xb), 33: OP(ID: 0x26, FLAGS: 0xb), 34: OP(ID: 0x27, FLAGS: 0xb), 35: OP(ID: 0x28, FLAGS: 0xb), 36: OP(ID: 0x2b, FLAGS: 0xb), 37: OP(ID: 0x2c, FLAGS: 0xb), 38: OP(ID: 0x2e, FLAGS: 0xb), 39: OP(ID: 0x30, FLAGS: 0xb), 40: OP(ID: 0x31, FLAGS: 0xb), 41: OP(ID: 0x32, FLAGS: 0xc), 42: OP(ID: 0x34, FLAGS: 0xb), 43: OP(ID: 0x35, FLAGS: 0xb), 44: OP(ID: 0x36, FLAGS: 0xb), 45: OP(ID: 0x37, FLAGS: 0xb), 46: OP(ID: 0x38, FLAGS: 0xb), 47: OP(ID: 0x39, FLAGS: 0xb), 48: OP(ID: 0x3a, FLAGS: 0xb), 49: OP(ID: 0x3b, FLAGS: 0xb), 50: OP(ID: 0x43, FLAGS: 0xb), 51: OP(ID: 0x3d, FLAGS: 0xb), 52: OP(ID: 0x3e, FLAGS: 0xa), 53: OP(ID: 0x3f, FLAGS: 0xb), 54: OP(ID: 0x41, FLAGS: 0xb), 55: OP(ID: 0x42, FLAGS: 0xb), 56: OP(ID: 0x44, FLAGS: 0xb), 57: OP(ID: 0x45, FLAGS: 0xb), 58: OP(ID: 0x49, FLAGS: 0xa), 59: OP(ID: 0x4a, FLAGS: 0xb), 60: OP(ID: 0x4f, FLAGS: 0xb), 61: OP(ID: 0x52, FLAGS: 0xb), 62: OP(ID: 0x51, FLAGS: 0xb), 63: OP(ID: 0x53, FLAGS: 0xb), 64: OP(ID: 0x54, FLAGS: 0xb), 65: OP(ID: 0x55, FLAGS: 0xb), 66: OP(ID: 0x57, FLAGS: 0xb), 67: OP(ID: 0x59, FLAGS: 0xb), 68: OP(ID: 0x5a, FLAGS: 0xb), 69: OP(ID: 0x5c, FLAGS: 0xb), 70: OP(ID: 0x5d, FLAGS: 0xb), 71: OP(ID: 0x5e, FLAGS: 0xb), 72: OP(ID: 0x5f, FLAGS: 0xa), 73: OP(ID: 0x60, FLAGS: 0xb), 74: OP(ID: 0x62, FLAGS: 0xb), 75: OP(ID: 0x63, FLAGS: 0xb), 76: OP(ID: 0x64, FLAGS: 0xa), 77: OP(ID: 0x65, FLAGS: 0xb), 78: OP(ID: 0x66, FLAGS: 0xb)], MCAST_GROUPS: [1: MCAST_GRP(GRP_ID: 0x7, NAME: \"config\\x00\"), 2: MCAST_GRP(GRP_ID: 0x8, NAME: \"scan\\x00\"), 3: MCAST_GRP(GRP_ID: 0x9, NAME: \"regulatory\\x00\"), 4: MCAST_GRP(GRP_ID: 0xa, NAME: \"mlme\\x00\")])"

ここで、nl80211 関連の group id 全てに参加します。こうすると、nl80211 の multicast が流れ込んでくることになります。

hostapd として起動させてみます。他の STA を接続し、解除すると次のようなシーケンスが出力されます。hostapd が association させるために投げている management frame の送信結果が漏れ聞こえてきます。そしておもむろに NL80211_CMD_NEW_STATION で新しい STA が接続されます。STA から接続解除すると NL80211_CMD_DEL_STATION が通知されます。

2015/02/16 11:52:45 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0x50, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x11, 0x4, 0x0, 0x8, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x32, 0x1, 0x8, 0x82, 0x84, 0x8b, 0x96, 0xc, 0x12, 0x18, 0x24, 0x3, 0x1, 0x1, 0x2a, 0x1, 0x4, 0x32, 0x4, 0x30, 0x48, 0x60, 0x6c, 0x7f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, COOKIE: 0xffff8800b21fa500)
2015/02/16 11:52:45 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0xb0, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x20, 0x28, 0x1, 0x0, 0x2, 0x0, 0xd, 0x0}, COOKIE: 0xffff8800b21fa000)
2015/02/16 11:52:45 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0x50, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x30, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x11, 0x4, 0x0, 0x8, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x32, 0x1, 0x8, 0x82, 0x84, 0x8b, 0x96, 0xc, 0x12, 0x18, 0x24, 0x3, 0x1, 0x1, 0x2a, 0x1, 0x4, 0x32, 0x4, 0x30, 0x48, 0x60, 0x6c, 0x7f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, COOKIE: 0xffff8800b21fa700)
2015/02/16 11:52:45 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0xb0, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x40, 0x28, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, COOKIE: 0xffff8800ad64b400)
2015/02/16 11:52:45 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0x10, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x50, 0x28, 0x11, 0x4, 0x0, 0x0, 0x1, 0xc0, 0x1, 0x8, 0x82, 0x84, 0x8b, 0x96, 0xc, 0x12, 0x18, 0x24, 0x32, 0x4, 0x30, 0x48, 0x60, 0x6c, 0x7f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, COOKIE: 0xffff8800b01c8900)
2015/02/16 11:52:45 NL80211_CMD_NEW_STATION attrs=NL80211_ATTR(IFINDEX: 0x7, MAC: []byte{0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d}, GENERATION: 0x5)
2015/02/16 11:52:54 NL80211_CMD_DEL_STATION attrs=NL80211_ATTR(IFINDEX: 0x7, MAC: []byte{0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d})
2015/02/16 11:52:55 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0xc0, 0x0, 0x3a, 0x1, 0x1c, 0xab, 0xa7, 0xf2, 0x13, 0x9d, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x0, 0x2a, 0x2, 0x0}, COOKIE: 0xffff8801b35d1200)
2015/02/16 14:41:52 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0xc0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x90, 0xf8, 0x3, 0x0}, COOKIE: 0xffff8800ab977d00)

次に hostapd を終了し、wpa_supplicant を起動させてみます。他の AP に接続し、解除すると次のようなシーケンスになります。

2015/02/16 14:45:36 NL80211_CMD_TRIGGER_SCAN attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, SCAN_SSIDS: [], SCAN_FREQUENCIES: [0: 0x96c, 1: 0x971, 2: 0x976, 3: 0x97b, 4: 0x980, 5: 0x985, 6: 0x98a, 7: 0x98f, 8: 0x994, 9: 0x999, 10: 0x99e, 11: 0x9a3, 12: 0x9a8, 13: 0x9b4])
2015/02/16 14:45:37 NL80211_CMD_NEW_SCAN_RESULTS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, SCAN_SSIDS: [], SCAN_FREQUENCIES: [0: 0x96c, 1: 0x971, 2: 0x976, 3: 0x97b, 4: 0x980, 5: 0x985, 6: 0x98a, 7: 0x98f, 8: 0x994, 9: 0x999, 10: 0x99e, 11: 0x9a3, 12: 0x9a8, 13: 0x9b4])
2015/02/16 14:45:37 NL80211_CMD_NEW_STATION attrs=NL80211_ATTR(IFINDEX: 0x7, MAC: []byte{0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0}, GENERATION: 0x7)
2015/02/16 14:45:37 NL80211_CMD_AUTHENTICATE attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, FRAME: []byte{0xb0, 0x0, 0x30, 0x1, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0xf0, 0x4a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0})
2015/02/16 14:45:37 NL80211_CMD_ASSOCIATE attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, FRAME: []byte{0x10, 0x0, 0x30, 0x1, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x0, 0x4b, 0x31, 0x4, 0x0, 0x0, 0x1, 0xc0, 0x1, 0x8, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, 0x32, 0x4, 0xc, 0x18, 0x30, 0x60, 0xdd, 0x18, 0x0, 0x50, 0xf2, 0x2, 0x1, 0x1, 0x0, 0x0, 0x3, 0xa4, 0x0, 0x0, 0x27, 0xa4, 0x0, 0x0, 0x42, 0x43, 0x5e, 0x0, 0x62, 0x32, 0x2f, 0x0, 0x2d, 0x1a, 0xee, 0x11, 0x17, 0xff, 0xff, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x16, 0xa, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0x1e, 0x0, 0x90, 0x4c, 0x33, 0xee, 0x11, 0x17, 0xff, 0xff, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0x1a, 0x0, 0x90, 0x4c, 0x34, 0xa, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0xe, 0x14, 0x0, 0xa, 0x0, 0x2c, 0x1, 0xc8, 0x0, 0x14, 0x0, 0x5, 0x0, 0x19, 0x0, 0x7f, 0x1, 0x1, 0xdd, 0x7, 0x0, 0xc, 0x43, 0x7, 0x0, 0x0, 0x0})
2015/02/16 14:45:37 NL80211_CMD_CONNECT attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, MAC: []byte{0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0}, STATUS_CODE: 0x0, RESP_IE: []byte{0x1, 0x8, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, 0x32, 0x4, 0xc, 0x18, 0x30, 0x60, 0xdd, 0x18, 0x0, 0x50, 0xf2, 0x2, 0x1, 0x1, 0x0, 0x0, 0x3, 0xa4, 0x0, 0x0, 0x27, 0xa4, 0x0, 0x0, 0x42, 0x43, 0x5e, 0x0, 0x62, 0x32, 0x2f, 0x0, 0x2d, 0x1a, 0xee, 0x11, 0x17, 0xff, 0xff, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x16, 0xa, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0x1e, 0x0, 0x90, 0x4c, 0x33, 0xee, 0x11, 0x17, 0xff, 0xff, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0x1a, 0x0, 0x90, 0x4c, 0x34, 0xa, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0xe, 0x14, 0x0, 0xa, 0x0, 0x2c, 0x1, 0xc8, 0x0, 0x14, 0x0, 0x5, 0x0, 0x19, 0x0, 0x7f, 0x1, 0x1, 0xdd, 0x7, 0x0, 0xc, 0x43, 0x7, 0x0, 0x0, 0x0})
2015/02/16 14:45:37 NL80211_CMD_REG_CHANGE attrs=NL80211_ATTR(REG_INITIATOR: 0x5, REG_TYPE: 0x5, REG_ALPHA2: "JP\x00", WIPHY: 0x2)
2015/02/16 14:50:38 NL80211_CMD_TRIGGER_SCAN attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, SCAN_SSIDS: [], SCAN_FREQUENCIES: [0: 0x98a, 1: 0x98f, 2: 0x994, 3: 0x999, 4: 0x99e, 5: 0x9a3, 6: 0x9a8, 7: 0x9b4], SCAN_FLAGS: 0x1)
2015/02/16 14:50:40 NL80211_CMD_NEW_SCAN_RESULTS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, SCAN_SSIDS: [], SCAN_FREQUENCIES: [0: 0x98a, 1: 0x98f, 2: 0x994, 3: 0x999, 4: 0x99e, 5: 0x9a3, 6: 0x9a8, 7: 0x9b4], SCAN_FLAGS: 0x1)
2015/02/16 14:50:40 NL80211_CMD_FRAME_TX_STATUS attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, WDEV: 0x200000001, FRAME: []byte{0xd0, 0x0, 0xda, 0x0, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0xa0, 0xff, 0x4, 0x0, 0x48, 0x1, 0x0}, COOKIE: 0xffff8800ad7c6c00)
2015/02/16 14:51:34 NL80211_CMD_DEL_STATION attrs=NL80211_ATTR(IFINDEX: 0x7, MAC: []byte{0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0})
2015/02/16 14:51:34 NL80211_CMD_DEAUTHENTICATE attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7, FRAME: []byte{0xc0, 0x0, 0x0, 0x0, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x10, 0x6f, 0x3f, 0xb0, 0x88, 0xfa, 0x0, 0x22, 0xcf, 0xe7, 0x6f, 0xf0, 0x0, 0x0, 0x3, 0x0})
2015/02/16 14:51:34 NL80211_CMD_DISCONNECT attrs=NL80211_ATTR(WIPHY: 0x2, IFINDEX: 0x7)
2015/02/16 14:51:34 NL80211_CMD_REG_CHANGE attrs=NL80211_ATTR(REG_INITIATOR: 0x5, REG_TYPE: 0x5, WIPHY: 0x0)
2015/02/16 14:51:34 NL80211_CMD_REG_CHANGE attrs=NL80211_ATTR(REG_INITIATOR: 0x5, REG_TYPE: 0x5, REG_ALPHA2: "JP\x00")
5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4