免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2772 | 回复: 1
打印 上一主题 下一主题

[C] [零献续集] 神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part4) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-01 10:42 |只看该作者 |倒序浏览
前面几个part见 http://bbs.chinaunix.net/viewthread.php?tid=1268246&;page=1#pid9274462
之所以把这个part提出来专门开贴,一是因为文件太长放在回复里面不方便阅读,二是这一部分发布相隔时间过长,三是这部分的高度的确是和原来的几部分持平的,是核心部分的介绍,应该开贴。
/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://hi.baidu.com/cc0cc
* Date: 11 01 2008
* FileName: Mythread.c
* 这个文件要从Access_Thread看起,因为在上一章节里,我们了解了pthread_create(&getaccess,NULL,Access_Thread,NULL);创建了一个叫getaccess的线程,正是运行的Access_Thread,在Access_Thread里,将完成一系列的过程,802.1x从这里才真正开始了。
***/
#include <gnome.h>
#include <sys/select.h>
#include "Mythread.h"
#include "connect.h"
#include "support.h"
#include "interface.h"

int i=0;
typedef struct{
                      long        tv_sec;            
                      long        tv_uec;            
                  }timeval;
                          
gint
keeplink(gpointer data)
{
pthread_t keeptest;
        fd_set readfds;
        timeval timeout={5,0};//设置超时
        BYTE recvbuf[1024];
        BYTE cmd;
        CMD_RECORD *cmd_record;
        int recvlen;
        int index=0;
        BYTE tmp=0;
        send_keeplink_request();//这也在connect.c里,用来构造一个包含指令和验证信息的包并发给服务器
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        if(1!=select(sockfd + 1,&readfds,NULL,NULL,&timeout))
        {//超时
                Acc_Keep_Link=2;
                g_message("1.keep lost,thread keeptest ok!");
                pthread_create(&keeptest,NULL,Keep_Thread,NULL);
                return FALSE;
        }
        recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);
        if (recvlen==-1 ) {
                                        Acc_Keep_Link=2;
                                        pthread_create(&keeptest,NULL,Keep_Thread,NULL);
                                        g_message("2.keep lost,thread keeptest ok!");
                                        return FALSE;
        }
        amt_decrypt(recvbuf,recvlen);//与认证过程大同小异
        if(0==check_packet(recvbuf,recvlen))
        {
                                        Acc_Keep_Link=2;
                                        pthread_create(&keeptest,NULL,Keep_Thread,NULL);
                                        g_message("3.keep lost,thread keeptest ok!");
                                        return FALSE;
        }
        cmd_record=get_attr(recvbuf);
        cmd=*recvbuf;
        if(cmd==4)        //收到send_keeplink_request对应的包
        {
                index=0;
                tmp=0;
                for (;(index<8)&&(attr_id[index]);index++) {
                        if (attr_id[index]==3) {
                                if (attr_val[8*(index+4*index)]!=1) {//发送send_keeplink_request失败
                                        Acc_Keep_Link=2;
                                        pthread_create(&keeptest,NULL,Keep_Thread,NULL);
                                        g_message("4.keep lost,thread keeptest ok!");
                                        return FALSE;
                                }
                        }
                }
                //AfxGetMainWnd()->;PostMessage(WM_KEEPLINK_RESULT,KEEPLINK_SUCCESSED,NULL);
                g_message("keeplink result success");
        }
        else
        {
                                        Acc_Keep_Link=2;
                                        pthread_create(&keeptest,NULL,Keep_Thread,NULL);
                                        g_message("5.keep lost,thread keeptest ok!");
                                        return FALSE;
        }
return TRUE;//至此 全过程结束(当然,你不是按照从上到下读着来的,而是按照我的提示来阅读的话)未来我会逐步分析connect.c和mdd.c里的几个函数,都是加密和解密的内容,主程序本身的流程关系不大,其中还包含了linuxc中使用ASM的方法,敬请关注http://hi.baidu.com/cc0cc
}

void
Link_Thread(void *arg)
{
guint send_timer;
if(Acc_Keep_Link!=1)return;
g_message("keep thread online!");
send_timer=gtk_timeout_add(30000,keeplink,NULL);//802.1x了,每三十秒发送一个认证请求 看keeplink
}
从这里看起↓ void
Access_Thread()
{
if(Acc_Keep_Link!=0)return;//这是个全局的标,任何情况下标被修改都应当退出线程
pthread_t keeplink;//这是一个孙线程的名字,根据协议规则需要在认证通过后定时发包
int times=0;//超时次数
fd_set readfds;//这个东东不知道要去补一下网络编程,[size=-1]异步套接字。文件描述符集,select调用时用的
timeval timeout;//设置超时为5秒  这个timeval struct在本文件有定义
timeout.tv_sec=5;
timeout.tv_uec=0;
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);        

