Annotation of linux/net/tcp/udp.c, revision 1.1.1.1

1.1       root        1: /* udp.c */
                      2: /*
                      3:     Copyright (C) 1992  Ross Biro
                      4: 
                      5:     This program is free software; you can redistribute it and/or modify
                      6:     it under the terms of the GNU General Public License as published by
                      7:     the Free Software Foundation; either version 2, or (at your option)
                      8:     any later version.
                      9: 
                     10:     This program is distributed in the hope that it will be useful,
                     11:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13:     GNU General Public License for more details.
                     14: 
                     15:     You should have received a copy of the GNU General Public License
                     16:     along with this program; if not, write to the Free Software
                     17:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
                     18: 
                     19:     The Author may be reached as [email protected] or
                     20:     C/O Department of Mathematics; Stanford University; Stanford, CA 94305
                     21: */
                     22: 
                     23: #include <linux/types.h>
                     24: #include <linux/sched.h>
                     25: #include <linux/fcntl.h>
                     26: #include <linux/socket.h>
                     27: #include <netinet/in.h>
                     28: #include "timer.h"
                     29: #include "ip.h"
                     30: #include "tcp.h"
                     31: #include "sock.h"
                     32: #include <linux/errno.h>
                     33: #include <linux/timer.h>
                     34: #include <asm/system.h>
                     35: #include <asm/segment.h>
                     36: #include "../kern_sock.h" /* for PRINTK */
                     37: #include "udp.h"
                     38: #include "icmp.h"
                     39: 
                     40: #define min(a,b) ((a)<(b)?(a):(b))
                     41: 
                     42: static void
                     43: print_uh(struct udp_header *uh)
                     44: {
                     45:        PRINTK("source = %d, dest = %d\n", net16(uh->source), net16(uh->dest));
                     46:        PRINTK("len = %d, check = %d\n", net16(uh->len), net16(uh->check));
                     47: }
                     48: 
                     49: 
                     50: int
                     51: udp_select (volatile struct sock *sk, int sel_type, select_table *wait)
                     52: {
                     53:    select_wait(sk->sleep, wait);
                     54:    switch (sel_type)
                     55:      {
                     56:        case SEL_IN:
                     57:        if (sk->rqueue != NULL) 
                     58:          {
                     59:             return (1);
                     60:          }
                     61:        return (0);
                     62: 
                     63:        case SEL_OUT:
                     64:        if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
                     65:          {
                     66:             return (1);
                     67:          }
                     68:        return (0);
                     69:        
                     70:        case SEL_EX:
                     71:        if (sk->err) return (1); /* can this ever happen? */
                     72:        return (0);
                     73:      }
                     74:    return (0);
                     75: }
                     76: 
                     77: /* this routine is called by the icmp module when it gets some
                     78:    sort of error condition.  If err < 0 then the socket should
                     79:    be closed and the error returned to the user.  If err > 0
                     80:    it's just the icmp type << 8 | icmp code.  
                     81:    header points to the first 8 bytes of the tcp header.  We need
                     82:    to find the appropriate port. */
                     83: 
                     84: void
                     85: udp_err (int err, unsigned char *header, unsigned long daddr,
                     86:         unsigned long saddr, struct ip_protocol *protocol)
                     87: {
                     88:    struct tcp_header *th;
                     89:    volatile struct sock *sk;
                     90:    
                     91:    th = (struct tcp_header *)header;
                     92:    sk = get_sock (&udp_prot, net16(th->dest), saddr, th->source, daddr);
                     93: 
                     94:    if (sk == NULL) return;
                     95:    if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8))
                     96:      {
                     97:        if (sk->cong_window > 1)
                     98:          sk->cong_window = sk->cong_window/2;
                     99:        return;
                    100:      }
                    101: 
                    102:    sk->err = icmp_err_convert[err & 0xff].errno;
                    103:    if (icmp_err_convert[err & 0xff].fatal)
                    104:      {
                    105:        sk->prot->close(sk, 0);
                    106:      }
                    107: 
                    108:    return;
                    109: 
                    110: }
                    111: 
                    112: static  unsigned short
                    113: udp_check (struct udp_header *uh, int len,
                    114:           unsigned long saddr, unsigned long daddr)
                    115: {
                    116:    unsigned long sum;
                    117:    PRINTK ("udp_check (uh=%X, len = %d, saddr = %X, daddr = %X)\n",
                    118:           uh, len, saddr, daddr);
                    119: 
                    120:    print_uh (uh);
                    121: 
                    122:   __asm__("\t addl %%ecx,%%ebx\n"
                    123:          "\t adcl %%edx,%%ebx\n"
                    124:          "\t adcl $0, %%ebx\n"
                    125:          : "=b" (sum)
                    126:          : "0" (daddr), "c" (saddr), "d" ((net16(len) << 16) + IP_UDP*256)
                    127:          : "cx","bx","dx" );
                    128: 
                    129:   if (len > 3)
                    130:     {
                    131:       __asm__(
                    132:              "\tclc\n"
                    133:              "1:\n"
                    134:              "\t lodsl\n"
                    135:              "\t adcl %%eax, %%ebx\n"
                    136:              "\t loop 1b\n"
                    137:              "\t adcl $0, %%ebx\n"
                    138:              : "=b" (sum) , "=S" (uh)
                    139:              : "0" (sum), "c" (len/4) ,"1" (uh)
                    140:              : "ax", "cx", "bx", "si" );
                    141:     }
                    142: 
                    143:   /* convert from 32 bits to 16 bits. */
                    144:   __asm__(
                    145:          "\t movl %%ebx, %%ecx\n"
                    146:          "\t shrl $16,%%ecx\n"
                    147:          "\t addw %%cx, %%bx\n"
                    148:          "\t adcw $0, %%bx\n"
                    149:          : "=b" (sum)
                    150:          : "0" (sum)
                    151:          : "bx", "cx");
                    152: 
                    153: 
                    154:   /* check for an extra word. */
                    155:   if ((len & 2) != 0)
                    156:     {
                    157:       __asm__("\t lodsw\n"
                    158:              "\t addw %%ax,%%bx\n"
                    159:              "\t adcw $0, %%bx\n"
                    160:              : "=b" (sum), "=S" (uh)
                    161:              : "0" (sum) ,"1" (uh)
                    162:              : "si", "ax", "bx");
                    163:     }
                    164: 
                    165:   /* now check for the extra byte. */
                    166:   if ((len & 1) != 0)
                    167:     {
                    168:       __asm__("\t lodsb\n"
                    169:              "\t movb $0,%%ah\n"
                    170:              "\t addw %%ax,%%bx\n"
                    171:              "\t adcw $0, %%bx\n"
                    172:              : "=b" (sum)
                    173:              : "0" (sum) ,"S" (uh)
                    174:              : "si", "ax", "bx");
                    175:     }
                    176:   /* we only want the bottom 16 bits, but we never cleared
                    177:      the top 16. */
                    178:    return ((~sum) & 0xffff);
                    179: }
                    180: 
                    181: static  void
                    182: udp_send_check (struct udp_header *uh, unsigned long saddr, 
                    183:                unsigned long daddr, int len, volatile struct sock *sk)
                    184: {
                    185:   uh->check = 0;
                    186:   if (sk && sk->no_check) return;
                    187:   uh->check = udp_check (uh, len, saddr, daddr);
                    188: }
                    189: 
                    190: static  int
                    191: udp_loopback (volatile struct sock *sk, unsigned short port,
                    192:              unsigned char *from,
                    193:              int len, unsigned long daddr, unsigned long saddr)
                    194: {
                    195:        struct udp_header *uh;
                    196:        struct sk_buff *skb;
                    197:        volatile struct sock *pair;
                    198:        sk->inuse = 1;
                    199: 
                    200:        PRINTK ("udp_loopback \n");
                    201: 
                    202:        pair = get_sock (sk->prot, net16(port), saddr,
                    203:                         sk->dummy_th.source, daddr);
                    204: 
                    205:        if (pair == NULL) return (0);
                    206: 
                    207:        skb = pair->prot->rmalloc (pair,
                    208:                                   sizeof (*skb) + sizeof (*uh) + len + 4,
                    209:                                   0);
                    210: 
                    211:        /* if we didn't get the memory, just drop the packet. */
                    212:        if (skb == NULL) return (len);
                    213: 
                    214:        skb->mem_addr = skb;
                    215:        skb->mem_len = sizeof (*skb) + len + sizeof (*uh) + 4;
                    216: 
                    217:        skb->daddr = saddr;
                    218:        skb->saddr = daddr;
                    219: 
                    220:        skb->len = len;
                    221:        skb->h.raw = (unsigned char *)(skb+1);
                    222: 
                    223:        uh = skb->h.uh;
                    224:        uh -> source = sk->dummy_th.source;
                    225:        uh -> dest = port;
                    226:        uh -> len = len + sizeof (*uh);
                    227:        verify_area (from , len);
                    228:        memcpy_fromfs(uh+1, from, len);
                    229:        pair->inuse = 1;
                    230:        if (pair->rqueue == NULL)
                    231:          {
                    232:                  pair->rqueue = skb;
                    233:                  skb->next = skb;
                    234:                  skb->prev = skb;
                    235:          }
                    236:        else
                    237:          {
                    238:                  skb->next = pair->rqueue;
                    239:                  skb->prev = pair->rqueue->prev;
                    240:                  skb->prev->next = skb;
                    241:                  skb->next->prev = skb;
                    242:          }
                    243:        wake_up (pair->sleep);
                    244:        release_sock (pair);
                    245:        release_sock (sk);
                    246:        return (len);
                    247: 
                    248: }
                    249: 
                    250: static int
                    251: udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
                    252:            int noblock,
                    253:            unsigned flags, struct sockaddr_in *usin, int addr_len)
                    254: {
                    255:        /* this should be easy, we just send the packet. */
                    256:        struct sk_buff *skb;
                    257:        struct udp_header *uh;
                    258:        unsigned char *buff;
                    259:        unsigned long saddr;
                    260:        int copied=0;
                    261:        int amt;
                    262:        struct device *dev=NULL;
                    263:        struct sockaddr_in sin;
                    264: 
                    265:        /* check the flags. */
                    266:        if (flags) return (-EINVAL);
                    267:        if (len < 0) return (-EINVAL);
                    268:        if (len == 0) return (0);
                    269: 
                    270:        PRINTK ("sendto len = %d\n", len);
                    271: 
                    272:        /* get and verify the address. */
                    273:        if (usin)
                    274:          {
                    275:                  if (addr_len < sizeof (sin))
                    276:                    return (-EINVAL);
                    277:                  verify_area (usin, sizeof (sin));
                    278:                  memcpy_fromfs (&sin, usin, sizeof(sin));
                    279:                  if (sin.sin_family &&
                    280:                      sin.sin_family != AF_INET)
                    281:                    return (-EINVAL);
                    282:                  if (sin.sin_port == 0)
                    283:                    return (-EINVAL);
                    284:          }
                    285:        else
                    286:          {
                    287:                  if (sk->state != TCP_ESTABLISHED)
                    288:                    return (-EINVAL);
                    289:                  sin.sin_family = AF_INET;
                    290:                  sin.sin_port = sk->dummy_th.dest;
                    291:                  sin.sin_addr.s_addr = sk->daddr;
                    292:          }
                    293: 
                    294:        /* check for a valid saddr. */
                    295:        saddr = sk->saddr;
                    296:        if ((saddr &  0xff000000) == 0)
                    297:          {
                    298:             saddr = MY_IP_ADDR;
                    299:          }
                    300: 
                    301:        /* if it's a broadcast, make sure we get it. */
                    302:        if ((sin.sin_addr.s_addr & 0xff000000) == 0)
                    303:          {
                    304:             int err;
                    305:             err = udp_loopback (sk, sin.sin_port, from, len,
                    306:                                 sin.sin_addr.s_addr, saddr);
                    307:             if (err < 0)
                    308:               return (err);
                    309:          }
                    310: 
                    311:        sk->inuse = 1;
                    312: 
                    313:        while (len > 0)
                    314:          {
                    315:                  int tmp;
                    316:                  skb = sk->prot->wmalloc (sk, len + sizeof (*skb)
                    317:                                               + sk->prot->max_header, 0);
                    318:                  /* this should never happen, but it is possible. */
                    319: 
                    320:                  if (skb == NULL)
                    321:                    {
                    322:                       printk ("udp_sendto: write buffer full?\n");
                    323:                       print_sk(sk);
                    324:                       release_sock (sk);
                    325:                       if (copied || !noblock)
                    326:                         return (copied);
                    327:                       return (-EAGAIN);
                    328:                    }
                    329: 
                    330:                  skb->mem_addr = skb;
                    331:                  skb->mem_len = len + sizeof (*skb) + sk->prot->max_header;
                    332:                  skb->sk = sk;
                    333:                  skb->free = 1;
                    334:                  skb->arp = 0;
                    335: 
                    336:                  /* now build the ip and dev header. */
                    337:                  buff = (unsigned char *)(skb+1);
                    338:                  tmp = sk->prot->build_header (skb, saddr,
                    339:                                                sin.sin_addr.s_addr, &dev,
                    340:                                                IP_UDP, sk->opt, skb->mem_len);
                    341:                  if (tmp < 0 )
                    342:                    {
                    343:                            sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
                    344:                            release_sock (sk);
                    345:                            return (tmp);
                    346:                    }
                    347:                  buff += tmp;
                    348: 
                    349:                  /* we shouldn't do this, instead we should just
                    350:                     let the ip protocol fragment the packet. */
                    351:                  amt = min (len + tmp + sizeof (*uh), dev->mtu);
                    352: 
                    353:                  PRINTK ("amt = %d, dev = %X, dev->mtu = %d\n",
                    354:                          amt, dev, dev->mtu);
                    355: 
                    356:                  skb->len = amt;
                    357:                  amt -= tmp; 
                    358: 
                    359:                  uh = (struct udp_header *)buff;
                    360:                  uh->len = net16(amt);
                    361:                  uh->source = sk->dummy_th.source;
                    362:                  uh->dest = sin.sin_port;
                    363: 
                    364:                  amt -= sizeof (*uh);
                    365:                  buff += sizeof (*uh);
                    366: 
                    367:                  verify_area (from, amt);
                    368:                  memcpy_fromfs( buff, from, amt);
                    369: 
                    370:                  len -= amt;
                    371:                  copied += amt;
                    372:                  from += amt;
                    373:                  udp_send_check (uh, saddr, sin.sin_addr.s_addr,
                    374:                                  amt+sizeof (*uh), sk);
                    375:                                  
                    376:                  sk->prot->queue_xmit (sk, dev, skb, 1);
                    377:          }
                    378:        release_sock (sk);
                    379:        return (copied);
                    380: }
                    381: 
                    382: static int
                    383: udp_write (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
                    384:           unsigned flags)
                    385: {
                    386:        return (udp_sendto (sk, buff, len, noblock, flags, NULL, 0));
                    387: }
                    388: 
                    389: int
                    390: udp_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
                    391:              int noblock,
                    392:              unsigned flags, struct sockaddr_in *sin, int *addr_len)
                    393: {
                    394:        /* this should be easy, if there is something there we
                    395:           return it, otherwise we block. */
                    396:        int copied=0;
                    397:        struct sk_buff *skb;
                    398:        if (len == 0) return (0);
                    399:        if (len < 0) return (-EINVAL);
                    400:        if (addr_len)
                    401:          {
                    402:                  verify_area (addr_len, sizeof(*addr_len));
                    403:                  put_fs_long (sizeof (*sin), addr_len);
                    404:          }
                    405:        sk->inuse = 1;
                    406:        while (sk->rqueue == NULL)
                    407:          {
                    408:             if (noblock)
                    409:               {
                    410:                  release_sock (sk);
                    411:                  return (-EAGAIN);
                    412:               }
                    413:             release_sock (sk);
                    414:             cli();
                    415:             if (sk->rqueue == NULL)
                    416:               {
                    417:                  interruptible_sleep_on (sk->sleep);
                    418:                  if (current->signal & ~current->blocked)
                    419:                    {
                    420:                       return (-ERESTARTSYS);
                    421:                    }
                    422:               }
                    423:             sti();
                    424:          }
                    425:        skb = sk->rqueue;
                    426: 
                    427:        if (!(flags & MSG_PEEK))
                    428:          {
                    429:                  if (skb->next == skb )
                    430:                    {
                    431:                            sk->rqueue = NULL;
                    432:                    }
                    433:                  else
                    434:                    {
                    435:                            sk->rqueue = sk->rqueue ->next;
                    436:                            skb->prev->next = skb->next;
                    437:                            skb->next->prev = skb->prev;
                    438:                    }
                    439:          }
                    440:        copied = min (len, skb->len);
                    441:        verify_area (to, copied);
                    442:        memcpy_tofs (to, skb->h.raw + sizeof (struct udp_header), copied);
                    443:        /* copy the address. */
                    444:        if (sin)
                    445:          {
                    446:                  struct sockaddr_in addr;
                    447:                  addr.sin_family = AF_INET;
                    448:                  addr.sin_port = skb->h.uh->source;
                    449:                  addr.sin_addr.s_addr = skb->daddr;
                    450:                  verify_area (sin, sizeof (*sin));
                    451:                  memcpy_tofs(sin, &addr, sizeof (*sin));
                    452:          }
                    453: 
                    454:        if (!(flags & MSG_PEEK))
                    455:          {
                    456:             free_skb (skb, FREE_READ);
                    457:          }
                    458:        release_sock (sk);
                    459:        return (copied);
                    460: 
                    461: }
                    462: 
                    463: 
                    464: int
                    465: udp_read (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
                    466:          unsigned flags)
                    467: {
                    468:        return (udp_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
                    469: }
                    470: 
                    471: int
                    472: udp_connect (volatile struct sock *sk, struct sockaddr_in *usin, int addr_len)
                    473: {
                    474:        struct sockaddr_in sin;
                    475:        if (addr_len < sizeof (sin)) return (-EINVAL);
                    476:        verify_area (usin, sizeof (sin));
                    477:        memcpy_fromfs (&sin, usin, sizeof (sin));
                    478:        if (sin.sin_family && sin.sin_family != AF_INET)
                    479:          return (-EAFNOSUPPORT);
                    480:        sk->daddr = sin.sin_addr.s_addr;
                    481:        sk->dummy_th.dest = sin.sin_port;
                    482:        sk->state = TCP_ESTABLISHED;
                    483:        return(0);
                    484: }
                    485: 
                    486: static void
                    487: udp_close(volatile struct sock *sk, int timeout)
                    488: {
                    489:        sk->inuse = 1;
                    490:        sk->state = TCP_CLOSE;
                    491:        if (sk->dead)
                    492:          destroy_sock (sk);
                    493:        else
                    494:          release_sock (sk);
                    495: }
                    496: 
                    497: int
                    498: udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                    499:        unsigned long daddr, unsigned short len,
                    500:        unsigned long saddr, int redo, struct ip_protocol *protocol)
                    501: {
                    502:        /* all we need to do is get the socket, and then do a checksum. */
                    503:        struct proto *prot=&udp_prot;
                    504:        volatile struct sock *sk;
                    505:        struct udp_header *uh;
                    506: 
                    507:        uh = (struct udp_header *) skb->h.uh;
                    508: 
                    509:        if (dev->add_arp) dev->add_arp (saddr, skb, dev);
                    510: 
                    511:        sk = get_sock (prot, net16(uh->dest), saddr, uh->source, daddr);
                    512: 
                    513:        /* if we don't know about the socket, forget about it. */
                    514:        if (sk == NULL &&
                    515:            (daddr & 0xff000000 != 0) && (daddr & 0xff000000 != 0xff000000))
                    516:          {
                    517:             icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, dev);
                    518:             skb->sk = NULL;
                    519:             free_skb (skb, 0);
                    520:             return (0);
                    521:          }
                    522: 
                    523: 
                    524:        if (!redo)
                    525:          {
                    526:             if (uh->check && udp_check (uh, len, saddr, daddr))
                    527:               {
                    528:                  PRINTK ("bad udp checksum\n");
                    529:                  skb->sk = NULL;
                    530:                  free_skb (skb, 0);
                    531:                  return (0);
                    532:               }
                    533: 
                    534:             skb->sk = sk;
                    535:             skb->dev = dev;
                    536:             skb->len = len;
                    537: 
                    538:             /* these are supposed to be switched. */
                    539:             skb->daddr = saddr;
                    540:             skb->saddr = daddr;
                    541: 
                    542:             /* Now deal with the in use. */
                    543:             cli();
                    544:             if (sk->inuse)
                    545:               {
                    546:                  if (sk->back_log == NULL)
                    547:                    {
                    548:                       sk->back_log = skb;
                    549:                       skb->next = skb;
                    550:                       skb->prev = skb;
                    551:                    }
                    552:                  else
                    553:                    {
                    554:                       skb->next = sk->back_log;
                    555:                       skb->prev = sk->back_log->prev;
                    556:                       skb->prev->next = skb;
                    557:                       skb->next->prev = skb;
                    558:                    }
                    559:                  sti();
                    560:                  return (0);
                    561:               }
                    562:             sk->inuse = 1;
                    563:             sti();
                    564:          }
                    565: 
                    566:        /* charge it too the socket. */
                    567:        if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
                    568:          {
                    569:             skb->sk = NULL;
                    570:             free_skb (skb, 0);
                    571:             release_sock (sk);
                    572:             return (0);
                    573:          }
                    574:             
                    575:        sk->rmem_alloc += skb->mem_len;
                    576: 
                    577:        /* At this point we should print the thing out. */
                    578:        PRINTK ("<< \n");
                    579:        print_sk (sk);
                    580: 
                    581:        /* now add it to the data chain and wake things up. */
                    582:        if (sk->rqueue == NULL)
                    583:          {
                    584:                  sk->rqueue = skb;
                    585:                  skb->next = skb;
                    586:                  skb->prev = skb;
                    587:          }
                    588:        else
                    589:          {
                    590:                  skb->next = sk->rqueue;
                    591:                  skb->prev = sk->rqueue->prev;
                    592:                  skb->prev->next = skb;
                    593:                  skb->next->prev = skb;
                    594:          }
                    595: 
                    596:        skb->len = len - sizeof (*uh);
                    597: 
                    598:        if (!sk->dead)
                    599:          wake_up (sk->sleep);
                    600: 
                    601:        release_sock (sk);
                    602:        return (0);
                    603: }
                    604: 
                    605: 
                    606: 
                    607: struct proto udp_prot =
                    608: {
                    609:   sock_wmalloc,
                    610:   sock_rmalloc,
                    611:   sock_wfree,
                    612:   sock_rfree,
                    613:   sock_rspace,
                    614:   sock_wspace,
                    615:   udp_close,
                    616:   udp_read,
                    617:   udp_write,
                    618:   udp_sendto,
                    619:   udp_recvfrom,
                    620:   ip_build_header,
                    621:   udp_connect,
                    622:   NULL,
                    623:   ip_queue_xmit,
                    624:   ip_retransmit,
                    625:   NULL,
                    626:   NULL,
                    627:   udp_rcv,
                    628:   udp_select,
                    629:   NULL,
                    630:   NULL,
                    631:   128,
                    632:   0,
                    633:   {NULL,}
                    634: };
                    635: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.