免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-15 11:41 |只看该作者 |倒序浏览
/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://hi.baidu.com/cc0cc
* Date: the Mid-Autumn Festival of 2008
***/
概要:这个软件是三年前的时候在学校里写的,主要目的是给广大的Linuxers一个上网的机会,不过后来在我推出后官方又出了个Linux下的拔号二进制包。
代码中的ASM汇编部分代码取自北航的高手xdkui(目前在MS就职),在此一并感谢他的努力hack。
声明:本代码只供学习使用,完全遵循计算机软件保护条例。

1.开发环境:
gtk+/gnome
Anjuta+Glade
2.文件树(截图):


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

论坛徽章:
0
2 [报告]
发表于 2008-09-15 11:42 |只看该作者

神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part2)

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://hi.baidu.com/cc0cc
* Date: the Mid-Autumn Festival of 2008
* FileName: main.c
***/
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <gtk/gtk.h>
#include <pthread.h>

#include <gnome.h>
/*如果没记错的话eggtrayicon.h/tray.h都是在Linux用来做系统托盘的头文件,参见
*http://hi.baidu.com/cc0cc/blog/item/26da147a4a428ce92f73b3da.html
*/
#include "eggtrayicon.h"
#include "tray.h"
#include "interface.h"
#include "support.h"
#include "connect.h"

/*系统托盘*/
static void activate_action (GtkAction * action);
static void net_quit (GtkAction * action);
static const gchar *ui_info =
    "<ui>"
    " <popup name='PopupMenu'>"
    "    <menuitem action='About'/>"
    "    <separator/>"
    "    <menuitem action='Quit'/>"
    " </popup>"
    "</ui>";
static GtkActionEntry entries[] = {
    {"Quit", GTK_STOCK_QUIT,    /* name, stock id */
    N_("_断开"), "<control>Q",    /* label, accelerator */
    N_("Quit"),        /* tooltip */
    G_CALLBACK (net_quit)},
    {"About", GTK_STOCK_ABOUT,    /* name, stock id */
    N_( "_关于"), "<control>A",    /* label, accelerator 关于断开*/
    N_("About"),        /* tooltip */
    G_CALLBACK (activate_action)},
};static guint n_entries = G_N_ELEMENTS (entries);
/*系统托盘END*/

/*GTK程序入口*/
int
main (int argc, char *argv[])
{

    GtkUIManager *ui;
    GError *error = NULL;
    GtkActionGroup *actions;
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
                      argc, argv,
                      GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR,
                      NULL);
window1 = create_window1 ();//这是第一个界面,也就是一出来的时候等待输入密码进行连接的界面
    //g_thread_create(thread1,NULL,NULL,NULL);//wait for the book :)
     //pthread_create(&tid,NULL,thread1,NULL);//it is not so good!
     tray = g_new0 (tray_demo, 1);//这里开始弄系统托盘
    tray->window_main = window1;
    create_tray(tray);
    actions = gtk_action_group_new ("Actions");
    gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
    gtk_action_group_add_actions (actions, entries, n_entries, NULL);
    ui = gtk_ui_manager_new ();
    gtk_ui_manager_insert_action_group (ui, actions, 0);
    gtk_window_add_accel_group (GTK_WINDOW (window1),
                    gtk_ui_manager_get_accel_group (ui));
    if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error))
    {
        g_message ("building menus failed: %s", error->message);
        g_error_free (error);
    }
    tray->ui = ui;
    tray->actions = actions;
    tray->menus = gtk_ui_manager_get_widget (ui, "/PopupMenu");//这段代码可以在gnome中国的网站上找到。。:)
g_message("ccc");   
gtk_widget_show (window1);
gtk_main ();g_message("here2!");
return 0;
}

//下面两个都是为系统托盘的事件做的
static void
activate_action (GtkAction * action)
{   GtkWidget *about;
    about = create_aboutdialog1 ();
     gtk_widget_show (about);
    return;
}
static void
net_quit (GtkAction * action)
{
    Acc_Keep_Link=-1;
    gtk_widget_show_all (window1);
    send_access_request();
    //g_message("net_quit!");
}

论坛徽章:
0
3 [报告]
发表于 2008-09-15 11:43 |只看该作者
该图片仅限百度用户交流使用

论坛徽章:
0
4 [报告]
发表于 2008-09-15 11:53 |只看该作者

神州数码802.1x局域网UDP拔号软件MyNet-Gnome源代码大分析(Part3)关键逻辑

/***
* Author: cc0cc
* E-mail: cc0cc@126.com
* WebSite: http://hi.baidu.com/cc0cc
* Date: the Mid-Autumn Festival of 2008
* FileName: callbacks.c
* Description: callbacks.c为事件处理的核心逻辑,是MyNet的中心
***/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include "Mythread.h"
#include "connect.h"
#include "callbacks.h"
#include "interface.h"
#include "support.h"

