我正在尝试使用原始套接字将数据包从发送器发送到接收器。当我在我的 Mac 或我的朋友戴尔(两者都安装了 Ubuntu 12.04)上同时部署发射器和接收器时,代码运行良好。我在两个不同的终端窗口中运行发射器和接收器,它工作正常。
但是当我在一台机器上运行发射器并在另一台机器上运行接收器时,接收器没有收到任何数据包。有人可以指出问题吗?我对套接字编程非常陌生,因此请原谅任何愚蠢的错误。
发射器:
/* 使用 sendto 发送数据包的函数 */
int SendPacket(int sockaddress,struct packet *mypacket, int packet_len)
{
int sent= 0;
if((sent = write(sockaddress, mypacket, packet_len)) != packet_len)
{ return 0; }
else
{ return 1; }
}
/* 为监视器接口创建原始套接字并将套接字绑定到接口的函数
*/
int create_raw_socket(char *dev)
{
struct sockaddr_ll sll;
struct ifreq ifr;
int fd, ifi, rb;
bzero(&sll, sizeof(sll));
bzero(&ifr, sizeof(ifr));
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
assert(fd != -1);
strncpy((char *)ifr.ifr_name, dev, IFNAMSIZ);
ifi = ioctl(fd, SIOCGIFINDEX, &ifr);
assert(ifi != -1);
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_family = PF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_pkttype = PACKET_OTHERHOST;
rb = bind(fd, (struct sockaddr *)&sll,sizeof(sll));
assert(rb != -1);
return fd;
}
/* 主功能 */
int main(int argc, char**argv)
{
int x,fd,s;
int sockaddress,len;
char dest_packet[PACKET_LENGTH];
int count= atoi(argv[2]);
char ch;
struct packet mypacket;
struct ieee80211_radiotap_header ratap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char addr1[ETH_ALEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char addr2[ETH_ALEN] = {0x13,0x22,0x33,0x44,0x55,0x66};
unsigned char addr3[ETH_ALEN] = {0x13,0x22,0x33,0x44,0x55,0x66};
/* Radio tap header data */
ratap_header.it_version = 0x00;
ratap_header.it_pad = 0x00;
ratap_header.it_len = 0x06;
ratap_header.it_pad2 = 0x00;
ratap_header.it_present = 0x8000;
mypacket.rtap_header = ratap_header;
/* ieee80211 header data */
iee802_header.frame_ctl = 0x0801;
iee802_header.duration_id = 0x0000;
strcpy(iee802_header.addr1,addr1);
strcpy(iee802_header.addr2,addr2);
strcpy(iee802_header.addr3,addr3);
iee802_header.seq_ctl = 0x1086;
mypacket.iee802_header=iee802_header;
/* Payload */
unsigned char payload[PACKET_LENGTH]="test";
unsigned char stop_injection[5]="stop";
strcpy(mypacket.payload , payload);
len = sizeof(mypacket) ;
/* Sending the packet over the interface */
printf("\n Press Y to start packet injection \n");
while((ch = getchar()) != 'Y');
while((count--) > 0)
{
sockaddress = create_raw_socket(argv[1]);
if(!SendPacket(sockaddress, &mypacket, len))
perror("Error sending packet");
else
{
printf("Packet sent successfully with payload : %s\n" , mypacket.payload);
printf("\n size of the packet being send is %d \n " , len);
}
}
/* Packet to indicate the end of reception */
strcpy(mypacket.payload , stop_injection);
len = sizeof(mypacket) ;
int temp=SendPacket(sockaddress , &mypacket , len);
close(sockaddress);
printf("\n End of packet transmission ........................ \n");
return 0;
}
接收者 :
int main(int argc, char **argv)
{
struct sockaddr addr;
int sock_fd, fromlen,s;
char buf[PACKET_LENGTH];
char *dev = argv[1];
struct packet mypacket;
struct packet *ptr;
int recv_count=0;
sock_fd = create_raw_socket(dev); /* Creating the raw socket */
printf("\n Waiting to receive packets ........ \n");
while(1)
{
fromlen=sizeof(addr);
int x= recvfrom(sock_fd,&mypacket,sizeof(struct packet),0,&addr,&fromlen);
struct sockaddr_ll* temp;
temp = (struct sockaddr_ll*)(&addr);
if(temp->sll_pkttype == 4)
{
recv_count++;
if(strcmp(mypacket.payload , "stop") == 0)
break;
/* Payload received */
printf("\nPayload Received from client : %s \n ", mypacket.payload);
}
}
close(sock_fd);
return 0;
数据结构 :
struct ieee80211_radiotap_header {
unsigned char it_version;
unsigned char it_pad;
uint16_t it_len;
uint16_t it_pad2;
uint32_t it_present;
};
/* Structure for 80211 header */
struct ieee80211_hdr_3addr {
uint16_t frame_ctl;
uint16_t duration_id;
unsigned char addr1[ETH_ALEN];
unsigned char addr2[ETH_ALEN];
unsigned char addr3[ETH_ALEN];
uint16_t seq_ctl;
} __attribute__ ((packed));
/* Structure of the packet containing the radiotap header, ieee802.11 header and payload
*/
struct packet {
struct ieee80211_radiotap_header rtap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char payload[30];
};