移植 tftp 客户端
来源:互联网 发布:微信显示网络出错1003 编辑:程序博客网 时间:2024/05/16 18:20
tftp网络协议分析
可以通过tftp下载Linux内核和程序文件到开发板运行。
tftp交互过程
tftp报文格式
每个包的数据不能超过512字节。
tftp协议属于udp协议,udp协议属于ip协议。
tftp网络协议的实现
arp.h
typedef unsigned int u32;typedef unsigned short u16;typedef unsigned char u8;typedef struct eth_hdr{ u8 d_mac[6]; u8 s_mac[6]; u16 type;}ETH_HDR;typedef struct arp_hdr{ ETH_HDR ethhdr; u16 hwtype; u16 protocol; u8 hwlen; u8 protolen; u16 opcode; u8 smac[6]; u8 sipaddr[4]; u8 dmac[6]; u8 dipaddr[4];}ARP_HDR;typedef struct ip_hdr{ ETH_HDR ethhdr; u8 vhl; u8 tos; u16 len; u16 ipid; u16 ipoffset; u8 ttl; u8 proto; u16 ipchksum; u8 srcipaddr[4]; u8 destipaddr[4];}IP_HDR;typedef struct udp_hdr{ IP_HDR iphdr; u16 sport; u16 dport; u16 len; u16 udpchksum;}UDP_HDR;typedef struct tftp_package{ u16 opcode; u16 blocknum; u8 data[0]; }TFTP_PAK;ARP_HDR arpbuf;#define PROTO_ARP 0x0806#define PROTO_IP 0x0800#define PROTO_UDP 0x11extern u8 host_mac_addr[6];extern u8 mac_addr[6];extern u8 ip_addr[4];extern u8 host_ip_addr[4];extern u16 packet_len;
arp.c
#include "arp.h"#define HON(n) ((((u16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))/*1.发送arp请求包*/void arp_request(){ /*1.构成arp请求包*/ memcpy(arpbuf.ethhdr.d_mac,host_mac_addr,6); memcpy(arpbuf.ethhdr.s_mac,mac_addr,6); arpbuf.ethhdr.type = HON(0x0806); arpbuf.hwtype = HON(1); arpbuf.protocol = HON(0x0800); arpbuf.hwlen = 6; arpbuf.protolen = 4; arpbuf.opcode = HON(1); memcpy(arpbuf.smac,mac_addr,6); memcpy(arpbuf.sipaddr,ip_addr,4); memcpy(arpbuf.dipaddr,host_ip_addr,4); packet_len = 14+28; /*2.调用dm9000发送函数,发送应答包*/ dm9000_tx(&arpbuf,packet_len);}/*2.解析arp应答包,提取mac*/u8 arp_process(u8 *buf, u32 len){ u32 i; ARP_HDR *arp_p = (ARP_HDR *)buf; if (packet_len<28) return 0; switch (HON(arp_p->opcode)) { case 2: /*arp响应包*/ memcpy(host_ip_addr,arp_p->sipaddr,4); printf("host ip is : "); for(i=0;i<4;i++) printf("%03d ",host_ip_addr[i]); printf("\n\r"); memcpy(host_mac_addr,arp_p->smac,6); printf("host mac is : "); for(i=0;i<6;i++) printf("%02x ",host_mac_addr[i]); printf("\n\r"); break; case 1: /*arp请求包*/ /*发送arp响应包*/ memcpy(arpbuf.ethhdr.d_mac,arp_p->smac,6); memcpy(arpbuf.ethhdr.s_mac,mac_addr,6); arpbuf.ethhdr.type = HON(0x0806); arpbuf.hwtype = HON(1); arpbuf.protocol = HON(0x0800); arpbuf.hwlen = 6; arpbuf.protolen = 4; arpbuf.opcode = HON(2); memcpy(arpbuf.smac,mac_addr,6); memcpy(arpbuf.sipaddr,ip_addr,4); memcpy(arpbuf.dmac,arp_p->smac,6); memcpy(arpbuf.dipaddr,arp_p->sipaddr,4); packet_len = 14+28; /*2.调用dm9000发送函数,发送应答包*/ dm9000_tx(&arpbuf,packet_len); break; }}void udp_process(u8* buf, u32 len){ UDP_HDR *udphdr = (UDP_HDR *)buf; tftp_process(buf,len,HON(udphdr->sport)); }void ip_process(u8 *buf, u32 len){ IP_HDR *p = (IP_HDR *)buf; switch(p->proto) { case PROTO_UDP: udp_process(buf,len); break; default: break; }}void net_handle(u8 *buf, u32 len){ ETH_HDR *p = (ETH_HDR *)buf; switch (HON(p->type)) { case PROTO_ARP: arp_process(buf,len); break; case PROTO_IP: ip_process(buf,len); break; default: break; }}void dm9000_arp(){ while(1) arp_request(); }
tftp.c
#include "string.h"#include "arp.h"u8 sendbuf[1024];u8* tftp_down_addr = 0x31000000;u16 serverport = 0;u16 curblock = 1;#define HON(n) ((((u16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))u16 checksum(u8 *ptr, int len){ u32 sum = 0; u16 *p = (u16 *)ptr; while (len > 1) { sum += *p++; len -= 2; } if(len == 1) sum += *(u8 *)p; while(sum>>16) sum = (sum&0xffff) + (sum>>16); return (u16)((~sum)&0xffff);}void tftp_send_request(const char *filename){ u8 *ptftp = &sendbuf[200]; u32 tftp_len = 0; UDP_HDR *udphdr; u8 *iphdr; ptftp[0] = 0x00; ptftp[1] = 0x01; tftp_len += 2 ; sprintf(&ptftp[tftp_len],"%s",filename); tftp_len += strlen(filename); ptftp[tftp_len] = '\0'; tftp_len += 1; sprintf(&ptftp[tftp_len],"%s","octet"); tftp_len += strlen("octect"); ptftp[tftp_len] = '\0'; tftp_len += 1; udphdr = ptftp-sizeof(UDP_HDR); iphdr = ptftp-sizeof(UDP_HDR)+ sizeof(ETH_HDR); /*UDP帧头信息*/ udphdr->sport = HON(48915); udphdr->dport = HON(69); udphdr->len = HON(tftp_len+sizeof(UDP_HDR)-sizeof(IP_HDR)); udphdr->udpchksum = 0x00; /*IP帧头信息*/ udphdr->iphdr.vhl = 0x45; udphdr->iphdr.tos = 0x00; udphdr->iphdr.len = HON(tftp_len+sizeof(UDP_HDR)-sizeof(ETH_HDR)); udphdr->iphdr.ipid = HON(0x00); udphdr->iphdr.ipoffset = HON(0x4000); udphdr->iphdr.ttl = 0xff; udphdr->iphdr.proto = 17; memcpy(udphdr->iphdr.srcipaddr,ip_addr,4); memcpy(udphdr->iphdr.destipaddr,host_ip_addr,4); udphdr->iphdr.ipchksum = 0; udphdr->iphdr.ipchksum = checksum(iphdr,20); memcpy(udphdr->iphdr.ethhdr.s_mac,mac_addr,6); memcpy(udphdr->iphdr.ethhdr.d_mac,host_mac_addr,6); udphdr->iphdr.ethhdr.type = HON(PROTO_IP); dm9000_tx((u32 *)udphdr,sizeof(UDP_HDR)+tftp_len);}void tftp_send_ack(u16 blocknum){ u8 *ptftp = &sendbuf[200]; u32 tftp_len = 0; UDP_HDR *udphdr; u8 *iphdr; ptftp[0] = 0x00; ptftp[1] = 0x04; tftp_len += 2 ; ptftp[2] = (blocknum&0xff00)>>8; ptftp[3] = (blocknum&0xff); tftp_len += 2 ; udphdr = ptftp-sizeof(UDP_HDR); iphdr = ptftp-sizeof(UDP_HDR)+ sizeof(ETH_HDR); /*UDP帧头信息*/ udphdr->sport = HON(48915); udphdr->dport = HON(serverport); udphdr->len = HON(tftp_len+sizeof(UDP_HDR)-sizeof(IP_HDR)); udphdr->udpchksum = 0x00; /*IP帧头信息*/ udphdr->iphdr.vhl = 0x45; udphdr->iphdr.tos = 0x00; udphdr->iphdr.len = HON(tftp_len+sizeof(UDP_HDR)-sizeof(ETH_HDR)); udphdr->iphdr.ipid = HON(0x00); udphdr->iphdr.ipoffset = HON(0x4000); udphdr->iphdr.ttl = 0xff; udphdr->iphdr.proto = 17; memcpy(udphdr->iphdr.srcipaddr,ip_addr,4); memcpy(udphdr->iphdr.destipaddr,host_ip_addr,4); udphdr->iphdr.ipchksum = 0; udphdr->iphdr.ipchksum = checksum(iphdr,20); memcpy(udphdr->iphdr.ethhdr.s_mac,mac_addr,6); memcpy(udphdr->iphdr.ethhdr.d_mac,host_mac_addr,6); udphdr->iphdr.ethhdr.type = HON(PROTO_IP); dm9000_tx((u32 *)udphdr,sizeof(UDP_HDR)+tftp_len);}void tftp_process(u8 *buf, u32 len, u16 port){ u32 i; u32 tftp_len; serverport = port; TFTP_PAK *ptftp = buf + sizeof(UDP_HDR); tftp_len = len - sizeof(UDP_HDR); if(HON(ptftp->opcode) == 3) { if (HON(ptftp->blocknum) == curblock) { for (i = 0;i<(tftp_len-4);i++) { *(tftp_down_addr) = *(ptftp->data+i); } tftp_send_ack(HON(ptftp->blocknum)); curblock++; if ((tftp_len-4)<512) curblock = 1; } }}
阅读全文
0 0
- 移植 tftp 客户端
- 专题18-移植tftp客户端
- Linux tftp 移植
- tftp下载客户端
- Ubuntu安装tftp客户端
- windows tftp客户端使用方法
- 简单的TFTP客户端
- tftp客户端设计小结
- 山寨版tftp客户端
- uboot 1.1.6 移植8900网卡+tftp
- uboot网络移植成功,tftp能用。
- 移植5- uboot之tftp启动kernel
- TFTP客户端,完全符合RFC-1350,源代码
- 基于TFTP传输协议的客户端编程
- linux下tftp使用(服务器和客户端)
- python udp通信模型,模拟TFTP客户端
- TFTP服务器与客户端的安装
- 依据TFTP协议的服务端和客户端
- linux抓包工具 tcpdump
- Java8学习笔记 — 【Lambda表达式】
- 快速解决HDU1022问题
- DrawerLayout 侧滑菜单
- 深度学习系列——关于神经网络理解的总结
- 移植 tftp 客户端
- iOS控件之指定圆角
- 安卓监听键盘的打开和关闭
- Android 6.0动态申请权限
- 二叉搜索树之红黑树
- EventBus两个Activity传值
- Centos Fail to start LSB:Bring up/down networking
- 点击通知打开activity的注意事项
- 关于thinkphp3.2.3 cookie 和PHPEXCEL 导出身份证号出现科学计数法