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

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