From: Ralph Ronnquist Date: Thu, 10 Nov 2022 03:11:08 +0000 (+1100) Subject: capturing for ipv4 X-Git-Tag: 1.6.1~9 X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=6cbe512525bf95cd04e7416f865c4a225d092490;p=rrq%2Frrqnet.git capturing for ipv4 --- diff --git a/rrqnet.c b/rrqnet.c index 005fd20..cf0617e 100644 --- a/rrqnet.c +++ b/rrqnet.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,8 @@ struct Allowed { // 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 }; @@ -83,6 +85,7 @@ typedef struct _PacketItem { QueueItem base; int fd; struct SockAddr src; + struct SockAddr dst; ssize_t len; unsigned char buffer[ BUFSIZE ]; } PacketItem; @@ -1256,6 +1259,46 @@ void todolist_initialize(int nbuf,int nthr) { } } +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 @@ -1266,18 +1309,24 @@ static void *doreadUDP(void *data) { 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 ); } @@ -1612,6 +1661,11 @@ int main(int argc, char *argv[]) { 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 ) {