网络编程- ping程序简单实现

   ping程序:ip 发送一个icmp回射请求,该节点以一个icmp回射应答。ipv4,ipv6点格式:

 0                7 8          15 16               31 

  typecode校验和
表示符表示符序列号
datadatadata
   以  ipv 4-- struct icmp 结构体中 icmp_id    ,icmp_type, icmp_code,icmp_seq,等;




表示符一般会设置为-----    pid


#include "ping.h"
  /*
  ipv4-icmp 发送数据函数
  */
  void send_v4(void)
  {
  int len;
  struct icmp*icmp;
  icmp=(struct icmp *)sendbuf;
  icmp->icmp_type=ICMP_ECHO;
  icmp->icmp_code=0;
  icmp->icmp_id=pid;
  icmp->icmp_seq=nsent++;
  memset(icmp->icmp_data,0x5a,datalen);//初始化
  gettimeofday((structtimeval *)icmp->icmp_data,NULL);
  len=8+datalen;
  icmp->icmp_cksum=in_cksum((uint16_t *)icmp,len);
  sendto(sockfd,sendbuf,len,0,pr->sasend,pr->salen);
  }
   

其实主要是icmpv6:

void send_v6(void)
  {
  #ifdef IPV6
  int len;
  struct icmp6_hdr * icmp6;
  icmp6=(strcut icmp6_hdr*)sendbuf;
  icmp6->icmp6_code=0;
  icmp6->icmp6_type=ICMP6_ECHO_REQUEST;
  icmp6->icmp6_id=pid;
  icmp6->icmp6_seq=nsent++;
  memset((icmp6+1),0x5a,datalen);
  gettimeofday((structtimeval*)(icmp6+1),NULL);
  len=8+datalen;
  sendto(sockfd,sendbuf,len,0,pr->sasend,pr->salen);
   
  #endif
  }


mian.c

#include "ping.h"
//赋值ipv4 ipv6
struct proto proto_v4={proc_v4,send_v4,NULL,NULL,0,IPPROTO_ICMP};
#ifdef IPV6
struct proto proto_v6={proc_v6,send_v6,NULL,NULL,0,IPPROTO_ICMPV6};
#endif
int datalen=56;
//icmp的大小
int main(int argc, char *argv[])
{
	int c;
	struct addrinfo *ai;
	char *h;
	opterr=0;
	while((c=getopt(argc,argv,"v"))!=1)
	{
		switch(c)
		{
			case 'v':
			verbose++;
			break;
			case '?':
			  err_quit("error parament !");
		}
	}
	if(optind!=argc-1)
		err_quit("usage : ping [-v] 
   
   
    
    ");
	host=argv[argc-1];
	pid=getpid() & 0xffff;
	ai=host_serv(host,NULL,0,0);
	h=inet_ntop_host(ai->ai_addr,ai->ai_addrlen);
	printf("PING %s (%s):%d data bytes\n",ai->ai_canonname?ai->ai_canonname:h,h,datalen);
	if(ai->ai_family==AF_INET)
	{
		pr=&proto_v4;
	
  #ifdef IPV6
	}else if(ai->ai_family==AF_INET6)
	{
		pr=&proto_v6;
		if(IN6_IS_ADDR_V4MAPPED( &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr )))
			err_quit("error : IPV6");
	#endif
	}
	else 
		err_quit("nothing i know!");
	pr->sasend=ai->ai_addr;
	pr->sarecv=calloc(1,ai->ai_addrlen);
	pr->salen=ai->ai_addrlen;
	readloop();
	return 0;
}
   
   


具体的icmp的原理过程,我认为参考一下tcp/ip [RFC0792][ RFC443],自己写着玩的一个烂代码,同时也是来源unix网络编程数据。自己好low才玩github没有多久,代码地址:

https://github.com/xiaozw1994/library-libs.git   这只是参考而已;

2、分享一个gcc编译多文件的方法:

   1、gcc    -o test.o  main.c test.c    //一般两个文件没有问题,具体意思大家都知道哈

   2、对于多文件变异是gcc 多个文件会报错:not support mutil-file ,大概是这个意思哈:此时要用一下命令:

   gcc   -shared  file.c -o file.o

   gcc  main.c -lfile.o -L path//路径要是绝对地址

3、如果文件多是还可以引入make命令,make -f make.debug 等,linux下的make 来进行;

4、当然也可以用写一个编译的脚本shell python,其实用C语言的 execl 写一个编译的命令也是可以的







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值