【 ... 】或
【【...】】之间的是我加的,其他的为代码或问题
按照自己的理解看的,不知对不对。
1. 在eloop_run()中,最后的对信号的处理,即套接字上有消息的处理是怎么做的,(看到了代码,但是不理解是在做什么,
static void eloop_process_pending_signals(void)
{
int i;
if (eloop.signaled == 0)
return;
eloop.signaled = 0;
if (eloop.pending_terminate) {
#ifndef CONFIG_NATIVE_WINDOWS
alarm(0);
#endif /* CONFIG_NATIVE_WINDOWS */
eloop.pending_terminate = 0;
}
for (i = 0; i < eloop.signal_count; i++) {
if (eloop.signals[i].signaled) {
eloop.signals[i].signaled = 0;
【这里开始对收到的信号处理,
这是指
#ifndef CONFIG_NATIVE_WINDOWS
eloop_register_signal(SIGHUP, handle_reload, NULL);
eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
#endif /* CONFIG_NATIVE_WINDOWS */
eloop_register_signal_terminate(handle_term, NULL);
注册的系统信号处理,这还不是你关心的内容了。还有收到TERM的处理】
eloop.signals[i].handler(eloop.signals[i].sig,
eloop.user_data,
eloop.signals[i].user_data);
}
}
})
eloop_run()是非阻塞socket,那么最后得到的是什么?如果没有返回值,又是做了什么操作?
【
系统运行期间一直在里面while循环的,
void eloop_run(void)
{
fd_set *rfds, *wfds, *efds;
int res;
struct timeval _tv;
struct os_time tv, now;
rfds = os_malloc(sizeof(*rfds));
wfds = os_malloc(sizeof(*wfds));
efds = os_malloc(sizeof(*efds));
if (rfds == NULL || wfds == NULL || efds == NULL) {
printf("eloop_run - malloc failed/n");
goto out;
}
while (!eloop.terminate &&
(eloop.timeout || eloop.readers.count > 0 ||
eloop.writers.count > 0 || eloop.exceptions.count > 0))
{
【【正常情况都在这里面循环,除非terminate为1,而这个有信号处理设置.
参见
eloop_register_signal_terminate(handle_term, NULL);
static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
{
wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
eloop_terminate();
}
void eloop_terminate(void)
{
eloop.terminate = 1;
}
】】
if (eloop.timeout) {
os_get_time(&now);
if (os_time_before(&now, &eloop.timeout->time))
os_time_sub(&eloop.timeout->time, &now, &tv);
else
tv.sec = tv.usec = 0;
#if 0
printf("next timeout in %lu.%06lu sec/n",
tv.sec, tv.usec);
#endif _tv.tv_sec = tv.sec;
_tv.tv_usec = tv.usec;
}
eloop_sock_table_set_fds(&eloop.readers, rfds);
eloop_sock_table_set_fds(&eloop.writers, wfds);
eloop_sock_table_set_fds(&eloop.exceptions, efds);
res = select(eloop.max_sock + 1, rfds, wfds, efds,
eloop.timeout ? &_tv : NULL);
if (res < 0 && errno != EINTR && errno != 0) {
perror("select");
goto out;
}
eloop_process_pending_signals();
/* check if some registered timeouts have occurred */
if (eloop.timeout) {
struct eloop_timeout *tmp;
os_get_time(&now);
if (!os_time_before(&now, &eloop.timeout->time)) {
tmp = eloop.timeout;
eloop.timeout = eloop.timeout->next;
tmp->handler(tmp->eloop_data,
tmp->user_data);
os_free(tmp);
}
}
if (res <= 0)
continue;
eloop_sock_table_dispatch(&eloop.readers, rfds);
eloop_sock_table_dispatch(&eloop.writers, wfds);
eloop_sock_table_dispatch(&eloop.exceptions, efds);
}
out:
os_free(rfds);
os_free(wfds);
os_free(efds);
}
【【
第一次的时候说到l2_packet_init
struct l2_packet_data * l2_packet_init(
const char *ifname, const u8 *own_addr, unsigned short protocol,
void (*rx_callback)(void *ctx, const u8 *src_addr,
const u8 *buf, size_t len),
void *rx_callback_ctx, int l2_hdr)
{
……
eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);
return l2;
}
call int eloop_register_read_sock(int sock, eloop_sock_handler handler,
void *eloop_data, void *user_data)
{ 这里handler即l2_packet_receive
return eloop_register_sock(sock, EVENT_TYPE_READ, handler,
eloop_data, user_data);
}
最后通过
static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
int sock, eloop_sock_handler handler,
void *eloop_data, void *user_data)
将socket可读消息的handler回调函数设为了l2_packet_receive,
(其实代码看madwifi还注册了别的,如hostapd.c里面的
/* TODO: merge with hostapd_driver_init() ? */
if (hostapd_wireless_event_init(hapd) < 0)
return -1;有注释说明会给hostapd_drive_init合并
应该也会对这些socket来说也会走到的,进行相应处理,未关注。
)
再回头看eloop_sock_table_dispatch(&eloop.readers, rfds);
static void eloop_sock_table_dispatch(struct eloop_sock_table *table,
fd_set *fds)
{
int i;
if (table == NULL || table->table == NULL)
return;
table->changed = 0;
for (i = 0; i < table->count; i++) {
if (FD_ISSET(table->table[i].sock, fds)) {
table->table[i].handler(table->table[i].sock,
table->table[i].eloop_data,
table->table[i].user_data);
if (table->changed)
break;
}
}
}这里的handler就是l2_packet_receive或madwifi_wireless_event_receive等函数
l2_packet_receiv这个有通过第一次说的l2_packet_init设的handle_read执行。
】】
】
客户端应该是以UDP的形式发包吧?我Device端使用eloop_run()来接收,期间eloop_run()是将EAPOL帧怎样存放的,你在第一次给我的回复中,使用Madwifi初始化中得到的,现在就是从eloop_run()的结果到ieee802_1x_receive()中参数调用*buf的过程不很明确,
【
认证阶段都没有ip,怎么会是UDP?
再一次看这个,当select到read-sock有消息时,最终call到这里
static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
struct l2_packet_data *l2 = eloop_ctx;
u8 buf[2300];
int res;
struct sockaddr_ll ll;
socklen_t fromlen;
os_memset(&ll, 0, sizeof(ll));
fromlen = sizeof(ll);
res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &ll,
&fromlen);
这里收raw_socket,注意是L2, 直接读取链路层数据。Res就是消息长度,地址在ll里面。
if (res < 0) {
perror("l2_packet_receive - recvfrom");
return;
}
这个就是第一次说的handle_read了
l2->rx_callback(l2->rx_callback_ctx, ll.sll_addr, buf, res);
}
】
2.对于函数static void handle_eap_response(struct hostapd_data *hapd,
struct sta_info *sta, struct eap_hdr *eap,
size_t len) ieee802_1x.c
按照理论是应该就收到客户端发来的response(即EAPOL_Response/identity和challenged password两种报文),作为device功能就是将这个报文转发给RADUIS就可以了,我这样的理解是否有问题?如此说来,我就对handle_eap_response()函数的操作看不懂了,没看懂他是怎么实现的这个目的
static void handle_eap_response(struct hostapd_data *hapd,
struct sta_info *sta, struct eap_hdr *eap,
size_t len)
{
u8 type, *data;
struct eapol_state_machine *sm = sta->eapol_sm;
if (sm == NULL)
return;
data = (u8 *) (eap + 1);
if (len < sizeof(*eap) + 1) {
printf("handle_eap_response: too short response data/n");
return;
}
sm->eap_type_supp = type = data[0];
hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "
"id=%d len=%d) from STA: EAP Response-%s (%d)",
eap->code, eap->identifier, be_to_host16(eap->length),
eap_type_text(type), type);
sm->dot1xAuthEapolRespFramesRx++;
wpabuf_free(sm->eap_if->eapRespData);
sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);
sm->eapolEap = TRUE;
}
请指教。
【A:
ieee802_1x_receive
1{
if IEEE802_1X_TYPE_EAP_PACKET
2{
call handle_eap
3{
if response
call handle_eap_response
exec sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);设置好respData即可
3}
2}
//执行状态机,里面完成转发等系列
eapol_auth_step(sta->eapol_sm);
1}
】