BYTE recvbuf[1024];
BYTE cmd;
CMD_RECORD *cmd_record;
int recvlen;
int index=0;
BYTE tmp=0;

        
retry://这里没办法,用了个goto 看后面就知道了,大概就是超时两次就置标志位了,最后结束运行
                if (times>=2) {
                Acc_Keep_Link=-1;//ACCESS_FAILED_TIMEOUT;
                return ;
        }
send_access_request();//这是开始发送包给服务器了,将会发送用户名密码MAC等一系列的东西给远端的服务器,另一个文件中(connet.c)将专门来介绍

int rt=select(sockfd + 1,&readfds,NULL,NULL,&timeout);//等着看有没有返回
//g_message("select id :%d",rt);
if(1!=rt)
        {//超时
                g_message("time out this");
                times++;
                goto retry;
        }
//有返回了!
recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);//接受返回
        if (recvlen==-1) {
                g_message("recvfrom faild");
               
        }
        amt_decrypt(recvbuf,recvlen);//将收到的recvbuf里的东西去解密 amt_decrypt是原程序中的解密算法,接收到的数据包得经过本函数解密,将在mdd.c中介绍
        if(check_packet(recvbuf,recvlen)==0&×<2)//check_packet检查解密amt_decrypt完后的数据包是否符合md5摘要
        {       g_message("check_packet bad here");
                times++;
                goto retry;//check_packet失败则重发数据包
        }
        cmd_record=get_attr(recvbuf);//取出对应的指令变成结构体链表CMD_RECORD
        cmd=*recvbuf;
        if(cmd==2)        //收到send_access_request对应的包
        {
                get_spec_attr(cmd_record);//把结构体链表CMD_RECORD里的东西分进全局变量attr_yy里 马上就要用到,attr_id存了cmd指令
                index=0;
                tmp=0;
               
                for (;(index<0x0A)&&(attr_id[index]!=0);index++) {
                        
                        if (attr_id[index]==3) {
                                tmp=attr_val[8*(index+4*index)];////attr_val给每个命令40字节
                        }
                }
                if (tmp==1) {//认证成功!
                    //g_message("ok");
                        gtk_widget_hide_all (linkwindow);
                        Acc_Keep_Link=1;
                        pthread_create(&keeplink,NULL,Link_Thread,NULL);//认证成功了,再创建一个线程用来保持连接 这回要去看Link_Thread了
                        return;
                }
                else
                {       g_message("server_back_err");
                        gtk_widget_hide_all (linkwindow);
                        Acc_Keep_Link=-1;
                        return ;
                }

        }

}


gint
keeptest(gpointer data)
{
pthread_t keeplink;
i++;
g_message("%d",i);
if (i>10){Acc_Keep_Link=-1;g_message("can't keeplink!");return FALSE;}
        fd_set readfds;
        timeval timeout={5,0};//设置超时
        BYTE recvbuf[1024];
        BYTE cmd;
        CMD_RECORD *cmd_record;
        int recvlen;
        int index=0;
        BYTE tmp=0;
        send_keeplink_request();
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        if(1!=select(sockfd + 1,&readfds,NULL,NULL,&timeout))
        {//超时
                g_message("1.keep lost,thread keeptest for once!");
                return TRUE;
        }
        recvlen=recvfrom(sockfd,(char *)recvbuf,sizeof(recvbuf),0,NULL,NULL);
        if (recvlen==-1 ) {
                                        g_message("2.keep lost,thread keeptest for once!");
                                        return TRUE;
        }
        amt_decrypt(recvbuf,recvlen);
        if(0==check_packet(recvbuf,recvlen))
        {
                                        g_message("3.keep lost,thread keeptest for once!");
                                        return TRUE;
        }
        cmd_record=get_attr(recvbuf);
        cmd=*recvbuf;
        if(cmd==4)        //收到send_keeplink_request对应的包
        {
                index=0;
                tmp=0;
                for (;(index<8)&&(attr_id[index]);index++) {
                        if (attr_id[index]==3) {
                                if (attr_val[8*(index+4*index)]!=1) {//发送send_keeplink_request失败
                                        g_message("4.keep lost,thread keeptest for once!");
                                        return TRUE;
                                }
                        }
                }
                        g_message("keeptest result success");
                        Acc_Keep_Link=1;
                        pthread_create(&keeplink,NULL,Link_Thread,NULL);
                        return FALSE;               
        }
        else
        {
                                        g_message("5.keep lost,thread keeptest for once!");
                                        return TRUE;
        }

return FALSE;
}

void
Keep_Thread()
{guint send_timer;
        if(Acc_Keep_Link!=2)return;
        send_timer=gtk_timeout_add(10000,keeptest,NULL);
}
/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://hi.baidu.com/cc0cc
* Date: 11 01 2008
* FileName: Mythread.c
***/

欢迎发表相关看法。

[ 本帖最后由 cc0cc 于 2008-11-1 10:44 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-11-01 11:14 |只看该作者
这个不怕被神州数码告啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP