1 #include "EthernetInterface.h"
6 #include "exceptions.h"
11 void print_eth_packet(
const unsigned char* packet,
int len){
12 printf(
"LEN:%d ", len);
13 for(
int i = 0; i < len; i++){
14 printf(
"%02X:",packet[i]);
19 bool packet_equals(
const unsigned char* pkt1,
20 const unsigned char* pkt2,
int size){
21 for(
int i = 0; i < size; i++){
22 if(pkt1[i] != pkt2[i])
return false;
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
33 #include <netpacket/packet.h>
40 void Get_MAC(
const char* if_name,
unsigned char* buffer){
42 if(getifaddrs(&ifap) == 0){
43 ifaddrs * iter = ifap;
45 sockaddr_ll * sal =
reinterpret_cast<sockaddr_ll*
>(iter->ifa_addr);
46 if(sal->sll_family == AF_PACKET){
47 if(!strcmp(if_name, iter->ifa_name)){
48 for(
int i = 0 ; i < sal->sll_halen; i++){
49 buffer[i] = sal->sll_addr[i];
54 iter = iter->ifa_next;
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <sys/ioctl.h>
65 #include <sys/sysctl.h>
67 #include <net/if_dl.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
74 void Get_MAC(
const char* if_name,
unsigned char* buffer){
79 struct if_msghdr *ifm;
80 struct sockaddr_dl *sdl;
86 mib[4] = NET_RT_IFLIST;
87 if ((mib[5] = if_nametoindex(if_name)) == 0) {
88 perror(
"if_nametoindex error");
92 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
93 perror(
"sysctl 1 error");
97 if ((buf = (
char*)malloc(len)) == NULL) {
98 perror(
"malloc error");
102 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
103 perror(
"sysctl 2 error");
107 ifm = (
struct if_msghdr *)buf;
108 sdl = (
struct sockaddr_dl *)(ifm + 1);
109 ptr = (
unsigned char *)LLADDR(sdl);
111 for(
int i = 0; i < 6; i++){
117 #ifdef _WIN32 //Not finished
118 #include <winsock2.h>
119 #include <iphlpapi.h>
121 void Get_MAC(
const char* if_name,
unsigned char* buffer){
123 std::vector<unsigned char> buf;
125 GetAdaptersAddresses(0, 0, 0, 0, &bufLen);
128 buf.resize(bufLen, 0);
129 IP_ADAPTER_ADDRESSES * ptr =
130 reinterpret_cast<IP_ADAPTER_ADDRESSES*
>(&buf[0]);
131 DWORD err = GetAdaptersAddresses(0, 0, 0, ptr, &bufLen);
136 if(ptr->PhysicalAddressLength)
153 CEthernet::CEthernet(){
154 unsigned int ipid = getpid();
155 host_pid[0] = (
unsigned char) (ipid>>8);
156 host_pid[1] = (
unsigned char) ipid;
157 interface += ETHERNET_INTERFACE;
159 LOG(logINTERFACE) <<
"Start initializing ethernet interface.";
163 CEthernet::~CEthernet(){
170 void CEthernet::Write(
const void *buffer,
unsigned int size){
171 for(
unsigned int i = 0 ; i < size; i++){
172 if(tx_payload_size == MAX_TX_DATA){
175 tx_frame[ETH_HEADER_SIZE + tx_payload_size] = ((
char*)buffer)[i];
179 void CEthernet::Flush(){
180 for(
int i =0; i < 6; i++){
181 tx_frame[i] = dtb_mac[i];
182 tx_frame[i+6] = host_mac[i];
186 tx_frame[14] = host_pid[0];
187 tx_frame[15] = host_pid[1];
190 tx_frame[17] = tx_payload_size >> 8;
191 tx_frame[18] = tx_payload_size;
193 IFLOG(logINTERFACE) {
194 std::stringstream st;
195 st << std::uppercase << std::hex;
196 for(
size_t i = 0; i < tx_payload_size + ETH_HEADER_SIZE; i++) {
197 st << std::setw(2) << std::setfill(
'0') << tx_frame[i];
199 st << std::nouppercase << std::dec;
200 LOG(logINTERFACE) <<
"Sent packet: " << st.str();
203 pcap_sendpacket(descr, tx_frame, tx_payload_size + ETH_HEADER_SIZE);
206 void CEthernet::Clear(){
210 void CEthernet::Read(
void *buffer,
unsigned int size){
212 for(
unsigned int i = 0; i < size; i++){
213 if(!rx_buffer.empty()){
214 ((
unsigned char*)buffer)[i] = rx_buffer.front();
215 rx_buffer.pop_front();
217 const unsigned char* rx_frame = pcap_next(descr, &header);
218 if(rx_frame == NULL){
222 printf(
"Error reading from ethernet.\n");
223 throw CRpcError(CRpcError::TIMEOUT);
227 IFLOG(logINTERFACE) {
228 std::stringstream st;
229 st << std::uppercase << std::hex;
230 for(
size_t i = 0; i < header.len; i++){
231 st << std::setw(2) << std::setfill(
'0') << rx_frame[i];
233 st << std::nouppercase << std::dec;
234 LOG(logINTERFACE) <<
"Received packet: " << st.str();
237 if(header.len < ETH_HEADER_SIZE){
242 if(!packet_equals(rx_frame,host_mac,6) ||
243 !packet_equals(rx_frame+14,host_pid,2) ||
248 LOG(logINTERFACE) <<
"Passed Filter.";
250 unsigned int rx_payload_size = rx_frame[17];
251 rx_payload_size = (rx_payload_size << 8) | rx_frame[18];
253 for(
unsigned int j =0; j < rx_payload_size;j++){
254 rx_buffer.push_back(rx_frame[j + ETH_HEADER_SIZE]);
261 void CEthernet::InitInterface(){
263 for(
int i =0; i < TX_FRAME_SIZE; i++){
268 char errbuf[PCAP_ERRBUF_SIZE];
269 descr = pcap_open_live(interface.c_str(), BUFSIZ,0,100,errbuf);
271 LOG(logINTERFACE) <<
"pcap_open_live() failed:";
272 LOG(logINTERFACE) <<
interface << " | " << errbuf;
273 throw CRpcError(CRpcError::IF_INIT_ERROR);
276 Get_MAC(interface.c_str(), host_mac);
277 for(
int i = 0; i < 6; i++) tx_frame[i+6] = host_mac[i];
280 bool CEthernet::EnumFirst(
unsigned int &nDevices){
282 nDevices = MAC_addresses.size();
285 bool CEthernet::EnumNext(
char name[]){
286 string MAC = MAC_addresses[MAC_counter];
287 MAC_counter = (MAC_counter + 1) % MAC_addresses.size();
289 for(
size_t i = 0; i < MAC.size(); i++){
294 bool CEthernet::Enum(
char name[],
unsigned int pos){
295 string MAC = MAC_addresses[pos];
297 for(
int i = 0; i < 10; i++){
303 bool CEthernet::Open(
char MAC_address[]){
305 bool success = Claim(((
unsigned char*)MAC_address)+7,
true);
306 if(!success)
return false;
307 for(
int i =0; i < 6; i++){
308 dtb_mac[i] = MAC_address[7+i];
314 void CEthernet::Close(){
316 bool success = Unclaim();
317 if(!success)
throw CRpcError(CRpcError::ETH_ERROR);
318 for(
int i =0; i < 6; i++){
320 tx_frame[i] = dtb_mac[i];
325 void CEthernet::Hello(){
326 unsigned char packet[17];
328 for(
int i = 0; i < 6; i++){
330 packet[i+6] = host_mac[i];
334 packet[14] = host_pid[0];
335 packet[15] = host_pid[1];
338 pcap_sendpacket(descr, packet,
sizeof(packet));
341 MAC_addresses.clear();
344 time_t startTime = time(NULL);
345 const unsigned char* rx_frame;
346 while(time(NULL) - startTime < 2){
347 rx_frame = pcap_next(descr, &header);
348 if(rx_frame == NULL)
continue;
349 if(header.len < 17)
continue;
351 if(rx_frame[12] != 0x08 || rx_frame[13] != 0x09)
continue;
353 if(!packet_equals(rx_frame + 14, host_pid, 2))
continue;
356 if(packet[16] != 0x1)
continue;
359 string mac(
"DTB_ETH ");
360 for(
int i = 0; i < 6; i++) mac[7+i] = rx_frame[6+i];
361 MAC_addresses.push_back(mac);
365 bool CEthernet::Claim(
const unsigned char* MAC,
bool force){
366 unsigned char packet[17];
368 for(
int i = 0; i < 6; i++){
370 packet[i+6] = host_mac[i];
374 packet[14] = host_pid[0];
375 packet[15] = host_pid[1];
376 packet[16] = (force) ? 0x4 : 0x2;
378 pcap_sendpacket(descr, packet,
sizeof(packet));
381 MAC_addresses.clear();
384 time_t startTime = time(NULL);
385 const unsigned char* rx_frame;
386 while(time(NULL) - startTime < 2){
387 rx_frame = pcap_next(descr, &header);
388 if(rx_frame == NULL)
continue;
389 if(header.len < 17)
continue;
391 if(rx_frame[12] != 0x08 || rx_frame[13] != 0x09)
continue;
392 if(!packet_equals(rx_frame + 14, host_pid, 2))
continue;
393 if(!packet_equals(rx_frame, host_mac, 6))
continue;
394 return rx_frame[16] == 0x1;
400 bool CEthernet::Unclaim(){
401 unsigned char packet[17];
403 for(
int i = 0; i < 6; i++){
404 packet[i] = dtb_mac[i];
405 packet[i+6] = host_mac[i];
409 packet[14] = host_pid[0];
410 packet[15] = host_pid[1];
413 pcap_sendpacket(descr, packet,
sizeof(packet));
415 MAC_addresses.clear();
418 time_t startTime = time(NULL);
419 const unsigned char* rx_frame;
420 while(time(NULL) - startTime < 2){
421 rx_frame = pcap_next(descr, &header);
422 if(rx_frame == NULL)
continue;
423 if(header.len < 17)
continue;
425 if(rx_frame[12] != 0x08 || rx_frame[13] != 0x09)
continue;
426 if(!packet_equals(rx_frame + 14, host_pid, 2))
continue;
427 if(!packet_equals(rx_frame, host_mac, 6))
continue;
429 return rx_frame[16] == 0x1;