Hi,

I'm trying to use raw sockets with libev, but have a problem getting
READ events firing. I have attached a example source code which
demonstrates my problem. I'm using 32bit Ubuntu 10.04 and the packaged
version of libev (3.8). Similar code with normal UDP sockets worked
fine.

/Torste Aikio
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/in.h>
#include <netpacket/packet.h>

#include <ev++.h>
#include <string>

#ifndef MAX_MESG_SIZE
#define MAX_MESG_SIZE 1500
#endif

class Socket {
public:
	Socket(const std::string &interface, int port);
	~Socket();
	void onSocketReadable(ev::io &w, int revents);

private:
	std::string ifaceName;
	int listenSocket;
	int listenPort;
	ev::io watcher;

	void initSocket(const std::string &interface, int port);
};

Socket::Socket(const std::string &interface, int port)
	: ifaceName(interface), listenPort(port)
{
	initSocket(interface, port);

	watcher.set<Socket, &Socket::onSocketReadable> (this);
	watcher.start(listenSocket, ev::READ);
}

Socket::~Socket()
{
	watcher.stop();
	close(listenSocket);
}

void Socket::initSocket(const std::string &interface, int port)
{
	listenSocket = socket(PF_PACKET, SOCK_RAW, IPPROTO_IP);
	if (listenSocket < 0)
	{
		throw std::runtime_error(std::string("socket: ") + strerror(errno));
	}

	if (fcntl(listenSocket, F_SETFL, O_NONBLOCK) < 0)
	{
		throw std::runtime_error(std::string("fcntl(O_NONBLOCK): ") + strerror(errno));
	}
}

void Socket::onSocketReadable(ev::io &w, int revents)
{
	fprintf(stderr, "Got incoming data\n");
	u_int8_t * mesg = (u_int8_t*)malloc(MAX_MESG_SIZE);
	struct sockaddr_ll clientAddr = {0};
	socklen_t clientAddrLength = sizeof(clientAddr);
	int size = recvfrom(listenSocket, mesg, MAX_MESG_SIZE, 0,
		(struct sockaddr *) &clientAddr, &clientAddrLength);
	if (size < 0)
	{
		perror("recvfrom");
	}
	free(mesg);
}



int main (int,char**)
{
	struct ev_loop *loop = EV_DEFAULT;
	Socket socket("eth1", 6767);

	ev_loop(loop, 0);

	return 0;
}
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to