[MID project] Daily Report from nnoo

发布于 2022-09-18 11:24:28 字数 19078 浏览 11 评论 0

1:今天主要浏览熟悉了一下g-bios的协议栈的实现,我先从上层应用程序看起。
    重要流程如下:
        app目录下tftp.c int main(int argc, char *argv[]);
                                                  net_tftp_load(&dlopt);
                                                  // 其中dlopt为struct tftp_opt的结构体,里面含有server_ip,file_name,load_addr等几个变量.
                                                  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
                                                 //在一全组数组注册sock结构体,并初始化收发队列.
                                                  skaddr = getaddr(nip);
                                                  //查找g_host_list链表(mac-ip表),如有匹配的ip就把mac-ip描述的结构体返回.
                                                  skaddr = gethostaddr(szServerIP);
                                                  //如果上一步返回为null.执行此函数,通过发动arp请求包获取主机mac地址.
                                                                          arp_send_packet((u8 *)&nip, NULL, ARP_OP_REQ);
                                                                          //组装arp包请求包.
                                                                                                                void ether_send_packet(struct sock_buff *skb, const u8 mac[], u16 eth_type);
                                                                                                                 //组装以太网包.
                                                                                                                 g_curr_ndev->send_packet(g_curr_ndev, skb);
                                                                                                                 向网卡发包.
                                                                           

                                                                                                   
                                                                            /*
                                                                                                在发过arp请求包后主机会返回一个arp回应包.
                                                                            */                                         
                           
                                                                           netif_rx_poll();
                                                                                                 g_curr_ndev->ndev_poll(g_curr_ndev);
                                                                                                  //调用注册的网卡收包函数.
                                                                                                   netif_rx(skb);
                                                                                                  //往上层抛包.
                                                                                                                       ......
                                                                                                                       case ETH_TYPE_ARP:
                                                                                       arp_recv_packet(skb);
                                                                                                                       //如果为arp包调用此函数.
                                                                                                                                                           ......
                                                                                                                                                           case ARP_OP_REP:
                                                                                                                                           if (getaddr(ip) == NULL)  
                                                                                                                                                            //如果为回应包并且没有此ip和mac关系对应,调用此函数.
                                                                                                                                                             memcpy(host->sk_addr.des_ip, arp_pkt->src_ip, 4);
                                                                                                                                     memcpy(host->sk_addr.des_mac, arp_pkt->src_mac, 6);
                                                                                                                                                             list_add_tail(&host->node, &g_host_list);
                                                                                                                                                             记录此ip和mac映射关系.并加入g_host_list链表表.                                                      
                    
                                                          sk_addr = getaddr(nip);                                                                                
                                                                           //查找g_host_list链表(mac-ip表),如有匹配的ip就把mac-ip描述的结构体返回.(此时应该已有mac地址)
                                                                           send(sockfd, pTftpPkt, nPktLen);
                                                                            //组tftp包

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

我爱人 2022-09-25 11:24:28

今天主要写了个tftp client程序,熟悉了基本的socket API:
                    socket(), sendto(),recvfrom()等函数。
     其中需要的几点如下:
     1:网络字节序问题。
     2:sendto(),recvfrom()主要用于无连接的首发。
     3:指针运用要高度注意,一旦出错排查很困难。
   
     熟悉socket的API有助于为G-BIOS编写与标准兼容的socket API.
       明天TASK上午分析G-bios整个网络协议栈,下午讨论G-BIOS socket API 实现.

       其中有个疑问再用sendto()函数向tftp server 发送ack包的时候,如果第5个参数和原结构体不是同一个地址,server总是发送第一的block包,
     我们分析可能是server把不同地址的sockaddr_in参数当做是不同的client进程去处理。

南渊 2022-09-25 11:24:28

今天分析了G-BIOS里面sendto()函数应该怎样实现.
   在G-BIOS里面定义如下:send(int fd, const void *buf, u32 n);
   在kernel里面的定义如下:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                                        const struct sockaddr *dest_addr, socklent_t addrlen);

   
kernel代码没有找到实现函数,但是我们根据昨天的现象推测,我们向服务器发送一个请求的时候端口号时一定的,但是服务器会fork出一个进程去
处理最高请求,此时client与server通信的端口是和以前的端口不一致的,是个随机的端口,所以在recvfrom()中根据从server收到包的端口号去从新
设置const struct sockaddr 里面的port参数,以后client就通过此端口和server通信,所以这个const struct sockaddr在client中不应该被人为的改变的。

在g-bios中和kernel思路是一样的,但是它是利用全局socket结构体里面的sockaddr来实现的,kernel里面socket中没有类似于sockaddr的结构体,它是通过外部的全局变量来实现的,所以在g-bios里面此结构体需要改变,函数也需要添加一个sockaddr,socket里面要去掉sockaddr,但是g-bios里面的arp表和sockaddr时同一个结构,所以需要重新定义一个arp表结构体。

第几種人 2022-09-25 11:24:28

今天主要修改了以下几个方面:
1:重新定义了一个arp映射表,改变以前与addr共用一个结构体情况。
2:添加了sendto(),recvfrom()两个函数参数只是为了和socket兼容,在函数内部并没有解析这些函数。
3:在socket结构体里面添加了family,protocol,type 3个参数。

近期任务:
1:在基于数据报的应用中,不会用到connect()函数,要去掉此函数。
2:安socket标准去重写tftp应用程序。
3:在ping命令中直接调用icmp发包函数,这个是不符合规范的,所以要添加一个原始socket去封装这些功能。

最舍不得你 2022-09-25 11:24:28

今天晚上身体不舒服,早早就回寝室了。

今天主要做了以下几件事情:
1:添加了了一个port_info结构体,里面含有收发队列和,协议类型, 和node, 添加了一个全局port_info. 头结点.
2:删除原socked结构体内的收发队列,添加了一个port_info的指针.
3:在socked()函数中实现port_info的填充和链表的加入,socket结构体和port_info的关联.
4:修改和收发队列相关函数,使其抛弃原socket里面的收发队列而使用port_info中的收发队列.

近期主要工作为实现tcp协议.

ヅ她的身影、若隐若现 2022-09-25 11:24:28

今天没什么进展,一直都在浏览tcp协议卷.

苏别ゝ 2022-09-25 11:24:28

本帖最后由 a469412293 于 2010-03-16 21:51 编辑

DONE:
      尝试建立TCP握手,但发包格式有问题,定位问题可能是校验和,TCP选项,字节序问题。
TODO:
      解决以上问题。

昨天寝室断网,此贴为昨天REPORT

月依秋水 2022-09-25 11:24:28

DONE:
      定位问题在字节序和校验和。
     在tcp结构体加packet属性解决字节序问题.初步解决校验和问题.
TODO:
      建立TCP三次握手.

醉生梦死 2022-09-25 11:24:28

DONE:
     1: 今天讨论了TCP的总体架构实现.
     2: 改写了connect()函数, 添加了tcp_packet()和init_tcpinfo()函数.
     3: 把tcpinfo结构体移到socket-->p_info中, 修改和添加tcpinfo中属性.
TODO:
     1:调试修改过的内容.
     2:初步实现tcp_layer_deliver()函数.

我不在是我 2022-09-25 11:24:28

补3.18

DONE:
       添加了parse()函数,进一步完善tcp_layer_deliver()函数.
TODO:
      还不能正常建立握手,继续调试.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文