Why does binding socket to interface fail? - c++

I'm trying to open a raw socket and bind my wireless interface to it. This is the code I am using:
//opening socket
if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1){
//if socket fails give error
perror("socket");
}
//binding socket to interface
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, "wlp0s19f2u3", 4) < 0)
perror("SIOCGIFHWBIND");
But when compiling and running with sudo I get a "SIOCGIFHWBIND: No such device".
I first thought this is because there I miss spelled the interface name but my iwconfig output is:
wlp0s19f2u3 IEEE 802.11 Mode:Monitor Frequency:2.462 GHz Tx-Power=20 dBm
and it isn't an issue with monitor mode because running the code while my wireless card is in managed mode gives the same output and I need the interface to be in monitor mode.
Please help and have a nice day!

Thanks Mark Setchell, turns out the 4 was from example code where they used something like "eth0" which has 4 chars. So replacing 4 with a strlen() of your interface works great. Thanks once again.

Related

Sniffing raw sockets (SOCK_RAW) without Administrator account in windows

I am creating a simple sniffer using c++ under visual studio , and windows 10 x64 , but when I tried to run it. I got Failed to create raw socket. which is because admin rights , but I was reaching on internet . I could use something like CAP_NET_ADMIN , but it is linux based . is there a way to do under windows such as wireshark non-root users works?
//Initialise Winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("WSAStartup() failed.\n");
return 1;
}
printf("Initialised");
//Create a RAW Socket
printf("\nCreating RAW Socket...");
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf("Failed to create raw socket.\n");
return 1;
}
printf("Created.");
Creating a Raw Socket:
Raw sockets offer the capability to manipulate the underlying
transport, so they can be used for malicious purposes that pose a
security threat. Therefore, only members of the Administrators group
can create sockets of type SOCK_RAW on Windows 2000 and later.
If anyone is getting this with Wine, you need to allow the wineserver to use Ping.SendPrivileged:
sudo setcap CAP_NET_RAW=ep /usr/bin/wine
sudo setcap CAP_NET_RAW=ep /usr/bin/wineserver
sudo setcap CAP_NET_RAW=ep YOUREXE.exe

Documentation for socket errors

I am creating a server-client application,this issue is that in the code below, I would get a failed to bind or failed to open socket message (see example code below).
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
qDebug() << "ERROR netserver: opening socket";
//more code here
}
or
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
qDebug() << "ERROR netserver: binding to socket";
//more code here
}
I am aware of C++ devs using the getLastError() but I do not find anything of the sort for sockets.
Does anyone know of a page/tutorial/wiki?
The failed to bind/open socket have typically a (non-developer) system error reason. These are not always that well reported :(
The reasons why that might happen, could be that the socket is already being listened on (ie. you are trying to run a second instance of the same program) or the previous socket haven't been closed properly by the OS after the previous program/instance exited. There are different ways to solve the last issue, but rather check it's not the first issue ;)
The other reason you might get these type of errors, is that the port being requested, is a privileged port, ie. anything less than 1024, which would require root (on Unix) type privilege.
On Unix, the friend there is "netstat -an" (Window I recall have a similar command)

How do I receive raw, layer 2 packets in C/C++?

How do I receive layer 2 packets in POSIXy C++? The packets only have src and dst MAC address, type/length, and custom formatted data. They're not TCP or UDP or IP or IGMP or ARP or whatever - they're a home-brewed format given unto me by the Hardware guys.
My socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW) never returns from its recvfrom().
I can send fine, I just can't receive no matter what options I fling at the network stack.
(Platform is VxWorks, but I can translate POSIX or Linux or whatever...)
receive code (current incarnation):
int s;
if ((s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) {
printf("socket create error.");
return -1;
}
struct ifreq _ifr;
strncpy(_ifr.ifr_name, "lltemac0", strlen("lltemac0"));
ioctl(s, IP_SIOCGIFINDEX, &_ifr);
struct sockaddr_ll _sockAttrib;
memset(&_sockAttrib, 0, sizeof(_sockAttrib));
_sockAttrib.sll_len = sizeof(_sockAttrib);
_sockAttrib.sll_family = AF_PACKET;
_sockAttrib.sll_protocol = IFT_ETHER;
_sockAttrib.sll_ifindex = _ifr.ifr_ifindex;
_sockAttrib.sll_hatype = 0xFFFF;
_sockAttrib.sll_pkttype = PACKET_HOST;
_sockAttrib.sll_halen = 6;
_sockAttrib.sll_addr[0] = 0x00;
_sockAttrib.sll_addr[1] = 0x02;
_sockAttrib.sll_addr[2] = 0x03;
_sockAttrib.sll_addr[3] = 0x12;
_sockAttrib.sll_addr[4] = 0x34;
_sockAttrib.sll_addr[5] = 0x56;
int _sockAttribLen = sizeof(_sockAttrib);
char packet[64];
memset(packet, 0, sizeof(packet));
if (recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)&_sockAttrib, &_sockAttribLen) < 0)
{
printf("packet receive error.");
}
// code never reaches here
I think the way to do this is to write your own Network Service that binds to the MUX layer in the VxWorks network stack. This is reasonably well documented in the VxWorks Network Programmer's Guide and something I have done a number of times.
A custom Network Service can be configured to see all layer 2 packets received on a network interface using the MUX_PROTO_SNARF service type, which is how Wind River's own WDB protocol works, or packets with a specific protocol type.
It is also possible to add a socket interface to your custom Network Service by writing a custom socket back-end that sits between the Network Service and the socket API. This is not required if you are happy to do the application processing in the Network Service.
You haven't said which version of VxWorks you are using but I think the above holds for VxWorks 5.5.x and 6.x
Have you tried setting the socket protocol to htons(ETH_P_ALL) as prescribed in packet(7)? What you're doing doesn't have much to do with IP (although IPPROTO_RAW may be some wildcard value, dunno)
I think this is going to be a bit tougher problem to solve than you expect. Given that it's not IP at all (or apparently any other protocol anything will recognize), I don't think you'll be able to solve your problem(s) entirely with user-level code. On Linux, I think you'd need to write your own device agnostic interface driver (probably using NAPI). Getting it to work under VxWorks will almost certainly be non-trivial (more like a complete rewrite from the ground-up than what most people would think of as a port).
Have you tried confirming via Wireshark that a packet has actually been sent from the other end?
Also, for debugging, ask your hardware guys if they have a debug pin (you can attach to a logic analyzer) that they can assert when it receives a packet. Just to make sure that the hardware is getting the packets fine.
First you need to specify the protocol as ETH_P_ALL so that your interface gets all the packet. Set your socket to be on promiscuous mode. Then bind your RAW socket to an interface before you perform a receive.

Socket Exception: "There are no more endpoints available from the endpoint mapper"

