rtnetlink 가 무선 네트워크 카드 정 보 를 받 는 소스 코드 인 스 턴 스 [전환] 를 분석 합 니 다.
77268 단어 TCPIP
rtnetlink wireless 【 】
: luther (gliethttp)
http://blog.chinaunix.net/u1/38994/showart_1353632.html
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/wireless.h>
#include <linux/sockios.h>
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define luther_printf(msg...) printf("===luther:=== "msg)
struct luther_context {
int ioctl_sock;
int event_sock;
char ifname[IFNAMSIZ + 1];
int ifindex;
int ifindex2;
int has_capability;
int we_version_compiled;
} luther_context = {
.ifname = "eth0",
.ifindex = -1,
.ifindex2 = -1,
};
static void luther_event_rtm_newlink(struct luther_context *ctx,
struct nlmsghdr *h, size_t len);
static void luther_event_rtm_dellink(struct luther_context *ctx,
struct nlmsghdr *h, size_t len);
static void luther_wext_event_wireless(struct luther_context *ctx,
char *data, int len);
static void luther_wext_event_link(struct luther_context *ctx, char *buf, size_t len,
int del);
static int luther_wext_get_range(struct luther_context *ctx);
static unsigned int if_nametoindex(const char *ifname);
int main(int argc, char *argv[])
{
struct sockaddr_nl local;
luther_context.ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (luther_context.ioctl_sock < 0) {
perror("socket(PF_INET,SOCK_DGRAM)");
return 0;
}
luther_context.event_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (luther_context.event_sock < 0) {
perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
close(luther_context.ioctl_sock);
return 0;
}
memset(&local, 0, sizeof(local));
local.nl_family = AF_NETLINK;
local.nl_groups = RTMGRP_LINK;
if (bind(luther_context.event_sock, (struct sockaddr *) &local, sizeof(local)) < 0) {
perror("bind(netlink)");
close(luther_context.ioctl_sock);
close(luther_context.event_sock);
return 0;
}
if (argc == 2) {
strcpy(luther_context.ifname, argv[1]);
}
if( luther_wext_get_range(&luther_context) < 0) {
close(luther_context.ioctl_sock);
close(luther_context.event_sock);
return 0;
}
luther_context.ifindex = luther_context.ifname[0] ? if_nametoindex(luther_context.ifname) : -1;
do {
char buf[8192];
int left;
struct sockaddr_nl from;
socklen_t fromlen;
struct nlmsghdr *h;
int sock = luther_context.event_sock;
struct luther_context *ctx = &luther_context;
int max_events = 10;
try_again:
fromlen = sizeof(from);
left = recvfrom(sock, buf, sizeof(buf), 0/* MSG_DONTWAIT */,
(struct sockaddr *) &from, &fromlen);
if (left < 0) {
if (errno != EINTR && errno != EAGAIN)
perror("recvfrom(netlink)");
return 0;
}
h = (struct nlmsghdr *) buf;
while (left >= (int) sizeof(*h)) {
int len, plen;
len = h->nlmsg_len;
plen = len - sizeof(*h);
if (len > left || plen < 0) {
luther_printf("Malformed netlink message: "
rtnetlin
"len=%d left=%d plen=%d/n",
len, left, plen);
break;
}
switch (h->nlmsg_type) {
case RTM_NEWLINK:
luther_event_rtm_newlink(ctx, h, plen);
break;
case RTM_DELLINK:
luther_event_rtm_dellink(ctx, h, plen);
break;
}
len = NLMSG_ALIGN(len);
left -= len;
h = (struct nlmsghdr *) ((char *) h + len);
}
if (left > 0) {
luther_printf("%d extra bytes in the end of netlink "
"message/n", left);
}
if (--max_events > 0) {
/*
* Try to receive all events in one eloop call in order to
* limit race condition on cases where AssocInfo event, Assoc
* event, and EAPOL frames are received more or less at the
* same time. We want to process the event messages first
* before starting EAPOL processing.
*/
goto try_again;
}
goto try_again;
} while (0) ;
}
static void luther_event_rtm_newlink(struct luther_context *ctx,
struct nlmsghdr *h, size_t len)
{
struct ifinfomsg *ifi;
int attrlen, nlmsg_len, rta_len;
struct rtattr * attr;
if (len < sizeof(*ifi))
return;
ifi = NLMSG_DATA(h);
if ((ctx->ifindex != ifi->ifi_index && ctx->ifindex2 != ifi->ifi_index) && (ctx->ifindex != -1)) {
luther_printf("Ignore event for foreign ifindex %d/n",
ifi->ifi_index);
return;
}
/*
luther_printf("RTM_NEWLINK: ifi_flags=0x%x "
"(%s%s)/n",
ifi->ifi_flags,
(ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
(ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "");
*/
nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
attrlen = h->nlmsg_len - nlmsg_len;
if (attrlen < 0)
return;
attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
if (attr->rta_type == IFLA_WIRELESS) {
luther_wext_event_wireless(
ctx, ((char *) attr) + rta_len,
attr->rta_len - rta_len);
} else if (attr->rta_type == IFLA_IFNAME) {
luther_wext_event_link(ctx,
((char *) attr) + rta_len,
attr->rta_len - rta_len, 0);
}
attr = RTA_NEXT(attr, attrlen);
}
}
static void luther_event_rtm_dellink(struct luther_context *ctx,
struct nlmsghdr *h, size_t len)
{
struct ifinfomsg *ifi;
int attrlen, nlmsg_len, rta_len;
struct rtattr * attr;
if (len < sizeof(*ifi))
return;
ifi = NLMSG_DATA(h);
nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
attrlen = h->nlmsg_len - nlmsg_len;
if (attrlen < 0)
return;
attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
if (attr->rta_type == IFLA_IFNAME) {
luther_wext_event_link(ctx,
((char *) attr) + rta_len,
attr->rta_len - rta_len, 1);
}
attr = RTA_NEXT(attr, attrlen);
}
}
static void luther_wext_event_wireless(struct luther_context *ctx,
char *data, int len)
{
struct iw_event iwe_buf, *iwe = &iwe_buf;
char *pos, *end, *custom, *buf;
pos = data;
end = data + len;
while (pos + IW_EV_LCP_LEN <= end) {
/* Event data may be unaligned, so make a local, aligned copy
* before processing. */
memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
luther_printf("event: cmd=0x%x len=%d/n",
iwe->cmd, iwe->len);
if (iwe->len <= IW_EV_LCP_LEN)
return;
custom = pos + IW_EV_POINT_LEN;
if (ctx->we_version_compiled > 18 &&
(iwe->cmd == IWEVMICHAELMICFAILURE ||
iwe->cmd == IWEVCUSTOM ||
iwe->cmd == IWEVASSOCREQIE ||
iwe->cmd == IWEVASSOCRESPIE ||
iwe->cmd == IWEVPMKIDCAND)) {
/* WE-19 removed the pointer from struct iw_point */
char *dpos = (char *) &iwe_buf.u.data.length;
int dlen = dpos - (char *) &iwe_buf;
memcpy(dpos, pos + IW_EV_LCP_LEN,
sizeof(struct iw_event) - dlen);
} else {
memcpy(&iwe_buf, pos, sizeof(struct iw_event));
custom += IW_EV_POINT_OFF;
}
switch (iwe->cmd) {
case SIOCGIWAP:
luther_printf("event: new AP: "
MACSTR,
MAC2STR((unsigned char *) iwe->u.ap_addr.sa_data));
if (memcmp(iwe->u.ap_addr.sa_data,
"/x00/x00/x00/x00/x00/x00", ETH_ALEN) ==
0 ||
memcmp(iwe->u.ap_addr.sa_data,
"/x44/x44/x44/x44/x44/x44", ETH_ALEN) ==
0) {
luther_printf("event : Disconnect/n");
} else {
luther_printf("event : Associated to a new BSS/n");
}
break;
case IWEVMICHAELMICFAILURE:
luther_printf("event : Michael MIC failure wireless/n");
break;
case IWEVCUSTOM:
if (custom + iwe->u.data.length > end)
return;
buf = malloc(iwe->u.data.length + 1);
if (buf == NULL)
return;
memcpy(buf, custom, iwe->u.data.length);
buf[iwe->u.data.length] = '/0';
luther_printf("event : custom -> %s/n", buf);
free(buf);
break;
case SIOCGIWSCAN:
luther_printf("event : scan_results/n");
break;
case IWEVASSOCREQIE:
luther_printf("event : AssocReq IE wireless/n");
break;
case IWEVASSOCRESPIE:
luther_printf("event : AssocResp IE wireless/n");
break;
case IWEVPMKIDCAND:
luther_printf("event : PMKID candidate wireless/n");
break;
}
pos += iwe->len;
}
}
static void luther_wext_event_link(struct luther_context *ctx, char *buf, size_t len,
int del)
{
luther_printf("RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s/n",
del ? "DEL" : "NEW",
buf,
rtnetlin
del ? "removed" : "added");
}
static int luther_wext_get_range(struct luther_context *ctx)
{
struct iw_range *range;
struct iwreq iwr;
int minlen;
size_t buflen;
/*
* Use larger buffer than struct iw_range in order to allow the
* structure to grow in the future.
*/
buflen = sizeof(struct iw_range) + 500;
range = calloc(buflen, 1);
if (range == NULL)
return -1;
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, ctx->ifname, IFNAMSIZ);
iwr.u.data.pointer = (caddr_t) range;
iwr.u.data.length = buflen;
minlen = ((char *) &range->enc_capa) - (char *) range +
sizeof(range->enc_capa);
if (ioctl(ctx->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
perror("ioctl[SIOCGIWRANGE]");
free(range);
return -1;
} else if (iwr.u.data.length >= minlen &&
range->we_version_compiled >= 18) {
/*
luther_printf("SIOCGIWRANGE: WE(compiled)=%d "
"WE(source)=%d enc_capa=0x%x/n",
range->we_version_compiled,
range->we_version_source,
range->enc_capa);
*/
ctx->has_capability = 1;
ctx->we_version_compiled = range->we_version_compiled;
} else {
luther_printf("SIOCGIWRANGE: too old (short) data - "
"assuming WPA is not supported/n");
}
free(range);
return 0;
}
static unsigned int if_nametoindex(const char *ifname)
{
struct ifreq ifr;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
return 0;
strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
ifr.ifr_ifindex = 0;
if (ioctl (fd, SIOCGIFINDEX, &ifr) < 0) {
return 0;
}
return ifr.ifr_ifindex;
}
luther@gliethttp:~$ arm-linux-gcc -o rtnetlink rtnetlink.c ;arm-linux-strip -s rtnetlink
/telephony/modules # tftp -r rtnetlink -g 192.168.100.1
/telephony/modules # ./rtnetlink &
===luther:=== event: cmd=0x8b06 len=8
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== event: cmd=0x8b19 len=8
===luther:=== event : scan_results
===luther:=== event: cmd=0x8b06 len=8
===luther:=== event: cmd=0x8b04 len=12
===luther:=== event: cmd=0x8b15 len=20
===luther:=== event: new AP: 00:1d:7e:a0:0e:81
===luther:=== event : Associated to a new BSS
===luther:=== event: cmd=0x8b1a len=22
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== event: cmd=0x8b06 len=8
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== event: cmd=0x8b19 len=8
===luther:=== event : scan_results
===luther:=== event: cmd=0x8b06 len=8
===luther:=== event: cmd=0x8b04 len=12
===luther:=== event: cmd=0x8b15 len=20
===luther:=== event: new AP: 00:1d:7e:a0:0e:81
===luther:=== event : Associated to a new BSS
===luther:=== event: cmd=0x8b1a len=22
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== RTM_NEWLINK, IFLA_IFNAME: Interface 'eth0' added
===luther:=== event: cmd=0x8c02 len=28
===luther:=== event : custom -> HS_DEACTIVATED
===luther:=== event: cmd=0x8c02 len=26
===luther:=== event : custom -> HS_ACTIVATED
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
네트워크 프로토콜이란?프로토콜(TCP/IP 등)을 사용하여 컴퓨터 간 통신이 가능합니다. 통신 프로토콜에는 다양한 역할이 있으며, 각 프로토콜이 연계되어 통신이 실현되고 있으며, 그 프로토콜은 계층적인 구조로 되어 있습니다. 예를 들어 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.