lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <402249329CEF3E49AACD14423D8386EE03C6B35C@SACEXCMBX03-PRD.hq.netapp.com>
Date:	Thu, 26 Apr 2012 09:37:31 +0000
From:	"S, Sreeram" <Sreeram.S@...app.com>
To:	Eric Dumazet <eric.dumazet@...il.com>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	Andy Lutomirski <luto@....edu>
CC:	"S, Sreeram" <Sreeram.S@...app.com>
Subject: IP options IP_RECVOPTS on Linux 2.6 - Kindly comment

Hi, 
    I am Sreeram. I work on TCP/IP on personal interest. I was going through the man page of ip(7). 
In the man page, it is documented that there is an option called IP_RECVOPTS which returns the IP header options as a control message. 
Exact snippet from the man-page is as follows:


       IP_RECVOPTS (since Linux 2.2)
              Pass all incoming IP options to the user in a IP_OPTIONS
              control  message.   The routing header and other options
              are already filled in for the local host.  Not supported
              for SOCK_STREAM sockets.

I have written a program which uses recvmsg() to receive the UDP message and also the incoming ancillary/control data.
In that program, I had enabled this option. But I could not get any IP header options ancillary/control message. Initially, I
had defined a pointer to the ip_opts structure defined in bits/in.h . The structure and its documentation are as follows:

#if defined __USE_MISC || defined __USE_GNU
/* Structure used to describe IP options for IP_OPTIONS and IP_RETOPTS.
   The `ip_dst' field is used for the first-hop gateway when using a
   source route (this gets put into the header proper).  */
struct ip_opts
  {
    struct in_addr ip_dst;      /* First hop; zero without source route.  */
    char ip_opts[40];           /* Actually variable in size.  */
  };

   Since, I did not receive the IP header options message in recvmsg(), I removed the pointer variable for this structure and the associated typecasting to the CMSG_DATA(..) and 
Introduced a counter to count the number of ancillary packets received. The count was 3 (IP_TTL and IP_TOS and SO_TIMESTAMP, all which I had enabled using setsockopt())
The program is as follows:

[root@...eramb-linux Server]# cat recvmsg.c 
/* This is a generic UDP server.                                        
 * This will return what it received from the client to the client.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 19000
#define SA struct sockaddr

int main(int argc, char **argv) {
    char data[128];
    int *ttlptr, count=0;
    int sock, retn, size, val=1;
    struct sockaddr_in peer;
    struct iovec iov;
    struct ip_opts *ipopts;
    struct msghdr msg;
    struct cmsghdr *cmsg;
    struct timeval *timeptr;
    
    /* Create a socket. */
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        perror("Socket");
        exit(-1);
    }
    printf("Socket created.\n");

    /* Set some options for this socket to get ancillary data. */
    setsockopt(sock, IPPROTO_IP, IP_RECVTTL, &val, sizeof(val));
    setsockopt(sock, IPPROTO_IP, IP_RECVTOS, &val, sizeof(val));
    setsockopt(sock, IPPROTO_IP, IP_RETOPTS, &val, sizeof(val));
    setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(val));

    /* Prepare the structure for 'bind'ing */
    memset(&peer, 0, sizeof(peer));
    peer.sin_family = AF_INET;
    peer.sin_port = htons(PORT);
    peer.sin_addr.s_addr = INADDR_ANY;

    /* Bind to an interface */
    retn = bind(sock, (SA *)&peer, sizeof(peer));    
    if (retn < 0) {
        perror("Bind");
        close(sock);
        exit(-1);
    }
    printf("Successfully bound to the interface.\n");

    /* Now, populate the msghdr to prepare it for use in recvmsg */
    memset(data, 0, sizeof(data));
    memset(&peer, 0, sizeof(peer));
    iov.iov_base = data;
    iov.iov_len = sizeof(data);
    msg.msg_name = &peer;
    msg.msg_namelen = sizeof(peer);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = calloc(1, 1024);
    msg.msg_controllen = 1024;
    msg.msg_flags = 0;

    /* Now, call recvmsg() */
    size = sizeof(peer);
    retn = recvmsg(sock, &msg, 0);
    if (retn < 0) {
        perror("recvfrom");
        close(sock);
        exit(-2);
    }
    printf("Received some data:\n");
    printf("    Client: %s\n", inet_ntoa(peer.sin_addr));
    printf("      Data: %s\n", data);

    /* Print ancillary data */
    for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 
        cmsg = CMSG_NXTHDR(&msg, cmsg)) {

        /* Check for TTL in ancillary data. */
        if ((cmsg->cmsg_level == IPPROTO_IP)
         &&(cmsg->cmsg_type == IP_TTL)) {
            ttlptr = (int *) CMSG_DATA(cmsg);
            val = *ttlptr;
            printf("       TTL: %d\n", val);
        }

        /* Check for TOS in ancillary data. */
        if ((cmsg->cmsg_level == IPPROTO_IP)
         &&(cmsg->cmsg_type == IP_TOS)) {
            ttlptr = (int *) CMSG_DATA(cmsg);
            val = *ttlptr;
            printf("       TOS: %d\n", val);
        }

        /* Get the timestamp of the message. */
        if ((cmsg->cmsg_level == SOL_SOCKET)
         && (cmsg->cmsg_type == SO_TIMESTAMP)) {
            timeptr = (struct timeval *) CMSG_DATA(cmsg);
            printf(" Timestamp: %s", ctime(&timeptr->tv_sec));
        }

        count++;
    }

    printf("Total ancillary packets: %d\n", count);
    close(sock);
    return(0);
}
[root@...eramb-linux Server]#
[root@...eramb-linux Server]# uname -a
Linux sreeramb-linux 2.6.35.6-45.fc14.i686 #1 SMP Mon Oct 18 23:56:17 UTC 2010 i686 i686 i386 GNU/Linux
[root@...eramb-linux Server]#

[ I am using Fedora Core 14]

   What could be the reason for not receiving the IP Options message? What should I enable to receive the same?

Kindly guide.

Regards,
Sreeram

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