公开TCP/IP 源代码

huguozhong141 2002-12-04 10:46:20
如果反响热烈的话我将贴出我我写的一个在TC 纯DOS 实现的一个TCP/IP 协议栈
这一个是是TFTP 协议的实现(下载),没反映的话就此打住。
请不要将此程序用于商业目的:)
此程序调用了其他文件的函数,以后会有说明。
本人现在找工作,如果那家公司对本人有 兴趣的话联系
hu_guozhong@yahoo.com.cn
QQ 34138008

int tftprequest(tftphdr *th, u_short request, u_char *name, u_char *mode)
{
u_char *cp;

th->th_opcode = htons(request);
cp = th->th_u.tu_stuff;
while(*name)
{
*cp++ = *name++;
}
*cp++ = '\0';
while(*mode)
{
*cp++ = *mode++;
}
*cp++ = '\0';
return cp - th->th_u.tu_stuff +2;
}

/*!
* \brief Download a file from a TFTP server and burn it into the flash ROM.
*
* \return 1 on success, 0 otherwise.
*/
int tftprev(void)
{
u_char retry;
int rlen = 0/*,rc=0*/;
int slen;
/* u_char *cp=tftpdata; ************************************/
int i;
u_short sport = 1024;
u_short dport = 69;
u_short block = 0;
tftphdr *thout,*threv;
/*
* Prepare the transmit buffer for a file request.
*/
thout=(tftphdr *)malloc(sizeof(tftphdr));
threv=(tftphdr *)malloc(sizeof(tftphdr));

printf("\n tftp request begin");
strcpy(bootpfile,"boot.txt");/****************************/
slen = tftprequest(thout, TFTP_RRQ, bootpfile, "octet");

/*
* Lopp until we receive a packet with less than 512 bytes of data.
*/
do {

/*
* Send file request or acknowledge and receive
* a data block.
*/
/* We destroy the nb in any case which is failed ,and free the memory */
for(retry = 0; retry < 1; retry++) {
if(sendto( dport, sport, thout,slen,server_ip) >=1) {
destroybuf();
delay(65500);
if((rlen = receive(dport,sport,threv,sizeof(tftphdr))) >= 4)
{
/* printf("\nthe times is=%d tftpdata length=%d\n",block+1,rlen); ***********************/
break;
}
else {
destroybuf();
continue;
}/* end if(receive())*/
} else
{
destroybuf();
continue;
}/* end if(sendto) */
} /* end for() */

/*
* Can't reach the TFTP server or got a malformed
* repsonse.
*/
if(rlen < 4)
{
free(thout);
free(threv);
return 0;
}
/*
* Accept data blocks only. Anything else will stop
* the transfer with an error.
*/
if(htons(threv->th_opcode) != TFTP_DATA)
{
if(htons(threv->th_opcode)==TFTP_ERROR)
printf("\nFILE NOT FIND OR TFTP SERVER NOT OPEN");
free(threv);
free(thout);
return 0;
}

/*
* If this was the first block we received, prepare
* the send buffer for sending ACKs.
*/
if(block == 0) {
dport=((udphdr *)nb.tp.vp)->sport;
dport=htons(dport);
/* printf("\nthe ACK de dport =%x",dport); */
thout->th_opcode = htons(TFTP_ACK);
slen = 4;
}

/*
* If this block is out of sequence, we ignore it.
* However, if we missed the first block, return
* with an error.
*/
if(htons(threv->th_u.tu_block) != block + 1) {
if(block == 0)
{
free(threv);
free(thout);
return 0;
}
continue;
}

/*
* Burn the received data into the flash ROM.
*/

if(rlen > 4)
{
/* memcpy(cp, threv->th_data, rlen - 4); *******************/
insertdata(block,threv->th_data,rlen-4); /*****************/
/* travelist(); */
/* cp=cp+rlen-4; ************************/
/* *cp='\0'; *************************************/
}
/*
* Update our block counter.
*/
/* printf("\nthe tftpdata1111=%s",tftpdata); */
block++;
thout->th_u.tu_block = htons(block);
destroybuf();
} while(rlen >= 516);/*end do? */
printf("\nBLOCK NUMBER IS:",block);
/*
* Send the last ACK.
*/

sendto(dport, sport,thout, slen,server_ip);
destroybuf();
free(thout);
free(threv);
return 1;
}
程序不完善的地方,欢迎大家提出修改意见!!!
...全文
978 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
huguozhong141 2002-12-08
  • 打赏
  • 举报
