最近在学习TCP/IP协议。在以前套接字基础上又学习了原始套接字的使用。并喜欢上了这个东西-因为它功能太强大了。

//Ping模拟  By RedIce
//E-mail:redice@see.xidian.edu.cn
//
// 最近在学习TCP/IP协议。在以前套接字基础上又学习了原始套接字的使用。
#include <winsock2.h> //Winsock API头文件
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,”ws2_32.lib”) //Winsock API连接库文件
/*IP头 结构*/
//BYTE<=>unsigned char,自定义类型
//USHORT<=>unsigned short,自定义类型
//UINT<=>unsigned int,自定义类型
//ULONG<=>unsigned long,自定义类型
typedef struct iphdr{
 BYTE  h_len:4;     //首部长度指的是IP层头部占32 bit字的数目
                   
//(也就是IP层头部包含多少个4字节,实际字节数4*hlen),
 BYTE  version:4;   //IP版本号
 BYTE  tos;         //服务类型TOS
 USHORT total_len;  //IP包总长度
 USHORT ident;      //标识
 USHORT frag_and_flags;  //标志位
 BYTE ttl;          //生存时间
 BYTE proto;        //协议
 USHORT checksum;   //IP首部校验和
 UINT  sourceIP;    //源IP地址(32位)
 UINT  destIP;      //目的IP地址(32位)
}IpHeader;
/*ICMP头 结构*/
typedef struct _ihdr{
 BYTE i_type;       //类型
发出的ICMP为8(ICMP_ECHO_REQUEST),接受到的ICMP为0
 BYTE i_code;       //代码
 USHORT i_cksum;    //ICMP包校验和
 USHORT i_id;       //识别号(一般用进程号作为标识号)
 USHORT i_seq;      //报文序列号(一般设置为0)
 ULONG timestamp;   //时间戳
}IcmpHeader;

* ping.c – Simple ping utility using SOCK_RAW
*
* This is a part of the Microsoft Source Code Samples.
* Copyright 1996-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
******************************************************************************/

下面是我用原始套接字实现的Ping.exe命令
这是运行后的效果(嘿嘿,还真相Ping程序,哈哈)
澳门新葡萄京所有网站 1

USHORT checksum(USHORT *,int); //函数声明:计算ICMP包校验和
void usage();       //函数声明:使用帮助

#pragma pack(4)

//Ping模拟  By RedIce
//E-mail:redice@see.xidian.edu.cn
//
#include <winsock2.h> //Winsock API头文件
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,”ws2_32.lib”) //Winsock API连接库文件
/*IP头 结构*/
//BYTE<=>unsigned char,自定义类型
//USHORT<=>unsigned short,自定义类型
//UINT<=>unsigned int,自定义类型
//ULONG<=>unsigned long,自定义类型
typedef struct iphdr{
 BYTE  h_len:4;    //首部长度指的是IP层头部占32 bit字的数目
       //(也就是IP层头部包含多少个4字节,实际字节数4*hlen),
 BYTE  version:4; //IP版本号
 BYTE  tos;      //服务类型TOS
 USHORT total_len; //IP包总长度 
 USHORT ident;     //标识
 USHORT frag_and_flags;  //标志位
 BYTE ttl;      //生存时间
 BYTE proto;    //协议
 USHORT checksum; //IP首部校验和
 UINT  sourceIP; //源IP地址(32位)
 UINT  destIP;  //目的IP地址(32位)
}IpHeader;
/*ICMP头 结构*/
typedef struct _ihdr{
 BYTE i_type;   //类型
发出的ICMP为8(ICMP_ECHO_REQUEST),接受到的ICMP为0
 BYTE i_code;   //代码
 USHORT i_cksum; //ICMP包校验和
 USHORT i_id;    //识别号(一般用进程号作为标识号)
 USHORT i_seq;   //报文序列号(一般设置为0)
 ULONG timestamp;//时间戳
}IcmpHeader;

void main(int argc,char *argv[])
{
 char *ICMP_DEST_IP;//目标主机IP
 WSADATA wsaData;
 struct sockaddr_in dest,from;//地址结构
 int datasize;      //ICMP报文大小
 int ret;           //API函数 返回值
 int i;             //循环计数器
 int attachsize=32; //ICMP数据包附加字节数,本程序默认为32字节
 int n=4;           //发送数据包个数,本程序默认发送4个ICMP数据包
 int timeout;       //延迟
 DWORD packetrecv=0;//收到的数据包
 DWORD mintime=0;   //用时最短时间
 DWORD maxtime=0;   //用时最长时间
 DWORD averagetime=0;//平均用时
 DWORD lostpercent=0;//丢包率
 DWORD start;       //发送ICMP包起始时间
 char *icmp_data;   //ICMP包
 char *recvbuf;     //ICMP应答接收缓冲区
 int fromlen=sizeof(from);//地址结构体的大小
 SOCKET sockRaw;    //原始套接字
 char *attachdata;  //ICMP包附加数据
 PHOSTENT hostinfo; //主机信息(域名->IP)
 //读取命令行参数
 if(1==argc)        //如果仅有一个默认的命令行参数则显示程序说明
                    //默认的第一个命令行参数为本程序的路径
 {
  usage();
  return;           //退出程序
 }
 else               //如果有多个命令行参数
 {
  for(i=1;i<=argc-1;i++)
  {
   if(strstr(argv[i],”-n”))//”-n” 指定发送ICMP数据包个数
   {
    n=atoi(argv[i+1]);
    i++;
   }
   if(strstr(argv[i],”-l”))//”-l” 指定每个包附加数据的大小
   {
    attachsize=atoi(argv[i+1]);
    i++;
   }
   if(strstr(argv[i],”-t”))//”-t” 死亡之Ping
   {
    n=999999;
   }
   if(strstr(argv[i],”?”))
   {
    usage();
    return;//退出程序
   }
  }
  ICMP_DEST_IP=argv[argc-1];
 }

#define WIN32_LEAN_AND_MEAN
#include
#include
#include

USHORT checksum(USHORT *,int); //函数声明:计算ICMP包校验和
void usage();//函数声明:使用帮助
void main(int argc,char *argv[])
{
 char *ICMP_DEST_IP;//目标主机IP
 WSADATA wsaData;
 struct sockaddr_in dest,from;//地址结构
 int datasize; //ICMP报文大小
 int ret;//API函数 返回值
 int i;//循环计数器
 int attachsize=32;//ICMP数据包附加字节数,本程序默认为32字节
 int n=4;//发送数据包个数,本程序默认发送4个ICMP数据包
 int timeout;//延迟
 DWORD packetrecv=0;//收到的数据包
 DWORD mintime=0;//用时最短时间
 DWORD maxtime=0;//用时最长时间
 DWORD averagetime=0;//平均用时
 DWORD lostpercent=0;//丢包率
 DWORD start;//发送ICMP包起始时间
 char *icmp_data;//ICMP包
 char *recvbuf;//ICMP应答接收缓冲区
 int fromlen=sizeof(from);//地址结构体的大小
 SOCKET sockRaw;//原始套接字
 char *attachdata;//ICMP包附加数据
 PHOSTENT hostinfo;//主机信息(域名->IP)
 //读取命令行参数
 if(1==argc)//如果仅有一个默认的命令行参数则显示程序说明
         //默认的第一个命令行参数为本程序的路径
 { 
  usage();
  return;//退出程序
 }
 else //如果有多个命令行参数
 {
  for(i=1;i<=argc-1;i++)
  {
   if(strstr(argv[i],”-n”))//”-n” 指定发送ICMP数据包个数
   {
    n=atoi(argv[i+1]);
    i++;
   }
   if(strstr(argv[i],”-l”))//”-l” 指定每个包附加数据的大小
   {
    attachsize=atoi(argv[i+1]);
    i++;
   }
   if(strstr(argv[i],”-t”))//”-t” 死亡之Ping
   {
    n=999999;
   }
   if(strstr(argv[i],”?”))
   {
    usage();
    return;//退出程序
   }
  }
  ICMP_DEST_IP=argv[argc-1];
 }

 //初始化Socket
 ret=WSAStartup(MAKEWORD(2,2), //Socket版本号
       &wsaData //指向WSADATA数据结构的指针
      );
 if(ret!=0)//WSAStartup调用成功返回0
 {
  printf(“初始化Socket出错!n”);
  return;//退出程序
 }
 //域名解析
 hostinfo=gethostbyname(ICMP_DEST_IP);
 if(NULL==hostinfo)
 {
  printf(“无法解析主机%s的IP地址!”,ICMP_DEST_IP);
  WSACleanup(); //中止Windows Sockets DLL的使用,释放资源
  return;
 }
 else
 {
  ICMP_DEST_IP=inet_ntoa(*(struct
in_addr*)*hostinfo->h_addr_list);
 }

#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0

 //初始化Socket
 ret=WSAStartup(MAKEWORD(2,2), //Socket版本号
       &wsaData //指向WSADATA数据结构的指针
      );
 if(ret!=0)//WSAStartup调用成功返回0
 {
  printf(“初始化Socket出错!n”);
  return;//退出程序 
 }
 //域名解析
 hostinfo=gethostbyname(ICMP_DEST_IP);
 if(NULL==hostinfo)
 {
  printf(“无法解析主机%s的IP地址!”,ICMP_DEST_IP);
  WSACleanup(); //中止Windows Sockets DLL的使用,释放资源
  return;
 }
 else
 {
  ICMP_DEST_IP=inet_ntoa(*(struct
in_addr*)*hostinfo->h_addr_list);
 }

 //创建原始套接字
 sockRaw=socket(AF_INET,//协议族(AF_INET: TCP_IP)
       SOCK_RAW,//套接字类型(原始套接字)
       IPPROTO_ICMP//协议类型(ICMP协议)
       );
 if(INVALID_SOCKET==sockRaw)//socket调用失败返回INVALID_SOCKET,反之返回套接字句柄
 {
  printf(“创建原始套接字出错!n”);
  WSACleanup(); //中止Windows Sockets DLL的使用,释放资源
  return;//退出程序
 }
 
 //设置目的IP
    memset(&dest,0,sizeof(dest));
 dest.sin_addr.S_un.S_addr=inet_addr(ICMP_DEST_IP);
 dest.sin_family=AF_INET;
 
 attachdata=(char*)malloc(attachsize);
 memset(attachdata,0,attachsize);//ICMP包数据部分 填充attachsize字节0
 datasize=sizeof(IcmpHeader)+attachsize;//ICMP数据包总大小(头+体)
 icmp_data=(char*)malloc(datasize);//根据上面计算的结果为ICMP包数据分配内存
 recvbuf=(char*)malloc(200);//
 memset(icmp_data,0,datasize);
 //ICMP数据包封装
 ((IcmpHeader *)icmp_data)->i_type=8;
 ((IcmpHeader *)icmp_data)->i_code=0;
 ((IcmpHeader *)icmp_data)->i_id=(USHORT)GetCurrentProcessId();
 ((IcmpHeader *)icmp_data)->timestamp=GetTickCount();
 ((IcmpHeader *)icmp_data)->i_seq=0;
 memcpy(icmp_data+sizeof(IcmpHeader),attachdata,attachsize);//ICMP包数据部分
填充32字节0
 ((IcmpHeader *)icmp_data)->i_cksum=0;
 //计算ICMP包校验和
 ((IcmpHeader *)icmp_data)->i_cksum=checksum((USHORT
*)icmp_data,datasize);
 timeout=1000;
 //设置发送延迟
 setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char
*)&timeout,sizeof(timeout));
 timeout=2000;
 //设置接受延迟
 setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char
*)&timeout,sizeof(timeout));
 printf(“Pinging %s with %d bytes of
data:nn”,ICMP_DEST_IP,attachsize);
 for(i=1;i<=n;i++)
 { start=GetTickCount();
  //发送第i个ICMP数据包
  ret=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr *)
&dest,sizeof(dest));
  if(SOCKET_ERROR==ret)
  {
   printf(“发送ICMP数据包%d出错!n”,i);
   continue;
  }
  //等待接收返回的ICMP数据包
  while(1)
  {
   if((GetTickCount()-start)>=1000)
   {
    printf(“Request timed out.n”);
    break;
   }
   memset(recvbuf,0,200);
   ret=recvfrom(sockRaw,recvbuf,200,0,(struct sockaddr *)
&from,&fromlen);
   if(SOCKET_ERROR==ret)
   {
    printf(“接收数据包%d出错!n”,i);
    break;
   }
   else
   {
    //显示返回ICMP包的信息
    unsigned short iphdrlen;//IP头长度
    IcmpHeader *icmphdr;
    DWORD timeuse;//数据包发送到接收用时
    int attachlen;//返回的ICMP数据包中数据段的大小
    timeuse=(GetTickCount()-start);
    if(0==packetrecv)
    {
     mintime=timeuse;
     maxtime=timeuse;
    }
    if(timeuse>maxtime) maxtime=timeuse;
    if(timeuse<mintime) mintime=timeuse;
    averagetime=averagetime+timeuse;
    iphdrlen=((IpHeader *)recvbuf)->h_len *4;
    icmphdr=(IcmpHeader *)(recvbuf+iphdrlen);
    attachlen=ret-iphdrlen-sizeof(IcmpHeader);
    printf(“Reply from %s: bytes=%d time=%d ms
TTL=%dn”,ICMP_DEST_IP,attachlen,timeuse,((IpHeader
*)recvbuf)->ttl);
    packetrecv++;
    break;
   }
 
  }
 }
 //显示统计信息
 lostpercent=100*((float)(n-packetrecv)/(float)n);//计算丢包率
 averagetime=(float)averagetime/(float)packetrecv;//计算平均用时
 printf(“nPing statistics for %s:n”,ICMP_DEST_IP);
 printf(”    Packets: Sent = %d, Received = %d, Lost = %d (%d %s
loss),n”,n,packetrecv,lostpercent,lostpercent,”%”);
 printf(“Approximate round trip times in milli-seconds:n”);
 printf(”    Minimum = %dms, Maximum = %dms, Average =
%dms”,maxtime,mintime,averagetime);
 free(recvbuf);
 free(icmp_data);
 closesocket(sockRaw);
 WSACleanup();
}
//计算ICMP数据包校验和
USHORT checksum(USHORT *buffer,int size)
{
 unsigned long cksum=0;
 while(size>1)
 {
  cksum+=*buffer++;
  size-=sizeof(USHORT);
 }
 if(size)
 {
  cksum+=*(UCHAR *)buffer;
 }
 cksum=(cksum>>16)+(cksum & 0xffff);
 cksum+=(cksum>>16);
 return (USHORT) (~cksum);
}
//使用说明
void usage()
{
 printf(“Ping程序模拟nn”);
 printf(“By RedIcen”);
 printf(“E-mail:redice@see.xidian.edu.cnn”);
 printf(“”);
 printf(“Usage: checknet.exe [-n count] [-l size] target_name
nn”);
 printf(“Options:n”);
 printf(” -n count       发送ICMP数据包的个数,默认为4个.n”);
    printf(” -l size       
每个ICMP包附加的数据字节数,默认为32字节.nn”);
}

#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)

 //创建原始套接字
 sockRaw=socket(AF_INET,//协议族(AF_INET: TCP_IP)
       SOCK_RAW,//套接字类型(原始套接字)
       IPPROTO_ICMP//协议类型(ICMP协议)
       );
 if(INVALID_SOCKET==sockRaw)//socket调用失败返回INVALID_SOCKET,反之返回套接字句柄
 {
  printf(“创建原始套接字出错!n”);
  WSACleanup(); //中止Windows Sockets DLL的使用,释放资源
  return;//退出程序
 }
 
 //设置目的IP
    memset(&dest,0,sizeof(dest));
 dest.sin_addr.S_un.S_addr=inet_addr(ICMP_DEST_IP);
 dest.sin_family=AF_INET;
 
 attachdata=(char*)malloc(attachsize);
 memset(attachdata,0,attachsize);//ICMP包数据部分 填充attachsize字节0
 datasize=sizeof(IcmpHeader)+attachsize;//ICMP数据包总大小(头+体)
 icmp_data=(char*)malloc(datasize);//根据上面计算的结果为ICMP包数据分配内存
 recvbuf=(char*)malloc(200);//
 memset(icmp_data,0,datasize);
 //ICMP数据包封装
 ((IcmpHeader *)icmp_data)->i_type=8;
 ((IcmpHeader *)icmp_data)->i_code=0;
 ((IcmpHeader *)icmp_data)->i_id=(USHORT)GetCurrentProcessId();
 ((IcmpHeader *)icmp_data)->timestamp=GetTickCount();
 ((IcmpHeader *)icmp_data)->i_seq=0;
 memcpy(icmp_data+sizeof(IcmpHeader),attachdata,attachsize);//ICMP包数据部分
填充32字节0
 ((IcmpHeader *)icmp_data)->i_cksum=0;
 //计算ICMP包校验和
 ((IcmpHeader *)icmp_data)->i_cksum=checksum((USHORT
*)icmp_data,datasize);
 timeout=1000;
 //设置发送延迟
 setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char
*)&timeout,sizeof(timeout));
 timeout=2000;
 //设置接受延迟
 setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char
*)&timeout,sizeof(timeout));
 printf(“Pinging %s with %d bytes of
data:nn”,ICMP_DEST_IP,attachsize);
 for(i=1;i<=n;i++)
 { start=GetTickCount();
  //发送第i个ICMP数据包
  ret=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr *)
&dest,sizeof(dest));
  if(SOCKET_ERROR==ret)
  {
   printf(“发送ICMP数据包%d出错!n”,i);
   continue;
  }
  //等待接收返回的ICMP数据包
  while(1)
  {
   if((GetTickCount()-start)>=1000)
   {
    printf(“Request timed out.n”);
    break;
   }
   memset(recvbuf,0,200);
   ret=recvfrom(sockRaw,recvbuf,200,0,(struct sockaddr *)
&from,&fromlen);
   if(SOCKET_ERROR==ret)
   {
    printf(“接收数据包%d出错!n”,i);
    break;
   }
   else
   {
    //显示返回ICMP包的信息
    unsigned short iphdrlen;//IP头长度
    IcmpHeader *icmphdr;
    DWORD timeuse;//数据包发送到接收用时
    int attachlen;//返回的ICMP数据包中数据段的大小
    timeuse=(GetTickCount()-start);
    if(0==packetrecv)
    {
     mintime=timeuse;
     maxtime=timeuse;
    }
    if(timeuse>maxtime) maxtime=timeuse;
    if(timeuse<mintime) mintime=timeuse;
    averagetime=averagetime+timeuse;
    iphdrlen=((IpHeader *)recvbuf)->h_len *4;
    icmphdr=(IpHeader *)(recvbuf+iphdrlen);
    attachlen=ret-iphdrlen-sizeof(IcmpHeader);
    printf(“Reply from %s: bytes=%d time=%d ms
TTL=%dn”,ICMP_DEST_IP,attachlen,timeuse,((IpHeader
*)recvbuf)->ttl);
    packetrecv++;
    break;
   }
  
  }
 }
 //显示统计信息
 lostpercent=100*((float)(n-packetrecv)/(float)n);//计算丢包率
 averagetime=(float)averagetime/(float)packetrecv;//计算平均用时
 printf(“nPing statistics for %s:n”,ICMP_DEST_IP);
 printf(”    Packets: Sent = %d, Received = %d, Lost = %d (%d %s
loss),n”,n,packetrecv,lostpercent,lostpercent,”%”);
 printf(“Approximate round trip times in milli-seconds:n”);
 printf(”    Minimum = %dms, Maximum = %dms, Average =
%dms”,maxtime,mintime,averagetime);
 free(recvbuf);
 free(icmp_data);
 closesocket(sockRaw);
 WSACleanup();
}
//计算ICMP数据包校验和
USHORT checksum(USHORT *buffer,int size)
{
 unsigned long cksum=0;
 while(size>1)
 {
  cksum+=*buffer++;
  size-=sizeof(USHORT);
 }
 if(size)
 {
  cksum+=*(UCHAR *)buffer;
 }
 cksum=(cksum>>16)+(cksum & 0xffff);
 cksum+=(cksum>>16);
 return (USHORT) (~cksum);
}
//使用说明
void usage()
{
 printf(“Ping程序模拟nn”);
 printf(“By RedIcen”);
 printf(“E-mail:redice@see.xidian.edu.cnn”);
 printf(“http://redice.1.suhai.com.cn\n\n”);
 printf(“Usage: checknet.exe [-n count] [-l size] target_name
nn”);
 printf(“Options:n”);
 printf(” -n count       发送ICMP数据包的个数,默认为4个.n”);
    printf(” -l size       
每个ICMP包附加的数据字节数,默认为32字节.nn”);
}

/* The IP header */
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum

澳门新葡萄京所有网站 2

unsigned int sourceIP;
unsigned int destIP;

}IpHeader;

//
// ICMP header
//
typedef struct _ihdr {
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
}IcmpHeader;

#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE 32
#define MAX_PACKET 1024

#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree (GetProcessHeap(),0,(p))

void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
void decode_resp(char *,int ,struct sockaddr_in *);

void Usage(char *progname){

fprintf(stderr,”Usage:n”);
fprintf(stderr,”%s [data_size]n”,progname);
fprintf(stderr,”datasize can be up to 1Kbn”);
ExitProcess(STATUS_FAILED);

}
int main(int argc, char **argv){

WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread,datasize;
int fromlen = sizeof(from);
int timeout = 1000;
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;

if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
fprintf(stderr,”WSAStartup failed: %dn”,GetLastError());
ExitProcess(STATUS_FAILED);
}

if (argc <2 ) {
Usage(argv[0]);
}
sockRaw = WSASocket (AF_INET,
SOCK_RAW,
IPPROTO_ICMP,
NULL, 0,0);

if (sockRaw == INVALID_SOCKET) {
fprintf(stderr,”WSASocket() failed: %dn”,WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,”failed to set recv timeout: %dn”,WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
timeout = 1000;
bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,”failed to set send timeout: %dn”,WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
memset(&dest,0,sizeof(dest));

hp = gethostbyname(argv[1]);

if (!hp){
addr = inet_addr(argv[1]);
}
if ((!hp) && (addr == INADDR_NONE) ) {
fprintf(stderr,”Unable to resolve %sn”,argv[1]);
ExitProcess(STATUS_FAILED);
}

if (hp != NULL)
memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
else
dest.sin_addr.s_addr = addr;

if (hp)
dest.sin_family = hp->h_addrtype;
else
dest.sin_family = AF_INET;

dest_ip = inet_ntoa(dest.sin_addr);

if (argc >2) {
datasize = atoi(argv[2]);
if (datasize == 0)
datasize = DEF_PACKET_SIZE;

}
else
datasize = D