4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief PacketSocketProtocol and PacketSocketHandle non-inline non-template implementation
32 #include "PacketSocketHandle.hh"
33 //#include "PacketSocketHandle.ih"
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <linux/if_packet.h>
39 #include <net/ethernet.h>
40 #include <netinet/in.h>
44 //#include "PacketSocketHandle.mpp"
46 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 prefix_ void senf::PacketSocketProtocol::init_client(SocketType type, int protocol)
51 int socktype = SOCK_RAW;
52 if (type == DatagramSocket)
53 socktype = SOCK_DGRAM;
56 int sock = ::socket(PF_PACKET, socktype, htons(protocol));
58 SENF_THROW_SYSTEM_EXCEPTION("::socket(...) failed.");
62 prefix_ unsigned senf::PacketSocketProtocol::available()
65 if (! fh().readable())
67 ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
69 SENF_THROW_SYSTEM_EXCEPTION("::recv(socket_fd) failed.");
73 prefix_ bool senf::PacketSocketProtocol::eof()
81 void do_mc(int fd, std::string const & interface, senf::MACAddress address, bool add)
83 struct packet_mreq mreq;
84 ::memset(&mreq, 0, sizeof(mreq));
85 mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
86 if (mreq.mr_ifindex == 0)
87 throw senf::SystemException(EINVAL);
88 mreq.mr_type = PACKET_MR_MULTICAST;
90 std::copy(address.begin(), address.end(), &mreq.mr_address[0]);
91 if (::setsockopt(fd, SOL_PACKET,
92 add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
93 &mreq, sizeof(mreq)) < 0)
94 throw senf::SystemException();
98 prefix_ void senf::PacketSocketProtocol::mcAdd(std::string const & interface,
99 MACAddress const & address)
102 do_mc(fd(), interface, address, true);
105 prefix_ void senf::PacketSocketProtocol::mcDrop(std::string const & interface,
106 MACAddress const & address)
109 do_mc(fd(), interface, address, false);
112 prefix_ void senf::PacketSocketProtocol::promisc(std::string const & interface, bool mode)
115 struct packet_mreq mreq;
116 ::memset(&mreq, 0, sizeof(mreq));
117 mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
118 if (mreq.mr_ifindex == 0)
119 throw senf::SystemException(EINVAL);
120 mreq.mr_type = PACKET_MR_PROMISC;
121 if (::setsockopt(fd(), SOL_PACKET,
122 mode ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
123 &mreq, sizeof(mreq)) < 0)
124 throw senf::SystemException();
127 //-/////////////////////////////////////////////////////////////////////////////////////////////////
129 //#include "PacketSocketHandle.mpp"
135 // c-file-style: "senf"
136 // indent-tabs-mode: nil
137 // ispell-local-dictionary: "american"
138 // compile-command: "scons -u test"
139 // comment-column: 40