回复
我完成的TCP/IP 只完成了
应用层的:DHCP 和TFTP 协议。
传输层为;UDP;
网络层为IPV4 但是,没写路由选择没写,(如果没代理只能在LAN 中工作)。
数据链路层的话 ,只支持NE2000 的网卡(驱动是我自己写的)。
程序能完成的事是:
一台破DOS 机器从LAN 中一台安装了DHCP和TFTP的服务器,能获得
IP 地址和下载所需要的文件。(也可以用于无盘)
我帖出来的目的
1。让一些不知道C语言能做什么的 人来 看看C的用处。
2。让大家看一看TCP/IP 的大概实现方法。
3。我之所以把帖子名搞的那么牛,只是想多几个人看看而已。-----如果不这样
根本没人看。
4。确实想找工作了。看看有没有人,来这里招人。---当然很失望:)
5。我只是想一些没入门的初学者帮些忙而已,但没想到受到这么多猜疑。----好象我拿了
别人分,的了别人的钱一样。
6。我不会再帖出来拉,何必费力不讨好了。帖出来我又不会得到什么好处。----
浪费我两个月写程序的心血。
Yijingsong 2002-12-07
  • 打赏
  • 举报
回复
请给我一份,非常感谢!
yijingsong@yeah.net
huguozhong141 2002-12-07
  • 打赏
  • 举报
回复
今天贴出DHCP 协议的实现:
/* copyright--------huguozhong ---------------------*/
/* ----------Have any question mail huguozhong@hotmail.com ----------*/
/*!
* \brief Initialize the global send frame for DHCP requests.
*
* \return Size of the frame.
*/
u_short initdhcp(bootphdr *bp)
{
u_char cookie[4]={0x63,0x82,0x53,0x63};
u_short i;
u_short len=sizeof(bootphdr);
u_char *bootp;
u_char *op=NULL;
bootp=(u_char *)bp;
op=bp->bp_options;
for(i=0;i<len;i++)
{
*(bootp+i)=0;
}

bp->bp_op = 1;
bp->bp_xid = 0x5c1d547e;
bp->bp_secs=0;
bp->bp_flags=0x0000;
bp->bp_htype = 1;
bp->bp_hlen = 6;
for(i = 0; i < 6; i++)
{
bp->bp_chaddr[i] = smac[i];
}
for(i = 0; i < 4; i++)
{
*op++ = cookie[i];
}
*op++ = DHCPOPT_MSGTYPE;
*op++ = 1;
*op++ = DHCP_DISCOVER;
*op++=0x3d;
*op++=0x07;
*op++=0x01;
for(i=0;i<6;i++)
{
*op++=smac[i];
}
/* Ip you want to get */
*op++=DHCPOPT_REQUESTIP;
*op++=0x04;
*op++=0xca;
*op++=0xc5;
*op++=0x76;
*op++=0x04;

/* the client identifier
* computer name
*/
*op++=0x0c;
*op++=0x07;
*op++=0x48;
*op++=0x31;
*op++=0x39;
*op++=0x30;
*op++=0x51;
*op++=0x30;
*op++=0x00;
*op++= DHCPOPT_END;
len=sizeof(bootphdr)-312+(op-bp->bp_options);
return len;
}
u_short dhcprequest(bootphdr *bpout,bootphdr *bprev)
{
u_char *op=NULL;
u_short len;
u_short i;
op =&bpout->bp_options[6];
*op++ = DHCP_REQUEST;
*op++=0x3d;
*op++=0x07;
*op++=0x01;
for(i=0;i<6;i++)
{
*op++=smac[i];
}
*op++ = DHCPOPT_REQUESTIP;
*op++ = 4;

*op++ = (u_char)(bprev->bp_yiaddr);
*op++ = (u_char)(bprev->bp_yiaddr >> 8);
*op++ = (u_char)(bprev->bp_yiaddr >> 16);
*op++ = (u_char)(bprev->bp_yiaddr >> 24);

/* the server ip */
*op++=DHCPOPT_SID;
*op++ = 4;

*op++ = (u_char)sid;
*op++ = (u_char)(sid >> 8);
*op++ = (u_char)(sid >> 16);
*op++ = (u_char)(sid >> 24);


/* client name */
*op++ = 0x0c ;
*op++ = 0x07 ;
*op++ = 0x48;
*op++ = 0x31 ;
*op++ = 0x59 ;
*op++ = 0x30 ;
*op++ = 0x51;
*op++ = 0x30;
*op++ = 0x01;
/* dhcp end */
*op++ = 0xff;
len=sizeof(bootphdr)-312+(op-bpout->bp_options);
return len;
}

