mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* IP options IP_RECVOPTS on Linux 2.6 - Kindly comment
@ 2012-04-26  9:37 S, Sreeram
       [not found] ` <CAO_LctSkkqctOEaC_CPDB7yHCzgAYe+G3rPQBFT3jh1-cCT22A@mail.gmail.com>
  0 siblings, 1 reply; 3+ messages in thread
From: S, Sreeram @ 2012-04-26  9:37 UTC (permalink / raw)
  To: Eric Dumazet, linux-kernel, Andy Lutomirski; +Cc: S, Sreeram

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 5588 bytes --]

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@sreeramb-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@sreeramb-linux Server]#
[root@sreeramb-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@sreeramb-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
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: IP options IP_RECVOPTS on Linux 2.6 - Kindly comment
       [not found]   ` <402249329CEF3E49AACD14423D8386EE03C6B5E5@SACEXCMBX03-PRD.hq.netapp.com>
@ 2012-04-27  5:31     ` Eric Dumazet
  2012-04-27  5:34       ` S, Sreeram
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2012-04-27  5:31 UTC (permalink / raw)
  To: S, Sreeram; +Cc: Ravishankar, linux-kernel, Andy Lutomirski

On Fri, 2012-04-27 at 05:25 +0000, S, Sreeram wrote:
> Thanks a lot Ravi for the response.
> 
> But, the IP header is 40 bytes and so I think I should expect all
> those 40 bytes to be returned to my program when I enable this option.
> Isnt that correct ?
> 
> Here, TTL and TOS are getting returned because I have explicitly
> enabled the returns of IP_RECVTTL and IP_RECVTOS to my program using
> setsockopt. Otherwise even they wouldn’t have been returned.
> 
> I still think that the kernel is not returning what it should return
> when I enable IP_RECVOPTS. Please correct me if you think I am wrong.
> 
>  
> 
> Also, what are the other ways of getting the IP header other than RAW
> sockets, if the current approach does not work?
> 
>  

IP options are not IP header.

Try to send an IP packets with options, and your program will work.





^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: IP options IP_RECVOPTS on Linux 2.6 - Kindly comment
  2012-04-27  5:31     ` Eric Dumazet
@ 2012-04-27  5:34       ` S, Sreeram
  0 siblings, 0 replies; 3+ messages in thread
From: S, Sreeram @ 2012-04-27  5:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Ravishankar, linux-kernel, Andy Lutomirski

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1367 bytes --]

Thanks Eric.
I shall try that and I will reply. Thanks for the hint.

Regards,
Sreeram

-----Original Message-----
From: Eric Dumazet [mailto:eric.dumazet@gmail.com] 
Sent: Friday, April 27, 2012 11:02 AM
To: S, Sreeram
Cc: Ravishankar; linux-kernel@vger.kernel.org; Andy Lutomirski
Subject: RE: IP options IP_RECVOPTS on Linux 2.6 - Kindly comment

On Fri, 2012-04-27 at 05:25 +0000, S, Sreeram wrote:
> Thanks a lot Ravi for the response.
> 
> But, the IP header is 40 bytes and so I think I should expect all 
> those 40 bytes to be returned to my program when I enable this option.
> Isnt that correct ?
> 
> Here, TTL and TOS are getting returned because I have explicitly 
> enabled the returns of IP_RECVTTL and IP_RECVTOS to my program using 
> setsockopt. Otherwise even they wouldn’t have been returned.
> 
> I still think that the kernel is not returning what it should return 
> when I enable IP_RECVOPTS. Please correct me if you think I am wrong.
> 
>  
> 
> Also, what are the other ways of getting the IP header other than RAW 
> sockets, if the current approach does not work?
> 
>  

IP options are not IP header.

Try to send an IP packets with options, and your program will work.




ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-04-27  5:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-26  9:37 IP options IP_RECVOPTS on Linux 2.6 - Kindly comment S, Sreeram
     [not found] ` <CAO_LctSkkqctOEaC_CPDB7yHCzgAYe+G3rPQBFT3jh1-cCT22A@mail.gmail.com>
     [not found]   ` <402249329CEF3E49AACD14423D8386EE03C6B5E5@SACEXCMBX03-PRD.hq.netapp.com>
2012-04-27  5:31     ` Eric Dumazet
2012-04-27  5:34       ` S, Sreeram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®