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

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