-
Notifications
You must be signed in to change notification settings - Fork 0
/
C_Net_Raw.cpp
120 lines (94 loc) · 3.88 KB
/
C_Net_Raw.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//////////////////////////////////////////////////////////////////////////////////
// [ Raw_Socket_Class_Source ]
//////////////////////////////////////////////////////////////////////////////////
#include "C_Net_Raw.hpp"
//////////////////////////////////////////////////////////////////////////////////
// [open]
//////////////////////////////////////////////////////////////////////////////////
int C_Net_Raw::open(const S_Net_Interface* pSInterface){
if(bOpen || !pSInterface) return(C_NET_RAW_ERROR);
memset(&socket_address, 0, sizeof(struct sockaddr_ll));
socket_address.sll_ifindex = pSInterface->dw_index;
socket_address.sll_halen = 6;
if((sockfd = socket(AF_PACKET, SOCK_RAW, 0x0300)) == -1){
cout << "ERROR: socket " << strerror(errno) << " Nr:" << errno << endl;
return(C_NET_RAW_ERROR);
}
bOpen = true;
////////////////////////////
struct ifreq ifopts; /* set promiscuous mode */
/* Set interface to promiscuous mode - do we need to do this every time? */
strncpy(ifopts.ifr_name, pSInterface->ps_Name, IFNAMSIZ - 1);
ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
/////////////////////////////
//struct timeval tv;
//tv.tv_sec = 30; /* 30 Secs Timeout */
//setsockopt(sockid, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));
return(C_NET_RAW_READY);
}
//////////////////////////////////////////////////////////////////////////////////
// [shutdown]
//////////////////////////////////////////////////////////////////////////////////
int C_Net_Raw::close(){
if(bOpen){
if(bRun) bRun = false;
::close(sockfd);
bOpen = false;
}
return(C_NET_RAW_READY);
}
//////////////////////////////////////////////////////////////////////////////////
// [send]
//////////////////////////////////////////////////////////////////////////////////
int C_Net_Raw::send(uint8_t* pData, uint32_t cData){
if(bOpen){
if(pData != 0 && cData > 0){
if(sendto(sockfd, pData, cData, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0){
cout << "ERROR: send " << strerror(errno) << " Nr:" << errno << endl;
return(C_NET_RAW_ERROR);
}
}
}else return(C_NET_RAW_ERROR);
return(C_NET_RAW_READY);
}
//////////////////////////////////////////////////////////////////////////////////
// [start]
//////////////////////////////////////////////////////////////////////////////////
int C_Net_Raw::start(int idEx, uint8_t* pBuf, uint32_t cBuf){
if(bRun || !bOpen || !pBuf || !cBuf) return(C_NET_RAW_ERROR);
////////////
pBuffer = pBuf;
cBuffer = cBuf;
id = idEx;
////////////
m_thread = thread([this]{this->run();});
m_thread.detach();
bRun = true;
return(C_NET_RAW_READY);
}
//////////////////////////////////////////////////////////////////////////////////
// [stop]
//////////////////////////////////////////////////////////////////////////////////
int C_Net_Raw::stop(){
if(!bRun || !bOpen) return(C_NET_RAW_ERROR);
bRun = false;
return(C_NET_RAW_READY);
}
//////////////////////////////////////////////////////////////////////////////////
// [run] (thread)
//////////////////////////////////////////////////////////////////////////////////
void C_Net_Raw::run(){
int cData = 0;
while(bRun){
cData = recvfrom(sockfd, pBuffer, cBuffer, 0, 0, 0);
if(cData > 0) m_signal_data.emit(id, cData);
}
}
//////////////////////////////////////////////////////////////////////////////////
// [signal_data]
//////////////////////////////////////////////////////////////////////////////////
C_Net_Raw::type_signal_data C_Net_Raw::signal_data(){
return(m_signal_data);
}