/*!
* \brief Retrive the specified DCHP option.
*
* \param opt Option to look for.
* \param ptr Pointer to the buffer that receives the option value.
* \param size Size of the buffer.
*
* \return Size of the retrieved option value or zero,
* if the specified option couldn't be found.
*/
u_char dhcpgetoption(bootphdr *bp,u_char opt, void *ptr, u_char size)
{
u_char *cp,*op;
u_char i;

cp = bp->bp_options + 4;
for(;;) {
if(*cp == DHCPOPT_PAD)
{
cp++;
continue;
}
if(*cp == DHCPOPT_END)
break;
if(*cp == opt)
{
if(*(cp+1)<size)
size=*(cp+1);
for(i=0;i<size;i++)
{
op=(u_char *)ptr;
*(op+i)=*(cp+2+i);
}
return *(cp+1); /* return the count of byte */
} /* end if */
cp++;
cp+=*cp; /* jump *cp byte */
cp++;
}/* end for*/
return 0;
}

/*!
* \brief Query any DHCP server on the local net.
*
* On success, this routine will fill some global
* \return 1 on success, 0 otherwise.
*/

int dhcpquery(void)
{
u_char type;
int i;
u_char retry;
u_short rlen;
u_short slen;
u_char *cp;
u_short dport=67;
u_short sport=68;
bootphdr *bpout=NULL,*bprev=NULL;
bpout=(bootphdr *)malloc(sizeof(bootphdr));
bprev=(bootphdr *)malloc(sizeof(bootphdr));
slen=initdhcp(bpout);
/* printf("\n Send the initdhcp discover:") ; */
slen=sendto(dport, sport, bpout, slen,server_ip);
destroybuf();
/*delay(65500);*/
for(retry=0;retry<10;retry++)
{
rlen = receive(dport,sport,bprev,sizeof(bootphdr));
if(slen&&rlen&&(bpout->bp_xid == bprev->bp_xid)
&&(dhcpgetoption(bprev,DHCPOPT_MSGTYPE,&type, 1)!=0)
&&type == DHCP_OFFER)
{
destroybuf();
break;
}
destroybuf();
}/* end for*/
if(retry >= 9)
{
printf("\nMaybe dhcp server not open or dhcp error");
free(bprev);
free(bpout);
return 0;
}

dhcpgetoption(bprev,DHCPOPT_SID,&sid,4);
printf("\n the server sid =%lx",htonl(sid));
/*
printf("\n have done discover-->server and server anspond the DHCP OFFER");
printf("\nDHCP REQUEST");
*/
slen=dhcprequest(bpout ,bprev);
slen=sendto(dport,sport,bpout,slen,server_ip);
for(retry=0;retry<10;retry++)
{
delay(65500);
rlen=receive(dport,sport,bprev,sizeof(bootphdr));
if(slen&&rlen&&(bprev->bp_xid==bpout->bp_xid)
&&(dhcpgetoption(bprev,DHCPOPT_MSGTYPE,&type,1)==1)
&&type==DHCP_ACK)
{
destroybuf();
/* printf("\nrecevid the DHCP_ACK"); */
break;
}
destroybuf();
}
if(retry>=9)
{
free(bprev);
free(bpout);
printf("\n received dhcpoffer but not received dhcp ACK");
return 0;
}
local_ip = bprev->bp_yiaddr;
/* server_ip =bprev->bp_siaddr; */
dhcpgetoption(bprev,DHCPOPT_SID,&sid,4);
server_ip=sid;
/*strcpy(bootpfile,"boot.txt");*/
/* printf("\nTHE bootpfilename=%s",bootpfile); */
dhcpgetoption(bprev,DHCPOPT_NETMASK, &netmask, 4);
dhcpgetoption(bprev,DHCPOPT_BROADCAST, &broadcast, 4);
dhcpgetoption(bprev,DHCPOPT_GATEWAY, &gateway, 4);
dhcpgetoption(bprev,DHCPOPT_DNS, &dns, 4);
/* dhcpgetoption(bprev,DHCPOPT_SID, &sid, 4); */
free(bprev);
free(bpout);
return 1;
}
huguozhong141 2002-12-06
  • 打赏
  • 举报