I am using winsock and C++ to set up a server application. The problem I'm having is that the call to listen results in a first chance exception. I guess normally these can be ignored (?) but I've found others having the same issue I am where it causes the application to hang every once in a while. Any help would be greatly appreciated.
The first chance exception is:
First-chance exception at 0x*12345678* in MyApp.exe: 0x000006D9: There are no more endpoints available from the endpoint mapper.
I've found some evidence that this could be cause by the socket And the code that I'm working with is as follows. The exception occurs on the call to listen in the fifth line from the bottom.
m_accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_accept_fd == INVALID_SOCKET)
{
return false;
}
int optval = 1;
if (setsockopt (m_accept_fd, SOL_SOCKET, SO_REUSEADDR,
(char*)&optval, sizeof(optval)))
{
closesocket(m_accept_fd);
m_accept_fd = INVALID_SOCKET;
return false;
}
struct sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = INADDR_ANY;
local_addr.sin_port = htons(m_port);
if (bind(m_accept_fd, (struct sockaddr *)&local_addr,
sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
closesocket(m_accept_fd);
return false;
}
if (listen (m_accept_fd, 5) == SOCKET_ERROR)
{
closesocket(m_accept_fd);
return false;
}
On a very busy server, you may be running out of Sockets. You may have to adjust some TCPIP parameters. Adjust these two in the registry:
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
MaxUserPort REG_DWORD 65534 (decimal)
TcpTimedWaitDelay REG_DWORD 60 (decimal)
By default, there's a few minutes delay between releasing a network port (socket) and when it can be reused. Also, depending on the OS version, there's only a few thousand in the range that windows will use. On the server, run this at a command prompt:
netstat -an
and look at the results (pipe to a file is easiest: netstat -an > netstat.txt). If you see a large number of ports from 1025->5000 in Timed Wait Delay status, then this is your problem and it's solved by adjusting up the max user port from 5000 to 65534 using the registry entry above. You can also adjust the delay by using the registry entry above to recycle the ports more quickly.
If this is not the problem, then the problem is likely the number of pending connections that you have set in your Listen() method.
The original problem has nothing to do with winsock. All the answers above are WRONG. Ignore the first-chance exception, it is not a problem with your application, just some internal error handling.
Are you actually seeing a problem, e.g., does the program end because of an unhandled exception?
The debugger may print the message even when there isn't a problem, for example, see here.
Uhh, maybe it's because you're limiting greatly the maximum number of incoming connections?
listen (m_accept_fd, 5)
// Limit here ^^^
If you allow a greater backlog, you should be able to handle your problem. Use something like SOMAXCONN instead of 5.
Also, if your problem is only on server startup, you might want to turn off LINGER (SO_LINGER) to prevent connections from hanging around and blocking the socket...
This won't answer your question directly, but since you're using C++, I would recommend using something like Boost::Asio to handle your socket code. This gives you a nice abstraction over the winsock API, and should allow you to more easily diagnose error conditions.

socket programming in client

I wrote this program in C++ and on Linux platform.
I wrote a client and server socket program.
In that client program, I wrote socket function and immediately after that I am doing some other actions not at all depending on socket (I wrote 2 for loops for some other logic).
After that I prepared the structures required for the socket and I wrote the connect function...in that I am getting error as unable to connect because connect is returning -1..
But for the same program, if I write that for loop's logic above the socket function and immediately after that structures, and connect function, then it is working fine..
What might be the reason I am not able to get? Please help me in this aspect. Here is my code
here index1 and index 2 are simple integer variables..The configstring is a char array contains 127.0.0.1:7005(address and port number)...address and port are char array variables to store address and port number..
struct sockaddr_in s1;
for(index1=0;configstring[index1]!=':';index1++)
{
address[index1] = configstring[index1];
}
address[index1++]='\0';
for(index2=0;configstring[index1]!='\0';index1++,index2++)
{
port[index2] = configstring[index1];
}
port[index2++]='\0';
int port_num = changeto_int(port);
if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf("unable to create a socket\n");
return 0;
}
s1.sin_family=AF_INET;
s1.sin_port=htons(port_num);
s1.sin_addr.s_addr=inet_addr(address);
memset(s1.sin_zero, '\0', sizeof s1.sin_zero);
int errno;
if(connect(sock_fd,(struct sockaddr *)&s1,sizeof(s1)) == -1)
{
printf("error:unable to connect\n");
printf("Error in connect(): %s\n", strerror( errno));
return -1;
}
First, never do something like this:
int errno;
errno is already defined for you.
More than that I suggest you to use perror() instead of
printf("Error in connect(): %s\n", strerror( errno));
Third, you can't call printf and than strerror( errno) because printf whould change
value of errno to success.
Third, I'd sugget to take a look on examples in internet and start from them.
I'd suggest to read man select_tut there are many good written code examples
of how to do and what.
Have you tried calling strerror on errno? connect() returning -1 would mean that errno has been set and should have more information about your error.
printf("Error in connect(): %s\n", strerror(errno));
Have you considered simply that your receiver is not listening properly for connections?
As others said, use perror to check errno and print some usable debug to the console.
Without your sample code there is no way to help you. There could be a million reasons. Perhaps there's a firewall on your machine blocking connections? Perhaps the server isn't listening, or is on an incorrect port (you did convert to network byte order didn't you?). Perhaps the client is connecting to a wrong address or port. Maybe you haven't set up your structures correctly.
I recommend reading Beej's Socket Programming Doo-Daa for a good introduction to sockets on Unix (and it follows on to Windows).
struct sockaddr_in s1;
could you please try memset of s1, at the beginning of your program.
I have experienced some thing similar to this.
Could you print debugging info about the address and port string ?
Remove the errno thing, include and use perror.
Compile with -Wall
Judging from your comment that perror() returns "socket operation on non socket"... How are your address and port variables declared? Is it possible that port[index2++]='\0' somehow overwrite onto sock_fd or such?
try adding :
inet_pton(AF_INET, your IP address, (void *)&server_address);
before making connection to the server.
Also,I have a hunch that the problem behind the scene could be around serverside.
Low level socket programming is tedious and error prone. You would be well advised to start using frameworks like Boost or ACE that shield you from these low level details and allow you to program platform independent.