PacketSocketHandle.cc
Go to the documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "PacketSocketHandle.hh"
00028
00029
00030
00031 #include <sys/types.h>
00032 #include <sys/socket.h>
00033 #include <netpacket/packet.h>
00034 #include <net/ethernet.h>
00035 #include <netinet/in.h>
00036 #include <net/if.h>
00037 #include <errno.h>
00038
00039
00040 #define prefix_
00041
00042
00043 prefix_ void senf::PacketSocketProtocol::init_client(SocketType type, int protocol)
00044 const
00045 {
00046 int socktype = SOCK_RAW;
00047 if (type == DatagramSocket)
00048 socktype = SOCK_DGRAM;
00049 if (protocol == -1)
00050 protocol = ETH_P_ALL;
00051 int sock = ::socket(PF_PACKET, socktype, htons(protocol));
00052 if (sock < 0)
00053 SENF_THROW_SYSTEM_EXCEPTION("::socket(...) failed.");
00054 fd(sock);
00055 }
00056
00057 prefix_ unsigned senf::PacketSocketProtocol::available()
00058 const
00059 {
00060 if (! fh().readable())
00061 return 0;
00062 ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
00063 if (l < 0)
00064 SENF_THROW_SYSTEM_EXCEPTION("::recv(socket_fd) failed.");
00065 return l;
00066 }
00067
00068 prefix_ bool senf::PacketSocketProtocol::eof()
00069 const
00070 {
00071 return false;
00072 }
00073
00074 namespace {
00075
00076 void do_mc(int fd, std::string const & interface, senf::MACAddress address, bool add)
00077 {
00078 struct packet_mreq mreq;
00079 ::memset(&mreq, 0, sizeof(mreq));
00080 mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
00081 if (mreq.mr_ifindex == 0)
00082 throw senf::SystemException(EINVAL);
00083 mreq.mr_type = PACKET_MR_MULTICAST;
00084 mreq.mr_alen = 6;
00085 std::copy(address.begin(), address.end(), &mreq.mr_address[0]);
00086 if (::setsockopt(fd, SOL_PACKET,
00087 add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
00088 &mreq, sizeof(mreq)) < 0)
00089 throw senf::SystemException();
00090 }
00091 }
00092
00093 prefix_ void senf::PacketSocketProtocol::mcAdd(std::string const & interface,
00094 MACAddress const & address)
00095 const
00096 {
00097 do_mc(fd(), interface, address, true);
00098 }
00099
00100 prefix_ void senf::PacketSocketProtocol::mcDrop(std::string const & interface,
00101 MACAddress const & address)
00102 const
00103 {
00104 do_mc(fd(), interface, address, false);
00105 }
00106
00107 prefix_ void senf::PacketSocketProtocol::promisc(std::string const & interface, bool mode)
00108 const
00109 {
00110 struct packet_mreq mreq;
00111 ::memset(&mreq, 0, sizeof(mreq));
00112 mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
00113 if (mreq.mr_ifindex == 0)
00114 throw senf::SystemException(EINVAL);
00115 mreq.mr_type = PACKET_MR_PROMISC;
00116 if (::setsockopt(fd(), SOL_PACKET,
00117 mode ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
00118 &mreq, sizeof(mreq)) < 0)
00119 throw senf::SystemException();
00120 }
00121
00122
00123 #undef prefix_
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135