回复
程序结构如下:
一、
程序简介:在纯DOS下:
1.客户机能得到从服务器发的IP地址.
2.服务器能根据客户机请求发送适当文件.
3.客户机能收到从服务器发过来的文件.
4.程序采用模块化设计方法,根据TCP/IP的层次结构编写而成.
二、
构成部分:
STRUCT.H:程序所有数据结构.
INTMAIN.C:程序入口
APP.C:应用层协议---- 我上一个发的APP.C 中的TFTP 协议
SOCKET.C:收报和发报 及全局变量 的初始化和 释放.
UDP.C: UDP协议.
ETHER.C 802.3,10M/100M以太网协议,NE2000网卡驱动.
ARP.C:-地址解析协议.
MISK.C:处理写程序中出现的杂项
CHECKSUM.C计算IP报头和UDP数据报校验和.
三、
此程序完成了DHCP TFTP 协议的所有内容。
此程序于16日完成的程序的区别是:
1。用链表来存储数据。存的数据大了一倍。
2。基本上做到了在那个函数中产生的 申请内存在 哪个函数 释放。
3。加入了更多注释。
4。解决了dhcp reveive十次没收到offer是的占用内存问题.
5.做了一个极其简单的界面.
使程序能做到模块化.-------多次传文件是会产生错误,用MODEMIAN()
做主函数,
但是程序用intmain()做主函数是没有任何问题.
5.1 使 ARP 协议 能单独 主动 完成.-----modemain()作到了.
5.2 可以是程序和一台机器做过ARP 后,每必要再做,特别是传完一个
文件再传另外一个时.
6。连续传几个文件时,程序死机的问题。
-----以前已经解决但今天重新出现。-----10.16
程序的问题有:
1。传输54.7k以上文件是会死机.
3。当服务器的dhcpserver关闭时,死循环中-----以解决。
2。但还需要完成ICMP 协议。
ICMP 包括主动探测对方和回应对方探测。
Lyongfei 2002-12-06
  • 打赏
  • 举报
回复
给我,也
L_yongfei@163.com
jian 2002-12-06
  • 打赏
  • 举报
回复
我喜欢看思路清晰的程序,先讲讲你的程序的大体框架吧
greysky123 2002-12-06
  • 打赏
  • 举报
回复
继续关注,希望能发全
huguozhong141 2002-12-06
  • 打赏
  • 举报
回复
我英语不是很好,注释可能有错误,如果发现了话,请指出来
用英语注释是为了在DOS 下使用方便
还有就是:大家觉得新开帖子发程序好,还是在本帖子里发程序好啊
xf810619 2002-12-05
  • 打赏
  • 举报
回复
sherrill_001@163.com

不胜感激
yzt001 2002-12-05
  • 打赏
  • 举报
回复
gz
Ericsson 2002-12-05
  • 打赏
  • 举报
回复
给我一份嘛,谢谢
aaronchow@sohu.com
风中老长 2002-12-05
  • 打赏
  • 举报