gchar line2[255];//用来存去掉回车后的字符串
void write_config(gchar *usr,gchar *pwd);//remember pwd
void write_new_config();//first time to write config
gchar * scape(gchar *line);//escapse the enter like '\n'
/*
* 关于mac和ip的:http://hi.baidu.com/cc0cc/blog/item/403cbb25a0cd9a6435a80fa7.html
*/
char *get_mac();//return the mac address
char *get_ip();//get ip address
int get_socket();
int tr_mac();//translate the mac address
int CreateMutex();//a file like mutex (互斥体,用来保证只能同时运行一个此软件,后来被干掉啦:))
int trayshow;

/*这个是window1,也就是软件一打开的时候会执行这个函数*/
void
on_window1_show                        (GtkWidget       *widget,
                                        gpointer         user_data)
{
/*
//采访一下:为什么要把这段干掉?
//A:因为在程序异常关闭的时候,老是不能自己删除掉原来的PID文件,于是就得手工去删除,实在是不爽,干脆不限制了。
char runfile[1024]="";
FILE *runfp;   
sprintf(runfile,"%s/.mynet/run.pid",getenv("HOME"));

if((runfp = fopen(runfile, "r")) != NULL)
    {   
    gtk_widget_hide(window1);
    getAtrBox = create_messagebox("错误","程序已经运行了!",0);
     gtk_widget_show (getAtrBox);
    }else{
        CreateMutex();
        }
*/
username[0x40]=0;
host[0x1E]=0;
memcpy(host,SERVER,strlen((char *)SERVER));
mac_addr[0x20]=0;
mac_Hex[6]=0;
ip_addr[0x20]=0;
passwd[0x40]=0;
server_type[0x40]=0;
memcpy(server_type,"internet",strlen((char *)"internet"));

gchar *line = ((char *) malloc(255));//is 255b enough?
char cfgfile[1024]="";
FILE *fp;   
   
sprintf(cfgfile,"%s/.mynet/config",getenv("HOME"));
if ((fp = fopen(cfgfile, "r")) == NULL)    write_new_config();//看出来这是在干什么了吗?这是把用户的当前设置给写进一个config文件,就算是windows里的注册表了
else
    {
    fgets(line,254,fp);
    gtk_entry_set_text ((GtkEntry *)entry1,(const gchar *)scape(line));
    memcpy(username,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    gtk_entry_set_text ((GtkEntry *)entry2,(const gchar *)scape(line));   
    memcpy(passwd,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    memcpy(ip_addr,scape(line),strlen(scape(line)));
    fgets(line,254,fp);
    memcpy(host,scape(line),strlen(scape(line)));g_message("here1");
    //get_socket((char *)scape(line));//host to
        g_message("%c",&line);
    fgets(line,254,fp);g_message("here3");
    memcpy(mac_addr,scape(line),strlen(scape(line)));g_message("here4");
    tr_mac();g_message("here5");
    }   
g_message("mem now here:usr:%s\npwd:%s\nip:%s\nmac:%s\nserver:%s",username,passwd,ip_addr,mac_addr,host);
free(line);
}

/*这是设置服务器的一个窗口*/
void
on_window2_show                        (GtkWidget       *widget,
                                        gpointer         user_data)
{
    gtk_entry_set_text ((GtkEntry *)entry3,(char *)ip_addr);

    gtk_entry_set_text ((GtkEntry *)entry4,(char *)host);   

    gtk_combo_box_append_text (GTK_COMBO_BOX (comboboxentry1),(char *)mac_addr);
    gtk_combo_box_set_active(GTK_COMBO_BOX (comboboxentry1),0);
   
}

/*这个是哪个button?...是设置属性的那个按钮*/
void
on_button3_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
    GtkWidget *mac_set;
    mac_set = create_window2 ();
     gtk_widget_show (mac_set);
    return;
}

/*
*这个是什么东东? 记好了,这个在后面要用的,用来数数的计时的。
*/
gint
flash_timeout(gpointer data)
{if(Acc_Keep_Link==-1){
    gtk_widget_hide_all (linkwindow);
    gtk_widget_show_all (window1);
    getAtrBox = create_messagebox("提示","与网络连接中断!",1);
     gtk_widget_show_all (getAtrBox);
    return FALSE;
    }
    create_tray(tray);
    return TRUE;
}

/*关键的一个来了!!这就是主界面中的连接按钮!主逻辑从它开始*/
void
on_button1_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{   
/*这个的意思是,如果连接的时候选择了记住密码,那么就要把用户名密码写进config文件去,不然的话就写个用户名得了*/
if(gtk_toggle_button_get_active((GtkToggleButton *)checkbutton1))
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            (gchar *)gtk_entry_get_text ((GtkEntry *)entry2));
else
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            "");   
gtk_widget_hide_all (window1);//所有窗口隐藏掉。。。
linkwindow = create_window3 ();//window3就是“请稍候”的那个窗口,大家都隐藏的时候它就要出来了
gtk_widget_show_all (linkwindow);
gint ptimer_flash=0;
gtk_timeout_remove(ptimer_flash);
ptimer_flash=gtk_timeout_add(15000,flash_timeout,NULL);    //这是一个计时器,每1.5秒执行一次flash_timeout
   
