Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2275865
  • 博文数量: 668
  • 博客积分: 10016
  • 博客等级: 上将
  • 技术积分: 8588
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-29 19:22
文章分类

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2009-01-01 08:52:42

昨天我们看到了inet_create()函数我们今天继续。函数比较大所以我们分段来看,本文针对的是2.6.26版本的linux内核,请朋友们注意。

sys_socketcall()-->sys_socket()-->sock_create()-->__sock_create()-->通过pf->create()--> inet_create()

static int inet_create(struct net *net, struct socket *sock, int protocol)
{/* wumingxiaozu */
    struct sock *sk;
    struct list_head *p;
    struct inet_protosw *answer;
    struct inet_sock *inet;
    struct proto *answer_prot;
    unsigned char answer_flags;
    char answer_no_check;
    int try_loading_module = 0;
    int err;

    if (sock->type != SOCK_RAW &&
     sock->type != SOCK_DGRAM &&
     !inet_ehash_secret)
        build_ehash_secret();/* wumingxiaozu */

    sock->state = SS_UNCONNECTED;

    /* Look for the requested type/protocol pair. */
    answer = NULL;

函数前边的几个数据结构我们暂且不做介绍,留待过程中相关调用的时候加以理解,如果罗列出来恐怕对于朋友们的旅游过程毫无益处还要增加大家的“负重”,因为上一节我们看到在socket的创建过程看到了在套接字文件系统中分配了专用的inode节点,并且在__sock_create()函数中将我们应用程序中设置的socket类型赋给了我们这里的socket套接字(插口),我们在上一节没有过多的贴出__sock_create ()函数的代码,在其内部有一句

 

sock->type = type;

 

sock是我们在linux内核中新创建的socket,这里将其的type设置为练习程序中调用时传递来的

 

server_fd = socket(AF_INET, SOCK_STREAM, 0);

 

即我们练习程序将socket设置为了SOCK_STREAM即表示为数据流类型的socket,所以结合这里的inet_create()函数的开头来看,这个函数首先是检查是否是SOCK_RAW (原始)SOCK_DGRAM(数据报,一般用于UDP协议) 类型的socket,并且判断是否已经有了加密字符如果没有就会调用build_ehash_secret来分配一个

 

sys_socketcall()-->sys_socket()-->sock_create()-->__sock_create()-->通过pf->create()--> inet_create()-->build_ehash_secret()

void build_ehash_secret(void)
{
    u32 rnd;
    do {
        get_random_bytes(&rnd, sizeof(rnd));
    } while (rnd == 0);/* wumingxiaozu */
    spin_lock_bh(&inetsw_lock);
    if (!inet_ehash_secret)
        inet_ehash_secret = rnd;
    spin_unlock_bh(&inetsw_lock);
}

get_random_bytes是取得一个随机数即,取得后赋值给加密字符使用。然后上面的函数中将socket设置为SS_UNCONNECTED未连接状态。当然我们看到了answer是一个struct inet_protosw结构变量,我们看一下关于这个结构的定义

 

 

struct inet_protosw {
    struct list_head list;

        /* These two fields form the lookup key. */
    unsigned short     type;     /* This is the 2nd argument to socket(2). */
    unsigned short     protocol; /* This is the L4 protocol number. */

    struct proto     *prot;/* wumingxiaozu */

    const struct proto_ops *ops;
  
    int capability; 
/* Which (if any) capability do
                 * we need to use this socket
                 * interface?
                                      */

    char no_check; /* checksum on rcv/xmit/none? */
    unsigned char     flags; /* See INET_PROTOSW_* below. */
};

按照tcp/ip协议的规定中,IP协议属于网络层部分,我们知道tcp/ip协议通常分为四层还有的分为五层(第五层是物理层即硬件层):应用层、运输层、网络层和链路层。

 

其实,根据很多资料上的分析应该加上第五层即物理层,也就是硬件部分,因为tcp/ip协议主要是针对为上层,即应用程序服务的角度出发的,很多资料没有进一步到达网卡的驱动内容,而本文将为朋友们展示出一套包含整个层次的传递过程甚至包含了网卡的驱动内容,我们将以嵌入式dm9000cs8900为例完成整个旅游的全过程,通过代码让大家以旅游的过程,彻底理解这些层的作用,不管你是一位底层还是应用层工程师,本文是绝佳的导游。有些朋友可能对tcp不甚了解我们也把关于tcp/ip协议的介绍放在这里供这部分朋友了解

 

TCP/UDP协议的由来
TCP (Transmission Control Protocol
传输控制协议)UDP(User Datagram Protocol用户的数据报协议)协议属于传输层协议(实际上从上图看我们是分别处于运输层和网络层)。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。TCP支持的应用协议主要有:TelnetFTPSMTP等;UDP支持的应用层协议主要有:NFS(网络文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等.

 

我们的主要路线是从服务器端的应用层一至到物理层,客户端也会有这样的过程,只不过,我们从第一节中的地图中看到我们会沿着客户端应用层到物理层的路线,追宗到服务器的物理层一直到达服务器的应用层。相信这个旅游过程的完成,大家不但对tcp/ip协议进一步的了解和吸收了,更对下一步从事此类的开发工作打下了坚实的基础,我相信阅读完本文朋友可以很容易上手tcp/ip协议方面的开发工作,也很容易上手网络驱动方面的自主研发,当然希望朋友不要学完后做破坏性的“黑客”,要象LINUX程序的“骇客”那样发扬GPL的精神,让我们国家的计算机事业向良性方向发展,不要将技术用在去黑别人的网站,控制别人的机器上,那不是本文的目的,更不是我所倡导的。

 

 

上面的这个数据结构是专门用于socketip协议的连接接口,也就是socket与网络层相关的一些信息保存在这个数据结构中,结构中的变量我们还是不加描述的好,避免太过于“书生气”在朋友们喜欢的情况下,可由你自己来完成注解变量的工作,这样即加深了印象又提高了对结构的掌握能力。

阅读(478) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~