root/drivers/net/slip.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ip_dump
  2. clh_dump
  3. sl_initialize
  4. sl_find
  5. sl_alloc
  6. sl_free
  7. sl_changedmtu
  8. sl_enqueue
  9. sl_dequeue
  10. sl_lock
  11. sl_unlock
  12. sl_bump
  13. sl_next
  14. sl_encaps
  15. sl_xmit
  16. sl_type_trans
  17. sl_header
  18. sl_add_arp
  19. sl_rebuild_header
  20. sl_open
  21. sl_close
  22. slip_recv
  23. slip_open
  24. sl_get_stats
  25. slip_close
  26. slip_esc
  27. slip_unesc
  28. slip_esc6
  29. slip_unesc6
  30. sl_set_mac_address
  31. slip_ioctl
  32. slip_init

   1 /*
   2  * slip.c       This module implements the SLIP protocol for kernel-based
   3  *              devices like TTY.  It interfaces between a raw TTY, and the
   4  *              kernel's INET protocol layers (via DDI).
   5  *
   6  * Version:     @(#)slip.c      0.7.6   05/25/93
   7  *
   8  * Authors:     Laurence Culhane, <loz@holmes.demon.co.uk>
   9  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  10  *
  11  * Fixes:
  12  *              Alan Cox        :       Sanity checks and avoid tx overruns.
  13  *                                      Has a new sl->mtu field.
  14  *              Alan Cox        :       Found cause of overrun. ifconfig sl0 mtu upwards.
  15  *                                      Driver now spots this and grows/shrinks its buffers(hack!).
  16  *                                      Memory leak if you run out of memory setting up a slip driver fixed.
  17  *              Matt Dillon     :       Printable slip (borrowed from NET2E)
  18  *      Pauline Middelink       :       Slip driver fixes.
  19  *              Alan Cox        :       Honours the old SL_COMPRESSED flag
  20  *              Alan Cox        :       KISS AX.25 and AXUI IP support
  21  *              Michael Riepe   :       Automatic CSLIP recognition added
  22  *              Charles Hedrick :       CSLIP header length problem fix.
  23  *              Alan Cox        :       Corrected non-IP cases of the above.
  24  */
  25  
  26 #include <asm/segment.h>
  27 #include <asm/system.h>
  28 
  29 #include <linux/config.h>
  30 #include <linux/types.h>
  31 #include <linux/kernel.h>
  32 #include <linux/sched.h>
  33 #include <linux/string.h>
  34 #include <linux/mm.h>
  35 #include <linux/socket.h>
  36 #include <linux/sockios.h>
  37 #include <linux/interrupt.h>
  38 #include <linux/tty.h>
  39 #include <linux/errno.h>
  40 #include <linux/stat.h>
  41 #include <linux/in.h>
  42 #include "inet.h"
  43 #include "dev.h"
  44 #ifdef CONFIG_AX25
  45 #include "ax25.h"
  46 #endif
  47 #include "eth.h"
  48 #include "ip.h"
  49 #include "route.h"
  50 #include "protocol.h"
  51 #include "tcp.h"
  52 #include "skbuff.h"
  53 #include "sock.h"
  54 #include "arp.h"
  55 #include "slip.h"
  56 #include "slhc.h"
  57 
  58 #define SLIP_VERSION    "0.7.5"
  59 
  60 /* Define some IP layer stuff.  Not all systems have it. */
  61 #ifdef SL_DUMP
  62 #   define      IP_VERSION      4       /* version# of our IP software  */
  63 #   define      IPF_F_OFFSET    0x1fff  /* Offset field                 */
  64 #   define      IPF_DF          0x4000  /* Don't fragment flag          */
  65 #   define      IPF_MF          0x2000  /* More Fragments flag          */
  66 #   define      IP_OF_COPIED    0x80    /* Copied-on-fragmentation flag */
  67 #   define      IP_OF_CLASS     0x60    /* Option class                 */
  68 #   define      IP_OF_NUMBER    0x1f    /* Option number                */
  69 #endif
  70 
  71 
  72 static struct slip      sl_ctrl[SL_NRUNIT];
  73 static struct tty_ldisc sl_ldisc;
  74 static int              already = 0;
  75 
  76 
  77 /* Dump the contents of an IP datagram. */
  78 static void
  79 ip_dump(unsigned char *ptr, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81 #ifdef SL_DUMP
  82   struct iphdr *ip;
  83   struct tcphdr *th;
  84   int dlen, doff;
  85 
  86   if (inet_debug != DBG_SLIP) return;
  87 
  88   ip = (struct iphdr *) ptr;
  89   th = (struct tcphdr *) (ptr + ip->ihl * 4);
  90   printk("\r%s -> %s seq %lx ack %lx len %d\n",
  91          in_ntoa(ip->saddr), in_ntoa(ip->daddr), 
  92          ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
  93   return;
  94 
  95   printk("\r*****\n");
  96   printk("%p %d\n", ptr, len);
  97   ip = (struct iphdr *) ptr;
  98   dlen = ntohs(ip->tot_len);
  99   doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);
 100 
 101 
 102   printk("SLIP: %s->", in_ntoa(ip->saddr));
 103   printk("%s\n", in_ntoa(ip->daddr));
 104   printk(" len %u ihl %u ver %u ttl %u prot %u",
 105         dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);
 106 
 107   if (ip->tos != 0) printk(" tos %u", ip->tos);
 108   if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
 109         printk(" id %u offs %u", ntohs(ip->id), doff);
 110 
 111   if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
 112   if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
 113   printk("\n*****\n");
 114 #endif
 115 }
 116 
 117 #if 0
 118 void clh_dump(unsigned char *cp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120   if (len > 60)
 121     len = 60;
 122   printk("%d:", len);
 123   while (len > 0) {
 124     printk(" %x", *cp++);
 125     len--;
 126   }
 127   printk("\n\n");
 128 }
 129 #endif
 130 
 131 /* Initialize a SLIP control block for use. */
 132 static void
 133 sl_initialize(struct slip *sl, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135   sl->inuse             = 0;
 136   sl->sending           = 0;
 137   sl->escape            = 0;
 138   sl->flags             = 0;
 139 #ifdef SL_ADAPTIVE
 140   sl->mode              = SL_MODE_ADAPTIVE;     /* automatic CSLIP recognition */
 141 #else
 142 #ifdef SL_COMPRESSED
 143   sl->mode              = SL_MODE_CSLIP | SL_MODE_ADAPTIVE;     /* Default */
 144 #else
 145   sl->mode              = SL_MODE_SLIP;         /* Default for non compressors */
 146 #endif
 147 #endif  
 148 
 149   sl->line              = dev->base_addr;
 150   sl->tty               = NULL;
 151   sl->dev               = dev;
 152   sl->slcomp            = NULL;
 153 
 154   /* Clear all pointers. */
 155   sl->rbuff             = NULL;
 156   sl->xbuff             = NULL;
 157   sl->cbuff             = NULL;
 158 
 159   sl->rhead             = NULL;
 160   sl->rend              = NULL;
 161   dev->rmem_end         = (unsigned long) NULL;
 162   dev->rmem_start       = (unsigned long) NULL;
 163   dev->mem_end          = (unsigned long) NULL;
 164   dev->mem_start        = (unsigned long) NULL;
 165 }
 166 
 167 
 168 /* Find a SLIP channel from its `tty' link. */
 169 static struct slip *
 170 sl_find(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172   struct slip *sl;
 173   int i;
 174 
 175   if (tty == NULL) return(NULL);
 176   for (i = 0; i < SL_NRUNIT; i++) {
 177         sl = &sl_ctrl[i];
 178         if (sl->tty == tty) return(sl);
 179   }
 180   return(NULL);
 181 }
 182 
 183 
 184 /* Find a free SLIP channel, and link in this `tty' line. */
 185 static inline struct slip *
 186 sl_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188   unsigned long flags;
 189   struct slip *sl;
 190   int i;
 191 
 192   save_flags (flags);
 193   cli();
 194   for (i = 0; i < SL_NRUNIT; i++) {
 195         sl = &sl_ctrl[i];
 196         if (sl->inuse == 0) {
 197                 sl->inuse = 1;
 198                 sl->tty = NULL;
 199                 restore_flags(flags);
 200                 return(sl);
 201         }
 202   }
 203   restore_flags(flags);
 204   return(NULL);
 205 }
 206 
 207 
 208 /* Free a SLIP channel. */
 209 static inline void
 210 sl_free(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212   unsigned long flags;
 213 
 214   if (sl->inuse) {
 215         save_flags(flags);
 216         cli();
 217         sl->inuse = 0;
 218         sl->tty = NULL;
 219         restore_flags(flags);
 220   }
 221 }
 222 
 223 /* MTU has been changed by the IP layer. Unfortunately we are not told about this, but
 224    we spot it ourselves and fix things up. We could be in an upcall from the tty
 225    driver, or in an ip packet queue. */
 226    
 227 static void sl_changedmtu(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229         struct device *dev=sl->dev;
 230         unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
 231         int l;
 232         int omtu=sl->mtu;
 233         
 234         sl->mtu=dev->mtu;
 235         l=(dev->mtu *2);
 236 /*
 237  * allow for arrival of larger UDP packets, even if we say not to
 238  * also fixes a bug in which SunOS sends 512-byte packets even with
 239  * an MSS of 128
 240  */
 241         if (l < (576 * 2))
 242           l = 576 * 2;
 243         
 244         DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n"));
 245         
 246         tb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 247         rb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 248         cb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 249         
 250         if(tb==NULL || rb==NULL || cb==NULL)
 251         {
 252                 printk("Unable to grow slip buffers. MTU change cancelled.\n");
 253                 sl->mtu=omtu;
 254                 dev->mtu=omtu;
 255                 if(tb!=NULL)
 256                         kfree(tb);
 257                 if(rb!=NULL)
 258                         kfree(rb);
 259                 if(cb!=NULL)
 260                         kfree(cb);
 261                 return;
 262         }
 263         
 264         cli();
 265         
 266         tf=(unsigned char *)sl->dev->mem_start;
 267         sl->dev->mem_start=(unsigned long)tb;
 268         sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
 269         rf=(unsigned char *)sl->dev->rmem_start;
 270         sl->dev->rmem_start=(unsigned long)rb;
 271         sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
 272         
 273         sl->xbuff = (unsigned char *) sl->dev->mem_start;
 274         sl->rbuff = (unsigned char *) sl->dev->rmem_start;
 275         sl->rend  = (unsigned char *) sl->dev->rmem_end;
 276         sl->rhead = sl->rbuff;
 277         
 278         cf=sl->cbuff;
 279         sl->cbuff=cb;
 280         
 281         sl->escape=0;
 282         sl->sending=0;
 283         sl->rcount=0;
 284 
 285         sti();  
 286         
 287         if(rf!=NULL)
 288                 kfree(rf);
 289         if(tf!=NULL)
 290                 kfree(tf);
 291         if(cf!=NULL)
 292                 kfree(cf);
 293 }
 294 
 295 
 296 /* Stuff one byte into a SLIP receiver buffer. */
 297 static inline void
 298 sl_enqueue(struct slip *sl, unsigned char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 299 {
 300   unsigned long flags;
 301 
 302   save_flags(flags);
 303   cli();
 304   if (sl->rhead < sl->rend) {
 305         *sl->rhead = c;
 306         sl->rhead++;
 307         sl->rcount++;
 308   } else sl->roverrun++;
 309   restore_flags(flags);
 310 }
 311 
 312 /* Release 'i' bytes from a SLIP receiver buffer. */
 313 static inline void
 314 sl_dequeue(struct slip *sl, int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 315 {
 316   unsigned long flags;
 317 
 318   save_flags(flags);
 319   cli();
 320   if (sl->rhead > sl->rbuff) {
 321         sl->rhead -= i;
 322         sl->rcount -= i;
 323   }
 324   restore_flags(flags);
 325 }
 326 
 327 
 328 /* Set the "sending" flag.  This must be atomic, hence the ASM. */
 329 static inline void
 330 sl_lock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 331 {
 332   unsigned long flags;
 333 
 334   save_flags(flags);
 335   cli();
 336   sl->sending = 1;
 337   sl->dev->tbusy = 1;
 338   restore_flags(flags);
 339 }
 340 
 341 
 342 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
 343 static inline void
 344 sl_unlock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 345 {
 346   unsigned long flags;
 347 
 348   save_flags(flags);
 349   cli();
 350   sl->sending = 0;
 351   sl->dev->tbusy = 0;
 352   restore_flags(flags);
 353 }
 354 
 355 
 356 /* Send one completely decapsulated IP datagram to the IP layer. */
 357 static void
 358 sl_bump(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360   int done;
 361   unsigned char c;
 362   unsigned long flags;
 363   int count;
 364 
 365   count = sl->rcount;
 366   if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
 367     if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
 368 #if 1
 369       /* ignore compressed packets when CSLIP is off */
 370       if (!(sl->mode & SL_MODE_CSLIP)) {
 371         printk("SLIP: compressed packet ignored\n");
 372         return;
 373       }
 374 #endif
 375       /* make sure we've reserved enough space for uncompress to use */
 376       save_flags(flags);
 377       cli();
 378       if ((sl->rhead + 80) < sl->rend) {
 379         sl->rhead += 80;
 380         sl->rcount += 80;
 381         done = 1;
 382       } else {
 383         sl->roverrun++;
 384         done = 0;
 385       }
 386       restore_flags(flags);
 387       if (! done)  /* not enough space available */
 388         return;
 389 
 390       count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
 391       if (count <= 0) {
 392         sl->errors++;
 393         return;
 394       }
 395     } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
 396       if (!(sl->mode & SL_MODE_CSLIP)) {
 397         /* turn on header compression */
 398         sl->mode |= SL_MODE_CSLIP;
 399         printk("SLIP: header compression turned on\n");
 400       }
 401       sl->rbuff[0] &= 0x4f;
 402       if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
 403         sl->errors++;
 404         return;
 405       }
 406     }
 407   }
 408 
 409   DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
 410   ip_dump(sl->rbuff, sl->rcount);
 411 
 412   /* Bump the datagram to the upper layers... */
 413   do {
 414         DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
 415                                         sl->rcount, sl->rbuff));
 416         /* clh_dump(sl->rbuff, count); */
 417         done = dev_rint(sl->rbuff, count, 0, sl->dev);
 418         if (done == 0 || done == 1) break;
 419   } while(1);
 420 
 421   sl->rpacket++;
 422 }
 423 
 424 
 425 /* TTY finished sending a datagram, so clean up. */
 426 static void
 427 sl_next(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 428 {
 429   DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
 430   sl_unlock(sl);
 431   dev_tint(sl->dev);
 432 }
 433 
 434 
 435 /* Encapsulate one IP datagram and stuff into a TTY queue. */
 436 static void
 437 sl_encaps(struct slip *sl, unsigned char *icp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 438 {
 439   unsigned char *bp, *p;
 440   int count;
 441 
 442   DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", icp, len));
 443   DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
 444   
 445   ip_dump(icp, len);
 446   
 447   if(sl->mtu != sl->dev->mtu)   /* Someone has been ifconfigging */
 448         sl_changedmtu(sl);
 449   
 450   if(len>sl->mtu)               /* Sigh, shouldn't occur BUT ... */
 451   {
 452         len=sl->mtu;
 453         printk("slip: truncating oversized transmit packet!\n");
 454   }
 455 
 456   p = icp;
 457   if(sl->mode & SL_MODE_CSLIP)
 458           len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
 459 
 460 #ifdef OLD  
 461   /*
 462    * Send an initial END character to flush out any
 463    * data that may have accumulated in the receiver
 464    * due to line noise.
 465    */
 466   bp = sl->xbuff;
 467   *bp++ = END;
 468   count = 1;
 469 
 470   /*
 471    * For each byte in the packet, send the appropriate
 472    * character sequence, according to the SLIP protocol.
 473    */
 474   while(len-- > 0) {
 475         c = *p++;
 476         switch(c) {
 477                 case END:
 478                         *bp++ = ESC;
 479                         *bp++ = ESC_END;
 480                         count += 2;
 481                         break;
 482                 case ESC:
 483                         *bp++ = ESC;
 484                         *bp++ = ESC_ESC;
 485                         count += 2;
 486                         break;
 487                 default:
 488                         *bp++ = c;
 489                         count++;
 490         }
 491   }
 492   *bp++ = END;  
 493   count++;
 494 #else
 495   if(sl->mode & SL_MODE_SLIP6)
 496         count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
 497   else
 498         count=slip_esc(p, (unsigned char *)sl->xbuff,len);
 499 #endif            
 500   sl->spacket++;
 501   bp = sl->xbuff;
 502 
 503   /* Tell TTY to send it on its way. */
 504   DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
 505   if (tty_write_data(sl->tty, (char *) bp, count,
 506              (void (*)(void *))sl_next, (void *) sl) == 0) {
 507         DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
 508         sl_next(sl);
 509   }
 510 }
 511 
 512 /*static void sl_hex_dump(unsigned char *x,int l)
 513 {
 514         int n=0;
 515         printk("sl_xmit: (%d bytes)\n",l);
 516         while(l)
 517         {
 518                 printk("%2X ",(int)*x++);
 519                 l--;
 520                 n++;
 521                 if(n%32==0)
 522                         printk("\n");
 523         }
 524         if(n%32)
 525                 printk("\n");
 526 }*/
 527 
 528 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 529 static int
 530 sl_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532   struct tty_struct *tty;
 533   struct slip *sl;
 534   int size;
 535 
 536   /* Find the correct SLIP channel to use. */
 537   sl = &sl_ctrl[dev->base_addr];
 538   tty = sl->tty;
 539   DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
 540                                 dev->name, skb, sl->sending));
 541 
 542   /*
 543    * If we are busy already- too bad.  We ought to be able
 544    * to queue things at this point, to allow for a little
 545    * frame buffer.  Oh well...
 546    */
 547   if (sl->sending) {
 548         DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
 549         sl->sbusy++;
 550         return(1);
 551   }
 552 
 553   /* We were not, so we are now... :-) */
 554   if (skb != NULL) {
 555 #ifdef CONFIG_AX25  
 556         if(sl->mode & SL_MODE_AX25)
 557         {
 558                 if(!skb->arp && dev->rebuild_header(skb->data,dev))
 559                 {
 560                         skb->dev=dev;
 561                         arp_queue(skb);
 562                         return 0;
 563                 }
 564                 skb->arp=1;
 565         }
 566 #endif          
 567         sl_lock(sl);
 568         size = skb->len;
 569         if (!(sl->mode & SL_MODE_AX25)) {
 570                 if (size < sizeof(struct iphdr)) {
 571                         printk("Runt IP frame fed to slip!\n");
 572                 } else {
 573                         size = ((struct iphdr *)(skb->data))->tot_len;
 574                         size = ntohs(size);
 575                 }
 576         }
 577         /*      sl_hex_dump(skb->data,skb->len);*/
 578         sl_encaps(sl, skb->data, size);
 579         if (skb->free)
 580                 kfree_skb(skb, FREE_WRITE);
 581   }
 582   return(0);
 583 }
 584 
 585 /* Return the frame type ID.  This is normally IP but maybe be AX.25. */
 586 static unsigned short
 587 sl_type_trans (struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 588 {
 589 #ifdef CONFIG_AX25
 590         struct slip *sl=&sl_ctrl[dev->base_addr];
 591         if(sl->mode&SL_MODE_AX25)
 592                 return(NET16(ETH_P_AX25));
 593 #endif
 594   return(NET16(ETH_P_IP));
 595 }
 596 
 597 
 598 /* Fill in the MAC-level header. Not used by SLIP. */
 599 static int
 600 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
     /* [previous][next][first][last][top][bottom][index][help] */
 601           unsigned long daddr, unsigned long saddr, unsigned len)
 602 {
 603 #ifdef CONFIG_AX25
 604   struct slip *sl=&sl_ctrl[dev->base_addr];
 605   if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
 606         return ax25_encapsulate_ip(buff,dev,type,daddr,saddr,len);
 607 #endif  
 608 
 609   return(0);
 610 }
 611 
 612 
 613 /* Add an ARP-entry for this device's broadcast address. Not used. */
 614 static void
 615 sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 616 {
 617 #ifdef CONFIG_AX25
 618         struct slip *sl=&sl_ctrl[dev->base_addr];
 619         
 620         if(sl->mode&SL_MODE_AX25)
 621                 arp_add(addr,((char *) skb->data)+8,dev);
 622 #endif          
 623 }
 624 
 625 
 626 /* Rebuild the MAC-level header.  Not used by SLIP. */
 627 static int
 628 sl_rebuild_header(void *buff, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 629 {
 630 #ifdef CONFIG_AX25
 631   struct slip *sl=&sl_ctrl[dev->base_addr];
 632   
 633   if(sl->mode&SL_MODE_AX25)
 634         return ax25_rebuild_header(buff,dev);
 635 #endif  
 636   return(0);
 637 }
 638 
 639 
 640 /* Open the low-level part of the SLIP channel. Easy! */
 641 static int
 642 sl_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 643 {
 644   struct slip *sl;
 645   unsigned char *p;
 646   unsigned long l;
 647 
 648   sl = &sl_ctrl[dev->base_addr];
 649   if (sl->tty == NULL) {
 650         DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
 651         return(-ENXIO);
 652   }
 653   sl->dev = dev;
 654 
 655   /*
 656    * Allocate the SLIP frame buffers:
 657    *
 658    * mem_end    Top of frame buffers
 659    * mem_start  Start of frame buffers
 660    * rmem_end   Top of RECV frame buffer
 661    * rmem_start Start of RECV frame buffer
 662    */
 663   l = (dev->mtu * 2);
 664 /*
 665  * allow for arrival of larger UDP packets, even if we say not to
 666  * also fixes a bug in which SunOS sends 512-byte packets even with
 667  * an MSS of 128
 668  */
 669   if (l < (576 * 2))
 670     l = 576 * 2;
 671 
 672   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 673   if (p == NULL) {
 674         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
 675         return(-ENOMEM);
 676   }
 677   
 678   sl->mtu               = dev->mtu;
 679   sl->dev->mem_start    = (unsigned long) p;
 680   sl->dev->mem_end      = (unsigned long) (sl->dev->mem_start + l);
 681 
 682   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 683   if (p == NULL) {
 684         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
 685         return(-ENOMEM);
 686   }
 687   sl->dev->rmem_start   = (unsigned long) p;
 688   sl->dev->rmem_end     = (unsigned long) (sl->dev->rmem_start + l);
 689 
 690   sl->xbuff             = (unsigned char *) sl->dev->mem_start;
 691   sl->rbuff             = (unsigned char *) sl->dev->rmem_start;
 692   sl->rend              = (unsigned char *) sl->dev->rmem_end;
 693   sl->rhead             = sl->rbuff;
 694 
 695   sl->escape            = 0;
 696   sl->sending           = 0;
 697   sl->rcount            = 0;
 698 
 699   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 700   if (p == NULL) {
 701         kfree((unsigned char *)sl->dev->mem_start);
 702         DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
 703         return(-ENOMEM);
 704   }
 705   sl->cbuff             = p;
 706 
 707   sl->slcomp = slhc_init(16, 16);
 708   if (sl->slcomp == NULL) {
 709         kfree((unsigned char *)sl->dev->mem_start);
 710         kfree((unsigned char *)sl->dev->rmem_start);
 711         kfree(sl->cbuff);
 712         DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
 713         return(-ENOMEM);
 714   }
 715 
 716   dev->flags|=IFF_UP;
 717   /* Needed because address '0' is special */
 718   if(dev->pa_addr==0)
 719         dev->pa_addr=ntohl(0xC0000001);
 720   DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
 721   return(0);
 722 }
 723 
 724 
 725 /* Close the low-level part of the SLIP channel. Easy! */
 726 static int
 727 sl_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 728 {
 729   struct slip *sl;
 730 
 731   sl = &sl_ctrl[dev->base_addr];
 732   if (sl->tty == NULL) {
 733         DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
 734         return(-EBUSY);
 735   }
 736   sl_free(sl);
 737 
 738   /* Free all SLIP frame buffers. */
 739   kfree(sl->rbuff);
 740   kfree(sl->xbuff);
 741   kfree(sl->cbuff);
 742   slhc_free(sl->slcomp);
 743 
 744   sl_initialize(sl, dev);
 745 
 746   DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
 747   return(0);
 748 }
 749 
 750 
 751 /*
 752  * Handle the 'receiver data ready' interrupt.
 753  * This function is called by the 'tty_io' module in the kernel when
 754  * a block of SLIP data has been received, which can now be decapsulated
 755  * and sent on to some IP layer for further processing.
 756  */
 757 static void
 758 slip_recv(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 759 {
 760   unsigned char buff[128];
 761   unsigned char *p;
 762   struct slip *sl;
 763   int count, error=0;
 764   
 765   DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
 766   if ((sl = sl_find(tty)) == NULL) return;      /* not connected */
 767 
 768   if(sl->mtu!=sl->dev->mtu)     /* Argh! mtu change time! - costs us the packet part received at the change */
 769         sl_changedmtu(sl);
 770         
 771   /* Suck the bytes out of the TTY queues. */
 772   do {
 773         count = tty_read_raw_data(tty, buff, 128);
 774         if (count <= 0)
 775         {
 776                 count= - count;
 777                 if(count)
 778                         error=1;
 779                 break;
 780         }
 781         p = buff;
 782 #ifdef OLD      
 783         while (count--) {
 784                 c = *p++;
 785                 if (sl->escape) {
 786                         if (c == ESC_ESC)
 787                                 sl_enqueue(sl, ESC);
 788                         else if (c == ESC_END)
 789                                 sl_enqueue(sl, END);
 790                         else
 791                                 printk ("SLIP: received wrong character\n");
 792                         sl->escape = 0;
 793                 } else {
 794                         if (c == ESC)
 795                                 sl->escape = 1;
 796                         else if (c == END) {
 797                                 if (sl->rcount > 2) sl_bump(sl);
 798                                 sl_dequeue(sl, sl->rcount);
 799                                 sl->rcount = 0;
 800                         } else  sl_enqueue(sl, c);
 801                 }
 802         }
 803 #else
 804         if(sl->mode & SL_MODE_SLIP6)
 805                 slip_unesc6(sl,buff,count,error);
 806         else
 807                 slip_unesc(sl,buff,count,error);
 808 #endif          
 809   } while(1);
 810   
 811 }
 812 
 813 
 814 /*
 815  * Open the high-level part of the SLIP channel.  
 816  * This function is called by the TTY module when the
 817  * SLIP line discipline is called for.  Because we are
 818  * sure the tty line exists, we only have to link it to
 819  * a free SLIP channel...
 820  */
 821 static int
 822 slip_open(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 823 {
 824   struct slip *sl;
 825 
 826   /* First make sure we're not already connected. */
 827   if ((sl = sl_find(tty)) != NULL) {
 828         DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
 829                                         tty->line, sl->dev->name));
 830         return(-EEXIST);
 831   }
 832 
 833   /* OK.  Find a free SLIP channel to use. */
 834   if ((sl = sl_alloc()) == NULL) {
 835         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
 836                                                 tty->line));
 837         return(-ENFILE);
 838   }
 839   sl->tty = tty;
 840   tty_read_flush(tty);
 841   tty_write_flush(tty);
 842 
 843   /* Perform the low-level SLIP initialization. */
 844   (void) sl_open(sl->dev);
 845   DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
 846                                 tty->line, sl->dev->name));
 847 
 848   /* Done.  We have linked the TTY line to a channel. */
 849   return(sl->line);
 850 }
 851 
 852  
 853 static struct enet_statistics *
 854 sl_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 855 {
 856     static struct enet_statistics stats;
 857     struct slip *sl;
 858     struct slcompress *comp;
 859 
 860     /* Find the correct SLIP channel to use. */
 861     sl = &sl_ctrl[dev->base_addr];
 862     if (! sl)
 863       return NULL;
 864 
 865     memset(&stats, 0, sizeof(struct enet_statistics));
 866 
 867     stats.rx_packets = sl->rpacket;
 868     stats.rx_over_errors = sl->roverrun;
 869     stats.tx_packets = sl->spacket;
 870     stats.tx_dropped = sl->sbusy;
 871     stats.rx_errors = sl->errors;
 872 
 873     comp = sl->slcomp;
 874     if (comp) {
 875       stats.rx_fifo_errors = comp->sls_i_compressed;
 876       stats.rx_dropped = comp->sls_i_tossed;
 877       stats.tx_fifo_errors = comp->sls_o_compressed;
 878       stats.collisions = comp->sls_o_misses;
 879     }
 880 
 881     return (&stats);
 882 }
 883 
 884 /*
 885  * Close down a SLIP channel.
 886  * This means flushing out any pending queues, and then restoring the
 887  * TTY line discipline to what it was before it got hooked to SLIP
 888  * (which usually is TTY again).
 889  */
 890 static void
 891 slip_close(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 892 {
 893   struct slip *sl;
 894 
 895   /* First make sure we're connected. */
 896   if ((sl = sl_find(tty)) == NULL) {
 897         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
 898         return;
 899   }
 900 
 901   (void) dev_close(sl->dev);
 902   DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
 903                                         tty->line, sl->dev->name));
 904 }
 905 
 906  
 907  /************************************************************************
 908   *                     STANDARD SLIP ENCAPSULATION                     *
 909   ************************************************************************
 910   *
 911   */
 912  
 913  int
 914  slip_esc(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 915  {
 916      int count = 0;
 917  
 918      /*
 919       * Send an initial END character to flush out any
 920       * data that may have accumulated in the receiver
 921       * due to line noise.
 922       */
 923  
 924      d[count++] = END;
 925  
 926      /*
 927       * For each byte in the packet, send the appropriate
 928       * character sequence, according to the SLIP protocol.
 929       */
 930  
 931      while(len-- > 0) {
 932         switch(*s) {
 933         case END:
 934             d[count++] = ESC;
 935             d[count++] = ESC_END;
 936             break;
 937         case ESC:
 938             d[count++] = ESC;
 939             d[count++] = ESC_ESC;
 940             break;
 941         default:
 942             d[count++] = *s;
 943         }
 944         ++s;
 945      }
 946      d[count++] = END;
 947      return(count);
 948  }
 949  
 950  void
 951  slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
 952  {
 953      int i;
 954  
 955      for (i = 0; i < count; ++i, ++s) {
 956         switch(*s) {
 957         case ESC:
 958             sl->flags |= SLF_ESCAPE;
 959             break;
 960         case ESC_ESC:
 961             if (sl->flags & SLF_ESCAPE)
 962                 sl_enqueue(sl, ESC);
 963             else
 964                 sl_enqueue(sl, *s);
 965             sl->flags &= ~SLF_ESCAPE;
 966             break;
 967         case ESC_END:
 968             if (sl->flags & SLF_ESCAPE)
 969                 sl_enqueue(sl, END);
 970             else
 971                 sl_enqueue(sl, *s);
 972             sl->flags &= ~SLF_ESCAPE;
 973             break;
 974         case END:
 975             if (sl->rcount > 2) 
 976                 sl_bump(sl);
 977             sl_dequeue(sl, sl->rcount);
 978             sl->rcount = 0;
 979             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
 980             break;
 981         default:
 982             sl_enqueue(sl, *s);
 983             sl->flags &= ~SLF_ESCAPE;
 984         }
 985      }
 986      if (error)
 987         sl->flags |= SLF_ERROR;
 988  }
 989  
 990  /************************************************************************
 991   *                      6 BIT SLIP ENCAPSULATION                       *
 992   ************************************************************************
 993   *
 994   */
 995  
 996  int
 997  slip_esc6(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 998  {
 999      int count = 0;
1000      int i;
1001      unsigned short v = 0;
1002      short bits = 0;
1003  
1004      /*
1005       * Send an initial END character to flush out any
1006       * data that may have accumulated in the receiver
1007       * due to line noise.
1008       */
1009  
1010      d[count++] = 0x70;
1011  
1012      /*
1013       * Encode the packet into printable ascii characters
1014       */
1015  
1016      for (i = 0; i < len; ++i) {
1017         v = (v << 8) | s[i];
1018         bits += 8;
1019         while (bits >= 6) {
1020             unsigned char c;
1021  
1022             bits -= 6;
1023             c = 0x30 + ((v >> bits) & 0x3F);
1024             d[count++] = c;
1025         }
1026      }
1027      if (bits) {
1028         unsigned char c;
1029  
1030         c = 0x30 + ((v << (6 - bits)) & 0x3F);
1031         d[count++] = c;
1032      }
1033      d[count++] = 0x70;
1034      return(count);
1035  }
1036  
1037  void
1038  slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
1039  {
1040      int i;
1041      unsigned char c;
1042  
1043      for (i = 0; i < count; ++i, ++s) {
1044         if (*s == 0x70) {
1045             if (sl->rcount > 8) {       /* XXX must be 2 for compressed slip */
1046  #ifdef NOTDEF
1047                 printk("rbuff %02x %02x %02x %02x\n",
1048                     sl->rbuff[0],
1049                     sl->rbuff[1],
1050                     sl->rbuff[2],
1051                     sl->rbuff[3]
1052                 );
1053  #endif
1054                 sl_bump(sl);
1055             }
1056             sl_dequeue(sl, sl->rcount);
1057             sl->rcount = 0;
1058             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
1059             sl->xbits = 0;
1060         } else if (*s >= 0x30 && *s < 0x70) {
1061             sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
1062             sl->xbits += 6;
1063             if (sl->xbits >= 8) {
1064                 sl->xbits -= 8;
1065                 c = (unsigned char)(sl->xdata >> sl->xbits);
1066                 sl_enqueue(sl, c);
1067             }
1068  
1069         }
1070      }
1071      if (error)
1072         sl->flags |= SLF_ERROR;
1073  }
1074 
1075 
1076 #ifdef CONFIG_AX25
1077 
1078 int sl_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
1079 {
1080         int err=verify_area(VERIFY_READ,addr,7);
1081         if(err)
1082                 return err;
1083         memcpy_fromfs(dev->dev_addr,addr,7);    /* addr is an AX.25 shifted ASCII mac address */
1084         return 0;
1085 }
1086 #endif
1087 
1088 
1089 /* Perform I/O control on an active SLIP channel. */
1090 static int
1091 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1092 {
1093   struct slip *sl;
1094   int err;
1095 
1096   /* First make sure we're connected. */
1097   if ((sl = sl_find(tty)) == NULL) {
1098         DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
1099         return(-EINVAL);
1100   }
1101 
1102   DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
1103   switch(cmd) {
1104         case SIOCGIFNAME:
1105                 err=verify_area(VERIFY_WRITE, arg, strlen(sl->dev->name) + 1);
1106                 if(err)
1107                         return err;
1108                 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
1109                 return(0);
1110         case SIOCGIFENCAP:
1111                 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
1112                 put_fs_long(sl->mode,(long *)arg);
1113                 return(0);
1114         case SIOCSIFENCAP:
1115                 err=verify_area(VERIFY_READ,arg,sizeof(long));
1116                 sl->mode=get_fs_long((long *)arg);
1117 #ifdef CONFIG_AX25              
1118                 if(sl->mode & SL_MODE_AX25)
1119                 {
1120                         sl->dev->addr_len=7;    /* sizeof an AX.25 addr */
1121                         sl->dev->hard_header_len=17;    /* We don't do digipeaters */
1122                         sl->dev->type=3;                /* AF_AX25 not an AF_INET device */
1123                 }
1124                 else
1125                 {
1126                         sl->dev->addr_len=0;    /* No mac addr in slip mode */
1127                         sl->dev->hard_header_len=0;
1128                         sl->dev->type=0;
1129                 }
1130 #endif          
1131                 return(0);
1132         case SIOCSIFHWADDR:
1133 #ifdef CONFIG_AX25      
1134                 return sl_set_mac_address(sl->dev,arg);
1135 #endif
1136         default:
1137                 return(-EINVAL);
1138   }
1139   return(-EINVAL);
1140 }
1141 
1142 
1143 /* Initialize the SLIP driver.  Called by DDI. */
1144 int
1145 slip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1146 {
1147   struct slip *sl;
1148   int i;
1149 #ifdef CONFIG_AX25  
1150   static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1151   static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1152 #endif
1153 
1154   sl = &sl_ctrl[dev->base_addr];
1155 
1156   if (already++ == 0) {
1157         printk("SLIP: version %s (%d channels)\n",
1158                                 SLIP_VERSION, SL_NRUNIT);
1159         printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1160 #ifdef CONFIG_AX25
1161         printk("AX25: KISS encapsulation enabled\n");
1162 #endif  
1163         /* Fill in our LDISC request block. */
1164         sl_ldisc.flags  = 0;
1165         sl_ldisc.open   = slip_open;
1166         sl_ldisc.close  = slip_close;
1167         sl_ldisc.read   = NULL;
1168         sl_ldisc.write  = NULL;
1169         sl_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
1170                                    unsigned int, unsigned long)) slip_ioctl;
1171         sl_ldisc.select = NULL;
1172         sl_ldisc.handler = slip_recv;
1173         if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
1174                 printk("ERROR: %d\n", i);
1175   }
1176 
1177   /* Set up the "SLIP Control Block". */
1178   sl_initialize(sl, dev);
1179 
1180   /* Clear all statistics. */
1181   sl->rcount            = 0;                    /* SLIP receiver count  */
1182   sl->rpacket           = 0;                    /* #frames received     */
1183   sl->roverrun          = 0;                    /* "overrun" counter    */
1184   sl->spacket           = 0;                    /* #frames sent out     */
1185   sl->sbusy             = 0;                    /* "xmit busy" counter  */
1186   sl->errors            = 0;                    /* not used at present  */
1187 
1188   /* Finish setting up the DEVICE info. */
1189   dev->mtu              = SL_MTU;
1190   dev->hard_start_xmit  = sl_xmit;
1191   dev->open             = sl_open;
1192   dev->stop             = sl_close;
1193   dev->hard_header      = sl_header;
1194   dev->add_arp          = sl_add_arp;
1195   dev->type_trans       = sl_type_trans;
1196   dev->get_stats        = sl_get_stats;
1197 #ifdef HAVE_SET_MAC_ADDR
1198 #ifdef CONFIG_AX25
1199   dev->set_mac_address  = sl_set_mac_address;
1200 #endif
1201 #endif
1202   dev->hard_header_len  = 0;
1203   dev->addr_len         = 0;
1204   dev->type             = 0;
1205 #ifdef CONFIG_AX25  
1206   memcpy(dev->broadcast,ax25_bcast,7);          /* Only activated in AX.25 mode */
1207   memcpy(dev->dev_addr,ax25_test,7);            /*    ""      ""       ""    "" */
1208 #endif  
1209   dev->queue_xmit       = dev_queue_xmit;
1210   dev->rebuild_header   = sl_rebuild_header;
1211   for (i = 0; i < DEV_NUMBUFFS; i++)
1212                 dev->buffs[i] = NULL;
1213 
1214   /* New-style flags. */
1215   dev->flags            = 0;
1216   dev->family           = AF_INET;
1217   dev->pa_addr          = 0;
1218   dev->pa_brdaddr       = 0;
1219   dev->pa_mask          = 0;
1220   dev->pa_alen          = sizeof(unsigned long);
1221 
1222   return(0);
1223 }

/* [previous][next][first][last][top][bottom][index][help] */