libcyberradio 22.01.24
TransmitSocket.cpp
1/***************************************************************************
2 * \file TransmitSocket.cpp
3 *
4 * \brief NDR651 transmitter socket class.
5 *
6 * \author NH
7 * \copyright Copyright (c) 2015-2021 CyberRadio Solutions, Inc.
8 *
9 */
10
11#include <sys/socket.h>
12#include <netinet/in.h>
13#include <linux/if_ether.h>
14#include <netinet/ip.h>
15#include <netinet/udp.h>
16#include <arpa/inet.h>
17#include <linux/filter.h>
18#include "LibCyberRadio/NDR651/TransmitSocket.h"
19#include <netpacket/packet.h>
20#include <net/ethernet.h>
21#include <net/if.h>
22#include <sys/types.h>
23#include <sys/ioctl.h>
24#include <stdio.h>
25#include <unistd.h>
26#include <ifaddrs.h>
27#include <iostream>
28
29
30namespace LibCyberRadio
31{
32 namespace NDR651
33 {
34
35 TransmitSocket::TransmitSocket(const std::string& ifname, unsigned int sport) :
36 _isBroadcast(true),
37 _txBytes(0),
38 _sendCount(0),
39 _byteCount(0),
40 _isRaw(geteuid()==0),
41 _ifname(ifname),
42 _sport(sport)
43 {
44 // TODO Auto-generated constructor stub
45 //_ifname = ifname;
46 //_usingRingBuffer = useRingBuffer;
47 _makeSocket();
48 }
49
51 // TODO Auto-generated destructor stub
52 }
53
54 bool TransmitSocket::_makeRawSocket() {
55 //~ std::cout << "\t..._makeRawSocket\n";
56 int optval; /* flag value for setsockopt */
57 int rv;
58 struct sockaddr_ll addr; /* link layer address */
59
60 //std::cout << "Creating socket...";
61 _sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));
62 //if (_sockfd< 0)
63 //std::cout << "ERROR?";
64 //else
65 //std::cout << "success!";
66 //std::cout << std::endl;
67
68 optval = 1;
69 setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR,
70 (const void *)&optval , sizeof(int));
71
72 /* bind the socket */
73 memset(&addr,0,sizeof(addr));
74 addr.sll_family=AF_PACKET;
75 addr.sll_protocol=htons(ETH_P_IP);
76 addr.sll_ifindex=if_nametoindex(_ifname.c_str());
77
78 //std::cout << "Binding socket...";
79 if (bind(_sockfd,(struct sockaddr*)&addr,sizeof(addr))) {
80 //std::cerr << "ERROR?";
81 } else {
82 //std::cout << "success!";
83 }
84 //std::cout << std::endl;
85 return _sockfd>0;
86 }
87
88 bool TransmitSocket::_makeUdpSocket() {
89 //~ std::cout << "\t..._makeUdpSocket\n";
90 int rv;
91 struct sockaddr_in serveraddr; /* server's addr */
92 struct ifreq ifr;
93 char str[INET_ADDRSTRLEN];
94
95 _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
96
97 // get interface's IP address
98 ifr.ifr_addr.sa_family = AF_INET;
99 strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
100 ioctl(_sockfd, SIOCGIFADDR, &ifr);
101
102 int optval = 1;
103 /*
104 * Set the "resuse address" flag
105 */
106 //~ rv = setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(int));
107
108 /*
109 * build the server's Internet address
110 */
111 memset((char *) &serveraddr, 0, sizeof(serveraddr));
112 serveraddr.sin_family = AF_INET;
113 serveraddr.sin_port = htons((unsigned short)_sport);
114 serveraddr.sin_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
115
116 /*
117 * bind: associate the parent socket with a port
118 */
119 //~ std::cout << "Binding socket...";
120 //~ if (bind(_sockfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
121 //~ std::cerr << "ERROR?";
122 //~ else
123 //~ std::cout << "success!";
124
125 /*
126 * Set destination address
127 */
128 if (_isBroadcast||true) {
129 rv = setsockopt(_sockfd, SOL_SOCKET, SO_BROADCAST, (const void *)&optval, sizeof(int) );
130 //std::cout << "setsockopt SO_BROADCAST: " << ((rv==0)?"Success":"Fail") << std::endl;
131
132 struct ifaddrs *ifap, *ifa;
133 struct sockaddr_in *sa;
134 char *addr;
135 std::string retString;
136 getifaddrs (&ifap);
137 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
138 if ( strcmp(ifa->ifa_name,_ifname.c_str())==0 ){
139 if (ifa->ifa_addr->sa_family==AF_INET) {
140 sa = (struct sockaddr_in *) ifa->ifa_ifu.ifu_broadaddr;
141 sa->sin_port = htons(_sport);
142 addr = inet_ntoa(sa->sin_addr);
143 rv = connect(_sockfd, (struct sockaddr *)sa, sizeof(sockaddr_in));
144 //~ std::cout << "Connect: " << ((rv==0)?"Success":"Fail") << std::endl;
145 break;
146 }
147 }
148 }
149 freeifaddrs(ifap);
150
151 } else {
152 std::cerr << "I NEED A DESTINATION ADDRESS" << std::endl;
153 }
154
155 //~ rv = setsockopt(_sockfd, SOL_SOCKET, SO_BINDTODEVICE, _ifname.c_str(), IF_NAMESIZE);
156 return _sockfd>0;
157 }
158
159 bool TransmitSocket::_makeSocket() {
160 //~ std::cout << "_makeSocket...\n";
161 if (_isRaw) {
162 return _makeRawSocket();
163 } else {
164 return _makeUdpSocket();
165 }
166 }
167
169 // Source MAC Address
170 char macstring[32];
171 struct ifreq ifr;
172 memset(&ifr, 0x00, sizeof(ifr));
173 strcpy(ifr.ifr_name, _ifname.c_str());
174 ioctl(_sockfd, SIOCGIFHWADDR, &ifr);
175 sprintf(macstring, "%02x:%02x:%02x:%02x:%02x:%02x",
176 (unsigned char)ifr.ifr_hwaddr.sa_data[0],
177 (unsigned char)ifr.ifr_hwaddr.sa_data[1],
178 (unsigned char)ifr.ifr_hwaddr.sa_data[2],
179 (unsigned char)ifr.ifr_hwaddr.sa_data[3],
180 (unsigned char)ifr.ifr_hwaddr.sa_data[4],
181 (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
182 return std::string(macstring);
183 }
184
186 struct ifreq ifr;
187 /* I want to get an IPv4 IP address */
188 ifr.ifr_addr.sa_family = AF_INET;
189 /* I want IP address attached to "eth0" */
190 strncpy(ifr.ifr_name, _ifname.c_str(), IFNAMSIZ-1);
191 ioctl(_sockfd, SIOCGIFADDR, &ifr);
192 /* display result */
193 return std::string(inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
194 }
195
197 struct ifaddrs *ifap, *ifa;
198 struct sockaddr_in *sa;
199 char *addr;
200 getifaddrs (&ifap);
201 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
202 if ( strcmp(ifa->ifa_name,_ifname.c_str())==0 ){
203 if (ifa->ifa_addr->sa_family==AF_INET) {
204 sa = (struct sockaddr_in *) ifa->ifa_ifu.ifu_broadaddr;
205 addr = inet_ntoa(sa->sin_addr);
206 break;
207 }
208 }
209 }
210 freeifaddrs(ifap);
211 return std::string(addr);
212 }
213
214 bool TransmitSocket::sendFrame(unsigned char * frame, const int & frameLen) {
215 _txMutex.lock();
216 _txBytes = send(_sockfd, frame, frameLen, 0);
217 _txMutex.unlock();
218 _sendCount ++;
219 _byteCount += _txBytes;
220 return (_txBytes>0);
221 }
222
223 } /* namespace NDR651 */
224}
virtual ~TransmitSocket()
Destroys a TransmitSocket object.
std::string getIpBroadcastAddress()
Gets the IP broadcast address.
std::string getIpAddress()
Gets the IP address.
TransmitSocket(const std::string &ifname, unsigned int sport)
Constructs a TransmitSocket object.
bool sendFrame(unsigned char *frame, const int &frameLen)
Sends a frame of data.
std::string getMacAddress()
Gets the MAC address.
Provides programming elements for controlling the CyberRadio Solutions NDR651 radio.
Defines functionality for LibCyberRadio applications.
Definition App.h:24