VirtualBox

Ignore:
Timestamp:
Dec 3, 2008 9:34:37 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
40325
Message:

slirp: code cosmetics for better readability (no semantics change)

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/bootp.h

    r7809 r14964  
    9393#define DHCP_OPT_LEN            312
    9494
    95 struct bootp_t {
    96     struct ip ip;
    97     struct udphdr udp;
    98     uint8_t bp_op;
    99     uint8_t bp_htype;
    100     uint8_t bp_hlen;
    101     uint8_t bp_hops;
    102     uint32_t bp_xid;
    103     uint16_t bp_secs;
    104     uint16_t unused;
     95struct bootp_t
     96{
     97    struct ip      ip;
     98    struct udphdr  udp;
     99    uint8_t        bp_op;
     100    uint8_t        bp_htype;
     101    uint8_t        bp_hlen;
     102    uint8_t        bp_hops;
     103    uint32_t       bp_xid;
     104    uint16_t       bp_secs;
     105    uint16_t       unused;
    105106    struct in_addr bp_ciaddr;
    106107    struct in_addr bp_yiaddr;
    107108    struct in_addr bp_siaddr;
    108109    struct in_addr bp_giaddr;
    109     uint8_t bp_hwaddr[16];
    110     uint8_t bp_sname[64];
    111     uint8_t bp_file[128];
    112     uint8_t bp_vend[DHCP_OPT_LEN];
     110    uint8_t        bp_hwaddr[16];
     111    uint8_t        bp_sname[64];
     112    uint8_t        bp_file[128];
     113    uint8_t        bp_vend[DHCP_OPT_LEN];
    113114};
    114115
  • trunk/src/VBox/Devices/Network/slirp/cksum.c

    r14470 r14964  
    4747
    4848#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
    49 #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
     49#define REDUCE { l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum); }
    5050
    5151int cksum(struct mbuf *m, int len)
    5252{
    53         register u_int16_t *w;
    54         register int sum = 0;
    55         register int mlen = 0;
    56         int byte_swapped = 0;
     53    register u_int16_t *w;
     54    register int sum = 0;
     55    register int mlen = 0;
     56    int byte_swapped = 0;
    5757
    58         union {
    59                 u_int8_t        c[2];
    60                 u_int16_t       s;
    61         } s_util;
    62         union {
    63                 u_int16_t s[2];
    64                 u_int32_t l;
    65         } l_util;
     58    union
     59    {
     60        u_int8_t  c[2];
     61        u_int16_t s;
     62    } s_util;
     63    union
     64    {
     65        u_int16_t s[2];
     66        u_int32_t l;
     67    } l_util;
    6668       
    67         if (m->m_len == 0)
    68            goto cont;
    69         w = mtod(m, u_int16_t *);
     69    if (m->m_len == 0)
     70        goto cont;
     71    w = mtod(m, u_int16_t *);
     72
     73    mlen = m->m_len;
    7074       
    71         mlen = m->m_len;
     75    if (len < mlen)
     76        mlen = len;
     77    len -= mlen;
     78    /*
     79     * Force to even boundary.
     80     */
     81    if ((1 & (long) w) && (mlen > 0))
     82    {
     83        REDUCE;
     84        sum <<= 8;
     85        s_util.c[0] = *(u_int8_t *)w;
     86        w = (u_int16_t *)((int8_t *)w + 1);
     87        mlen--;
     88        byte_swapped = 1;
     89    }
     90    /*
     91     * Unroll the loop to make overhead from
     92     * branches &c small.
     93     */
     94    while ((mlen -= 32) >= 0)
     95    {
     96        sum += w[ 0]; sum += w[ 1]; sum += w[ 2]; sum += w[ 3];
     97        sum += w[ 4]; sum += w[ 5]; sum += w[ 6]; sum += w[ 7];
     98        sum += w[ 8]; sum += w[ 9]; sum += w[10]; sum += w[11];
     99        sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
     100        w += 16;
     101    }
     102    mlen += 32;
     103    while ((mlen -= 8) >= 0)
     104    {
     105        sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
     106        w += 4;
     107    }
     108    mlen += 8;
     109    if (mlen == 0 && byte_swapped == 0)
     110        goto cont;
     111    REDUCE;
     112    while ((mlen -= 2) >= 0)
     113    {
     114        sum += *w++;
     115    }
    72116       
    73         if (len < mlen)
    74            mlen = len;
    75         len -= mlen;
    76         /*
    77          * Force to even boundary.
    78          */
    79         if ((1 & (long) w) && (mlen > 0)) {
    80                 REDUCE;
    81                 sum <<= 8;
    82                 s_util.c[0] = *(u_int8_t *)w;
    83                 w = (u_int16_t *)((int8_t *)w + 1);
    84                 mlen--;
    85                 byte_swapped = 1;
     117    if (byte_swapped)
     118    {
     119        REDUCE;
     120        sum <<= 8;
     121        byte_swapped = 0;
     122        if (mlen == -1)
     123        {
     124            s_util.c[1] = *(u_int8_t *)w;
     125            sum += s_util.s;
     126            mlen = 0;
    86127        }
    87         /*
    88          * Unroll the loop to make overhead from
    89          * branches &c small.
    90          */
    91         while ((mlen -= 32) >= 0) {
    92                 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
    93                 sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
    94                 sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
    95                 sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
    96                 w += 16;
    97         }
    98         mlen += 32;
    99         while ((mlen -= 8) >= 0) {
    100                 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
    101                 w += 4;
    102         }
    103         mlen += 8;
    104         if (mlen == 0 && byte_swapped == 0)
    105            goto cont;
    106         REDUCE;
    107         while ((mlen -= 2) >= 0) {
    108                 sum += *w++;
    109         }
    110        
    111         if (byte_swapped) {
    112                 REDUCE;
    113                 sum <<= 8;
    114                 byte_swapped = 0;
    115                 if (mlen == -1) {
    116                         s_util.c[1] = *(u_int8_t *)w;
    117                         sum += s_util.s;
    118                         mlen = 0;
    119                 } else
    120                    
    121                    mlen = -1;
    122         } else if (mlen == -1)
    123            s_util.c[0] = *(u_int8_t *)w;
     128        else
     129            mlen = -1;
     130    }
     131    else if (mlen == -1)
     132        s_util.c[0] = *(u_int8_t *)w;
    124133       
    125134cont:
    126135#ifdef DEBUG
    127         if (len) {
    128                 DEBUG_ERROR((dfd, "cksum: out of data\n"));
    129                 DEBUG_ERROR((dfd, " len = %d\n", len));
    130         }
     136    if (len)
     137    {
     138        DEBUG_ERROR((dfd, "cksum: out of data\n"));
     139        DEBUG_ERROR((dfd, " len = %d\n", len));
     140    }
    131141#endif
    132         if (mlen == -1) {
    133                 /* The last mbuf has odd # of bytes. Follow the
    134                  standard (the odd byte may be shifted left by 8 bits
    135                            or not as determined by endian-ness of the machine) */
    136                 s_util.c[1] = 0;
    137                 sum += s_util.s;
    138         }
    139         REDUCE;
    140         return (~sum & 0xffff);
     142    if (mlen == -1)
     143    {
     144        /* The last mbuf has odd # of bytes. Follow the
     145           standard (the odd byte may be shifted left by 8 bits
     146           or not as determined by endian-ness of the machine) */
     147        s_util.c[1] = 0;
     148        sum += s_util.s;
     149    }
     150    REDUCE;
     151    return (~sum & 0xffff);
    141152}
  • trunk/src/VBox/Devices/Network/slirp/icmp_var.h

    r1076 r14964  
    4242 * of the internet control message protocol.
    4343 */
    44 struct icmpstat_t {
     44struct icmpstat_t
     45{
    4546/* statistics related to input messages processed */
    46         u_long  icps_received;          /* #ICMP packets received */
    47         u_long  icps_tooshort;          /* packet < ICMP_MINLEN */
    48         u_long  icps_checksum;          /* bad checksum */
    49         u_long  icps_notsupp;           /* #ICMP packets not supported */
    50         u_long  icps_badtype;           /* #with bad type feild */
    51         u_long  icps_reflect;           /* number of responses */
     47    u_long  icps_received;              /* #ICMP packets received */
     48    u_long      icps_tooshort;          /* packet < ICMP_MINLEN */
     49    u_long      icps_checksum;          /* bad checksum */
     50    u_long      icps_notsupp;           /* #ICMP packets not supported */
     51    u_long  icps_badtype;               /* #with bad type feild */
     52    u_long      icps_reflect;           /* number of responses */
    5253};
    5354
  • trunk/src/VBox/Devices/Network/slirp/if.h

    r14476 r14964  
    1717#undef if_mtu
    1818extern int      if_mtu;
    19 extern int      if_mru; /* MTU and MRU */
     19extern int      if_mru;         /* MTU and MRU */
    2020extern int      if_comp;        /* Flags for compression */
    2121extern int      if_maxlinkhdr;
     
    2424                                 * (to prevent allocing too many mbufs) */
    2525
    26 extern  struct mbuf if_fastq;                  /* fast queue (for interactive data) */
    27 extern  struct mbuf if_batchq;                 /* queue for non-interactive data */
     26extern  struct mbuf if_fastq;   /* fast queue (for interactive data) */
     27extern  struct mbuf if_batchq;  /* queue for non-interactive data */
    2828extern  struct mbuf *next_m;
    2929
  • trunk/src/VBox/Devices/Network/slirp/ip_output.c

    r14470 r14964  
    5555ip_output(PNATState pData, struct socket *so, struct mbuf *m0)
    5656{
    57         register struct ip *ip;
    58         register struct mbuf *m = m0;
    59         register int hlen = sizeof(struct ip );
    60         int len, off, error = 0;
    61 
    62         DEBUG_CALL("ip_output");
    63         DEBUG_ARG("so = %lx", (long)so);
    64         DEBUG_ARG("m0 = %lx", (long)m0);
    65 
    66         /* We do no options */
    67 /*      if (opt) {
    68  *              m = ip_insertoptions(m, opt, &len);
    69  *              hlen = len;
    70  *      }
    71  */
    72         ip = mtod(m, struct ip *);
    73         /*
    74          * Fill in IP header.
    75          */
    76         ip->ip_v = IPVERSION;
    77         ip->ip_off &= IP_DF;
    78         ip->ip_id = htons(ip_currid++);
    79         ip->ip_hl = hlen >> 2;
    80         ipstat.ips_localout++;
    81 
    82         /*
    83          * Verify that we have any chance at all of being able to queue
    84          *      the packet or packet fragments
    85          */
    86         /* XXX Hmmm... */
    87 /*      if (if_queued > if_thresh && towrite <= 0) {
    88  *              error = ENOBUFS;
    89  *              goto bad;
    90  *      }
    91  */
    92 
    93         /*
    94          * If small enough for interface, can just send directly.
    95          */
    96         if ((u_int16_t)ip->ip_len <= if_mtu) {
    97                 ip->ip_len = htons((u_int16_t)ip->ip_len);
    98                 ip->ip_off = htons((u_int16_t)ip->ip_off);
    99                 ip->ip_sum = 0;
    100                 ip->ip_sum = cksum(m, hlen);
    101 
    102                 if_output(pData, so, m);
    103                 goto done;
    104         }
    105 
    106         /*
    107          * Too large for interface; fragment if possible.
    108          * Must be able to put at least 8 bytes per fragment.
    109          */
    110         if (ip->ip_off & IP_DF) {
    111                 error = -1;
    112                 ipstat.ips_cantfrag++;
    113                 goto bad;
    114         }
    115 
    116         len = (if_mtu - hlen) &~ 7;       /* ip databytes per packet */
    117         if (len < 8) {
    118                 error = -1;
    119                 goto bad;
    120         }
     57    register struct ip *ip;
     58    register struct mbuf *m = m0;
     59    register int hlen = sizeof(struct ip );
     60    int len, off, error = 0;
     61
     62    DEBUG_CALL("ip_output");
     63    DEBUG_ARG("so = %lx", (long)so);
     64    DEBUG_ARG("m0 = %lx", (long)m0);
     65
     66#if 0 /* We do no options */
     67    if (opt)
     68    {
     69        m = ip_insertoptions(m, opt, &len);
     70        hlen = len;
     71    }
     72#endif
     73    ip = mtod(m, struct ip *);
     74    /*
     75     * Fill in IP header.
     76     */
     77    ip->ip_v = IPVERSION;
     78    ip->ip_off &= IP_DF;
     79    ip->ip_id = htons(ip_currid++);
     80    ip->ip_hl = hlen >> 2;
     81    ipstat.ips_localout++;
     82
     83    /*
     84     * Verify that we have any chance at all of being able to queue
     85     *      the packet or packet fragments
     86     */
     87#if 0 /* XXX Hmmm... */
     88    if (if_queued > if_thresh && towrite <= 0)
     89    {
     90        error = ENOBUFS;
     91        goto bad;
     92    }
     93#endif
     94
     95    /*
     96     * If small enough for interface, can just send directly.
     97     */
     98    if ((u_int16_t)ip->ip_len <= if_mtu)
     99    {
     100        ip->ip_len = htons((u_int16_t)ip->ip_len);
     101        ip->ip_off = htons((u_int16_t)ip->ip_off);
     102        ip->ip_sum = 0;
     103        ip->ip_sum = cksum(m, hlen);
     104
     105        if_output(pData, so, m);
     106        goto done;
     107    }
     108
     109    /*
     110     * Too large for interface; fragment if possible.
     111     * Must be able to put at least 8 bytes per fragment.
     112     */
     113    if (ip->ip_off & IP_DF)
     114    {
     115        error = -1;
     116        ipstat.ips_cantfrag++;
     117        goto bad;
     118    }
     119
     120    len = (if_mtu - hlen) &~ 7;       /* ip databytes per packet */
     121    if (len < 8)
     122    {
     123        error = -1;
     124        goto bad;
     125    }
    121126
    122127    {
     
    130135        m0 = m;
    131136        mhlen = sizeof (struct ip);
    132         for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
    133           register struct ip *mhip;
    134           m = m_get(pData);
    135           if (m == 0) {
    136             error = -1;
    137             ipstat.ips_odropped++;
    138             goto sendorfree;
    139           }
    140           m->m_data += if_maxlinkhdr;
    141           mhip = mtod(m, struct ip *);
    142           *mhip = *ip;
    143 
    144                 /* No options */
    145 /*              if (hlen > sizeof (struct ip)) {
    146  *                      mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
    147  *                      mhip->ip_hl = mhlen >> 2;
    148  *              }
    149  */
    150           m->m_len = mhlen;
    151           mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
    152           if (ip->ip_off & IP_MF)
    153             mhip->ip_off |= IP_MF;
    154           if (off + len >= (u_int16_t)ip->ip_len)
    155             len = (u_int16_t)ip->ip_len - off;
    156           else
    157             mhip->ip_off |= IP_MF;
    158           mhip->ip_len = htons((u_int16_t)(len + mhlen));
    159 
    160           if (m_copy(m, m0, off, len) < 0) {
    161             error = -1;
    162             goto sendorfree;
    163           }
    164 
    165           mhip->ip_off = htons((u_int16_t)mhip->ip_off);
    166           mhip->ip_sum = 0;
    167           mhip->ip_sum = cksum(m, mhlen);
    168           *mnext = m;
    169           mnext = &m->m_nextpkt;
    170           ipstat.ips_ofragments++;
     137        for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len)
     138        {
     139            register struct ip *mhip;
     140            m = m_get(pData);
     141            if (m == 0)
     142            {
     143                error = -1;
     144                ipstat.ips_odropped++;
     145                goto sendorfree;
     146            }
     147            m->m_data += if_maxlinkhdr;
     148            mhip = mtod(m, struct ip *);
     149            *mhip = *ip;
     150
     151#if 0 /* No options */
     152            if (hlen > sizeof (struct ip))
     153            {
     154                mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
     155                mhip->ip_hl = mhlen >> 2;
     156            }
     157#endif
     158            m->m_len = mhlen;
     159            mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
     160            if (ip->ip_off & IP_MF)
     161                mhip->ip_off |= IP_MF;
     162            if (off + len >= (u_int16_t)ip->ip_len)
     163                len = (u_int16_t)ip->ip_len - off;
     164            else
     165                mhip->ip_off |= IP_MF;
     166            mhip->ip_len = htons((u_int16_t)(len + mhlen));
     167
     168            if (m_copy(m, m0, off, len) < 0)
     169            {
     170                error = -1;
     171                goto sendorfree;
     172            }
     173
     174            mhip->ip_off = htons((u_int16_t)mhip->ip_off);
     175            mhip->ip_sum = 0;
     176            mhip->ip_sum = cksum(m, mhlen);
     177            *mnext = m;
     178            mnext = &m->m_nextpkt;
     179            ipstat.ips_ofragments++;
    171180        }
    172181        /*
     
    180189        ip->ip_sum = 0;
    181190        ip->ip_sum = cksum(m, hlen);
     191
    182192sendorfree:
    183         for (m = m0; m; m = m0) {
    184                 m0 = m->m_nextpkt;
    185                 m->m_nextpkt = 0;
    186                 if (error == 0)
    187                         if_output(pData, so, m);
    188                 else
    189                         m_freem(pData, m);
     193        for (m = m0; m; m = m0)
     194        {
     195            m0 = m->m_nextpkt;
     196            m->m_nextpkt = 0;
     197            if (error == 0)
     198                if_output(pData, so, m);
     199            else
     200                m_freem(pData, m);
    190201        }
    191202
    192203        if (error == 0)
    193                 ipstat.ips_fragmented++;
     204            ipstat.ips_fragmented++;
    194205    }
    195206
    196207done:
    197         return (error);
     208    return (error);
    198209
    199210bad:
    200         m_freem(pData, m0);
    201         goto done;
     211    m_freem(pData, m0);
     212    goto done;
    202213}
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r14391 r14964  
    22#define _LIBSLIRP_H
    33
    4 #ifdef _WIN32
    5 #include <winsock2.h>
    6 #ifdef __cplusplus
     4#ifdef RT_OS_WINDOWS
     5# include <winsock2.h>
     6# ifdef __cplusplus
    77extern "C" {
    8 #endif
     8# endif
    99int inet_aton(const char *cp, struct in_addr *ia);
    10 #ifdef __cplusplus
     10# ifdef __cplusplus
    1111}
    12 #endif
     12# endif
    1313#else
    14 #ifdef RT_OS_OS2 /* temporary workaround, see ticket #127 */
    15 # include <sys/time.h>
    16 #endif
    17 #include <sys/select.h>
    18 #include <arpa/inet.h>
     14# ifdef RT_OS_OS2 /* temporary workaround, see ticket #127 */
     15#  include <sys/time.h>
     16# endif
     17# include <sys/select.h>
     18# include <arpa/inet.h>
    1919#endif
    2020
  • trunk/src/VBox/Devices/Network/slirp/main.h

    r1076 r14964  
    1010#endif
    1111
    12 #define TOWRITEMAX 512
    13 
    14 
    15 /*
    16  * Get the difference in 2 times from updtim()
    17  * Allow for wraparound times, "just in case"
    18  * x is the greater of the 2 (current time) and y is
    19  * what it's being compared against.
    20  */
    21 #define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)
    22 
    23 
    24 #define PROTO_SLIP 0x1
    25 #ifdef USE_PPP
    26 #define PROTO_PPP 0x2
    27 #endif
    28 
    2912void if_encap(PNATState pData, const uint8_t *ip_data, int ip_data_len);
  • trunk/src/VBox/Devices/Network/slirp/mbuf.c

    r14470 r14964  
    2222m_init(PNATState pData)
    2323{
    24         m_freelist.m_next = m_freelist.m_prev = &m_freelist;
    25         m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
    26         mbuf_alloced = 0;
    27         msize_init(pData);
     24    m_freelist.m_next = m_freelist.m_prev = &m_freelist;
     25    m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
     26    mbuf_alloced = 0;
     27    msize_init(pData);
    2828}
    2929
     
    3131msize_init(PNATState pData)
    3232{
    33         /*
    34          * Find a nice value for msize
    35          * XXX if_maxlinkhdr already in mtu
    36          */
    37         msize = (if_mtu>if_mru?if_mtu:if_mru) +
    38                         if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
     33    /*
     34     * Find a nice value for msize
     35     * XXX if_maxlinkhdr already in mtu
     36     */
     37    msize = (if_mtu>if_mru ? if_mtu : if_mru)
     38          + if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
    3939}
    4040
     
    5050m_get(PNATState pData)
    5151{
    52         register struct mbuf *m;
    53         int flags = 0;
    54 
    55         DEBUG_CALL("m_get");
    56 
    57         if (m_freelist.m_next == &m_freelist) {
    58                 m = (struct mbuf *)malloc(msize);
    59                 if (m == NULL) goto end_error;
    60                 mbuf_alloced++;
    61                 if (mbuf_alloced > mbuf_thresh)
    62                         flags = M_DOFREE;
    63                 if (mbuf_alloced > mbuf_max)
    64                         mbuf_max = mbuf_alloced;
    65         } else {
    66                 m = m_freelist.m_next;
    67                 remque(pData, m);
    68         }
    69 
    70         /* Insert it in the used list */
    71         insque(pData, m,&m_usedlist);
    72         m->m_flags = (flags | M_USEDLIST);
    73 
    74         /* Initialise it */
    75         m->m_size = msize - sizeof(struct m_hdr);
    76         m->m_data = m->m_dat;
    77         m->m_len = 0;
    78         m->m_nextpkt = 0;
    79         m->m_prevpkt = 0;
     52    register struct mbuf *m;
     53    int flags = 0;
     54
     55    DEBUG_CALL("m_get");
     56
     57    if (m_freelist.m_next == &m_freelist)
     58    {
     59        m = (struct mbuf *)malloc(msize);
     60        if (m == NULL) goto
     61            end_error;
     62        mbuf_alloced++;
     63        if (mbuf_alloced > mbuf_thresh)
     64            flags = M_DOFREE;
     65        if (mbuf_alloced > mbuf_max)
     66            mbuf_max = mbuf_alloced;
     67    }
     68    else
     69    {
     70        m = m_freelist.m_next;
     71        remque(pData, m);
     72    }
     73
     74    /* Insert it in the used list */
     75    insque(pData, m, &m_usedlist);
     76    m->m_flags = (flags | M_USEDLIST);
     77
     78    /* Initialise it */
     79    m->m_size = msize - sizeof(struct m_hdr);
     80    m->m_data = m->m_dat;
     81    m->m_len = 0;
     82    m->m_nextpkt = 0;
     83    m->m_prevpkt = 0;
     84
    8085end_error:
    81         DEBUG_ARG("m = %lx", (long )m);
    82         return m;
     86    DEBUG_ARG("m = %lx", (long )m);
     87    return m;
    8388}
    8489
     
    8792{
    8893
    89   DEBUG_CALL("m_free");
    90   DEBUG_ARG("m = %lx", (long )m);
    91 
    92   if(m) {
     94    DEBUG_CALL("m_free");
     95    DEBUG_ARG("m = %lx", (long )m);
     96
     97    if(m)
     98    {
    9399        /* Remove from m_usedlist */
    94100        if (m->m_flags & M_USEDLIST)
    95            remque(pData, m);
     101            remque(pData, m);
    96102
    97103        /* If it's M_EXT, free() it */
    98104        if (m->m_flags & M_EXT)
    99            free(m->m_ext);
     105            free(m->m_ext);
    100106
    101107        /*
    102108         * Either free() it or put it on the free list
    103109         */
    104         if (m->m_flags & M_DOFREE) {
    105                 u32ptr_done(pData, ptr_to_u32(pData, m), m);
    106                 free(m);
    107                 mbuf_alloced--;
    108         } else if ((m->m_flags & M_FREELIST) == 0) {
    109                 insque(pData, m,&m_freelist);
    110                 m->m_flags = M_FREELIST; /* Clobber other flags */
    111         }
    112   } /* if(m) */
     110        if (m->m_flags & M_DOFREE)
     111        {
     112            u32ptr_done(pData, ptr_to_u32(pData, m), m);
     113            free(m);
     114            mbuf_alloced--;
     115        }
     116        else if ((m->m_flags & M_FREELIST) == 0)
     117        {
     118            insque(pData, m,&m_freelist);
     119            m->m_flags = M_FREELIST; /* Clobber other flags */
     120        }
     121    } /* if(m) */
    113122}
    114123
     
    121130m_cat(PNATState pData, register struct mbuf *m, register struct mbuf *n)
    122131{
    123         /*
    124          * If there's no room, realloc
    125          */
    126         if (M_FREEROOM(m) < n->m_len)
    127                 m_inc(m,m->m_size+MINCSIZE);
    128 
    129         memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
    130         m->m_len += n->m_len;
    131 
    132         m_free(pData, n);
     132    /*
     133     * If there's no room, realloc
     134     */
     135    if (M_FREEROOM(m) < n->m_len)
     136        m_inc(m,m->m_size+MINCSIZE);
     137
     138    memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
     139    m->m_len += n->m_len;
     140
     141    m_free(pData, n);
    133142}
    134143
     
    136145/* make m size bytes large */
    137146void
    138 m_inc(m, size)
    139         struct mbuf *m;
    140         int size;
    141 {
    142         int datasize;
    143 
    144         /* some compiles throw up on gotos.  This one we can fake. */
    145         if(m->m_size>size) return;
    146 
    147         if (m->m_flags & M_EXT) {
    148           datasize = m->m_data - m->m_ext;
    149           m->m_ext = (char *)realloc(m->m_ext,size);
    150 /*              if (m->m_ext == NULL)
    151  *                      return (struct mbuf *)NULL;
    152  */
    153           m->m_data = m->m_ext + datasize;
    154         } else {
    155           char *dat;
    156           datasize = m->m_data - m->m_dat;
    157           dat = (char *)malloc(size);
    158 /*              if (dat == NULL)
    159  *                      return (struct mbuf *)NULL;
    160  */
    161           memcpy(dat, m->m_dat, m->m_size);
    162 
    163           m->m_ext = dat;
    164           m->m_data = m->m_ext + datasize;
    165           m->m_flags |= M_EXT;
    166         }
    167 
    168         m->m_size = size;
    169 
    170 }
    171 
    172 
    173 
    174 void
    175 m_adj(m, len)
    176         struct mbuf *m;
    177         int len;
    178 {
    179         if (m == NULL)
    180                 return;
    181         if (len >= 0) {
    182                 /* Trim from head */
    183                 m->m_data += len;
    184                 m->m_len -= len;
    185         } else {
    186                 /* Trim from tail */
    187                 len = -len;
    188                 m->m_len -= len;
    189         }
     147m_inc(struct mbuf *m, int size)
     148{
     149    int datasize;
     150
     151    /* some compiles throw up on gotos.  This one we can fake. */
     152    if (m->m_size>size)
     153        return;
     154
     155    if (m->m_flags & M_EXT)
     156    {
     157        datasize = m->m_data - m->m_ext;
     158        m->m_ext = (char *)realloc(m->m_ext,size);
     159#if 0
     160        if (m->m_ext == NULL)
     161            return (struct mbuf *)NULL;
     162#endif
     163        m->m_data = m->m_ext + datasize;
     164    }
     165    else
     166    {
     167        char *dat;
     168        datasize = m->m_data - m->m_dat;
     169        dat = (char *)malloc(size);
     170#if 0
     171        if (dat == NULL)
     172            return (struct mbuf *)NULL;
     173#endif
     174        memcpy(dat, m->m_dat, m->m_size);
     175
     176        m->m_ext = dat;
     177        m->m_data = m->m_ext + datasize;
     178        m->m_flags |= M_EXT;
     179    }
     180
     181    m->m_size = size;
     182}
     183
     184
     185void
     186m_adj(struct mbuf *m, int len)
     187{
     188    if (m == NULL)
     189        return;
     190    if (len >= 0)
     191    {
     192        /* Trim from head */
     193        m->m_data += len;
     194        m->m_len -= len;
     195    }
     196    else
     197    {
     198        /* Trim from tail */
     199        len = -len;
     200        m->m_len -= len;
     201    }
    190202}
    191203
     
    195207 */
    196208int
    197 m_copy(n, m, off, len)
    198         struct mbuf *n, *m;
    199         int off, len;
    200 {
    201         if (len > M_FREEROOM(n))
    202                 return -1;
    203 
    204         memcpy((n->m_data + n->m_len), (m->m_data + off), len);
    205         n->m_len += len;
    206         return 0;
     209m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
     210{
     211    if (len > M_FREEROOM(n))
     212        return -1;
     213
     214    memcpy((n->m_data + n->m_len), (m->m_data + off), len);
     215    n->m_len += len;
     216    return 0;
    207217}
    208218
     
    216226dtom(PNATState pData, void *dat)
    217227{
    218         struct mbuf *m;
    219 
    220         DEBUG_CALL("dtom");
    221         DEBUG_ARG("dat = %lx", (long )dat);
    222 
    223         /* bug corrected for M_EXT buffers */
    224         for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
    225           if (m->m_flags & M_EXT) {
    226             if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
    227               return m;
    228           } else {
    229             if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
    230               return m;
    231           }
    232         }
    233 
    234         DEBUG_ERROR((dfd, "dtom failed"));
    235 
    236         return (struct mbuf *)0;
    237 }
    238 
     228    struct mbuf *m;
     229
     230    DEBUG_CALL("dtom");
     231    DEBUG_ARG("dat = %lx", (long )dat);
     232
     233    /* bug corrected for M_EXT buffers */
     234    for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
     235    {
     236        if (m->m_flags & M_EXT)
     237        {
     238            if (   (char *)dat >=  m->m_ext
     239                && (char *)dat <  (m->m_ext + m->m_size))
     240                return m;
     241        }
     242        else
     243        {
     244            if (   (char *)dat >=  m->m_dat
     245                && (char *)dat <  (m->m_dat + m->m_size))
     246                return m;
     247        }
     248    }
     249
     250    DEBUG_ERROR((dfd, "dtom failed"));
     251
     252    return (struct mbuf *)0;
     253}
  • trunk/src/VBox/Devices/Network/slirp/mbuf.h

    r14470 r14964  
    6161/* XXX should union some of these! */
    6262/* header at beginning of each mbuf: */
    63 struct m_hdr {
    64         struct  mbuf *mh_next;          /* Linked list of mbufs */
    65         struct  mbuf *mh_prev;
    66         struct  mbuf *mh_nextpkt;       /* Next packet in queue/record */
    67         struct  mbuf *mh_prevpkt; /* Flags aren't used in the output queue */
    68         int     mh_flags;         /* Misc flags */
     63struct m_hdr
     64{
     65    struct  mbuf *mh_next;     /* Linked list of mbufs */
     66    struct  mbuf *mh_prev;
     67    struct  mbuf *mh_nextpkt;  /* Next packet in queue/record */
     68    struct  mbuf *mh_prevpkt;  /* Flags aren't used in the output queue */
     69    int     mh_flags;          /* Misc flags */
    6970
    70         int     mh_size;                /* Size of data */
    71         struct  socket *mh_so;
     71    int     mh_size;           /* Size of data */
     72    struct  socket *mh_so;
    7273
    73         caddr_t mh_data;                /* Location of data */
    74         int     mh_len;                 /* Amount of data in this mbuf */
     74    caddr_t mh_data;           /* Location of data */
     75    int     mh_len;            /* Amount of data in this mbuf */
    7576#ifdef VBOX_WITH_BSD_REASS
    76         void *header;                   /*XXX: in real BSD sources this field lays in pkthdr structure*/
     77    void *header;              /*XXX: in real BSD sources this field lays in pkthdr structure*/
    7778#endif
    7879};
     
    9293#define M_TRAILINGSPACE M_FREEROOM
    9394
    94 struct mbuf {
    95         struct  m_hdr m_hdr;
    96         union M_dat {
    97                 char    m_dat_[1]; /* ANSI don't like 0 sized arrays */
    98                 char    *m_ext_;
    99         } M_dat;
     95struct mbuf
     96{
     97    struct  m_hdr m_hdr;
     98    union M_dat
     99    {
     100        char    m_dat_[1]; /* ANSI don't like 0 sized arrays */
     101        char    *m_ext_;
     102    } M_dat;
    100103};
    101104
     
    129132#endif /* VBOX_WITH_BSD_REASS */
    130133
    131 /*
    132  * Mbuf statistics. XXX
    133  */
    134 
    135 struct mbstat {
    136         int mbs_alloced;                /* Number of mbufs allocated */
    137 
    138 };
    139 
    140 extern struct   mbstat mbstat;
    141134extern int mbuf_alloced;
    142135extern struct mbuf m_freelist, m_usedlist;
  • trunk/src/VBox/Devices/Network/slirp/misc.c

    r14638 r14964  
    1111#ifndef HAVE_INET_ATON
    1212int
    13 inet_aton(cp, ia)
    14         const char *cp;
    15         struct in_addr *ia;
     13inet_aton(const char *cp, struct in_addr *ia)
    1614{
    17         u_int32_t addr = inet_addr(cp);
    18         if (addr == 0xffffffff)
    19                 return 0;
    20         ia->s_addr = addr;
    21         return 1;
     15    u_int32_t addr = inet_addr(cp);
     16    if (addr == 0xffffffff)
     17        return 0;
     18    ia->s_addr = addr;
     19    return 1;
    2220}
    2321#endif
     
    2927getouraddr(PNATState pData)
    3028{
    31         our_addr.s_addr = loopback_addr.s_addr;
     29    our_addr.s_addr = loopback_addr.s_addr;
    3230}
    3331
    3432#if SIZEOF_CHAR_P == 8 && !defined(VBOX_WITH_BSD_REASS)
    3533
    36 struct quehead_32 {
    37         u_int32_t qh_link;
    38         u_int32_t qh_rlink;
     34struct quehead_32
     35{
     36    u_int32_t qh_link;
     37    u_int32_t qh_rlink;
    3938};
    4039
     
    4241insque_32(PNATState pData, void *a, void *b)
    4342{
    44         register struct quehead_32 *element = (struct quehead_32 *) a;
    45         register struct quehead_32 *head = (struct quehead_32 *) b;
    46         struct quehead_32 *link = u32_to_ptr(pData, head->qh_link, struct quehead_32 *);
     43    register struct quehead_32 *element = (struct quehead_32 *) a;
     44    register struct quehead_32 *head = (struct quehead_32 *) b;
     45    struct quehead_32 *link = u32_to_ptr(pData, head->qh_link, struct quehead_32 *);
    4746
    48         element->qh_link = head->qh_link;
    49         element->qh_rlink = ptr_to_u32(pData, head);
    50         Assert(link->qh_rlink == element->qh_rlink);
    51         link->qh_rlink = head->qh_link = ptr_to_u32(pData, element);
     47    element->qh_link = head->qh_link;
     48    element->qh_rlink = ptr_to_u32(pData, head);
     49    Assert(link->qh_rlink == element->qh_rlink);
     50    link->qh_rlink = head->qh_link = ptr_to_u32(pData, element);
    5251}
    5352
     
    5554remque_32(PNATState pData, void *a)
    5655{
    57         register struct quehead_32 *element = (struct quehead_32 *) a;
    58         struct quehead_32 *link = u32_to_ptr(pData, element->qh_link, struct quehead_32 *);
    59         struct quehead_32 *rlink = u32_to_ptr(pData, element->qh_rlink, struct quehead_32 *);
     56    register struct quehead_32 *element = (struct quehead_32 *) a;
     57    struct quehead_32 *link = u32_to_ptr(pData, element->qh_link, struct quehead_32 *);
     58    struct quehead_32 *rlink = u32_to_ptr(pData, element->qh_rlink, struct quehead_32 *);
    6059
    61         u32ptr_done(pData, link->qh_rlink, element);
    62         link->qh_rlink = element->qh_rlink;
    63         rlink->qh_link = element->qh_link;
    64         element->qh_rlink = 0;
     60    u32ptr_done(pData, link->qh_rlink, element);
     61    link->qh_rlink = element->qh_rlink;
     62    rlink->qh_link = element->qh_link;
     63    element->qh_rlink = 0;
    6564}
    6665
    6766#endif /* SIZEOF_CHAR_P == 8 && !VBOX_WITH_BSD_REASS */
    6867
    69 struct quehead {
    70         struct quehead *qh_link;
    71         struct quehead *qh_rlink;
     68struct quehead
     69{
     70    struct quehead *qh_link;
     71    struct quehead *qh_rlink;
    7272};
    7373
     
    7575insque(PNATState pData, void *a, void *b)
    7676{
    77         register struct quehead *element = (struct quehead *) a;
    78         register struct quehead *head = (struct quehead *) b;
    79         element->qh_link = head->qh_link;
    80         head->qh_link = (struct quehead *)element;
    81         element->qh_rlink = (struct quehead *)head;
    82         ((struct quehead *)(element->qh_link))->qh_rlink
    83         = (struct quehead *)element;
     77    register struct quehead *element = (struct quehead *) a;
     78    register struct quehead *head = (struct quehead *) b;
     79    element->qh_link = head->qh_link;
     80    head->qh_link = (struct quehead *)element;
     81    element->qh_rlink = (struct quehead *)head;
     82    ((struct quehead *)(element->qh_link))->qh_rlink = (struct quehead *)element;
    8483}
    8584
     
    8786remque(PNATState pData, void *a)
    8887{
    89   register struct quehead *element = (struct quehead *) a;
    90   ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
    91   ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
    92   element->qh_rlink = NULL;
    93   /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
    94 }
    95 
    96 /* #endif */
    97 
    98 
    99 int
    100 add_exec(ex_ptr, do_pty, exec, addr, port)
    101         struct ex_list **ex_ptr;
    102         int do_pty;
    103         char *exec;
    104         int addr;
    105         int port;
    106 {
    107         struct ex_list *tmp_ptr;
    108 
    109         /* First, check if the port is "bound" */
    110         for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
    111                 if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
    112                    return -1;
    113         }
    114 
    115         tmp_ptr = *ex_ptr;
    116         *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
    117         (*ex_ptr)->ex_fport = port;
    118         (*ex_ptr)->ex_addr = addr;
    119         (*ex_ptr)->ex_pty = do_pty;
    120         (*ex_ptr)->ex_exec = strdup(exec);
    121         (*ex_ptr)->ex_next = tmp_ptr;
    122         return 0;
    123 }
    124 
    125 #ifndef HAVE_STRERROR
    126 
    127 /*
    128  * For systems with no strerror
    129  */
    130 
    131 extern int sys_nerr;
    132 extern char *sys_errlist[];
    133 
    134 char *
    135 strerror(error)
    136         int error;
    137 {
    138         if (error < sys_nerr)
    139            return sys_errlist[error];
    140         else
    141            return "Unknown error.";
    142 }
    143 
    144 #endif
    145 
    146 
    147 #ifndef HAVE_STRDUP
    148 char *
    149 strdup(str)
    150         const char *str;
    151 {
    152         char *bptr;
    153 
    154         bptr = (char *)malloc(strlen(str)+1);
    155         strcpy(bptr, str);
    156 
    157         return bptr;
    158 }
    159 #endif
    160 
    161 #ifdef BAD_SPRINTF
    162 
    163 #undef vsprintf
    164 #undef sprintf
    165 
    166 /*
    167  * Some BSD-derived systems have a sprintf which returns char *
    168  */
    169 
    170 int
    171 vsprintf_len(string, format, args)
    172         char *string;
    173         const char *format;
    174         va_list args;
    175 {
    176         vsprintf(string, format, args);
    177         return strlen(string);
     88    register struct quehead *element = (struct quehead *) a;
     89    ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
     90    ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
     91    element->qh_rlink = NULL;
     92    /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
    17893}
    17994
    18095int
    181 #ifdef __STDC__
    182 sprintf_len(char *string, const char *format, ...)
    183 #else
    184 sprintf_len(va_alist) va_dcl
    185 #endif
     96add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port)
    18697{
    187         va_list args;
    188 #ifdef __STDC__
    189         va_start(args, format);
    190 #else
    191         char *string;
    192         char *format;
    193         va_start(args);
    194         string = va_arg(args, char *);
    195         format = va_arg(args, char *);
    196 #endif
    197         vsprintf(string, format, args);
    198         return strlen(string);
     98    struct ex_list *tmp_ptr;
     99
     100    /* First, check if the port is "bound" */
     101    for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next)
     102    {
     103        if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
     104            return -1;
     105    }
     106
     107    tmp_ptr = *ex_ptr;
     108    *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
     109    (*ex_ptr)->ex_fport = port;
     110    (*ex_ptr)->ex_addr = addr;
     111    (*ex_ptr)->ex_pty = do_pty;
     112    (*ex_ptr)->ex_exec = strdup(exec);
     113    (*ex_ptr)->ex_next = tmp_ptr;
     114    return 0;
    199115}
    200116
    201 #endif
    202 
    203 void
    204 u_sleep(usec)
    205         int usec;
    206 {
    207         struct timeval t;
    208         fd_set fdset;
    209 
    210         FD_ZERO(&fdset);
    211 
    212         t.tv_sec = 0;
    213         t.tv_usec = usec * 1000;
    214 
    215         select(0, &fdset, &fdset, &fdset, &t);
    216 }
    217117
    218118/*
    219119 * Set fd blocking and non-blocking
    220120 */
    221 
    222121void
    223 fd_nonblock(fd)
    224         int fd;
     122fd_nonblock(int fd)
    225123{
    226124#ifdef FIONBIO
    227         int opt = 1;
     125    int opt = 1;
    228126
    229         ioctlsocket(fd, FIONBIO, &opt);
     127    ioctlsocket(fd, FIONBIO, &opt);
    230128#else
    231         int opt;
     129    int opt;
    232130
    233         opt = fcntl(fd, F_GETFL, 0);
    234         opt |= O_NONBLOCK;
    235         fcntl(fd, F_SETFL, opt);
     131    opt = fcntl(fd, F_GETFL, 0);
     132    opt |= O_NONBLOCK;
     133    fcntl(fd, F_SETFL, opt);
    236134#endif
    237135}
    238136
    239137void
    240 fd_block(fd)
    241         int fd;
     138fd_block(int fd)
    242139{
    243140#ifdef FIONBIO
    244         int opt = 0;
     141    int opt = 0;
    245142
    246         ioctlsocket(fd, FIONBIO, &opt);
     143    ioctlsocket(fd, FIONBIO, &opt);
    247144#else
    248         int opt;
     145    int opt;
    249146
    250         opt = fcntl(fd, F_GETFL, 0);
    251         opt &= ~O_NONBLOCK;
    252         fcntl(fd, F_SETFL, opt);
     147    opt = fcntl(fd, F_GETFL, 0);
     148    opt &= ~O_NONBLOCK;
     149    fcntl(fd, F_SETFL, opt);
    253150#endif
    254151}
  • trunk/src/VBox/Devices/Network/slirp/misc.h

    r1824 r14964  
    99#define _MISC_H_
    1010
    11 struct ex_list {
    12         int ex_pty;                     /* Do we want a pty? */
    13         int ex_addr;                    /* The last byte of the address */
    14         int ex_fport;                   /* Port to telnet to */
    15         char *ex_exec;                  /* Command line of what to exec */
    16         struct ex_list *ex_next;
     11struct ex_list
     12{
     13    int ex_pty;          /* Do we want a pty? */
     14    int ex_addr;         /* The last byte of the address */
     15    int ex_fport;        /* Port to telnet to */
     16    char *ex_exec;       /* Command line of what to exec */
     17    struct ex_list *ex_next;
    1718};
    1819
    1920extern struct ex_list *exec_list;
    2021
    21 #ifndef HAVE_STRDUP
    22 char *strdup _P((const char *));
    23 #endif
    24 
    25 void do_wait _P((int));
    26 
    27 #define EMU_NONE 0x0
     22#define EMU_NONE      0x0
    2823
    2924/* TCP emulations */
    30 #define EMU_CTL 0x1
    31 #define EMU_FTP 0x2
    32 #define EMU_KSH 0x3
    33 #define EMU_IRC 0x4
     25#define EMU_CTL       0x1
     26#define EMU_FTP       0x2
     27#define EMU_KSH       0x3
     28#define EMU_IRC       0x4
    3429#define EMU_REALAUDIO 0x5
    35 #define EMU_RLOGIN 0x6
    36 #define EMU_IDENT 0x7
    37 #define EMU_RSH 0x8
     30#define EMU_RLOGIN    0x6
     31#define EMU_IDENT     0x7
     32#define EMU_RSH       0x8
    3833
    3934#define EMU_NOCONNECT 0x10      /* Don't connect */
    4035
    4136/* UDP emulations */
    42 #define EMU_TALK        0x1
    43 #define EMU_NTALK       0x2
    44 #define EMU_CUSEEME     0x3
     37#define EMU_TALK      0x1
     38#define EMU_NTALK     0x2
     39#define EMU_CUSEEME   0x3
    4540
    46 struct tos_t {
    47         u_int16_t lport;
    48         u_int16_t fport;
    49         u_int8_t tos;
    50         u_int8_t emu;
     41struct tos_t
     42{
     43    u_int16_t lport;
     44    u_int16_t fport;
     45    u_int8_t tos;
     46    u_int8_t emu;
    5147};
    5248
    53 struct emu_t {
    54         u_int16_t lport;
    55         u_int16_t fport;
    56         u_int8_t tos;
    57         u_int8_t emu;
    58         struct emu_t *next;
     49struct emu_t
     50{
     51    u_int16_t lport;
     52    u_int16_t fport;
     53    u_int8_t tos;
     54    u_int8_t emu;
     55    struct emu_t *next;
    5956};
    6057
     
    7572void relay _P((int));
    7673void add_emu _P((char *));
    77 void u_sleep _P((int));
    7874void fd_nonblock _P((int));
    7975void fd_block _P((int));
    80 int rsh_exec _P((struct socket *, struct socket *, char *, char *, char *));
    8176
    8277#endif
  • trunk/src/VBox/Devices/Network/slirp/sbuf.c

    r14470 r14964  
    1717
    1818void
    19 sbfree(sb)
    20         struct sbuf *sb;
    21 {
    22         free(sb->sb_data);
    23 }
    24 
    25 void
    26 sbdrop(sb, num)
    27         struct sbuf *sb;
    28         int num;
    29 {
    30         /*
    31          * We can only drop how much we have
    32          * This should never succeed
    33          */
    34         if(num > sb->sb_cc)
    35                 num = sb->sb_cc;
    36         sb->sb_cc -= num;
    37         sb->sb_rptr += num;
    38         if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
    39                 sb->sb_rptr -= sb->sb_datalen;
    40 
    41 }
    42 
    43 void
    44 sbreserve(sb, size)
    45         struct sbuf *sb;
    46         int size;
    47 {
    48         if (sb->sb_data) {
    49                 /* Already alloced, realloc if necessary */
    50                 if (sb->sb_datalen != size) {
    51                         sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
    52                         sb->sb_cc = 0;
    53                         if (sb->sb_wptr)
    54                            sb->sb_datalen = size;
    55                         else
    56                            sb->sb_datalen = 0;
    57                 }
    58         } else {
    59                 sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
    60                 sb->sb_cc = 0;
    61                 if (sb->sb_wptr)
    62                    sb->sb_datalen = size;
    63                 else
    64                    sb->sb_datalen = 0;
     19sbfree(struct sbuf *sb)
     20{
     21    free(sb->sb_data);
     22}
     23
     24void
     25sbdrop(struct sbuf *sb, int num)
     26{
     27    /*
     28     * We can only drop how much we have
     29     * This should never succeed
     30     */
     31    if (num > sb->sb_cc)
     32        num = sb->sb_cc;
     33    sb->sb_cc -= num;
     34    sb->sb_rptr += num;
     35    if (sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
     36        sb->sb_rptr -= sb->sb_datalen;
     37
     38}
     39
     40void
     41sbreserve(struct sbuf *sb, int size)
     42{
     43    if (sb->sb_data)
     44    {
     45        /* Already alloced, realloc if necessary */
     46        if (sb->sb_datalen != size)
     47        {
     48            sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
     49            sb->sb_cc = 0;
     50            if (sb->sb_wptr)
     51                sb->sb_datalen = size;
     52            else
     53                sb->sb_datalen = 0;
    6554        }
     55    }
     56    else
     57    {
     58        sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
     59        sb->sb_cc = 0;
     60        if (sb->sb_wptr)
     61            sb->sb_datalen = size;
     62        else
     63            sb->sb_datalen = 0;
     64    }
    6665}
    6766
     
    7574sbappend(PNATState pData, struct socket *so, struct mbuf *m)
    7675{
    77         int ret = 0;
    78 
    79         DEBUG_CALL("sbappend");
    80         DEBUG_ARG("so = %lx", (long)so);
    81         DEBUG_ARG("m = %lx", (long)m);
    82         DEBUG_ARG("m->m_len = %d", m->m_len);
    83 
    84         /* Shouldn't happen, but...  e.g. foreign host closes connection */
    85         if (m->m_len <= 0) {
    86                 m_free(pData, m);
    87                 return;
    88         }
    89 
     76    int ret = 0;
     77
     78    DEBUG_CALL("sbappend");
     79    DEBUG_ARG("so = %lx", (long)so);
     80    DEBUG_ARG("m = %lx", (long)m);
     81    DEBUG_ARG("m->m_len = %d", m->m_len);
     82
     83    /* Shouldn't happen, but...  e.g. foreign host closes connection */
     84    if (m->m_len <= 0)
     85    {
     86        m_free(pData, m);
     87        return;
     88    }
     89
     90    /*
     91     * If there is urgent data, call sosendoob
     92     * if not all was sent, sowrite will take care of the rest
     93     * (The rest of this function is just an optimisation)
     94     */
     95    if (so->so_urgc)
     96    {
     97        sbappendsb(&so->so_rcv, m);
     98        m_free(pData, m);
     99        sosendoob(so);
     100        return;
     101    }
     102
     103    /*
     104     * We only write if there's nothing in the buffer,
     105     * ottherwise it'll arrive out of order, and hence corrupt
     106     */
     107    if (!so->so_rcv.sb_cc)
     108        ret = send(so->s, m->m_data, m->m_len, 0);
     109
     110    if (ret <= 0)
     111    {
    90112        /*
    91          * If there is urgent data, call sosendoob
    92          * if not all was sent, sowrite will take care of the rest
    93          * (The rest of this function is just an optimisation)
     113         * Nothing was written
     114         * It's possible that the socket has closed, but
     115         * we don't need to check because if it has closed,
     116         * it will be detected in the normal way by soread()
    94117         */
    95         if (so->so_urgc) {
    96                 sbappendsb(&so->so_rcv, m);
    97                 m_free(pData, m);
    98                 sosendoob(so);
    99                 return;
    100         }
    101 
     118        sbappendsb(&so->so_rcv, m);
     119    }
     120    else if (ret != m->m_len)
     121    {
    102122        /*
    103          * We only write if there's nothing in the buffer,
    104          * ottherwise it'll arrive out of order, and hence corrupt
     123         * Something was written, but not everything..
     124         * sbappendsb the rest
    105125         */
    106         if (!so->so_rcv.sb_cc)
    107            ret = send(so->s, m->m_data, m->m_len, 0);
    108 
    109         if (ret <= 0) {
    110                 /*
    111                  * Nothing was written
    112                  * It's possible that the socket has closed, but
    113                  * we don't need to check because if it has closed,
    114                  * it will be detected in the normal way by soread()
    115                  */
    116                 sbappendsb(&so->so_rcv, m);
    117         } else if (ret != m->m_len) {
    118                 /*
    119                  * Something was written, but not everything..
    120                  * sbappendsb the rest
    121                  */
    122                 m->m_len -= ret;
    123                 m->m_data += ret;
    124                 sbappendsb(&so->so_rcv, m);
    125         } /* else */
    126         /* Whatever happened, we free the mbuf */
    127         m_free(pData, m);
     126        m->m_len -= ret;
     127        m->m_data += ret;
     128        sbappendsb(&so->so_rcv, m);
     129    } /* else */
     130    /* Whatever happened, we free the mbuf */
     131    m_free(pData, m);
    128132}
    129133
     
    133137 */
    134138void
    135 sbappendsb(sb, m)
    136          struct sbuf *sb;
    137          struct mbuf *m;
    138 {
    139         int len, n,  nn;
    140 
    141         len = m->m_len;
    142 
    143         if (sb->sb_wptr < sb->sb_rptr) {
    144                 n = sb->sb_rptr - sb->sb_wptr;
    145                 if (n > len) n = len;
    146                 memcpy(sb->sb_wptr, m->m_data, n);
    147         } else {
    148                 /* Do the right edge first */
    149                 n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
    150                 if (n > len) n = len;
    151                 memcpy(sb->sb_wptr, m->m_data, n);
    152                 len -= n;
    153                 if (len) {
    154                         /* Now the left edge */
    155                         nn = sb->sb_rptr - sb->sb_data;
    156                         if (nn > len) nn = len;
    157                         memcpy(sb->sb_data,m->m_data+n,nn);
    158                         n += nn;
    159                 }
     139sbappendsb(struct sbuf *sb, struct mbuf *m)
     140{
     141    int len, n,  nn;
     142
     143    len = m->m_len;
     144
     145    if (sb->sb_wptr < sb->sb_rptr)
     146    {
     147        n = sb->sb_rptr - sb->sb_wptr;
     148        if (n > len) n = len;
     149        memcpy(sb->sb_wptr, m->m_data, n);
     150    }
     151    else
     152    {
     153        /* Do the right edge first */
     154        n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
     155        if (n > len) n = len;
     156        memcpy(sb->sb_wptr, m->m_data, n);
     157        len -= n;
     158        if (len)
     159        {
     160            /* Now the left edge */
     161            nn = sb->sb_rptr - sb->sb_data;
     162            if (nn > len)
     163                nn = len;
     164            memcpy(sb->sb_data,m->m_data+n,nn);
     165            n += nn;
    160166        }
    161 
    162         sb->sb_cc += n;
    163         sb->sb_wptr += n;
    164         if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
    165                 sb->sb_wptr -= sb->sb_datalen;
     167    }
     168
     169    sb->sb_cc += n;
     170    sb->sb_wptr += n;
     171    if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
     172        sb->sb_wptr -= sb->sb_datalen;
    166173}
    167174
     
    172179 */
    173180void
    174 sbcopy(sb, off, len, to)
    175         struct sbuf *sb;
    176         int off;
    177         int len;
    178         char *to;
    179 {
    180         char *from;
    181 
    182         from = sb->sb_rptr + off;
    183         if (from >= sb->sb_data + sb->sb_datalen)
    184                 from -= sb->sb_datalen;
    185 
    186         if (from < sb->sb_wptr) {
    187                 if (len > sb->sb_cc) len = sb->sb_cc;
    188                 memcpy(to,from,len);
    189         } else {
    190                 /* re-use off */
    191                 off = (sb->sb_data + sb->sb_datalen) - from;
    192                 if (off > len) off = len;
    193                 memcpy(to,from,off);
    194                 len -= off;
    195                 if (len)
    196                    memcpy(to+off,sb->sb_data,len);
    197         }
    198 }
    199 
     181sbcopy(struct sbuf *sb, int off, int len, char *to)
     182{
     183    char *from;
     184
     185    from = sb->sb_rptr + off;
     186    if (from >= sb->sb_data + sb->sb_datalen)
     187        from -= sb->sb_datalen;
     188
     189    if (from < sb->sb_wptr)
     190    {
     191        if (len > sb->sb_cc) len = sb->sb_cc;
     192        memcpy(to,from,len);
     193    }
     194    else
     195    {
     196        /* re-use off */
     197        off = (sb->sb_data + sb->sb_datalen) - from;
     198        if (off > len) off = len;
     199        memcpy(to,from,off);
     200        len -= off;
     201        if (len)
     202            memcpy(to+off,sb->sb_data,len);
     203    }
     204}
     205
  • trunk/src/VBox/Devices/Network/slirp/sbuf.h

    r14470 r14964  
    1212#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
    1313
    14 struct sbuf {
    15         u_int   sb_cc;          /* actual chars in buffer */
    16         u_int   sb_datalen;     /* Length of data  */
    17         char    *sb_wptr;       /* write pointer. points to where the next
    18                                  * bytes should be written in the sbuf */
    19         char    *sb_rptr;       /* read pointer. points to where the next
    20                                  * byte should be read from the sbuf */
    21         char    *sb_data;       /* Actual data */
     14struct sbuf
     15{
     16    u_int   sb_cc;          /* actual chars in buffer */
     17    u_int   sb_datalen;     /* Length of data  */
     18    char    *sb_wptr;       /* write pointer. points to where the next
     19                             * bytes should be written in the sbuf */
     20    char    *sb_rptr;       /* read pointer. points to where the next
     21                             * byte should be read from the sbuf */
     22    char    *sb_data;       /* Actual data */
    2223};
    2324
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r14951 r14964  
    10551055            return 2;
    10561056        if (do_slowtimo)
    1057             return 500;
     1057            return 500; /* see PR_SLOWHZ */
    10581058    }
    10591059    return 0;
  • trunk/src/VBox/Devices/Network/slirp/slirp.h

    r14951 r14964  
    260260void if_start _P((PNATState));
    261261
    262 #ifdef BAD_SPRINTF
    263 # define vsprintf vsprintf_len
    264 # define sprintf sprintf_len
    265  extern int vsprintf_len _P((char *, const char *, va_list));
    266  extern int sprintf_len _P((char *, const char *, ...));
    267 #endif
    268 
    269 #ifdef DECLARE_SPRINTF
    270 # ifndef BAD_SPRINTF
    271  extern int vsprintf _P((char *, const char *, va_list));
    272 # endif
    273  extern int vfprintf _P((FILE *, const char *, va_list));
    274 #endif
    275 
    276 #ifndef HAVE_STRERROR
    277  extern char *strerror _P((int error));
    278 #endif
    279 
    280262#ifndef HAVE_INDEX
    281263 char *index _P((const char *, int));
  • trunk/src/VBox/Devices/Network/slirp/slirp_config.h

    r14951 r14964  
    7777#endif
    7878
    79 /* Define if you have strerror */
    80 #define HAVE_STRERROR
    81 
    82 /* Define if you have strdup() */
    83 #define HAVE_STRDUP
    84 
    8579/* Define according to how time.h should be included */
    8680#define TIME_WITH_SYS_TIME 0
     
    9286/* Define if the machine is big endian */
    9387/*#undef WORDS_BIGENDIAN */
    94 
    95 /* Define if your sprintf returns char * instead of int */
    96 #undef BAD_SPRINTF
    9788
    9889/* Define if you have readv */
     
    10495# define DECLARE_IOVEC
    10596#endif
    106 
    107 /* Define if a declaration of sprintf/fprintf is needed */
    108 #undef DECLARE_SPRINTF
    10997
    11098/* Define if you have a POSIX.1 sys/wait.h */
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r14951 r14964  
    1717so_init()
    1818{
    19         /* Nothing yet */
    2019}
    2120
    2221
    2322struct socket *
    24 solookup(head, laddr, lport, faddr, fport)
    25         struct socket *head;
    26         struct in_addr laddr;
    27         u_int lport;
    28         struct in_addr faddr;
    29         u_int fport;
    30 {
    31         struct socket *so;
    32 
    33         for (so = head->so_next; so != head; so = so->so_next) {
    34                 if (so->so_lport == lport &&
    35                     so->so_laddr.s_addr == laddr.s_addr &&
    36                     so->so_faddr.s_addr == faddr.s_addr &&
    37                     so->so_fport == fport)
    38                    break;
    39         }
    40 
    41         if (so == head)
    42            return (struct socket *)NULL;
    43         return so;
    44 
     23solookup(struct socket *head, struct in_addr laddr,
     24         u_int lport, struct in_addr faddr, u_int fport)
     25{
     26    struct socket *so;
     27
     28    for (so = head->so_next; so != head; so = so->so_next)
     29    {
     30        if (   so->so_lport        == lport
     31            && so->so_laddr.s_addr == laddr.s_addr
     32            && so->so_faddr.s_addr == faddr.s_addr
     33            && so->so_fport        == fport)
     34            return so;
     35    }
     36
     37    return (struct socket *)NULL;
    4538}
    4639
     
    5346socreate()
    5447{
    55   struct socket *so;
    56 
    57   so = (struct socket *)malloc(sizeof(struct socket));
    58   if(so) {
    59     memset(so, 0, sizeof(struct socket));
    60     so->so_state = SS_NOFDREF;
    61     so->s = -1;
    62   }
    63   return(so);
     48    struct socket *so;
     49
     50    so = (struct socket *)malloc(sizeof(struct socket));
     51    if(so)
     52    {
     53        memset(so, 0, sizeof(struct socket));
     54        so->so_state = SS_NOFDREF;
     55        so->s = -1;
     56    }
     57    return so;
    6458}
    6559
     
    7064sofree(PNATState pData, struct socket *so)
    7165{
    72   if (so->so_emu==EMU_RSH && so->extra) {
    73         sofree(pData, so->extra);
    74         so->extra=NULL;
    75   }
    76   if (so == tcp_last_so)
    77     tcp_last_so = &tcb;
    78   else if (so == udp_last_so)
    79     udp_last_so = &udb;
    80 
    81   m_free(pData, so->so_m);
    82 
    83 
    84   if(so->so_next && so->so_prev)
    85     remque(pData, so);  /* crashes if so is not in a queue */
    86 
    87   free(so);
     66    if (so == tcp_last_so)
     67        tcp_last_so = &tcb;
     68    else if (so == udp_last_so)
     69        udp_last_so = &udb;
     70
     71    m_free(pData, so->so_m);
     72
     73    if(so->so_next && so->so_prev)
     74        remque(pData, so);  /* crashes if so is not in a queue */
     75
     76    free(so);
    8877}
    8978
     
    9685soread(PNATState pData, struct socket *so)
    9786{
    98         int n, nn, lss, total;
    99         struct sbuf *sb = &so->so_snd;
    100         int len = sb->sb_datalen - sb->sb_cc;
    101         struct iovec iov[2];
    102         int mss = so->so_tcpcb->t_maxseg;
    103 
    104         DEBUG_CALL("soread");
    105         DEBUG_ARG("so = %lx", (long )so);
    106 
     87    int n, nn, lss, total;
     88    struct sbuf *sb = &so->so_snd;
     89    int len = sb->sb_datalen - sb->sb_cc;
     90    struct iovec iov[2];
     91    int mss = so->so_tcpcb->t_maxseg;
     92
     93    DEBUG_CALL("soread");
     94    DEBUG_ARG("so = %lx", (long )so);
     95
     96    /*
     97     * No need to check if there's enough room to read.
     98     * soread wouldn't have been called if there weren't
     99     */
     100
     101    len = sb->sb_datalen - sb->sb_cc;
     102
     103    iov[0].iov_base = sb->sb_wptr;
     104    iov[1].iov_base = 0;
     105    iov[1].iov_len  = 0;
     106    if (sb->sb_wptr < sb->sb_rptr)
     107    {
     108        iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
     109        /* Should never succeed, but... */
     110        if (iov[0].iov_len > len)
     111            iov[0].iov_len = len;
     112        if (iov[0].iov_len > mss)
     113            iov[0].iov_len -= iov[0].iov_len%mss;
     114        n = 1;
     115    }
     116    else
     117    {
     118        iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
     119        /* Should never succeed, but... */
     120        if (iov[0].iov_len > len) iov[0].iov_len = len;
     121        len -= iov[0].iov_len;
     122        if (len)
     123        {
     124            iov[1].iov_base = sb->sb_data;
     125            iov[1].iov_len = sb->sb_rptr - sb->sb_data;
     126            if(iov[1].iov_len > len)
     127                iov[1].iov_len = len;
     128            total = iov[0].iov_len + iov[1].iov_len;
     129            if (total > mss)
     130            {
     131                lss = total % mss;
     132                if (iov[1].iov_len > lss)
     133                {
     134                    iov[1].iov_len -= lss;
     135                    n = 2;
     136                }
     137                else
     138                {
     139                    lss -= iov[1].iov_len;
     140                    iov[0].iov_len -= lss;
     141                    n = 1;
     142                }
     143            }
     144            else
     145                n = 2;
     146        }
     147        else
     148        {
     149            if (iov[0].iov_len > mss)
     150                iov[0].iov_len -= iov[0].iov_len%mss;
     151            n = 1;
     152        }
     153    }
     154
     155#ifdef HAVE_READV
     156    nn = readv(so->s, (struct iovec *)iov, n);
     157    DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
     158#else
     159    nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
     160#endif
     161    if (nn <= 0)
     162    {
     163#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
    107164        /*
    108          * No need to check if there's enough room to read.
    109          * soread wouldn't have been called if there weren't
     165         * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that
     166         * _could_ mean that the connection is closed. But we will receive an
     167         * FD_CLOSE event later if the connection was _really_ closed. With
     168         * www.youtube.com I see this very often. Closing the socket too early
     169         * would be dangerous.
    110170         */
    111 
    112         len = sb->sb_datalen - sb->sb_cc;
    113 
    114         iov[0].iov_base = sb->sb_wptr;
    115         iov[1].iov_base = 0;
    116         iov[1].iov_len  = 0;
    117         if (sb->sb_wptr < sb->sb_rptr) {
    118                 iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
    119                 /* Should never succeed, but... */
    120                 if (iov[0].iov_len > len)
    121                    iov[0].iov_len = len;
    122                 if (iov[0].iov_len > mss)
    123                    iov[0].iov_len -= iov[0].iov_len%mss;
    124                 n = 1;
    125         } else {
    126                 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
    127                 /* Should never succeed, but... */
    128                 if (iov[0].iov_len > len) iov[0].iov_len = len;
    129                 len -= iov[0].iov_len;
    130                 if (len) {
    131                         iov[1].iov_base = sb->sb_data;
    132                         iov[1].iov_len = sb->sb_rptr - sb->sb_data;
    133                         if(iov[1].iov_len > len)
    134                            iov[1].iov_len = len;
    135                         total = iov[0].iov_len + iov[1].iov_len;
    136                         if (total > mss) {
    137                                 lss = total%mss;
    138                                 if (iov[1].iov_len > lss) {
    139                                         iov[1].iov_len -= lss;
    140                                         n = 2;
    141                                 } else {
    142                                         lss -= iov[1].iov_len;
    143                                         iov[0].iov_len -= lss;
    144                                         n = 1;
    145                                 }
    146                         } else
    147                                 n = 2;
    148                 } else {
    149                         if (iov[0].iov_len > mss)
    150                            iov[0].iov_len -= iov[0].iov_len%mss;
    151                         n = 1;
    152                 }
    153         }
    154 
    155 #ifdef HAVE_READV
    156         nn = readv(so->s, (struct iovec *)iov, n);
    157         DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
    158 #else
    159         nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
    160 #endif
    161         if (nn <= 0) {
    162 #if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
    163             /*
    164              * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that
    165              * _could_ mean that the connection is closed. But we will receive an
    166              * FD_CLOSE event later if the connection was _really_ closed. With
    167              * www.youtube.com I see this very often. Closing the socket too early
    168              * would be dangerous.
    169              */
    170                 if (nn == 0)
    171                         return 0;
    172 #endif
    173                 if (nn < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
    174                         return 0;
    175                 else {
    176                         /* nn == 0 means peer has performed an orderly shutdown */
    177                         DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
    178                         sofcantrcvmore(so);
    179                         tcp_sockclosed(pData, sototcpcb(so));
    180                         return -1;
    181                 }
    182         }
     171        if (nn == 0)
     172            return 0;
     173#endif
     174        if (nn < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
     175            return 0;
     176        else
     177        {
     178            /* nn == 0 means peer has performed an orderly shutdown */
     179            DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n",
     180                        nn, errno,strerror(errno)));
     181            sofcantrcvmore(so);
     182            tcp_sockclosed(pData, sototcpcb(so));
     183            return -1;
     184        }
     185    }
    183186
    184187#ifndef HAVE_READV
    185         /*
    186          * If there was no error, try and read the second time round
    187          * We read again if n = 2 (ie, there's another part of the buffer)
    188          * and we read as much as we could in the first read
    189          * We don't test for <= 0 this time, because there legitimately
    190          * might not be any more data (since the socket is non-blocking),
    191          * a close will be detected on next iteration.
    192          * A return of -1 wont (shouldn't) happen, since it didn't happen above
    193          */
    194         if (n == 2 && nn == iov[0].iov_len) {
    195             int ret;
    196             ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
    197             if (ret > 0)
    198                 nn += ret;
    199         }
    200 
    201         DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
    202 #endif
    203 
    204         /* Update fields */
    205         sb->sb_cc += nn;
    206         sb->sb_wptr += nn;
    207         if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
    208                 sb->sb_wptr -= sb->sb_datalen;
    209         return nn;
     188    /*
     189     * If there was no error, try and read the second time round
     190     * We read again if n = 2 (ie, there's another part of the buffer)
     191     * and we read as much as we could in the first read
     192     * We don't test for <= 0 this time, because there legitimately
     193     * might not be any more data (since the socket is non-blocking),
     194     * a close will be detected on next iteration.
     195     * A return of -1 wont (shouldn't) happen, since it didn't happen above
     196     */
     197    if (n == 2 && nn == iov[0].iov_len)
     198    {
     199        int ret;
     200        ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
     201        if (ret > 0)
     202            nn += ret;
     203    }
     204
     205    DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
     206#endif
     207
     208    /* Update fields */
     209    sb->sb_cc += nn;
     210    sb->sb_wptr += nn;
     211    if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
     212        sb->sb_wptr -= sb->sb_datalen;
     213    return nn;
    210214}
    211215
     
    220224sorecvoob(PNATState pData, struct socket *so)
    221225{
    222         struct tcpcb *tp = sototcpcb(so);
    223 
    224         DEBUG_CALL("sorecvoob");
    225         DEBUG_ARG("so = %lx", (long)so);
    226 
    227         /*
    228          * We take a guess at how much urgent data has arrived.
    229          * In most situations, when urgent data arrives, the next
    230          * read() should get all the urgent data.  This guess will
    231          * be wrong however if more data arrives just after the
    232          * urgent data, or the read() doesn't return all the
    233          * urgent data.
    234          */
    235         soread(pData, so);
    236         tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
    237         tp->t_force = 1;
    238         tcp_output(pData, tp);
    239         tp->t_force = 0;
     226    struct tcpcb *tp = sototcpcb(so);
     227
     228    DEBUG_CALL("sorecvoob");
     229    DEBUG_ARG("so = %lx", (long)so);
     230
     231    /*
     232     * We take a guess at how much urgent data has arrived.
     233     * In most situations, when urgent data arrives, the next
     234     * read() should get all the urgent data.  This guess will
     235     * be wrong however if more data arrives just after the
     236     * urgent data, or the read() doesn't return all the
     237     * urgent data.
     238     */
     239    soread(pData, so);
     240    tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
     241    tp->t_force = 1;
     242    tcp_output(pData, tp);
     243    tp->t_force = 0;
    240244}
    241245
     
    245249 */
    246250int
    247 sosendoob(so)
    248         struct socket *so;
    249 {
    250         struct sbuf *sb = &so->so_rcv;
    251         char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
    252 
    253         int n, len;
    254 
    255         DEBUG_CALL("sosendoob");
    256         DEBUG_ARG("so = %lx", (long)so);
    257         DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
    258 
    259         if (so->so_urgc > 2048)
    260            so->so_urgc = 2048; /* XXXX */
    261 
    262         if (sb->sb_rptr < sb->sb_wptr) {
    263                 /* We can send it directly */
    264                 n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
    265                 so->so_urgc -= n;
    266 
    267                 DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
    268         } else {
    269                 /*
    270                  * Since there's no sendv or sendtov like writev,
    271                  * we must copy all data to a linear buffer then
    272                  * send it all
    273                  */
    274                 len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
    275                 if (len > so->so_urgc) len = so->so_urgc;
    276                 memcpy(buff, sb->sb_rptr, len);
    277                 so->so_urgc -= len;
    278                 if (so->so_urgc) {
    279                         n = sb->sb_wptr - sb->sb_data;
    280                         if (n > so->so_urgc) n = so->so_urgc;
    281                         memcpy((buff + len), sb->sb_data, n);
    282                         so->so_urgc -= n;
    283                         len += n;
    284                 }
    285                 n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
     251sosendoob(struct socket *so)
     252{
     253    struct sbuf *sb = &so->so_rcv;
     254    char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
     255
     256    int n, len;
     257
     258    DEBUG_CALL("sosendoob");
     259    DEBUG_ARG("so = %lx", (long)so);
     260    DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
     261
     262    if (so->so_urgc > sizeof(buff))
     263        so->so_urgc = sizeof(buff); /* XXX */
     264
     265    if (sb->sb_rptr < sb->sb_wptr)
     266    {
     267        /* We can send it directly */
     268        n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
     269        so->so_urgc -= n;
     270
     271        DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n",
     272                    n, so->so_urgc));
     273    }
     274    else
     275    {
     276        /*
     277         * Since there's no sendv or sendtov like writev,
     278         * we must copy all data to a linear buffer then
     279         * send it all
     280         */
     281        len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
     282        if (len > so->so_urgc) len = so->so_urgc;
     283        memcpy(buff, sb->sb_rptr, len);
     284        so->so_urgc -= len;
     285        if (so->so_urgc)
     286        {
     287            n = sb->sb_wptr - sb->sb_data;
     288            if (n > so->so_urgc)
     289                n = so->so_urgc;
     290            memcpy(buff + len, sb->sb_data, n);
     291            so->so_urgc -= n;
     292            len += n;
     293        }
     294        n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
    286295#ifdef DEBUG
    287                 if (n != len)
    288                    DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
    289 #endif
    290                 DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
    291         }
    292 
    293         sb->sb_cc -= n;
    294         sb->sb_rptr += n;
    295         if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
    296                 sb->sb_rptr -= sb->sb_datalen;
    297 
    298         return n;
     296        if (n != len)
     297            DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
     298#endif
     299        DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n",
     300                    n, so->so_urgc));
     301    }
     302
     303    sb->sb_cc -= n;
     304    sb->sb_rptr += n;
     305    if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
     306        sb->sb_rptr -= sb->sb_datalen;
     307
     308    return n;
    299309}
    300310
     
    306316sowrite(PNATState pData, struct socket *so)
    307317{
    308         int  n,nn;
    309         struct sbuf *sb = &so->so_rcv;
    310         int len = sb->sb_cc;
    311         struct iovec iov[2];
    312 
    313         DEBUG_CALL("sowrite");
    314         DEBUG_ARG("so = %lx", (long)so);
    315 
    316         if (so->so_urgc) {
    317                 sosendoob(so);
    318                 if (sb->sb_cc == 0)
    319                         return 0;
    320         }
    321 
    322         /*
    323          * No need to check if there's something to write,
    324          * sowrite wouldn't have been called otherwise
    325          */
    326 
    327         len = sb->sb_cc;
    328 
    329         iov[0].iov_base = sb->sb_rptr;
    330         iov[1].iov_base = 0;
    331         iov[1].iov_len  = 0;
    332         if (sb->sb_rptr < sb->sb_wptr) {
    333                 iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
    334                 /* Should never succeed, but... */
    335                 if (iov[0].iov_len > len) iov[0].iov_len = len;
    336                 n = 1;
    337         } else {
    338                 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
    339                 if (iov[0].iov_len > len) iov[0].iov_len = len;
    340                 len -= iov[0].iov_len;
    341                 if (len) {
    342                         iov[1].iov_base = sb->sb_data;
    343                         iov[1].iov_len = sb->sb_wptr - sb->sb_data;
    344                         if (iov[1].iov_len > len) iov[1].iov_len = len;
    345                         n = 2;
    346                 } else
    347                         n = 1;
    348         }
    349         /* Check if there's urgent data to send, and if so, send it */
    350 
     318    int  n,nn;
     319    struct sbuf *sb = &so->so_rcv;
     320    int len = sb->sb_cc;
     321    struct iovec iov[2];
     322
     323    DEBUG_CALL("sowrite");
     324    DEBUG_ARG("so = %lx", (long)so);
     325
     326    if (so->so_urgc)
     327    {
     328        sosendoob(so);
     329        if (sb->sb_cc == 0)
     330            return 0;
     331    }
     332
     333    /*
     334     * No need to check if there's something to write,
     335     * sowrite wouldn't have been called otherwise
     336     */
     337
     338    len = sb->sb_cc;
     339
     340    iov[0].iov_base = sb->sb_rptr;
     341    iov[1].iov_base = 0;
     342    iov[1].iov_len  = 0;
     343    if (sb->sb_rptr < sb->sb_wptr)
     344    {
     345        iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
     346        /* Should never succeed, but... */
     347        if (iov[0].iov_len > len) iov[0].iov_len = len;
     348        n = 1;
     349    }
     350    else
     351    {
     352        iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
     353        if (iov[0].iov_len > len) iov[0].iov_len = len;
     354        len -= iov[0].iov_len;
     355        if (len)
     356        {
     357            iov[1].iov_base = sb->sb_data;
     358            iov[1].iov_len = sb->sb_wptr - sb->sb_data;
     359            if (iov[1].iov_len > len)
     360                iov[1].iov_len = len;
     361            n = 2;
     362        }
     363        else
     364            n = 1;
     365    }
     366    /* Check if there's urgent data to send, and if so, send it */
    351367#ifdef HAVE_READV
    352         nn = writev(so->s, (const struct iovec *)iov, n);
    353 
    354         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
     368    nn = writev(so->s, (const struct iovec *)iov, n);
     369    DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
    355370#else
    356         nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
    357 #endif
    358         /* This should never happen, but people tell me it does *shrug* */
    359         if (nn < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
    360                 return 0;
    361 
    362         if (nn < 0 || (nn == 0 && iov[0].iov_len > 0)) {
    363                 DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
    364                         so->so_state, errno));
    365                 sofcantsendmore(so);
    366                 tcp_sockclosed(pData, sototcpcb(so));
    367                 return -1;
    368         }
     371    nn = send(so->s, iov[0].iov_base, iov[0].iov_len, 0);
     372#endif
     373    /* This should never happen, but people tell me it does *shrug* */
     374    if (nn < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
     375        return 0;
     376
     377    if (nn < 0 || (nn == 0 && iov[0].iov_len > 0))
     378    {
     379        DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
     380                   so->so_state, errno));
     381        sofcantsendmore(so);
     382        tcp_sockclosed(pData, sototcpcb(so));
     383        return -1;
     384    }
    369385
    370386#ifndef HAVE_READV
    371         if (n == 2 && nn == iov[0].iov_len) {
    372             int ret;
    373             ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
    374             if (ret > 0)
    375                 nn += ret;
    376         }
    377         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
    378 #endif
    379 
    380         /* Update sbuf */
    381         sb->sb_cc -= nn;
    382         sb->sb_rptr += nn;
    383         if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
    384                 sb->sb_rptr -= sb->sb_datalen;
    385 
    386         /*
    387          * If in DRAIN mode, and there's no more data, set
    388          * it CANTSENDMORE
    389          */
    390         if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
    391                 sofcantsendmore(so);
    392 
    393         return nn;
     387    if (n == 2 && nn == iov[0].iov_len)
     388    {
     389        int ret;
     390        ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
     391        if (ret > 0)
     392            nn += ret;
     393    }
     394    DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
     395#endif
     396
     397    /* Update sbuf */
     398    sb->sb_cc -= nn;
     399    sb->sb_rptr += nn;
     400    if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
     401        sb->sb_rptr -= sb->sb_datalen;
     402
     403    /*
     404     * If in DRAIN mode, and there's no more data, set
     405     * it CANTSENDMORE
     406     */
     407    if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
     408        sofcantsendmore(so);
     409
     410    return nn;
    394411}
    395412
     
    400417sorecvfrom(PNATState pData, struct socket *so)
    401418{
    402         struct sockaddr_in addr;
    403         socklen_t addrlen = sizeof(struct sockaddr_in);
    404 
    405         DEBUG_CALL("sorecvfrom");
    406         DEBUG_ARG("so = %lx", (long)so);
    407 
    408         if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
    409           char buff[256];
    410           int len;
    411 
    412           len = recvfrom(so->s, buff, 256, 0,
    413                          (struct sockaddr *)&addr, &addrlen);
    414           /* XXX Check if reply is "correct"? */
    415 
    416           if(len == -1 || len == 0) {
    417             u_char code=ICMP_UNREACH_PORT;
    418 
    419             if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
    420             else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
     419    struct sockaddr_in addr;
     420    socklen_t addrlen = sizeof(struct sockaddr_in);
     421
     422    DEBUG_CALL("sorecvfrom");
     423    DEBUG_ARG("so = %lx", (long)so);
     424
     425    if (so->so_type == IPPROTO_ICMP)
     426    {
     427        /* This is a "ping" reply */
     428        char buff[256];
     429        int len;
     430
     431        len = recvfrom(so->s, buff, sizeof(buff), 0,
     432                       (struct sockaddr *)&addr, &addrlen);
     433        /* XXX Check if reply is "correct"? */
     434
     435        if(len == -1 || len == 0)
     436        {
     437            u_char code = ICMP_UNREACH_PORT;
     438
     439            if (errno == EHOSTUNREACH)
     440                code=ICMP_UNREACH_HOST;
     441            else if(errno == ENETUNREACH)
     442                code=ICMP_UNREACH_NET;
    421443
    422444            DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
    423445                        errno,strerror(errno)));
    424446            icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
    425           } else {
     447        }
     448        else
     449        {
    426450#ifdef VBOX_WITH_SLIRP_ICMP
    427451            struct ip *ip;
     
    439463            icmp_reflect(pData, so->so_m);
    440464            so->so_m = 0; /* Don't m_free() it again! */
    441           }
    442           /* No need for this socket anymore, udp_detach it */
    443           udp_detach(pData, so);
    444         } else {                                /* A "normal" UDP packet */
    445           struct mbuf *m;
    446           int len, n;
    447 
    448           if (!(m = m_get(pData))) return;
    449           m->m_data += if_maxlinkhdr;
    450 
    451           /*
    452            * XXX Shouldn't FIONREAD packets destined for port 53,
    453            * but I don't know the max packet size for DNS lookups
    454            */
    455           len = M_FREEROOM(m);
    456           /* if (so->so_fport != htons(53)) { */
    457           ioctlsocket(so->s, FIONREAD, &n);
    458 
    459           if (n > len) {
    460             n = (m->m_data - m->m_dat) + m->m_len + n + 1;
    461             m_inc(m, n);
    462             len = M_FREEROOM(m);
    463           }
    464           /* } */
    465 
    466           m->m_len = recvfrom(so->s, m->m_data, len, 0,
    467                               (struct sockaddr *)&addr, &addrlen);
    468           DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
    469                       m->m_len, errno,strerror(errno)));
    470           if(m->m_len<0) {
     465        }
     466        /* No need for this socket anymore, udp_detach it */
     467        udp_detach(pData, so);
     468    }
     469    else
     470    {
     471        /* A "normal" UDP packet */
     472        struct mbuf *m;
     473        int len, n;
     474
     475        if (!(m = m_get(pData)))
     476            return;
     477        m->m_data += if_maxlinkhdr;
     478
     479        /*
     480         * XXX Shouldn't FIONREAD packets destined for port 53,
     481         * but I don't know the max packet size for DNS lookups
     482         */
     483        len = M_FREEROOM(m);
     484        /* if (so->so_fport != htons(53)) */
     485        {
     486            ioctlsocket(so->s, FIONREAD, &n);
     487
     488            if (n > len)
     489            {
     490                n = (m->m_data - m->m_dat) + m->m_len + n + 1;
     491                m_inc(m, n);
     492                len = M_FREEROOM(m);
     493            }
     494        }
     495
     496        m->m_len = recvfrom(so->s, m->m_data, len, 0,
     497                            (struct sockaddr *)&addr, &addrlen);
     498        DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
     499                    m->m_len, errno,strerror(errno)));
     500        if(m->m_len < 0)
     501        {
    471502            u_char code=ICMP_UNREACH_PORT;
    472503
    473             if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
    474             else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
     504            if (errno == EHOSTUNREACH)
     505                code=ICMP_UNREACH_HOST;
     506            else if(errno == ENETUNREACH)
     507                code=ICMP_UNREACH_NET;
    475508
    476509            DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
    477510            icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
    478511            m_free(pData, m);
    479           } else {
    480           /*
    481            * Hack: domain name lookup will be used the most for UDP,
    482            * and since they'll only be used once there's no need
    483            * for the 4 minute (or whatever) timeout... So we time them
    484            * out much quicker (10 seconds  for now...)
    485            */
    486             if (so->so_expire) {
    487               if (so->so_fport == htons(53))
    488                 so->so_expire = curtime + SO_EXPIREFAST;
    489               else
    490                 so->so_expire = curtime + SO_EXPIRE;
     512        }
     513        else
     514        {
     515            /*
     516             * Hack: domain name lookup will be used the most for UDP,
     517             * and since they'll only be used once there's no need
     518             * for the 4 minute (or whatever) timeout... So we time them
     519             * out much quicker (10 seconds  for now...)
     520             */
     521            if (so->so_expire)
     522            {
     523                if (so->so_fport == htons(53))
     524                    so->so_expire = curtime + SO_EXPIREFAST;
     525                else
     526                    so->so_expire = curtime + SO_EXPIRE;
    491527            }
    492528
    493             /*          if (m->m_len == len) {
    494              *                  m_inc(m, MINCSIZE);
    495              *                  m->m_len = 0;
    496              *          }
    497              */
     529#if 0
     530            if (m->m_len == len)
     531            {
     532                m_inc(m, MINCSIZE);
     533                m->m_len = 0;
     534            }
     535#endif           
    498536
    499537            /*
     
    502540             */
    503541            udp_output(pData, so, m, &addr);
    504           } /* rx error */
    505         } /* if ping packet */
     542        } /* rx error */
     543    } /* if ping packet */
    506544}
    507545
     
    512550sosendto(PNATState pData, struct socket *so, struct mbuf *m)
    513551{
    514         int ret;
    515         struct sockaddr_in addr;
     552    int ret;
     553    struct sockaddr_in addr;
    516554#if 0
    517         struct sockaddr_in host_addr;
    518 #endif
    519 
    520         DEBUG_CALL("sosendto");
    521         DEBUG_ARG("so = %lx", (long)so);
    522         DEBUG_ARG("m = %lx", (long)m);
    523 
    524         addr.sin_family = AF_INET;
    525         if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr) {
    526           /* It's an alias */
    527           uint32_t last_byte = ntohl(so->so_faddr.s_addr) & ~pData->netmask;
    528           switch(last_byte) {
     555    struct sockaddr_in host_addr;
     556#endif
     557
     558    DEBUG_CALL("sosendto");
     559    DEBUG_ARG("so = %lx", (long)so);
     560    DEBUG_ARG("m = %lx", (long)m);
     561
     562    addr.sin_family = AF_INET;
     563    if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr)
     564    {
     565        /* It's an alias */
     566        uint32_t last_byte = ntohl(so->so_faddr.s_addr) & ~pData->netmask;
     567        switch(last_byte)
     568        {
    529569#if 0
    530           /* handle this case at 'default:' */
    531           case CTL_BROADCAST:
    532             addr.sin_addr.s_addr = INADDR_BROADCAST;
    533 # if 0
    534             /* Send the packet to host to fully emulate broadcast */
    535             /** @todo r=klaus: on Linux host this causes the host to receive
    536              * the packet twice for some reason. And I cannot find any place
    537              * in the man pages which states that sending a broadcast does not
    538              * reach the host itself. */
    539             host_addr.sin_family = AF_INET;
    540             host_addr.sin_port = so->so_fport;
    541             host_addr.sin_addr = our_addr;
    542             sendto(so->s, m->m_data, m->m_len, 0,
    543                   (struct sockaddr *)&host_addr, sizeof (struct sockaddr));
    544 # endif
    545             break;
    546 #endif
    547           case CTL_DNS:
    548             if (!get_dns_addr(pData, &dns_addr))
    549                 addr.sin_addr = dns_addr;
    550             else
    551                 addr.sin_addr = loopback_addr;
    552             break;
    553           case CTL_ALIAS:
    554           default:
    555             if (last_byte == ~pData->netmask)
    556               addr.sin_addr.s_addr = INADDR_BROADCAST;
    557             else
    558               addr.sin_addr = loopback_addr;
    559             break;
    560           }
    561         } else
    562           addr.sin_addr = so->so_faddr;
    563         addr.sin_port = so->so_fport;
    564 
    565         DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
    566 
    567         /* Don't care what port we get */
    568         ret = sendto(so->s, m->m_data, m->m_len, 0,
    569                      (struct sockaddr *)&addr, sizeof (struct sockaddr));
    570         if (ret < 0)
    571                 return -1;
    572 
    573         /*
    574          * Kill the socket if there's no reply in 4 minutes,
    575          * but only if it's an expirable socket
    576          */
    577         if (so->so_expire)
    578                 so->so_expire = curtime + SO_EXPIRE;
    579         so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
    580         return 0;
     570            /* handle this case at 'default:' */
     571            case CTL_BROADCAST:
     572                addr.sin_addr.s_addr = INADDR_BROADCAST;
     573                /* Send the packet to host to fully emulate broadcast */
     574                /** @todo r=klaus: on Linux host this causes the host to receive
     575                 * the packet twice for some reason. And I cannot find any place
     576                 * in the man pages which states that sending a broadcast does not
     577                 * reach the host itself. */
     578                host_addr.sin_family = AF_INET;
     579                host_addr.sin_port = so->so_fport;
     580                host_addr.sin_addr = our_addr;
     581                sendto(so->s, m->m_data, m->m_len, 0,
     582                        (struct sockaddr *)&host_addr, sizeof (struct sockaddr));
     583                break;
     584#endif
     585            case CTL_DNS:
     586                if (!get_dns_addr(pData, &dns_addr))
     587                    addr.sin_addr = dns_addr;
     588                else
     589                    addr.sin_addr = loopback_addr;
     590                break;
     591            case CTL_ALIAS:
     592            default:
     593                if (last_byte == ~pData->netmask)
     594                    addr.sin_addr.s_addr = INADDR_BROADCAST;
     595                else
     596                    addr.sin_addr = loopback_addr;
     597                break;
     598        }
     599    }
     600    else
     601        addr.sin_addr = so->so_faddr;
     602    addr.sin_port = so->so_fport;
     603
     604    DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n",
     605                ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
     606
     607    /* Don't care what port we get */
     608    ret = sendto(so->s, m->m_data, m->m_len, 0,
     609                 (struct sockaddr *)&addr, sizeof (struct sockaddr));
     610    if (ret < 0)
     611        return -1;
     612
     613    /*
     614     * Kill the socket if there's no reply in 4 minutes,
     615     * but only if it's an expirable socket
     616     */
     617    if (so->so_expire)
     618        so->so_expire = curtime + SO_EXPIRE;
     619    so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
     620    return 0;
    581621}
    582622
     
    587627solisten(PNATState pData, u_int port, u_int32_t laddr, u_int lport, int flags)
    588628{
    589         struct sockaddr_in addr;
    590         struct socket *so;
    591         socklen_t addrlen = sizeof(addr);
    592         int s, opt = 1;
    593 
    594         DEBUG_CALL("solisten");
    595         DEBUG_ARG("port = %d", port);
    596         DEBUG_ARG("laddr = %x", laddr);
    597         DEBUG_ARG("lport = %d", lport);
    598         DEBUG_ARG("flags = %x", flags);
    599 
    600         if ((so = socreate()) == NULL) {
    601           /* free(so);      Not sofree() ??? free(NULL) == NOP */
    602           return NULL;
    603         }
    604 
    605         /* Don't tcp_attach... we don't need so_snd nor so_rcv */
    606         if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) {
    607                 free(so);
    608                 return NULL;
    609         }
    610         insque(pData, so,&tcb);
    611 
    612         /*
    613          * SS_FACCEPTONCE sockets must time out.
    614          */
    615         if (flags & SS_FACCEPTONCE)
    616            so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
    617 
    618         so->so_state = (SS_FACCEPTCONN|flags);
    619         so->so_lport = lport; /* Kept in network format */
    620         so->so_laddr.s_addr = laddr; /* Ditto */
    621 
    622         addr.sin_family = AF_INET;
    623         addr.sin_addr.s_addr = INADDR_ANY;
    624         addr.sin_port = port;
    625 
    626         if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
    627             (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
    628             (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
    629             (listen(s,1) < 0)) {
     629    struct sockaddr_in addr;
     630    struct socket *so;
     631    socklen_t addrlen = sizeof(addr);
     632    int s, opt = 1;
     633
     634    DEBUG_CALL("solisten");
     635    DEBUG_ARG("port = %d", port);
     636    DEBUG_ARG("laddr = %x", laddr);
     637    DEBUG_ARG("lport = %d", lport);
     638    DEBUG_ARG("flags = %x", flags);
     639
     640    if ((so = socreate()) == NULL)
     641    {
     642        /* free(so);      Not sofree() ??? free(NULL) == NOP */
     643        return NULL;
     644    }
     645
     646    /* Don't tcp_attach... we don't need so_snd nor so_rcv */
     647    if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL)
     648    {
     649        free(so);
     650        return NULL;
     651    }
     652    insque(pData, so,&tcb);
     653
     654    /*
     655     * SS_FACCEPTONCE sockets must time out.
     656     */
     657    if (flags & SS_FACCEPTONCE)
     658        so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
     659
     660    so->so_state = (SS_FACCEPTCONN|flags);
     661    so->so_lport = lport; /* Kept in network format */
     662    so->so_laddr.s_addr = laddr; /* Ditto */
     663
     664    addr.sin_family = AF_INET;
     665    addr.sin_addr.s_addr = INADDR_ANY;
     666    addr.sin_port = port;
     667
     668    if (   ((s = socket(AF_INET,SOCK_STREAM,0)) < 0)
     669        || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0)
     670        || (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0)
     671        || (listen(s,1) < 0))
     672    {
    630673#ifdef RT_OS_WINDOWS
    631                 int tmperrno = WSAGetLastError(); /* Don't clobber the real reason we failed */
    632                 closesocket(s);
    633                 sofree(pData, so);
    634                 /* Restore the real errno */
    635                 WSASetLastError(tmperrno);
     674        int tmperrno = WSAGetLastError(); /* Don't clobber the real reason we failed */
     675        closesocket(s);
     676        sofree(pData, so);
     677        /* Restore the real errno */
     678        WSASetLastError(tmperrno);
    636679#else
    637                 int tmperrno = errno; /* Don't clobber the real reason we failed */
    638                 close(s);
    639                 sofree(pData, so);
    640                 /* Restore the real errno */
    641                 errno = tmperrno;
    642 #endif
    643                 return NULL;
    644         }
    645         setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
    646 
    647         getsockname(s,(struct sockaddr *)&addr,&addrlen);
    648         so->so_fport = addr.sin_port;
    649         if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
    650            so->so_faddr = alias_addr;
    651         else
    652            so->so_faddr = addr.sin_addr;
    653 
    654         so->s = s;
    655         return so;
     680        int tmperrno = errno; /* Don't clobber the real reason we failed */
     681        close(s);
     682        sofree(pData, so);
     683        /* Restore the real errno */
     684        errno = tmperrno;
     685#endif
     686        return NULL;
     687    }
     688    setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
     689
     690    getsockname(s,(struct sockaddr *)&addr,&addrlen);
     691    so->so_fport = addr.sin_port;
     692    if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
     693        so->so_faddr = alias_addr;
     694    else
     695        so->so_faddr = addr.sin_addr;
     696
     697    so->s = s;
     698    return so;
    656699}
    657700
     
    662705 */
    663706void
    664 sorwakeup(so)
    665         struct socket *so;
    666 {
    667 /*      sowrite(so); */
    668 /*      FD_CLR(so->s,&writefds); */
     707sorwakeup(struct socket *so)
     708{
     709#if 0
     710    sowrite(so);
     711    FD_CLR(so->s,&writefds);
     712#endif
    669713}
    670714
     
    675719 */
    676720void
    677 sowwakeup(so)
    678         struct socket *so;
    679 {
    680         /* Nothing, yet */
     721sowwakeup(struct socket *so)
     722{
    681723}
    682724
     
    688730 */
    689731void
    690 soisfconnecting(so)
    691         register struct socket *so;
    692 {
    693         so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
    694                           SS_FCANTSENDMORE|SS_FWDRAIN);
    695         so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
    696 }
    697 
    698 void
    699 soisfconnected(so)
    700         register struct socket *so;
    701 {
    702         so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
    703         so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
    704 }
    705 
    706 void
    707 sofcantrcvmore(so)
    708         struct  socket *so;
    709 {
    710         if ((so->so_state & SS_NOFDREF) == 0) {
    711                 shutdown(so->s,0);
    712         }
    713         so->so_state &= ~(SS_ISFCONNECTING);
    714         if (so->so_state & SS_FCANTSENDMORE)
    715            so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */
    716         else
    717            so->so_state |= SS_FCANTRCVMORE;
    718 }
    719 
    720 void
    721 sofcantsendmore(so)
    722         struct socket *so;
    723 {
    724         if ((so->so_state & SS_NOFDREF) == 0) {
    725             shutdown(so->s,1);           /* send FIN to fhost */
    726         }
    727         so->so_state &= ~(SS_ISFCONNECTING);
    728         if (so->so_state & SS_FCANTRCVMORE)
    729            so->so_state = SS_NOFDREF; /* as above */
    730         else
    731            so->so_state |= SS_FCANTSENDMORE;
    732 }
    733 
    734 void
    735 soisfdisconnected(so)
    736         struct socket *so;
    737 {
    738 /*      so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */
    739 /*      close(so->s); */
    740 /*      so->so_state = SS_ISFDISCONNECTED; */
    741         /*
    742          * XXX Do nothing ... ?
    743          */
     732soisfconnecting(struct socket *so)
     733{
     734    so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
     735                      SS_FCANTSENDMORE|SS_FWDRAIN);
     736    so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
     737}
     738
     739void
     740soisfconnected(struct socket *so)
     741{
     742    so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
     743    so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
     744}
     745
     746void
     747sofcantrcvmore(struct  socket *so)
     748{
     749    if ((so->so_state & SS_NOFDREF) == 0)
     750    {
     751        shutdown(so->s,0);
     752    }
     753    so->so_state &= ~(SS_ISFCONNECTING);
     754    if (so->so_state & SS_FCANTSENDMORE)
     755        so->so_state = SS_NOFDREF; /* Don't select it */
     756                                   /* XXX close() here as well? */
     757    else
     758        so->so_state |= SS_FCANTRCVMORE;
     759}
     760
     761void
     762sofcantsendmore(struct socket *so)
     763{
     764    if ((so->so_state & SS_NOFDREF) == 0)
     765        shutdown(so->s, 1);           /* send FIN to fhost */
     766
     767    so->so_state &= ~(SS_ISFCONNECTING);
     768    if (so->so_state & SS_FCANTRCVMORE)
     769        so->so_state = SS_NOFDREF; /* as above */
     770    else
     771        so->so_state |= SS_FCANTSENDMORE;
     772}
     773
     774void
     775soisfdisconnected(struct socket *so)
     776{
     777#if 0
     778    so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED);
     779    close(so->s);
     780    so->so_state = SS_ISFDISCONNECTED;
     781    /*
     782     * XXX Do nothing ... ?
     783     */
     784#endif
    744785}
    745786
     
    749790 */
    750791void
    751 sofwdrain(so)
    752         struct socket *so;
    753 {
    754         if (so->so_rcv.sb_cc)
    755                 so->so_state |= SS_FWDRAIN;
    756         else
    757                 sofcantsendmore(so);
    758 }
    759 
     792sofwdrain(struct socket *so)
     793{
     794    if (so->so_rcv.sb_cc)
     795        so->so_state |= SS_FWDRAIN;
     796    else
     797        sofcantsendmore(so);
     798}
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r14470 r14964  
    1818 */
    1919
    20 struct socket {
    21   struct socket *so_next,*so_prev;      /* For a linked list of sockets */
     20struct socket
     21{
     22    struct socket   *so_next;
     23    struct socket   *so_prev;    /* For a linked list of sockets */
    2224
    23   int s;                           /* The actual socket */
     25    int s;                       /* The actual socket */
    2426
    25                         /* XXX union these with not-yet-used sbuf params */
    26   struct mbuf *so_m;               /* Pointer to the original SYN packet,
    27                                     * for non-blocking connect()'s, and
    28                                     * PING reply's */
    29   struct tcpiphdr *so_ti;          /* Pointer to the original ti within
    30                                     * so_mconn, for non-blocking connections */
    31   int so_urgc;
    32   struct in_addr so_faddr;         /* foreign host table entry */
    33   struct in_addr so_laddr;         /* local host table entry */
    34   u_int16_t so_fport;              /* foreign port */
    35   u_int16_t so_lport;              /* local port */
     27    /* XXX union these with not-yet-used sbuf params */
     28    struct mbuf     *so_m;       /* Pointer to the original SYN packet,
     29                                  * for non-blocking connect()'s, and
     30                                  * PING reply's */
     31    struct tcpiphdr *so_ti;      /* Pointer to the original ti within
     32                                  * so_mconn, for non-blocking connections */
     33    int            so_urgc;
     34    struct in_addr  so_faddr;    /* foreign host table entry */
     35    struct in_addr  so_laddr;    /* local host table entry */
     36    u_int16_t       so_fport;    /* foreign port */
     37    u_int16_t       so_lport;    /* local port */
    3638
    37   u_int8_t      so_iptos;       /* Type of service */
    38   u_int8_t      so_emu;         /* Is the socket emulated? */
     39    u_int8_t        so_iptos;    /* Type of service */
     40    u_int8_t        so_emu;      /* Is the socket emulated? */
    3941
    40   u_char        so_type;                /* Type of socket, UDP or TCP */
    41   int   so_state;               /* internal state flags SS_*, below */
     42    u_char          so_type;     /* Type of socket, UDP or TCP */
     43    int             so_state;    /* internal state flags SS_*, below */
    4244
    43   struct        tcpcb *so_tcpcb;        /* pointer to TCP protocol control block */
    44   u_int so_expire;              /* When the socket will expire */
     45    struct tcpcb    *so_tcpcb;   /* pointer to TCP protocol control block */
     46    u_int           so_expire;   /* When the socket will expire */
    4547
    46   int   so_queued;              /* Number of packets queued from this socket */
    47   int   so_nqueued;             /* Number of packets queued in a row
    48                                  * Used to determine when to "downgrade" a session
    49                                          * from fastq to batchq */
     48    int             so_queued;   /* Number of packets queued from this socket */
     49    int             so_nqueued;  /* Number of packets queued in a row
     50                                  * Used to determine when to "downgrade" a session
     51                                  * from fastq to batchq */
    5052
    51   struct sbuf so_rcv;           /* Receive buffer */
    52   struct sbuf so_snd;           /* Send buffer */
    53   void * extra;                 /* Extra pointer */
     53    struct sbuf     so_rcv;      /* Receive buffer */
     54    struct sbuf     so_snd;      /* Send buffer */
    5455};
    5556
     
    7475extern struct socket tcb;
    7576
    76 
    7777#if defined(DECLARE_IOVEC) && !defined(HAVE_READV)
    78 struct iovec {
    79         char *iov_base;
    80         size_t iov_len;
     78struct iovec
     79{
     80    char *iov_base;
     81    size_t iov_len;
    8182};
    8283#endif
  • trunk/src/VBox/Devices/Network/slirp/tcp_timer.c

    r14470 r14964  
    4444tcp_fasttimo(PNATState pData)
    4545{
    46         register struct socket *so;
    47         register struct tcpcb *tp;
    48 
    49         DEBUG_CALL("tcp_fasttimo");
    50 
    51         so = tcb.so_next;
    52         if (so)
     46    register struct socket *so;
     47    register struct tcpcb *tp;
     48
     49    DEBUG_CALL("tcp_fasttimo");
     50
     51    so = tcb.so_next;
     52    if (so)
    5353        for (; so != &tcb; so = so->so_next)
    54                 if ((tp = (struct tcpcb *)so->so_tcpcb) &&
    55                     (tp->t_flags & TF_DELACK)) {
    56                         tp->t_flags &= ~TF_DELACK;
    57                         tp->t_flags |= TF_ACKNOW;
    58                         tcpstat.tcps_delack++;
    59                         (void) tcp_output(pData, tp);
    60                 }
     54            if (   (tp = (struct tcpcb *)so->so_tcpcb)
     55                && (tp->t_flags & TF_DELACK))
     56            {
     57                tp->t_flags &= ~TF_DELACK;
     58                tp->t_flags |= TF_ACKNOW;
     59                tcpstat.tcps_delack++;
     60                (void) tcp_output(pData, tp);
     61            }
    6162}
    6263
     
    6970tcp_slowtimo(PNATState pData)
    7071{
    71         register struct socket *ip, *ipnxt;
    72         register struct tcpcb *tp;
    73         register int i;
    74 
    75         DEBUG_CALL("tcp_slowtimo");
    76 
    77         /*
    78          * Search through tcb's and update active timers.
    79          */
    80         ip = tcb.so_next;
    81         if (ip == 0)
    82            return;
    83         for (; ip != &tcb; ip = ipnxt) {
    84                 ipnxt = ip->so_next;
    85                 tp = sototcpcb(ip);
    86                 if (tp == 0)
    87                         continue;
    88                 for (i = 0; i < TCPT_NTIMERS; i++) {
    89                         if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
    90                                 tcp_timers(pData, tp,i);
    91                                 if (ipnxt->so_prev != ip)
    92                                         goto tpgone;
    93                         }
    94                 }
    95                 tp->t_idle++;
    96                 if (tp->t_rtt)
    97                    tp->t_rtt++;
     72    register struct socket *ip, *ipnxt;
     73    register struct tcpcb *tp;
     74    register int i;
     75
     76    DEBUG_CALL("tcp_slowtimo");
     77
     78    /*
     79     * Search through tcb's and update active timers.
     80     */
     81    ip = tcb.so_next;
     82    if (ip == 0)
     83        return;
     84    for (; ip != &tcb; ip = ipnxt)
     85    {
     86        ipnxt = ip->so_next;
     87        tp = sototcpcb(ip);
     88        if (tp == 0)
     89            continue;
     90        for (i = 0; i < TCPT_NTIMERS; i++)
     91        {
     92            if (tp->t_timer[i] && --tp->t_timer[i] == 0)
     93            {
     94                tcp_timers(pData, tp,i);
     95                if (ipnxt->so_prev != ip)
     96                    goto tpgone;
     97            }
     98        }
     99        tp->t_idle++;
     100        if (tp->t_rtt)
     101            tp->t_rtt++;
    98102tpgone:
    99                 ;
    100         }
    101         tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
     103        ;
     104    }
     105    tcp_iss += TCP_ISSINCR / PR_SLOWHZ;         /* increment iss */
    102106#ifdef TCP_COMPAT_42
    103         if ((int)tcp_iss < 0)
    104                 tcp_iss = 0;                            /* XXX */
     107    if ((int)tcp_iss < 0)
     108        tcp_iss = 0;                            /* XXX */
    105109#endif
    106         tcp_now++;                                      /* for timestamps */
     110    tcp_now++;                                  /* for timestamps */
    107111}
    108112
     
    111115 */
    112116void
    113 tcp_canceltimers(tp)
    114         struct tcpcb *tp;
    115 {
    116         register int i;
    117 
    118         for (i = 0; i < TCPT_NTIMERS; i++)
    119                 tp->t_timer[i] = 0;
     117tcp_canceltimers(struct tcpcb *tp)
     118{
     119    register int i;
     120
     121    for (i = 0; i < TCPT_NTIMERS; i++)
     122        tp->t_timer[i] = 0;
    120123}
    121124
    122 const int       tcp_backoff[TCP_MAXRXTSHIFT + 1] =
    123    { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
     125const int  tcp_backoff[TCP_MAXRXTSHIFT + 1] =
     126{
     127    1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64
     128};
    124129
    125130/*
     
    129134tcp_timers(PNATState pData, register struct tcpcb *tp, int timer)
    130135{
    131         register int rexmt;
    132 
    133         DEBUG_CALL("tcp_timers");
    134 
    135         switch (timer) {
    136 
     136    register int rexmt;
     137
     138    DEBUG_CALL("tcp_timers");
     139
     140    switch (timer)
     141    {
    137142        /*
    138143         * 2 MSL timeout in shutdown went off.  If we're closed but
     
    142147         */
    143148        case TCPT_2MSL:
    144                 if (tp->t_state != TCPS_TIME_WAIT &&
     149            if (tp->t_state != TCPS_TIME_WAIT &&
    145150                    tp->t_idle <= tcp_maxidle)
    146                         tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
    147                 else
    148                         tp = tcp_close(pData, tp);
    149                 break;
     151                tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
     152            else
     153                tp = tcp_close(pData, tp);
     154            break;
    150155
    151156        /*
     
    155160         */
    156161        case TCPT_REXMT:
    157 
     162            /*
     163             * XXX If a packet has timed out, then remove all the queued
     164             * packets for that session.
     165             */
     166            if (++tp->t_rxtshift > TCP_MAXRXTSHIFT)
     167            {
    158168                /*
    159                  * XXXXX If a packet has timed out, then remove all the queued
    160                  * packets for that session.
     169                 * This is a hack to suit our terminal server here at the uni of canberra
     170                 * since they have trouble with zeroes... It usually lets them through
     171                 * unharmed, but under some conditions, it'll eat the zeros.  If we
     172                 * keep retransmitting it, it'll keep eating the zeroes, so we keep
     173                 * retransmitting, and eventually the connection dies...
     174                 * (this only happens on incoming data)
     175                 *
     176                 * So, if we were gonna drop the connection from too many retransmits,
     177                 * don't... instead halve the t_maxseg, which might break up the NULLs and
     178                 * let them through
     179                 *
     180                 * *sigh*
    161181                 */
    162 
    163                 if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
    164                         /*
    165                          * This is a hack to suit our terminal server here at the uni of canberra
    166                          * since they have trouble with zeroes... It usually lets them through
    167                          * unharmed, but under some conditions, it'll eat the zeros.  If we
    168                          * keep retransmitting it, it'll keep eating the zeroes, so we keep
    169                          * retransmitting, and eventually the connection dies...
    170                          * (this only happens on incoming data)
    171                          *
    172                          * So, if we were gonna drop the connection from too many retransmits,
    173                          * don't... instead halve the t_maxseg, which might break up the NULLs and
    174                          * let them through
    175                          *
    176                          * *sigh*
    177                          */
    178 
    179                         tp->t_maxseg >>= 1;
    180                         if (tp->t_maxseg < 32) {
    181                                 /*
    182                                  * We tried our best, now the connection must die!
    183                                  */
    184                                 tp->t_rxtshift = TCP_MAXRXTSHIFT;
    185                                 tcpstat.tcps_timeoutdrop++;
    186                                 tp = tcp_drop(pData, tp, tp->t_softerror);
    187                                 /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
    188                                 return (tp); /* XXX */
    189                         }
    190 
    191                         /*
    192                          * Set rxtshift to 6, which is still at the maximum
    193                          * backoff time
    194                          */
    195                         tp->t_rxtshift = 6;
     182                tp->t_maxseg >>= 1;
     183                if (tp->t_maxseg < 32)
     184                {
     185                    /*
     186                     * We tried our best, now the connection must die!
     187                     */
     188                    tp->t_rxtshift = TCP_MAXRXTSHIFT;
     189                    tcpstat.tcps_timeoutdrop++;
     190                    tp = tcp_drop(pData, tp, tp->t_softerror);
     191                    /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
     192                    return (tp); /* XXX */
    196193                }
    197                 tcpstat.tcps_rexmttimeo++;
    198                 rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
    199                 TCPT_RANGESET(tp->t_rxtcur, rexmt,
     194
     195                /*
     196                 * Set rxtshift to 6, which is still at the maximum
     197                 * backoff time
     198                 */
     199                tp->t_rxtshift = 6;
     200            }
     201            tcpstat.tcps_rexmttimeo++;
     202            rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
     203            TCPT_RANGESET(tp->t_rxtcur, rexmt,
    200204                    (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
    201                 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
    202                 /*
    203                  * If losing, let the lower level know and try for
    204                  * a better route.  Also, if we backed off this far,
    205                  * our srtt estimate is probably bogus.  Clobber it
    206                  * so we'll take the next rtt measurement as our srtt;
    207                  * move the current srtt into rttvar to keep the current
    208                  * retransmit times until then.
    209                  */
    210                 if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
    211 /*                      in_losing(tp->t_inpcb); */
    212                         tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
    213                         tp->t_srtt = 0;
    214                 }
    215                 tp->snd_nxt = tp->snd_una;
    216                 /*
    217                  * If timing a segment in this window, stop the timer.
    218                  */
    219                 tp->t_rtt = 0;
    220                 /*
    221                  * Close the congestion window down to one segment
    222                  * (we'll open it by one segment for each ack we get).
    223                  * Since we probably have a window's worth of unacked
    224                  * data accumulated, this "slow start" keeps us from
    225                  * dumping all that data as back-to-back packets (which
    226                  * might overwhelm an intermediate gateway).
    227                  *
    228                  * There are two phases to the opening: Initially we
    229                  * open by one mss on each ack.  This makes the window
    230                  * size increase exponentially with time.  If the
    231                  * window is larger than the path can handle, this
    232                  * exponential growth results in dropped packet(s)
    233                  * almost immediately.  To get more time between
    234                  * drops but still "push" the network to take advantage
    235                  * of improving conditions, we switch from exponential
    236                  * to linear window opening at some threshold size.
    237                  * For a threshold, we use half the current window
    238                  * size, truncated to a multiple of the mss.
    239                  *
    240                  * (the minimum cwnd that will give us exponential
    241                  * growth is 2 mss.  We don't allow the threshold
    242                  * to go below this.)
    243                  */
    244                 {
     205            tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
     206            /*
     207             * If losing, let the lower level know and try for
     208             * a better route.  Also, if we backed off this far,
     209             * our srtt estimate is probably bogus.  Clobber it
     210             * so we'll take the next rtt measurement as our srtt;
     211             * move the current srtt into rttvar to keep the current
     212             * retransmit times until then.
     213             */
     214            if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4)
     215            {
     216/*              in_losing(tp->t_inpcb); */
     217                tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
     218                tp->t_srtt = 0;
     219            }
     220            tp->snd_nxt = tp->snd_una;
     221            /*
     222             * If timing a segment in this window, stop the timer.
     223             */
     224            tp->t_rtt = 0;
     225            /*
     226             * Close the congestion window down to one segment
     227             * (we'll open it by one segment for each ack we get).
     228             * Since we probably have a window's worth of unacked
     229             * data accumulated, this "slow start" keeps us from
     230             * dumping all that data as back-to-back packets (which
     231             * might overwhelm an intermediate gateway).
     232             *
     233             * There are two phases to the opening: Initially we
     234             * open by one mss on each ack.  This makes the window
     235             * size increase exponentially with time.  If the
     236             * window is larger than the path can handle, this
     237             * exponential growth results in dropped packet(s)
     238             * almost immediately.  To get more time between
     239             * drops but still "push" the network to take advantage
     240             * of improving conditions, we switch from exponential
     241             * to linear window opening at some threshold size.
     242             * For a threshold, we use half the current window
     243             * size, truncated to a multiple of the mss.
     244             *
     245             * (the minimum cwnd that will give us exponential
     246             * growth is 2 mss.  We don't allow the threshold
     247             * to go below this.)
     248             */
     249            {
    245250                u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
    246251                if (win < 2)
    247                         win = 2;
     252                    win = 2;
    248253                tp->snd_cwnd = tp->t_maxseg;
    249254                tp->snd_ssthresh = win * tp->t_maxseg;
    250255                tp->t_dupacks = 0;
    251                 }
    252                 (void) tcp_output(pData, tp);
    253                 break;
     256            }
     257            (void) tcp_output(pData, tp);
     258            break;
    254259
    255260        /*
     
    258263         */
    259264        case TCPT_PERSIST:
    260                 tcpstat.tcps_persisttimeo++;
    261                 tcp_setpersist(tp);
    262                 tp->t_force = 1;
    263                 (void) tcp_output(pData, tp);
    264                 tp->t_force = 0;
    265                 break;
     265            tcpstat.tcps_persisttimeo++;
     266            tcp_setpersist(tp);
     267            tp->t_force = 1;
     268            (void) tcp_output(pData, tp);
     269            tp->t_force = 0;
     270            break;
    266271
    267272        /*
     
    270275         */
    271276        case TCPT_KEEP:
    272                 tcpstat.tcps_keeptimeo++;
    273                 if (tp->t_state < TCPS_ESTABLISHED)
    274                         goto dropit;
    275 
    276 /*              if (tp->t_socket->so_options & SO_KEEPALIVE && */
    277                 if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
    278                         if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
    279                                 goto dropit;
    280                         /*
    281                          * Send a packet designed to force a response
    282                          * if the peer is up and reachable:
    283                          * either an ACK if the connection is still alive,
    284                          * or an RST if the peer has closed the connection
    285                          * due to timeout or reboot.
    286                          * Using sequence number tp->snd_una-1
    287                          * causes the transmitted zero-length segment
    288                          * to lie outside the receive window;
    289                          * by the protocol spec, this requires the
    290                          * correspondent TCP to respond.
    291                          */
    292                         tcpstat.tcps_keepprobe++;
     277            tcpstat.tcps_keeptimeo++;
     278            if (tp->t_state < TCPS_ESTABLISHED)
     279                goto dropit;
     280/*          if (tp->t_socket->so_options & SO_KEEPALIVE && */
     281            if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
     282                if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
     283                    goto dropit;
     284                /*
     285                 * Send a packet designed to force a response
     286                 * if the peer is up and reachable:
     287                 * either an ACK if the connection is still alive,
     288                 * or an RST if the peer has closed the connection
     289                 * due to timeout or reboot.
     290                 * Using sequence number tp->snd_una-1
     291                 * causes the transmitted zero-length segment
     292                 * to lie outside the receive window;
     293                 * by the protocol spec, this requires the
     294                 * correspondent TCP to respond.
     295                 */
     296                tcpstat.tcps_keepprobe++;
    293297#ifdef TCP_COMPAT_42
    294                         /*
    295                          * The keepalive packet must have nonzero length
    296                          * to get a 4.2 host to respond.
    297                          */
    298                         tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
     298                /*
     299                 * The keepalive packet must have nonzero length
     300                 * to get a 4.2 host to respond.
     301                 */
     302                tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
    299303                            tp->rcv_nxt - 1, tp->snd_una - 1, 0);
    300304#else
    301                         tcp_respond(pData, tp, &tp->t_template, (struct mbuf *)NULL,
    302                             tp->rcv_nxt, tp->snd_una - 1, 0);
     305                tcp_respond(pData, tp, &tp->t_template, (struct mbuf *)NULL,
     306                        tp->rcv_nxt, tp->snd_una - 1, 0);
    303307#endif
    304                         tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
    305                 } else
    306                         tp->t_timer[TCPT_KEEP] = tcp_keepidle;
    307                 break;
     308                tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
     309            }
     310            else
     311                tp->t_timer[TCPT_KEEP] = tcp_keepidle;
     312            break;
    308313
    309314        dropit:
    310                 tcpstat.tcps_keepdrops++;
    311                 tp = tcp_drop(pData, tp, 0); /* ETIMEDOUT); */
    312                 break;
    313         }
    314 
    315         return (tp);
     315            tcpstat.tcps_keepdrops++;
     316            tp = tcp_drop(pData, tp, 0); /* ETIMEDOUT); */
     317            break;
     318    }
     319
     320    return tp;
    316321}
  • trunk/src/VBox/Devices/Network/slirp/tcp_timer.h

    r14470 r14964  
    103103
    104104#define TCPTV_MIN       (  1*PR_SLOWHZ)         /* minimum allowable value */
    105 /* #define      TCPTV_REXMTMAX  ( 64*PR_SLOWHZ) */      /* max allowable REXMT value */
    106105#define TCPTV_REXMTMAX  ( 12*PR_SLOWHZ)         /* max allowable REXMT value */
    107106
  • trunk/src/VBox/Devices/Network/slirp/tcpip.h

    r1 r14964  
    4141 * Tcp+ip header, after ip options removed.
    4242 */
    43 struct tcpiphdr {
    44         struct  ipovly ti_i;            /* overlaid ip structure */
    45         struct  tcphdr ti_t;            /* tcp header */
     43struct tcpiphdr
     44{
     45    struct      ipovly ti_i;            /* overlaid ip structure */
     46    struct      tcphdr ti_t;            /* tcp header */
    4647};
    4748#define ti_next         ti_i.ih_next
     
    6768 * of the packet
    6869 */
    69 struct tcpiphdr_2 {
    70         struct tcpiphdr dummy;
    71         char first_char;
     70struct tcpiphdr_2
     71{
     72    struct tcpiphdr dummy;
     73    char first_char;
    7274};
    7375
  • trunk/src/VBox/Devices/Network/slirp/tftp.c

    r14470 r14964  
    3434static void tftp_session_terminate(struct tftp_session *spt)
    3535{
    36   spt->in_use = 0;
     36    spt->in_use = 0;
    3737}
    3838
    3939static int tftp_session_allocate(PNATState pData, struct tftp_t *tp)
    4040{
    41   struct tftp_session *spt;
    42   int k;
    43 
    44   for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
    45     spt = &tftp_sessions[k];
    46 
    47     if (!spt->in_use)
    48         goto found;
    49 
    50     /* sessions time out after 5 inactive seconds */
    51     if ((int)(curtime - spt->timestamp) > 5000)
    52         goto found;
    53   }
    54 
    55   return -1;
     41    struct tftp_session *spt;
     42    int k;
     43
     44    for (k = 0; k < TFTP_SESSIONS_MAX; k++)
     45    {
     46        spt = &tftp_sessions[k];
     47
     48        if (!spt->in_use)
     49            goto found;
     50
     51        /* sessions time out after 5 inactive seconds */
     52        if ((int)(curtime - spt->timestamp) > 5000)
     53            goto found;
     54    }
     55
     56    return -1;
    5657
    5758 found:
    58   memset(spt, 0, sizeof(*spt));
    59   memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
    60   spt->client_port = tp->udp.uh_sport;
    61 
    62   tftp_session_update(pData, spt);
    63 
    64   return k;
     59    memset(spt, 0, sizeof(*spt));
     60    memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
     61    spt->client_port = tp->udp.uh_sport;
     62
     63    tftp_session_update(pData, spt);
     64
     65    return k;
    6566}
    6667
    6768static int tftp_session_find(PNATState pData, struct tftp_t *tp)
    6869{
    69   struct tftp_session *spt;
    70   int k;
    71 
    72   for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
    73     spt = &tftp_sessions[k];
    74 
    75     if (spt->in_use) {
    76       if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) {
    77         if (spt->client_port == tp->udp.uh_sport) {
    78           return k;
     70    struct tftp_session *spt;
     71    int k;
     72
     73    for (k = 0; k < TFTP_SESSIONS_MAX; k++)
     74    {
     75        spt = &tftp_sessions[k];
     76
     77        if (spt->in_use)
     78        {
     79            if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip)))
     80            {
     81                if (spt->client_port == tp->udp.uh_sport)
     82                    return k;
     83            }
    7984        }
    80       }
    81     }
    82   }
    83 
    84   return -1;
     85    }
     86
     87    return -1;
    8588}
    8689
     
    8891                          u_int8_t *buf, int len)
    8992{
    90   int fd;
    91   int bytes_read = 0;
    92   char buffer[1024];
    93   int n;
    94 
    95   n = RTStrPrintf(buffer, sizeof(buffer), "%s/%s",
    96                tftp_prefix, spt->filename);
    97   if (n >= sizeof(buffer))
    98     return -1;
    99 
    100   fd = open(buffer, O_RDONLY | O_BINARY);
    101 
    102   if (fd < 0) {
    103     return -1;
    104   }
    105 
    106   if (len) {
    107     lseek(fd, block_nr * 512, SEEK_SET);
    108 
    109     bytes_read = read(fd, buf, len);
    110   }
    111 
    112   close(fd);
    113 
    114   return bytes_read;
     93    int fd;
     94    int bytes_read = 0;
     95    char buffer[1024];
     96    int n;
     97
     98    n = RTStrPrintf(buffer, sizeof(buffer), "%s/%s",
     99                    tftp_prefix, spt->filename);
     100    if (n >= sizeof(buffer))
     101        return -1;
     102
     103    fd = open(buffer, O_RDONLY | O_BINARY);
     104    if (fd < 0)
     105        return -1;
     106
     107    if (len)
     108    {
     109        lseek(fd, block_nr * 512, SEEK_SET);
     110        bytes_read = read(fd, buf, len);
     111    }
     112
     113    close(fd);
     114
     115    return bytes_read;
    115116}
    116117
     
    126127
    127128    m = m_get(pData);
    128 
    129129    if (!m)
    130130        return -1;
     
    160160                           struct tftp_t *recv_tp)
    161161{
    162   struct sockaddr_in saddr, daddr;
    163   struct mbuf *m;
    164   struct tftp_t *tp;
    165   int nobytes;
    166 
    167   m = m_get(pData);
    168 
    169   if (!m) {
    170     return -1;
    171   }
    172 
    173   memset(m->m_data, 0, m->m_size);
    174 
    175   m->m_data += if_maxlinkhdr;
    176   tp = (void *)m->m_data;
    177   m->m_data += sizeof(struct udpiphdr);
    178 
    179   tp->tp_op = htons(TFTP_ERROR);
    180   tp->x.tp_error.tp_error_code = htons(errorcode);
    181   strcpy((char *)tp->x.tp_error.tp_msg, msg);
    182 
    183   saddr.sin_addr = recv_tp->ip.ip_dst;
    184   saddr.sin_port = recv_tp->udp.uh_dport;
    185 
    186   daddr.sin_addr = spt->client_ip;
    187   daddr.sin_port = spt->client_port;
    188 
    189   nobytes = 2;
    190 
    191   m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
    192         sizeof(struct ip) - sizeof(struct udphdr);
    193 
    194   udp_output2(pData, NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
    195 
    196   tftp_session_terminate(spt);
    197 
    198   return 0;
     162    struct sockaddr_in saddr, daddr;
     163    struct mbuf *m;
     164    struct tftp_t *tp;
     165    int nobytes;
     166
     167    m = m_get(pData);
     168    if (!m)
     169        return -1;
     170
     171    memset(m->m_data, 0, m->m_size);
     172
     173    m->m_data += if_maxlinkhdr;
     174    tp = (void *)m->m_data;
     175    m->m_data += sizeof(struct udpiphdr);
     176
     177    tp->tp_op = htons(TFTP_ERROR);
     178    tp->x.tp_error.tp_error_code = htons(errorcode);
     179    strcpy((char *)tp->x.tp_error.tp_msg, msg);
     180
     181    saddr.sin_addr = recv_tp->ip.ip_dst;
     182    saddr.sin_port = recv_tp->udp.uh_dport;
     183
     184    daddr.sin_addr = spt->client_ip;
     185    daddr.sin_port = spt->client_port;
     186
     187    nobytes = 2;
     188
     189    m->m_len = sizeof(struct tftp_t)
     190             - 514
     191             + 3
     192             + strlen(msg)
     193             - sizeof(struct ip)
     194             - sizeof(struct udphdr);
     195
     196    udp_output2(pData, NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
     197
     198    tftp_session_terminate(spt);
     199
     200    return 0;
    199201}
    200202
     
    204206                          struct tftp_t *recv_tp)
    205207{
    206   struct sockaddr_in saddr, daddr;
    207   struct mbuf *m;
    208   struct tftp_t *tp;
    209   int nobytes;
    210 
    211   if (block_nr < 1) {
    212     return -1;
    213   }
    214 
    215   m = m_get(pData);
    216 
    217   if (!m) {
    218     return -1;
    219   }
    220 
    221   memset(m->m_data, 0, m->m_size);
    222 
    223   m->m_data += if_maxlinkhdr;
    224   tp = (void *)m->m_data;
    225   m->m_data += sizeof(struct udpiphdr);
    226 
    227   tp->tp_op = htons(TFTP_DATA);
    228   tp->x.tp_data.tp_block_nr = htons(block_nr);
    229 
    230   saddr.sin_addr = recv_tp->ip.ip_dst;
    231   saddr.sin_port = recv_tp->udp.uh_dport;
    232 
    233   daddr.sin_addr = spt->client_ip;
    234   daddr.sin_port = spt->client_port;
    235 
    236   nobytes = tftp_read_data(pData, spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
    237 
    238   if (nobytes < 0) {
    239     m_free(pData, m);
    240 
    241     /* send "file not found" error back */
    242 
    243     tftp_send_error(pData, spt, 1, "File not found", tp);
    244 
    245     return -1;
    246   }
    247 
    248   m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
    249         sizeof(struct ip) - sizeof(struct udphdr);
    250 
    251   udp_output2(pData, NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
    252 
    253   if (nobytes == 512) {
    254     tftp_session_update(pData, spt);
    255   }
    256   else {
    257     tftp_session_terminate(spt);
    258   }
    259 
    260   return 0;
     208    struct sockaddr_in saddr, daddr;
     209    struct mbuf *m;
     210    struct tftp_t *tp;
     211    int nobytes;
     212
     213    if (block_nr < 1)
     214        return -1;
     215
     216    m = m_get(pData);
     217    if (!m)
     218        return -1;
     219
     220    memset(m->m_data, 0, m->m_size);
     221
     222    m->m_data += if_maxlinkhdr;
     223    tp = (void *)m->m_data;
     224    m->m_data += sizeof(struct udpiphdr);
     225
     226    tp->tp_op = htons(TFTP_DATA);
     227    tp->x.tp_data.tp_block_nr = htons(block_nr);
     228
     229    saddr.sin_addr = recv_tp->ip.ip_dst;
     230    saddr.sin_port = recv_tp->udp.uh_dport;
     231
     232    daddr.sin_addr = spt->client_ip;
     233    daddr.sin_port = spt->client_port;
     234
     235    nobytes = tftp_read_data(pData, spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
     236    if (nobytes < 0)
     237    {
     238        m_free(pData, m);
     239        /* send "file not found" error back */
     240        tftp_send_error(pData, spt, 1, "File not found", tp);
     241        return -1;
     242    }
     243
     244    m->m_len = sizeof(struct tftp_t)
     245             - (512 - nobytes)
     246             - sizeof(struct ip)
     247             - sizeof(struct udphdr);
     248
     249    udp_output2(pData, NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
     250
     251    if (nobytes == 512)
     252        tftp_session_update(pData, spt);
     253    else
     254        tftp_session_terminate(spt);
     255
     256    return 0;
    261257}
    262258
    263259static void tftp_handle_rrq(PNATState pData, struct tftp_t *tp, int pktlen)
    264260{
    265   struct tftp_session *spt;
    266   int s, k, n;
    267   u_int8_t *src, *dst;
    268 
    269   s = tftp_session_allocate(pData, tp);
    270 
    271   if (s < 0) {
    272     return;
    273   }
    274 
    275   spt = &tftp_sessions[s];
    276 
    277   src = tp->x.tp_buf;
    278   dst = spt->filename;
    279   n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
    280 
    281   /* get name */
    282 
    283   for (k = 0; k < n; k++) {
    284     if (k < TFTP_FILENAME_MAX) {
    285       dst[k] = src[k];
    286     }
    287     else {
    288       return;
    289     }
    290 
    291     if (src[k] == '\0') {
    292       break;
    293     }
    294   }
    295 
    296   if (k >= n) {
    297     return;
    298   }
    299 
    300   k++;
    301 
    302   /* check mode */
    303   if ((n - k) < 6) {
    304     return;
    305   }
    306 
    307   if (memcmp(&src[k], "octet\0", 6) != 0) {
    308       tftp_send_error(pData, spt, 4, "Unsupported transfer mode", tp);
    309       return;
    310   }
    311 
    312   k += 6; /* skipping octet */
    313 
    314   /* do sanity checks on the filename */
    315 
    316   if (   !strncmp((const char*)spt->filename, "../", 3)
    317       || (spt->filename[strlen((const char *)spt->filename) - 1] == '/')
    318       ||  strstr((const char *)spt->filename, "/../")) {
    319       tftp_send_error(pData, spt, 2, "Access violation", tp);
    320       return;
    321   }
    322 
    323   /* only allow exported prefixes */
    324 
    325   if (!tftp_prefix) {
    326       tftp_send_error(pData, spt, 2, "Access violation", tp);
    327       return;
    328   }
    329 
    330   /* check if the file exists */
    331 
    332   if (tftp_read_data(pData, spt, 0, spt->filename, 0) < 0) {
    333       tftp_send_error(pData, spt, 1, "File not found", tp);
    334       return;
    335   }
    336 
    337   if (src[n - 1] != 0) {
    338       tftp_send_error(pData, spt, 2, "Access violation", tp);
    339       return;
    340   }
    341 
    342   while (k < n) {
    343       const char *key, *value;
    344 
    345       key = (const char *)src + k;
    346       k += strlen(key) + 1;
    347 
    348       if (k >= n) {
    349           tftp_send_error(pData, spt, 2, "Access violation", tp);
    350           return;
    351       }
    352 
    353       value = (const char *)src + k;
    354       k += strlen(value) + 1;
    355 
    356       if (strcmp(key, "tsize") == 0) {
    357           int tsize = atoi(value);
    358           struct stat stat_p;
    359 
    360           if (tsize == 0 && tftp_prefix) {
    361               char buffer[1024];
    362               int len;
    363 
    364               len = RTStrPrintf(buffer, sizeof(buffer), "%s/%s",
    365                              tftp_prefix, spt->filename);
    366 
    367               if (stat(buffer, &stat_p) == 0)
    368                   tsize = stat_p.st_size;
    369               else {
    370                   tftp_send_error(pData, spt, 1, "File not found", tp);
    371                   return;
    372               }
    373           }
    374 
    375           tftp_send_oack(pData, spt, "tsize", tsize, tp);
    376       }
    377   }
    378 
    379   tftp_send_data(pData, spt, 1, tp);
     261    struct tftp_session *spt;
     262    int s, k, n;
     263    u_int8_t *src, *dst;
     264
     265    s = tftp_session_allocate(pData, tp);
     266    if (s < 0)
     267        return;
     268
     269    spt = &tftp_sessions[s];
     270
     271    src = tp->x.tp_buf;
     272    dst = spt->filename;
     273    n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
     274
     275    /* get name */
     276    for (k = 0; k < n; k++)
     277    {
     278        if (k < TFTP_FILENAME_MAX)
     279            dst[k] = src[k];
     280        else
     281            return;
     282
     283        if (src[k] == '\0')
     284            break;
     285    }
     286
     287    if (k >= n)
     288        return;
     289
     290    k++;
     291
     292    /* check mode */
     293    if ((n - k) < 6)
     294        return;
     295
     296    if (memcmp(&src[k], "octet\0", 6) != 0)
     297    {
     298        tftp_send_error(pData, spt, 4, "Unsupported transfer mode", tp);
     299        return;
     300    }
     301
     302    k += 6; /* skipping octet */
     303
     304    /* do sanity checks on the filename */
     305    if (   !strncmp((const char*)spt->filename, "../", 3)
     306        || (spt->filename[strlen((const char *)spt->filename) - 1] == '/')
     307        ||  strstr((const char *)spt->filename, "/../")) {
     308        tftp_send_error(pData, spt, 2, "Access violation", tp);
     309        return;
     310    }
     311
     312    /* only allow exported prefixes */
     313    if (!tftp_prefix)
     314    {
     315        tftp_send_error(pData, spt, 2, "Access violation", tp);
     316        return;
     317    }
     318
     319    /* check if the file exists */
     320    if (tftp_read_data(pData, spt, 0, spt->filename, 0) < 0)
     321    {
     322        tftp_send_error(pData, spt, 1, "File not found", tp);
     323        return;
     324    }
     325
     326    if (src[n - 1] != 0)
     327    {
     328        tftp_send_error(pData, spt, 2, "Access violation", tp);
     329        return;
     330    }
     331
     332    while (k < n)
     333    {
     334        const char *key, *value;
     335
     336        key = (const char *)src + k;
     337        k += strlen(key) + 1;
     338
     339        if (k >= n)
     340        {
     341            tftp_send_error(pData, spt, 2, "Access violation", tp);
     342            return;
     343        }
     344
     345        value = (const char *)src + k;
     346        k += strlen(value) + 1;
     347
     348        if (strcmp(key, "tsize") == 0)
     349        {
     350            int tsize = atoi(value);
     351            struct stat stat_p;
     352
     353            if (tsize == 0 && tftp_prefix)
     354            {
     355                char buffer[1024];
     356                int len;
     357
     358                len = RTStrPrintf(buffer, sizeof(buffer), "%s/%s",
     359                                  tftp_prefix, spt->filename);
     360                if (stat(buffer, &stat_p) == 0)
     361                    tsize = stat_p.st_size;
     362                else
     363                {
     364                    tftp_send_error(pData, spt, 1, "File not found", tp);
     365                    return;
     366                }
     367            }
     368
     369            tftp_send_oack(pData, spt, "tsize", tsize, tp);
     370        }
     371    }
     372
     373    tftp_send_data(pData, spt, 1, tp);
    380374}
    381375
    382376static void tftp_handle_ack(PNATState pData, struct tftp_t *tp, int pktlen)
    383377{
    384   int s;
    385 
    386   s = tftp_session_find(pData, tp);
    387 
    388   if (s < 0) {
    389     return;
    390   }
    391 
    392   if (tftp_send_data(pData, &tftp_sessions[s],
    393                      ntohs(tp->x.tp_data.tp_block_nr) + 1,
    394                      tp) < 0) {
    395     return;
    396   }
     378    int s;
     379
     380    s = tftp_session_find(pData, tp);
     381    if (s < 0)
     382        return;
     383
     384    if (tftp_send_data(pData, &tftp_sessions[s],
     385                       ntohs(tp->x.tp_data.tp_block_nr) + 1, tp) < 0)
     386    {
     387        /* XXX */
     388    }
    397389}
    398390
    399391void tftp_input(PNATState pData, struct mbuf *m)
    400392{
    401   struct tftp_t *tp = (struct tftp_t *)m->m_data;
    402 
    403   switch(ntohs(tp->tp_op)) {
    404   case TFTP_RRQ:
    405     tftp_handle_rrq(pData, tp, m->m_len);
    406     break;
    407 
    408   case TFTP_ACK:
    409     tftp_handle_ack(pData, tp, m->m_len);
    410     break;
    411   }
    412 }
     393    struct tftp_t *tp = (struct tftp_t *)m->m_data;
     394
     395    switch(ntohs(tp->tp_op))
     396    {
     397        case TFTP_RRQ:
     398            tftp_handle_rrq(pData, tp, m->m_len);
     399            break;
     400
     401        case TFTP_ACK:
     402            tftp_handle_ack(pData, tp, m->m_len);
     403            break;
     404    }
     405}
  • trunk/src/VBox/Devices/Network/slirp/tftp.h

    r14470 r14964  
    1414#define TFTP_FILENAME_MAX 512
    1515
    16 struct tftp_t {
    17   struct ip ip;
    18   struct udphdr udp;
    19   u_int16_t tp_op;
    20   union {
    21     struct {
    22       u_int16_t tp_block_nr;
    23       u_int8_t tp_buf[512];
    24     } tp_data;
    25     struct {
    26       u_int16_t tp_error_code;
    27       u_int8_t tp_msg[512];
    28     } tp_error;
    29     u_int8_t tp_buf[512 + 2];
    30   } x;
     16struct tftp_t
     17{
     18    struct ip ip;
     19    struct udphdr udp;
     20    u_int16_t tp_op;
     21    union
     22    {
     23        struct
     24        {
     25            u_int16_t tp_block_nr;
     26            u_int8_t  tp_buf[512];
     27        } tp_data;
     28        struct
     29        {
     30            u_int16_t tp_error_code;
     31            u_int8_t  tp_msg[512];
     32        } tp_error;
     33        u_int8_t tp_buf[512 + 2];
     34    } x;
    3135};
    3236
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette