成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux網絡編程:原始套接字編程及實例分析

網絡 通信技術
原始套接字編程和之前的UDP 編程差不多,無非就是創建一個套接字后,通過這個套接字接收數據或者發送數據。區別在于,原始套接字可以自行組裝數據包(偽裝本地 IP,本地 MAC),可以接收本機網卡上所有的數據幀(數據包)。另外,必須在管理員權限下才能使用原始套接字。

一、原始套接字能干什么?

通常情況下程序員接所接觸到的套接字(Socket)為兩類:

(1)流式套接字(SOCK_STREAM):一種面向連接的Socket,針對于面向連接的TCP 服務應用;

(2)數據報式套接字(SOCK_DGRAM):一種無連接的Socket,對應于無連接的UDP 服務應用。

從用戶的角度來看,SOCK_STREAM、SOCK_DGRAM 這兩類套接字似乎的確涵蓋了TCP/IP 應用的全部,因為基于TCP/IP 的應用,從協議棧的層次上講,在傳輸層的確只可能建立于TCP 或 UDP協議之上,而SOCK_STREAM、SOCK_DGRAM 又分別對應于TCP和UDP,所以幾乎所有的應用都可以用這兩類套接字實現。 

[[130856]] 

但是,當我們面對如下問題時,SOCK_STREAM、SOCK_DGRAM 將顯得這樣無助:

(1)怎樣發送一個自定義的IP 包?

(2)怎樣發送一個ICMP 協議包?

(3)怎樣分析所有經過網絡的包,而不管這樣包是否是發給自己的?

(4)怎樣偽裝本地的IP 地址?

這使得我們必須面對另外一個深刻的主題——原始套接字(SOCK_RAW)。原始套接字廣泛應用于高級網絡編程,也是一種廣泛的黑客手段。著名的網絡sniffer(一種基于被動偵聽原理的網絡分析方式)、拒絕服務攻擊(DOS)、IP 欺騙等都可以通過原始套接字實現。

原始套接字(SOCK_RAW)可以用來自行組裝數據包,可以接收本機網卡上所有的數據幀(數據包),對于監聽網絡流量和分析網絡數據很有作用。

原始套接字是基于IP 數據包的編程(SOCK_PACKET 是基于數據鏈路層的編程)。另外,必須在管理員權限下才能使用原始套接字。

原始套接字(SOCK_RAW)與標準套接字(SOCK_STREAM、SOCK_DGRAM)的區別在于原始套接字直接置“根”于操作系統網絡核心(Network Core),而 SOCK_STREAM、SOCK_DGRAM 則“懸浮”于 TCP 和 UDP 協議的外圍。 

[[130857]] 

流式套接字只能收發 TCP 協議的數據,數據報套接字只能收發 UDP 協議的數據,原始套接字可以收發內核沒有處理的數據包。

#p#

二、原始套接字編程

原始套接字編程和之前的UDP 編程差不多,無非就是創建一個套接字后,通過這個套接字接收數據或者發送數據。區別在于,原始套接字可以自行組裝數據包(偽裝本地 IP,本地 MAC),可以接收本機網卡上所有的數據幀(數據包)。另外,必須在管理員權限下才能使用原始套接字。

原始套接字的創建:

int socket ( int family, int type, int protocol );

參數:

family:協議族 這里寫 PF_PACKET

type: 套接字類,這里寫 SOCK_RAW

protocol:協議類別,指定可以接收或發送的數據包類型,不能寫 “0”,取值如下,注意,傳參時需要用 htons() 進行字節序轉換。

ETH_P_IP:IPV4數據包

ETH_P_ARP:ARP數據包

ETH_P_ALL:任何協議類型的數據包

返回值:

成功( >0 ):套接字,這里為鏈路層的套接字

失敗( <0 ):出錯

實例如下:

  1. // 所需頭文件    
  2. #include <sys/socket.h>    
  3. #include <netinet/ether.h>    
  4. #include <stdio.h>  // perror    
  5.     
  6. int main(int argc,charchar *argv[])    
  7. {    
  8.     int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );    
  9.     
  10.     if(sock_raw_fd < 0){    
  11.         perror("socket");    
  12.         return -1;    
  13.     }    
  14.         
  15.     return 0;    
  16. }   

獲取鏈路層的數據包:

ssize_t recvfrom( int sockfd,

void *buf,

size_t nbytes,

int flags,

struct sockaddr *from,

socklen_t *addrlen );

參數:

sockfd: 原始套接字

buf: 接收數據緩沖區

nbytes: 接收數據緩沖區的大小

flags: 套接字標志(常為0)

from: 這里沒有用,寫 NULL

addrlen:這里沒有用,寫 NULL

返回值:

成功:接收到的字符數

失?。?1

實例如下:

  1. #include <stdio.h>    
  2. #include <netinet/in.h>    
  3. #include <sys/socket.h>    
  4. #include <netinet/ether.h>    
  5.     
  6. int main(int argc,charchar *argv[])    
  7. {    
  8.     unsigned char buf[1024] = {0};    
  9.     int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));    
  10.     
  11.     //獲取鏈路層的數據包    
  12.     int len = recvfrom(sock_raw_fd, buf, sizeof(buf), 0, NULL, NULL);    
  13.     printf("len = %d\n", len);    
  14.     
  15.     return 0;    
  16. }   

混雜模式

默認的情況下,我們接收數據,目的地址是本地地址,才會接收。有時候我們想接收所有經過網卡的所有數據流,而不論其目的地址是否是它,這時候我們需要設置網卡為混雜模式。

網卡的混雜模式一般在網絡管理員分析網絡數據作為網絡故障診斷手段時用到,同時這個模式也被網絡黑客利用來作為網絡數據竊聽的入口。在 Linux 操作系統中設置網卡混雜模式時需要管理員權限。在 Windows 操作系統和 Linux 操作系統中都有使用混雜模式的抓包工具,比如著名的開源軟件 Wireshark。

通過命令給 Linux 網卡設置混雜模式(需要管理員權限)

設置混雜模式:ifconfig eth0 promisc 

[[130858]] 

取消混雜模式:ifconfig eth0 -promisc 

[[130859]] 

通過代碼給 Linux 網卡設置混雜模式 

[[130860]] 

代碼如下:

  1. struct ifreq ethreq;    //網絡接口地址    
  2.         
  3. strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);         //指定網卡名稱    
  4. if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, &ethreq)) //獲取網絡接口    
  5. {    
  6.     perror("ioctl");    
  7.     close(sock_raw_fd);    
  8.     exit(-1);    
  9. }    
  10.     
  11. ethreq.ifr_flags |= IFF_PROMISC;    
  12. if(-1 == ioctl(sock_raw_fd, SIOCSIFINDEX, &ethreq)) //網卡設置混雜模式    
  13. {    
  14.     perror("ioctl");    
  15.     close(sock_raw_fd);    
  16.     exit(-1);    
  17. }   

發送自定義的數據包:

ssize_t sendto( int sockfd,

const void *buf,

size_t nbytes,int flags,

const struct sockaddr *to,

socklen_t addrlen );

參數:

sockfd: 原始套接字

buf: 發送數據緩沖區

nbytes: 發送數據緩沖區的大小

flags: 一般為 0

to: 本機網絡接口,指發送的數據應該從本機的哪個網卡出去,而不是以前的目的地址

addrlen:to 所指向內容的長度

返回值:

成功:發送數據的字符數

失?。?-1

本機網絡接口的定義 

[[130861]] 

發送完整代碼如下:

  1. struct sockaddr_ll sll;                 //原始套接字地址結構    
  2. struct ifreq ethreq;                    //網絡接口地址    
  3.     
  4. strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);         //指定網卡名稱    
  5. if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq))    //獲取網絡接口    
  6. {    
  7.     perror("ioctl");    
  8.     close(sock_raw_fd);    
  9.     exit(-1);    
  10. }    
  11.     
  12. /*將網絡接口賦值給原始套接字地址結構*/    
  13. bzero(&sll, sizeof(sll));    
  14. sll.sll_ifindex = ethreq.ifr_ifindex;    
  15.     
  16. // 發送數據    
  17. // send_msg, msg_len 這里還沒有定義,模擬一下    
  18. int len = sendto(sock_raw_fd, send_msg, msg_len, 0 , (struct sockaddr *)&sll, sizeof(sll));    
  19. if(len == -1)    
  20. {    
  21.     perror("sendto");    
  22. }   

這里頭文件情況如下:

  1. #include <net/if.h>// struct ifreq    
  2. #include <sys/ioctl.h> // ioctl、SIOCGIFADDR    
  3. #include <sys/socket.h> // socket    
  4. #include <netinet/ether.h> // ETH_P_ALL    
  5. #include <netpacket/packet.h> // struct sockaddr_ll 

#p#

三、原始套接字實例:MAC頭部報文分析

由上得知,我們可以通過原始套接字以及 recvfrom( ) 可以獲取鏈路層的數據包,那我們接收的鏈路層數據包到底長什么樣的呢?

鏈路層封包格式 

[[130862]] 

MAC 頭部(有線局域網) 

[[130863]] 

注意:CRC、PAD 在組包時可以忽略

鏈路層數據包的其中一種情況:

  1. unsigned char msg[1024] = {    
  2.     //--------------組MAC--------14------    
  3.     0xb8, 0x88, 0xe3, 0xe1, 0x10, 0xe6, // dst_mac: b8:88:e3:e1:10:e6    
  4.     0xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19, // src_mac: c8:9c:dc:b7:0f:19    
  5.     0x08, 0x00,                         // 類型:0x0800 IP協議    
  6.     // …… ……    
  7.     // …… ……    
  8. };   

接收的鏈路層數據包,并對其進行簡單分析:

  1. #include <stdio.h>    
  2. #include <string.h>    
  3. #include <stdlib.h>    
  4. #include <sys/socket.h>    
  5. #include <netinet/in.h>    
  6. #include <arpa/inet.h>    
  7. #include <netinet/ether.h>    
  8.     
  9. int main(int argc,charchar *argv[])    
  10. {    
  11.     int i = 0;    
  12.     unsigned char buf[1024] = "";    
  13.     int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));    
  14.     while(1)    
  15.     {    
  16.         unsigned char src_mac[18] = "";    
  17.         unsigned char dst_mac[18] = "";    
  18.         //獲取鏈路層的數據幀    
  19.         recvfrom(sock_raw_fd, buf, sizeof(buf),0,NULL,NULL);    
  20.         //從buf里提取目的mac、源mac    
  21.         sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);    
  22.         sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);    
  23.         //判斷是否為IP數據包    
  24.         if(buf[12]==0x08 && buf[13]==0x00)    
  25.         {       
  26.             printf("______________IP數據報_______________\n");    
  27.             printf("MAC:%s >> %s\n",src_mac,dst_mac);    
  28.         }//判斷是否為ARP數據包    
  29.         else if(buf[12]==0x08 && buf[13]==0x06)    
  30.         {    
  31.             printf("______________ARP數據報_______________\n");    
  32.             printf("MAC:%s >> %s\n",src_mac,dst_mac);    
  33.         }//判斷是否為RARP數據包    
  34.         else if(buf[12]==0x80 && buf[13]==0x35)    
  35.         {    
  36.             printf("______________RARP數據報_______________\n");    
  37.             printf("MAC:%s>>%s\n",src_mac,dst_mac);    
  38.         }    
  39.     }    
  40.     return 0;    
  41. }   

記得以管理者權限運行程序:

 

[[130864]]
責任編輯:藍雨淚 來源: CSDN博客
相關推薦

2021-02-05 15:20:06

網絡安全套接字命令

2014-12-15 09:28:54

UDP

2015-05-28 10:47:38

Unix網絡編程TCP

2014-12-11 09:20:30

TCP

2012-01-06 13:58:47

JavaTCP

2009-03-10 13:59:41

C#套接字編程

2020-10-15 19:10:05

LinuxAPI函數

2015-10-16 09:33:26

TCPIP網絡協議

2021-03-14 18:22:23

套接字網絡通信

2014-12-17 09:22:10

網絡·安全技術周刊

2013-12-27 13:39:23

Java套接字

2009-06-30 16:51:56

2021-04-26 10:32:38

網絡安全PE編程工具

2021-04-30 18:50:44

網絡安全PE編程添加節區

2021-04-25 21:25:09

網絡安全網絡安全編程PE編程

2021-04-28 14:35:48

網絡安全PE編程代碼

2024-08-13 08:27:24

PythonTCP協議網絡編程

2009-12-18 09:54:10

Linux Shell

2009-07-06 18:24:56

Servlet實例

2021-01-18 10:35:18

網絡安全Windows代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色综合国产 | 精品日韩在线 | 狠狠爱免费视频 | 玖玖国产 | 精品日韩一区 | 免费人成激情视频在线观看冫 | 欧美黑人一区 | 最新国产精品 | 国产三级 | 国产精品欧美精品日韩精品 | 久久这里只有精品首页 | 免费观看av| 草樱av | 天天射天天干 | 羞羞视频在线观看 | 99精品视频一区二区三区 | 国产精品一区在线 | 精品亚洲一区二区三区四区五区 | 91毛片网 | 精品国产伦一区二区三区观看说明 | 亚洲小视频| 中文字幕在线观看国产 | 国产精品久久久久久久久久久免费看 | www.日本在线 | 欧美a视频 | 精品久久精品 | www国产亚洲精品久久网站 | 免费在线观看91 | 国产一区二区三区四区五区3d | 福利视频一区二区三区 | 亚洲精品成人网 | 中文字幕 国产 | 国产精品久久网 | 成人激情视频在线 | 日韩一区二区三区精品 | 亚洲欧美一区二区三区在线 | 少妇淫片aaaaa毛片叫床爽 | 三区在线| 日本黄色激情视频 | 九九成人 | 欧美一区二区在线 |