回复
有意思,关注!
huguozhong141 2002-12-05
  • 打赏
  • 举报
回复
各位兄弟:
我忙于找工作和考试,没时间用邮件一个一个回复,请大家原谅。
如果回复超过十次的话 以后程序全部在泛型技术论坛发布。
bolm 2002-12-05
  • 打赏
  • 举报
回复
也给我一份吧,谢谢了!!!
BOLM@ETANG.COM
d3e 2002-12-05
  • 打赏
  • 举报
回复
d3e@163.com
谢谢了
Li_Dinosaur 2002-12-05
  • 打赏
  • 举报
回复
能给我一份吗?:)
look544@163.com 谢谢你了。
huguozhong141 2002-12-05
  • 打赏
  • 举报
回复
泛型技术论坛没人进,在此发布数据结构和全局变量。
/* copyright--------huguozhong ---------------------*/
/* ----------Have any question mail huguozhong@hotmail.com ----------*/

typedef unsigned int u_short;
typedef int u_int;
typedef unsigned char u_char;
typedef unsigned long u_long;
typedef unsigned long long u_longlong;

/* the base data unit */
typedef struct{
u_short sz; /* output is header size inout is datagram length */
u_char *vp; /* use to point the datagram or header */
}databuf;

/* the tftp datagram header */
typedef struct {
short th_opcode; /* packet type */
union {
short tu_block; /* block # */
short tu_code; /* error code */
char tu_stuff[1]; /* request packet stuff */
} th_u;
char th_data[512]; /* data or error string */
} tftphdr;



/* DHCP data format */
typedef struct {
u_char bp_op; /* \brief Packet opcode type: 1=request, 2=reply */
u_char bp_htype; /*\brief Hardware address type: 1=Ethernet */
u_char bp_hlen; /*\brief Hardware address length: 6 for Ethernet */
u_char bp_hops; /* \brief Gateway hops */
u_long bp_xid; /* \brief Transaction ID */
u_short bp_secs; /* \brief Seconds since boot began */
u_short bp_flags;
u_long bp_ciaddr; /* client ipaddress ,commonly is 0*/
u_long bp_yiaddr; /* the ip address ,you want to get */
u_long bp_siaddr; /* commonly is 0*/
u_long bp_giaddr; /* commonly is 0 */
u_char bp_chaddr[16];
char bp_sname[64]; /* client computer name */
char bp_file[128]; /*\brief Boot file name */
u_char bp_options[312]; /* brief Vendor-specific area */
} bootphdr;



/* the udp datagram header */
typedef struct{
u_short sport; /*source udp port*/
u_short dport; /*target udp port */
u_short ulen; /*udp datagram length contain the header and data */
u_short cksum; /* udp checksum is the pseudo checksum **** */
}udphdr;

/*the internet paket header */
typedef struct{
u_char vandhl; /*contain the version and the internet packet header length*/
u_char tos; /* type of server */
u_short iplen; /* the internet length=internet header length+data length */
u_short id; /* datagram id use to caption the only datagram */
u_short flags; /*commonly is zero */
u_char ttl; /* time to live */
u_char ipp; /* the next pocotol is udp or tcp */
u_short cksum; /* Internet header checksum */
u_long saddr; /* the source ip address */
u_long daddr; /* detination addresss */
}iphdr;



/* ethernet header format */
typedef struct
{
u_char dmac[6]; /* detination hardware address */
u_char smac[6]; /* source hardware address */
u_short type; /*!< \brief Protocol type. */
}etherhdr;


/*!
* \typedef ETHERARP
* \brief Ethernet ARP protocol type.
*/
typedef struct
{
u_short arp_hrd; /* \brief Format of hardware address.
* Nut/Net supports ARPHRD_ETHER only.
*/
u_short arp_pro; /* \brief Format of protocol address.
* Only ETHERTYPE_IP is supported by Nut/Net.
*/
u_char arp_hln; /* \brief Length of hardware address. */
u_char arp_pln; /* Length of protocol address */
u_short arp_op; /* Operation type */
u_char arp_sha[6] ; /* Source hardware address */
u_long arp_spa; /* Source IP address */
u_char arp_tha[6] ; /* Target hardware address */
u_long arp_tpa; /* Target IP address */
}etherarp;

