Re: exim and ipoptions

Top Page
Delete this message
Reply to this message
Author: Niels Provos
Date:  
To: Nigel Metheringham
CC: exim-users
Subject: Re: exim and ipoptions
On Wed, 5 Feb 1997, Nigel Metheringham wrote:
> To save me having to extract a copy of sendmail (after just going to the
> trouble of preventing it being installed when I upgraded a Linux system
> yesterday), could you split out the code fragment that sendmail uses to do
> this, please.

Okay, here follows the code from daemon.c sendmail-8.8.3 which display the
source routes , I will annotate the bug in it:
#if IP_SRCROUTE
    /*
    **  Extract IP source routing information.
    **
    **    Format of output for a connection from site a through b
    **    through c to d:
    **        loose:      @site-c@site-b:site-a
    **        strict:       !@site-c@site-b:site-a
    **
    **    o - pointer within ipopt_list structure.
    **    q - pointer within ls/ss rr route data
    **    p - pointer to hbuf
    */


    if (RealHostAddr.sa.sa_family == AF_INET)
    {
        int ipoptlen, j;
        u_char *q;
        u_char *o;
        int l;
        struct in_addr addr;
        struct ipoption ipopt;


        ipoptlen = sizeof ipopt;
        if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS,
                   (char *) &ipopt, &ipoptlen) < 0)
            goto noipsr;
        if (ipoptlen == 0)
            goto noipsr;
        o = (u_char *) ipopt.ipopt_list;
        while (o != NULL && o < (u_char *) &ipopt + ipoptlen)
        {
            switch (*o)
            {
              case IPOPT_EOL: 
                o = NULL;
                break;


              case IPOPT_NOP:
                o++;
                break;


              case IPOPT_SSRR:
              case IPOPT_LSRR:
                p = &hbuf[strlen(hbuf)];
                l = sizeof hbuf - (hbuf - p) - 6;
                snprintf(p, SPACELEFT(hbuf, p), " [%s@%.*s",
                    *o == IPOPT_SSRR ? "!" : "",
                    l > 240 ? 120 : l / 2,
                    inet_ntoa(ipopt.ipopt_dst));
                i = strlen(p);
                p += i;
                l -= strlen(p);


                /* o[1] is option length */
                j = *++o / sizeof(struct in_addr) - 1;


                /* q skips length and router pointer to data */
                q = o + 2;
                for ( ; j >= 0; j--)
                {
                    memcpy(&addr, q, sizeof(addr));
                    snprintf(p, SPACELEFT(hbuf, p),
                        "%c%.*s",
                        j != 0 ? '@' : ':',
                        l > 240 ? 120 :
                            j == 0 ? l : l / 2,
                        inet_ntoa(addr));
                    i = strlen(p);
                    p += i;
                    l -= i + 1;
                    q += sizeof(struct in_addr); 
                }
                o += *o;
[ According to rfc791 the option length gives the length of option type
  plus option length plus all data bytes, so the code should read:
                o += *o -1;
  or something to the same end. ]
                break;


              default:
                /* Skip over option */
                o += o[1];
                break;
            }
        }
        snprintf(p, SPACELEFT(hbuf, p), "]");
        goto postipsr;
    }
#endif



- PHYSnet Rechnerverbund     PGP V2.6 Public key via finger or key server
  Niels Provos               
  Universitaet Hamburg       WWW: http://www.physnet.uni-hamburg.de/provos/   
  Jungiusstrasse 9           E-Mail: provos@???
  Germany 20355 Hamburg      Tel.:   +49 40 4123-2504     Fax: -6571