[MID project] Daily Report from nnoo
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
今天主要写了个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进程去处理。
今天分析了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表结构体。
今天主要修改了以下几个方面:
1:重新定义了一个arp映射表,改变以前与addr共用一个结构体情况。
2:添加了sendto(),recvfrom()两个函数参数只是为了和socket兼容,在函数内部并没有解析这些函数。
3:在socket结构体里面添加了family,protocol,type 3个参数。
近期任务:
1:在基于数据报的应用中,不会用到connect()函数,要去掉此函数。
2:安socket标准去重写tftp应用程序。
3:在ping命令中直接调用icmp发包函数,这个是不符合规范的,所以要添加一个原始socket去封装这些功能。
今天晚上身体不舒服,早早就回寝室了。
今天主要做了以下几件事情:
1:添加了了一个port_info结构体,里面含有收发队列和,协议类型, 和node, 添加了一个全局port_info. 头结点.
2:删除原socked结构体内的收发队列,添加了一个port_info的指针.
3:在socked()函数中实现port_info的填充和链表的加入,socket结构体和port_info的关联.
4:修改和收发队列相关函数,使其抛弃原socket里面的收发队列而使用port_info中的收发队列.
近期主要工作为实现tcp协议.
今天没什么进展,一直都在浏览tcp协议卷.
本帖最后由 a469412293 于 2010-03-16 21:51 编辑
DONE:
尝试建立TCP握手,但发包格式有问题,定位问题可能是校验和,TCP选项,字节序问题。
TODO:
解决以上问题。
昨天寝室断网,此贴为昨天REPORT
DONE:
定位问题在字节序和校验和。
在tcp结构体加packet属性解决字节序问题.初步解决校验和问题.
TODO:
建立TCP三次握手.
DONE:
1: 今天讨论了TCP的总体架构实现.
2: 改写了connect()函数, 添加了tcp_packet()和init_tcpinfo()函数.
3: 把tcpinfo结构体移到socket-->p_info中, 修改和添加tcpinfo中属性.
TODO:
1:调试修改过的内容.
2:初步实现tcp_layer_deliver()函数.
补3.18
DONE:
添加了parse()函数,进一步完善tcp_layer_deliver()函数.
TODO:
还不能正常建立握手,继续调试.