/* The netbuf is used to save the data ,and
* transport data.
*/
typedef struct{
databuf ap; /* Application layer data */
databuf tp; /* Transport layer data */
databuf nw; /*Network layer data */
databuf dl; /* Datalink layer data */
}netbuf;

/* record the target port and source port
* in net order
*/
typedef struct udp_socket {
u_short dport; /* server port in network byte order */
u_short sport; /* Local port number in network byte order. */
}udpsocket;

typedef struct tftp{
u_short block;
u_char buf[513]; /* buf[512]='\0'*/
struct tftp *next;
}tftplist;

/* CONST in this program */
#define NBAF_APPLICATION 0x08
#define NBAF_TRANSPORT 0x04
#define NBAF_NETWORK 0x02
#define NBAF_DATALINK 0x01
#define NBAF_ALL 0x0f

#define IPVERSION 4
#define IP_DF 0x4000 /*!< \brief Don't fragment flag. */
#define IP_MF 0x2000 /*!< \brief More fragments flag. */
#define IP_OFFMASK 0x1fff /*!< \brief Mask for fragmenting bits. */

#define IPPROTO_UDP 17
#define IPPROTO_IP 0
#define IPPROTO_ARP 20
#define IPPROTO_TCP 6
#define IPPROTO_ICMP 1
#define IPPROTO_DHCP 2


#define TFTP_RRQ 01 /* \brief TFTP read request packet. */
#define TFTP_WRQ 02 /* \brief TFTP write request packet. */
#define TFTP_DATA 03 /* \brief TFTP data packet. */
#define TFTP_ACK 04 /* \brief TFTP acknowledgement packet. */
#define TFTP_ERROR 05 /* \brief TFTP error packet. */
#define TFTP_OACK 06 /* \brief TFTP option acknowledgement packet. */
#define ARPOP_REQUEST 0x0001 /* ARP operation type :request */
#define ARPOP_REPLY 0x0002 /* ARP operation type :reply */
#define ETHERTYPE_IP 0x0008 /* \brief deal with Protocol type is IP. */
#define ETHERTYPE_ARP 0x0608 /* brief deal with protocol type is ARP */


#define DHCPOPT_PAD 0 /* DHCP pad */
#define DHCPOPT_NETMASK 1
#define DHCPOPT_GATEWAY 3
#define DHCPOPT_DNS 6
#define DHCPOPT_HOSTNAME 12
#define DHCPOPT_DOMAIN 15
#define DHCPOPT_BROADCAST 28
#define DHCPOPT_REQUESTIP 50
#define DHCPOPT_LEASETIME 51 /* DHCP IP lease time */
#define DHCPOPT_MSGTYPE 53
#define DHCPOPT_SID 54 /* DHCP server IP address */
#define DHCPOPT_RENEWALTIME 58
#define DHCPOPT_REBINDTIME 59
#define DHCPOPT_END 255 /* DHCP finished */

#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_INFORM 8

extern u_char smac[6]={0x00,0x80,0xC8,0x68,0xDB,0x72};

netbuf nb; /* Can only be destroy in application layer */
u_long netmask=0xffffff00;
u_long broadcast;
u_long gateway;
u_char bootpfile[128];
u_long sid;
u_long dns;
u_long local_ip; /* use to record the local ip address */
u_long server_ip; /* use to record the ditination address */
tftplist *tl=NULL;
/* u_char tftpdata[20000];***************//* save stransport file's data */

/* copyright--------huguozhong ---------------------*/
/* ----------Have any question mail huguozhong@hotmail.com ----------*/
用户 昵称 2002-12-05
  • 打赏
  • 举报
回复
u'd publish it at c/c++ foundation board
用户 昵称 2002-12-05
  • 打赏
  • 举报
回复
wonderful
shantian 2002-12-05
  • 打赏
  • 举报
回复
up
加载更多回复(5)

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