pthread_t getaccess;
Acc_Keep_Link=0;
memcpy(username,(char *)gtk_entry_get_text ((GtkEntry *)entry1),strlen((char *)gtk_entry_get_text ((GtkEntry *)entry1)));
memcpy(passwd,(char *)gtk_entry_get_text ((GtkEntry *)entry2),strlen((char *)gtk_entry_get_text ((GtkEntry *)entry2)));
pthread_create(&getaccess,NULL,Access_Thread,NULL);//这会创建一个叫getaccess的线程
}

/*垃圾按钮~~就是获取服务的那个按钮*/
void
on_button4_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
memcpy(host,(char *)gtk_entry_get_text ((GtkEntry *)entry4),strlen((gchar *)gtk_entry_get_text ((GtkEntry *)entry4)));
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            "");

    get_socket((char *)gtk_entry_get_text ((GtkEntry *)entry4));
    getAtrBox = create_messagebox("提示","恭喜,获取服务成功!",1);
     gtk_widget_show (getAtrBox);
    return;//sorry i can not understand what is this
}

/*
* 当断开网络时会用
*/
void
before_quit                      (GtkWidget       *widget,
                                        gpointer         user_data)
{
/*
char cfgfile[1024]="";
sprintf(cfgfile,"%s/.mynet/run.pid",getenv("HOME"));
unlink(cfgfile);//delete mutex file*/
   
if(gtk_toggle_button_get_active((GtkToggleButton *)checkbutton1))
write_config((gchar *)gtk_entry_get_text ((GtkEntry *)entry1),
            (gchar *)gtk_entry_get_text ((GtkEntry *)entry2));//remember the passwd
close(sockfd);
gtk_main_quit();
}

/*先说过的,用来写文件记录用户的基本信息的*/
void write_new_config()
{
int log;
char filename[1024];
char log_string[1024];
char filepath[1024];
char *dir;
strcpy(log_string,"");
strcat(log_string,"\n");memcpy(username,"0",strlen((char *)username));
strcat(log_string,"\n");memcpy(passwd,"0",strlen((char *)passwd));
get_ip();   
strcat(log_string,(char *)ip_addr);strcat(log_string,"\n");
strcat(log_string,SERVER);strcat(log_string,"\n");
get_mac();tr_mac();
strcat(log_string,(char *)mac_addr);strcat(log_string,"\n");
dir=getenv("HOME");
sprintf(filepath,"%s/.mynet/",dir);
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%sconfig",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
}

/*下面这个东东把line也就是存成文件了的用户名密码(原来是回车分隔的),这些东东一行一行地取出来*/
gchar * scape(gchar *line)
{
int i;
int j;
for(i=0;i<254;i++)line2=NULL;//这个主要目的是全部干成空的
for(i=0;i<254;i++){if((line=='\n')||(line=='\r'))break;}//一旦遇到回车直接就over掉
for(j=0;j<i;j++){line2[j]=line[j];/*g_message("%c",line[j]);*/}//复制到line2中
return line2;
}

/*和write_new_config相比少个new,在用户名密码更改的时候才用的*/
void write_config( gchar* usr, gchar* pwd)
{
int log;
char filename[1024];
char log_string[1024];
char filepath[1024];

strcpy(log_string,"");
strcat(log_string,usr);strcat(log_string,"\n");
strcat(log_string,pwd);strcat(log_string,"\n");
strcat(log_string,(char *)ip_addr);strcat(log_string,"\n");
strcat(log_string,(char *)host);strcat(log_string,"\n");
strcat(log_string,(char *)mac_addr);strcat(log_string,"\n");

sprintf(filepath,"%s/.mynet/",getenv("HOME"));
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%sconfig",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
}

void
delete_event                     (GtkButton       *button,
                                        gpointer         user_data)
{
before_quit((GtkWidget *)button,(gpointer)user_data);
}

