linux看请求报文发送的ip,Linux C 实现最简单的ICMP_ECHO请求报文发送

弄了两天,终于搞定了!把最简单的icmp报文发送实现了。本程序在linux环境编写,使用原始套接字。

实现步骤:

1、得到protocol实体(protoent,声明于);

2、初始化地址结构(sockaddr_in,声明于);

3、创建套接字(socket(),声明于,参数声明于);

4、更改socket选项,更改发送缓冲区大小(setsockopt(),声明于);

5、发送报文(sendto(),声明于);

6、关闭socket描述符(close(),声明于);

代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

typedef unsigned char byte;

typedef unsigned long ulong;

typedef unsigned short ushort;

const char* proto_name

="icmp";

const char* ip_str

="10.14.4.167";

#define SEND_BUFF1024

#define CK_NULL(___ent,___str)({\

if(___ent==NULL)printf(___str);\

})

#define PRT_ADDR_TEST(___addr)({\

printf("direction ip is:%d.%d.%d.%d\r\n",\

(___addr&0x000000ff), \

(___addr&0x0000ff00)>>8,\

(___addr&0x00ff0000)>>16,\

(___addr&0xff000000)>>24\

);\

})

byte

send_buffer[SEND_BUFF];

// declare function

ushort

icmp_cal_cksum(byte*,int);

void

icmp_create(){

struct icmp* icmph=

(struct icmp*)send_buffer;

int pid,

i,

data_len;

pid=getuid();

data_len=SEND_BUFF-8;// send_length sub icmp header_length

icmph->icmp_type=ICMP_ECHO;

icmph->icmp_code=0;

icmph->icmp_cksum=0;

icmph->icmp_seq=0;

icmph->icmp_id=pid;

for(i=0;i

icmph->icmp_data[i]=i;

icmph->icmp_cksum=icmp_cal_cksum((byte*)icmph,data_len);

}

ushort

icmp_cal_cksum(byte* _data,int _data_len){

int sum=0;

int odd=_data_len&0x01;

ushort* value=(ushort*)_data;

while(_data_len& 0xfffe){

sum+=*(ushort*)_data;

_data+=2;

_data_len-=2;

}

if(odd){

ushort tmp=((*_data)<<8)&0xff00;

sum+=tmp;

}

sum=(sum>>16)+(sum&0xffff);

sum+=(sum>>16);

return ~sum;

}

int

main(int argc,char** argv){

// socket fd

int sockfd;

// return err code

int err_code;

// send data length

int snd_len;

// long addr

ulong addr_l;

// protocol entity

struct protoent* protocol;

// socket send buffer length

int send_buff=SEND_BUFF;

// protocol socket address

struct sockaddr_in dest_addr;

// get protocol entity

protocol=getprotobyname(proto_name);

CK_NULL(protocol,"error! cannot get protocol entity!!!\r\n");

// convert ip str to u_long

addr_l=inet_addr(ip_str);

if(addr_l==INADDR_NONE){

printf("error! cannot convert ip str to long addr!!!\r\n");

return -1;

}

addr_l=htonl(addr_l);

PRT_ADDR_TEST(addr_l);

// set memory 0

bzero((char*)&dest_addr,sizeof(dest_addr));

// full sockaddr_in struct

memcpy((char*)&dest_addr.sin_addr,&addr_l,sizeof(addr_l));

sockfd=socket(AF_INET,SOCK_RAW,protocol->p_proto);

if(sockfd<0){

printf("error!cannot create sockfd!\r\n");

return -1;

}

err_code=setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&send_buff,sizeof(send_buff));

icmp_create();

snd_len=sendto(sockfd,send_buffer,send_buff,0,(struct sockaddr*)&dest_addr,sizeof(dest_addr));

if(snd_len

printf("error!send data length is not enougth!\r\n");

return -1;

}

printf("data has sended length=%d\r\n",snd_len);

close(sockfd);

return 0;

}

注:创建原始套接字时应使用管理员权限,否则会创建失败!好像也有代码中获取权限的方法,但我没有去查相关资料。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值