#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
// Details of actualized connections.
struct Remote {
- struct SockAddr uaddr;
+ struct SockAddr uaddr; // The remote IP address
+ struct SockAddr iaddr; // The receiving IP address
struct Allowed *spec; // Rule being instantiated
struct timeval rec_when; // Last received packet time, in seconds
};
QueueItem base;
int fd;
struct SockAddr src;
+ struct SockAddr dst;
ssize_t len;
unsigned char buffer[ BUFSIZE ];
} PacketItem;
}
}
+static ssize_t recvpacket(int fd,PacketItem *p) {
+ int flags = udp6? IPV6_PKTINFO : IP_PKTINFO;
+ socklen_t addrlen =
+ udp6? sizeof( p->src.in6 ) : sizeof( p->src.in4 );
+ struct iovec buffer = {
+ .iov_base = p->buffer,
+ .iov_len = BUFSIZE
+ };
+ char data[1000];
+ struct msghdr msg = {
+ .msg_name = &p->src.in,
+ .msg_namelen = addrlen,
+ .msg_iov = &buffer,
+ .msg_iovlen = 1,
+ .msg_control = data,
+ .msg_controllen = sizeof( data ),
+ .msg_flags = flags // Return value
+ };
+ p->len = recvmsg( fd, &msg, flags );
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR( &msg );
+ VERBOSE3OUT( "anc %p %ld\n", cmsg, p->len );
+ for ( ; cmsg; cmsg = CMSG_NXTHDR( &msg, cmsg ) ) {
+ VERBOSE3OUT( "anc type = %d\n", cmsg->cmsg_type );
+ }
+ cmsg = CMSG_FIRSTHDR( &msg );
+ if ( cmsg ) {
+ if ( udp6 ) {
+ } else {
+ struct in_pktinfo* pinf = (struct in_pktinfo*) CMSG_DATA( cmsg );
+ p->dst.in4.sin_family = AF_INET;
+ p->dst.in4.sin_addr = pinf->ipi_addr;
+ VERBOSE3OUT( "DEST= %d %s\n",
+ pinf->ipi_ifindex, inet_stoa( &p->dst ) );
+ }
+ }
+ return p->len;
+}
+
+
+
// Read a full UDP packet into the given buffer, associate with a
// connection, or create a new connection, the decrypt the as
// specified, and capture the sender MAC address. The connection table
int fd = ((ReaderData *) data)->fd;
while ( 1 ) {
PacketItem *todo = (PacketItem *) Queue_getItem( &todolist.free );
+#if 0
socklen_t addrlen =
udp6? sizeof( todo->src.in6 ) : sizeof( todo->src.in4 );
+#endif
memset( &todo->src, 0, sizeof( todo->src ) );
todo->fd = fd;
+#if 0
todo->len = recvfrom(
fd, todo->buffer, BUFSIZE, 0, &todo->src.in, &addrlen );
- if ( todo->len == -1) {
+#endif
+ VERBOSE3OUT( "Reading packet\n" );
+ ssize_t len = recvpacket( fd, todo );
+ if ( len == -1) {
perror( "Receiving UDP" );
exit( 1 );
}
#ifdef GPROF
- if ( todo->len == 17 &&
+ if ( len == 17 &&
memcmp( todo->buffer, "STOPSTOPSTOPSTOP", 16 ) == 0 ) {
exit( 0 );
}
exit(1);
}
VERBOSEOUT( "Using ipv4 UDP at %d\n", udp_fd );
+ int opt = 1;
+ if ( setsockopt( udp_fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) ) {
+ fprintf( stderr, "Error configuring socket!\n");
+ exit(1);
+ }
} else {
// set up ipv6 socket
if ( ( udp_fd = socket( AF_INET6, SOCK_DGRAM, 0 ) ) == 0 ) {