char *
get_mac()
{
        int nSocket;
        struct ifreq struReq;
        nSocket = socket(PF_INET,SOCK_STREAM,0);
        memset(&struReq,0,sizeof(struReq));
        strncpy(struReq.ifr_name, "eth0", sizeof(struReq.ifr_name));   
        ioctl(nSocket,SIOCGIFHWADDR,&struReq);
        close(nSocket);
        //strcpy(mac_addr,(BYTE)ether_ntoa(struReq.ifr_hwaddr.sa_data));
        memcpy(mac_addr,(char *)ether_ntoa(struReq.ifr_hwaddr.sa_data),strlen((char *)ether_ntoa(struReq.ifr_hwaddr.sa_data)));
        //g_message("\n get_mac: %s\n",(char *)ether_ntoa(struReq.ifr_hwaddr.sa_data)+1);
        //g_message("\n mem_mac : %s lenth:%d\n",mac_addr,strlen((char *)mac_addr));
        return 0;
}

char *
get_ip()
{
           int sock;
           struct sockaddr_in sin;
           struct ifreq ifr;   
           sock = socket(AF_INET, SOCK_DGRAM, 0);
           if (sock == -1)
           {
                       perror("socket");
                       return "";                          
           }
            
           strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));      
   
           if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
           {
                       perror("ioctl");
                       return "";
           }

           memcpy(&sin, &ifr.ifr_addr, sizeof(sin));   
           close(sock);
           memcpy(ip_addr,inet_ntoa(sin.sin_addr),strlen(inet_ntoa(sin.sin_addr)));
           //g_message("\n get_ip:eth0: %s\n",inet_ntoa(sin.sin_addr));
           //g_message("\n mem_ip: %s",ip_addr);
           return "";
}

int
get_socket()
{ char *ser;
    ser=(gchar *)gtk_entry_get_text ((GtkEntry *)entry4);
    //digtalser
           sockfd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
           if (sockfd == -1)
           {
                       perror("socket");
                       return 0;                          
           }
           client.sin_family=AF_INET;
           client.sin_port=htons(3848);
           //client.sin_addr=inet_addr(host);   
           inet_pton(AF_INET, ser, &client.sin_addr);            
           //g_message("udp socket ok!%d",sockfd);
           return 1;
}
int
chToHex(int x)//字符转成十六进制用
{
if(x>=97&&x<=102)x=x-87;
else x=x-48;
return x;
}
int
tr_mac()
{
int p,i;

p=0;
for(i=0;i<6;i++)
    {
    if (mac_addr[p+1]==':'){mac_Hex=chToHex((int)mac_addr[p]);p+=2;}
      else{mac_Hex=16*(chToHex((int)mac_addr[p]))+chToHex((char)mac_addr[p+1]);p+=3;}   
    }
//g_message("%s",mac_addr);
//for(i=0;i<6;i++)
//g_message("%d---%c-%c-%c-%c",mac_Hex,mac_addr,mac_addr[i+1],mac_addr[i+2],mac_addr[i+3]);
return 0;
}

int
CreateMutex()//a file like mutex
{
int log;
char filename[1024];
char log_string[1024];
char filepath[1024];
char *dir;
strcpy(log_string,"MyNet");
dir=getenv("HOME");
sprintf(filepath,"%s/.mynet/",dir);
mkdir(filepath,O_RDWR|O_CREAT|O_TRUNC);
chmod(filepath,0777);
sprintf(filename,"%srun.pid",filepath);
log=open(filename,O_RDWR|O_CREAT|O_TRUNC,0777);
chmod(filename,0777);
write(log,log_string,strlen(log_string));
close(log);   
return 1;   
}

void
delete_getAtrBox()
{
gtk_widget_hide (getAtrBox);
}

论坛徽章:
0
5 [报告]
发表于 2008-09-15 11:55 |只看该作者
Part4将讲述getaccess线程内的故事,该线程完整再现UDP拔号的情境,待续。。。

论坛徽章:
0
6 [报告]
发表于 2008-09-15 11:58 |只看该作者
共有多少part?

论坛徽章:
0
7 [报告]
发表于 2008-09-15 12:00 |只看该作者
四五个应该能写完了,一个一个文件介绍嘛

论坛徽章:
3
天蝎座
日期:2014-10-25 13:44:312015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:48:31
8 [报告]
发表于 2008-09-17 23:32 |只看该作者
原帖由 麦兜转转 于 2008-9-17 22:45 发表
神州的优点在于中低配机器性价比高,总的来说还是值得考虑的.



别乱灌水,弄清楚“神舟”和“神州数码”的区别先!!

论坛徽章:
0
9 [报告]
发表于 2008-09-18 00:36 |只看该作者
原帖由 麦兜转转 于 2008-9-17 22:45 发表
神州的优点在于中低配机器性价比高,总的来说还是值得考虑的.

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
10 [报告]
发表于 2009-05-10 17:49 |只看该作者
你要是整个附件就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP