主函式:
/*ping.c*/
#include #include #include #include #include #include #include #include #include #include #include /*bzero*/
#include #include /*儲存已經傳送包的狀態值*/
typedef struct pingm_pakcetpingm_pakcet;
static pingm_pakcet pingpacket[128];
static pingm_pakcet *icmp_findpacket(int seq);
static unsigned short icmp_cksum(unsigned char *data, int len);
static struct timeval icmp_tvsub(struct timeval end,struct timeval begin);
static void icmp_statistics(void);
static void icmp_pack(struct icmp *icmph, int seq, struct timeval *tv, int length );
static int icmp_unpack(char *buf,int len);
static void *icmp_recv(void *argv);
static void *icmp_send(void *argv);
static void icmp_sigint(int signo);
static void icmp_usage();
#define k 1024
#define buffersize 72 /*傳送緩衝區大小*/
static char send_buff[buffersize];
static char recv_buff[2*k]; /*為防止接收溢位,接收緩衝區設定大一些*/
static struct sockaddr_in dest; /*目的位址*/
static int rawsock = 0; /*傳送和接收執行緒需要的socket描述符*/
static pid_t pid=0; /*程序pid*/
static int alive = 0; /*是否接收到退出訊號*/
static short packet_send = 0; /*已經傳送的資料報有多少*/
static short packet_recv = 0; /*已經接收的資料報有多少*/
static char dest_str[80]; /*目的主機字串*/
static struct timeval tv_begin, tv_end,tv_interval;
/*本程式開始傳送、結束和時間間隔*/
static void icmp_usage()
/*主程式*/
int main(int argc, char *argv)
/*獲取協議型別icmp*/
protocol = getprotobyname(protoname);
if (protocol == null)
/*複製目的位址字串*/
memcpy(dest_str, argv[1], strlen(argv[1])+1);
memset(pingpacket, 0, sizeof(pingm_pakcet) * 128);
/*socket初始化*/
rawsock = socket(af_inet, sock_raw, protocol->p_proto);
if(rawsock < 0)
/*為了與其他程序的ping程式區別,加入pid*/
pid = getuid();
/*增大接收緩衝區,防止接收的包被覆蓋*/
setsockopt(rawsock, sol_socket, so_rcvbuf, &size, sizeof(size));
bzero(&dest, sizeof(dest));
/*獲取目的位址的ip位址*/
dest.sin_family = af_inet;
/*輸入的目的位址為字串ip位址*/
inaddr = inet_addr(argv[1]);
if(inaddr == inaddr_none)
/*將位址複製到dest中*/
memcpy((char *)&dest.sin_addr, host->h_addr, host->h_length);
} else /*為ip位址字串*/
/*列印提示*/
inaddr = dest.sin_addr.s_addr;
printf("ping %s (%ld.%ld.%ld.%ld) 56(84) bytes of data.\n",
dest_str,
(inaddr&0x000000ff)>>0,
(inaddr&0x0000ff00)>>8,
(inaddr&0x00ff0000)>>16,
(inaddr&0xff000000)>>24);
/*擷取訊號sigint,將icmp_sigint掛接上*/
signal(sigint, icmp_sigint);
alive = 1; /*初始化為可執行*/
pthread_t send_id, recv_id; /*建立兩個執行緒,用於傳送和接收*/
int err = 0;
err = pthread_create(&send_id, null, icmp_send, null); /*傳送*/
if(err < 0)
err = pthread_create(&recv_id, null, icmp_recv, null); /*接收*/
if(err < 0)
/*等待執行緒結束*/
pthread_join(send_id, null);
pthread_join(recv_id, null);
/*清理並列印統計結果*/
close(rawsock);
icmp_statistics();
return 0;
}
原始套接字
資料出處 實際上,我們常用的網路程式設計都是在應用層的報文的收發操作,也就是大多數程式設計師接觸到的流式套接字 sock stream 和資料報式套接字 sock dgram 而這些資料報都是由系統提供的協議棧實現,使用者只需要填充應用層報文即可,由系統完成底層報文頭的填充並傳送。然而在某些情況下需...
原始套接字
參考1 原始套接字能幹什麼?參考2 原始套接字抓包實踐 參考3 各層頭結構 通過原始套接字,我們可以抓取所有傳送到本機的ip包 包括ip頭和tcp udp icmp包頭 也可以抓取所有本機收到的幀 包括資料鏈路層協議頭 普通的套接字無法處理icmp igmp等網路報文,而sock raw可以。利用原...
原始套接字
利用原始套接字實現乙個tcp syn flooding 程式 要求 客戶端不斷向攻擊端傳送syn連線請求 客戶端在傳送資料時,通過源位址隨機位址的方式隱藏自己的 位址 檢驗 在shell下通過 netstat tn 檢查syn recv連線數檢驗自己的程式是否成功 好像有點問題。不能偽造mac位址。...