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->data,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(skb->data,skb->len);*/
 559         sl_encaps(sl, skb->data, 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->data)+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   dev->flags|=IFF_UP;
 690   /* Needed because address '0' is special */
 691   if(dev->pa_addr==0)
 692         dev->pa_addr=ntohl(0xC0000001);
 693   DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
 694   return(0);
 695 }
 696 
 697 
 698 /* Close the low-level part of the SLIP channel. Easy! */
 699 static int
 700 sl_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 701 {
 702   struct slip *sl;
 703 
 704   sl = &sl_ctrl[dev->base_addr];
 705   if (sl->tty == NULL) {
 706         DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
 707         return(-EBUSY);
 708   }
 709   sl_free(sl);
 710 
 711   /* Free all SLIP frame buffers. */
 712   kfree(sl->rbuff);
 713   kfree(sl->xbuff);
 714   kfree(sl->cbuff);
 715   slhc_free(sl->slcomp);
 716 
 717   sl_initialize(sl, dev);
 718 
 719   DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
 720   return(0);
 721 }
 722 
 723 
 724 /*
 725  * Handle the 'receiver data ready' interrupt.
 726  * This function is called by the 'tty_io' module in the kernel when
 727  * a block of SLIP data has been received, which can now be decapsulated
 728  * and sent on to some IP layer for further processing.
 729  */
 730 static void
 731 slip_recv(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 732 {
 733   unsigned char buff[128];
 734   unsigned char *p;
 735   struct slip *sl;
 736   int count, error=0;
 737   
 738   DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
 739   if ((sl = sl_find(tty)) == NULL) return;      /* not connected */
 740 
 741   if(sl->mtu!=sl->dev->mtu)     /* Argh! mtu change time! - costs us the packet part received at the change */
 742         sl_changedmtu(sl);
 743         
 744   /* Suck the bytes out of the TTY queues. */
 745   do {
 746         count = tty_read_raw_data(tty, buff, 128);
 747         if (count <= 0)
 748         {
 749                 count= - count;
 750                 if(count)
 751                         error=1;
 752                 break;
 753         }
 754         p = buff;
 755 #ifdef OLD      
 756         while (count--) {
 757                 c = *p++;
 758                 if (sl->escape) {
 759                         if (c == ESC_ESC)
 760                                 sl_enqueue(sl, ESC);
 761                         else if (c == ESC_END)
 762                                 sl_enqueue(sl, END);
 763                         else
 764                                 printk ("SLIP: received wrong character\n");
 765                         sl->escape = 0;
 766                 } else {
 767                         if (c == ESC)
 768                                 sl->escape = 1;
 769                         else if (c == END) {
 770                                 if (sl->rcount > 2) sl_bump(sl);
 771                                 sl_dequeue(sl, sl->rcount);
 772                                 sl->rcount = 0;
 773                         } else  sl_enqueue(sl, c);
 774                 }
 775         }
 776 #else
 777         if(sl->mode & SL_MODE_SLIP6)
 778                 slip_unesc6(sl,buff,count,error);
 779         else
 780                 slip_unesc(sl,buff,count,error);
 781 #endif          
 782   } while(1);
 783   
 784 }
 785 
 786 
 787 /*
 788  * Open the high-level part of the SLIP channel.  
 789  * This function is called by the TTY module when the
 790  * SLIP line discipline is called for.  Because we are
 791  * sure the tty line exists, we only have to link it to
 792  * a free SLIP channel...
 793  */
 794 static int
 795 slip_open(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797   struct slip *sl;
 798 
 799   /* First make sure we're not already connected. */
 800   if ((sl = sl_find(tty)) != NULL) {
 801         DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
 802                                         tty->line, sl->dev->name));
 803         return(-EEXIST);
 804   }
 805 
 806   /* OK.  Find a free SLIP channel to use. */
 807   if ((sl = sl_alloc()) == NULL) {
 808         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
 809                                                 tty->line));
 810         return(-ENFILE);
 811   }
 812   sl->tty = tty;
 813   tty_read_flush(tty);
 814   tty_write_flush(tty);
 815 
 816   /* Perform the low-level SLIP initialization. */
 817   (void) sl_open(sl->dev);
 818   DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
 819                                 tty->line, sl->dev->name));
 820 
 821   /* Done.  We have linked the TTY line to a channel. */
 822   return(sl->line);
 823 }
 824 
 825  
 826 static struct enet_statistics *
 827 sl_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 828 {
 829     static struct enet_statistics stats;
 830     struct slip *sl;
 831     struct slcompress *comp;
 832 
 833     /* Find the correct SLIP channel to use. */
 834     sl = &sl_ctrl[dev->base_addr];
 835     if (! sl)
 836       return NULL;
 837 
 838     memset(&stats, 0, sizeof(struct enet_statistics));
 839 
 840     stats.rx_packets = sl->rpacket;
 841     stats.rx_over_errors = sl->roverrun;
 842     stats.tx_packets = sl->spacket;
 843     stats.tx_dropped = sl->sbusy;
 844     stats.rx_errors = sl->errors;
 845 
 846     comp = sl->slcomp;
 847     if (comp) {
 848       stats.rx_fifo_errors = comp->sls_i_compressed;
 849       stats.rx_dropped = comp->sls_i_tossed;
 850       stats.tx_fifo_errors = comp->sls_o_compressed;
 851       stats.collisions = comp->sls_o_misses;
 852     }
 853 
 854     return (&stats);
 855 }
 856 
 857 /*
 858  * Close down a SLIP channel.
 859  * This means flushing out any pending queues, and then restoring the
 860  * TTY line discipline to what it was before it got hooked to SLIP
 861  * (which usually is TTY again).
 862  */
 863 static void
 864 slip_close(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 865 {
 866   struct slip *sl;
 867 
 868   /* First make sure we're connected. */
 869   if ((sl = sl_find(tty)) == NULL) {
 870         DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
 871         return;
 872   }
 873 
 874   (void) dev_close(sl->dev);
 875   DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
 876                                         tty->line, sl->dev->name));
 877 }
 878 
 879  
 880  /************************************************************************
 881   *                     STANDARD SLIP ENCAPSULATION                     *
 882   ************************************************************************
 883   *
 884   */
 885  
 886  int
 887  slip_esc(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 888  {
 889      int count = 0;
 890  
 891      /*
 892       * Send an initial END character to flush out any
 893       * data that may have accumulated in the receiver
 894       * due to line noise.
 895       */
 896  
 897      d[count++] = END;
 898  
 899      /*
 900       * For each byte in the packet, send the appropriate
 901       * character sequence, according to the SLIP protocol.
 902       */
 903  
 904      while(len-- > 0) {
 905         switch(*s) {
 906         case END:
 907             d[count++] = ESC;
 908             d[count++] = ESC_END;
 909             break;
 910         case ESC:
 911             d[count++] = ESC;
 912             d[count++] = ESC_ESC;
 913             break;
 914         default:
 915             d[count++] = *s;
 916         }
 917         ++s;
 918      }
 919      d[count++] = END;
 920      return(count);
 921  }
 922  
 923  void
 924  slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
 925  {
 926      int i;
 927  
 928      for (i = 0; i < count; ++i, ++s) {
 929         switch(*s) {
 930         case ESC:
 931             sl->flags |= SLF_ESCAPE;
 932             break;
 933         case ESC_ESC:
 934             if (sl->flags & SLF_ESCAPE)
 935                 sl_enqueue(sl, ESC);
 936             else
 937                 sl_enqueue(sl, *s);
 938             sl->flags &= ~SLF_ESCAPE;
 939             break;
 940         case ESC_END:
 941             if (sl->flags & SLF_ESCAPE)
 942                 sl_enqueue(sl, END);
 943             else
 944                 sl_enqueue(sl, *s);
 945             sl->flags &= ~SLF_ESCAPE;
 946             break;
 947         case END:
 948             if (sl->rcount > 2) 
 949                 sl_bump(sl);
 950             sl_dequeue(sl, sl->rcount);
 951             sl->rcount = 0;
 952             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
 953             break;
 954         default:
 955             sl_enqueue(sl, *s);
 956             sl->flags &= ~SLF_ESCAPE;
 957         }
 958      }
 959      if (error)
 960         sl->flags |= SLF_ERROR;
 961  }
 962  
 963  /************************************************************************
 964   *                      6 BIT SLIP ENCAPSULATION                       *
 965   ************************************************************************
 966   *
 967   */
 968  
 969  int
 970  slip_esc6(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 971  {
 972      int count = 0;
 973      int i;
 974      unsigned short v = 0;
 975      short bits = 0;
 976  
 977      /*
 978       * Send an initial END character to flush out any
 979       * data that may have accumulated in the receiver
 980       * due to line noise.
 981       */
 982  
 983      d[count++] = 0x70;
 984  
 985      /*
 986       * Encode the packet into printable ascii characters
 987       */
 988  
 989      for (i = 0; i < len; ++i) {
 990         v = (v << 8) | s[i];
 991         bits += 8;
 992         while (bits >= 6) {
 993             unsigned char c;
 994  
 995             bits -= 6;
 996             c = 0x30 + ((v >> bits) & 0x3F);
 997             d[count++] = c;
 998         }
 999      }
1000      if (bits) {
1001         unsigned char c;
1002  
1003         c = 0x30 + ((v << (6 - bits)) & 0x3F);
1004         d[count++] = c;
1005      }
1006      d[count++] = 0x70;
1007      return(count);
1008  }
1009  
1010  void
1011  slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
     /* [previous][next][first][last][top][bottom][index][help] */
1012  {
1013      int i;
1014      unsigned char c;
1015  
1016      for (i = 0; i < count; ++i, ++s) {
1017         if (*s == 0x70) {
1018             if (sl->rcount > 8) {       /* XXX must be 2 for compressed slip */
1019  #ifdef NOTDEF
1020                 printk("rbuff %02x %02x %02x %02x\n",
1021                     sl->rbuff[0],
1022                     sl->rbuff[1],
1023                     sl->rbuff[2],
1024                     sl->rbuff[3]
1025                 );
1026  #endif
1027                 sl_bump(sl);
1028             }
1029             sl_dequeue(sl, sl->rcount);
1030             sl->rcount = 0;
1031             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
1032             sl->xbits = 0;
1033         } else if (*s >= 0x30 && *s < 0x70) {
1034             sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
1035             sl->xbits += 6;
1036             if (sl->xbits >= 8) {
1037                 sl->xbits -= 8;
1038                 c = (unsigned char)(sl->xdata >> sl->xbits);
1039                 sl_enqueue(sl, c);
1040             }
1041  
1042         }
1043      }
1044      if (error)
1045         sl->flags |= SLF_ERROR;
1046  }
1047 
1048 
1049 #ifdef CONFIG_AX25
1050 
1051 int sl_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
1052 {
1053         int err=verify_area(VERIFY_READ,addr,7);
1054         if(err)
1055                 return err;
1056         memcpy_fromfs(dev->dev_addr,addr,7);    /* addr is an AX.25 shifted ASCII mac address */
1057         return 0;
1058 }
1059 #endif
1060 
1061 
1062 /* Perform I/O control on an active SLIP channel. */
1063 static int
1064 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1065 {
1066   struct slip *sl;
1067   int err;
1068 
1069   /* First make sure we're connected. */
1070   if ((sl = sl_find(tty)) == NULL) {
1071         DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
1072         return(-EINVAL);
1073   }
1074 
1075   DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
1076   switch(cmd) {
1077         case SIOCGIFNAME:
1078                 err=verify_area(VERIFY_WRITE, arg, 16);
1079                 if(err)
1080                         return -err;
1081                 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
1082                 return(0);
1083         case SIOCGIFENCAP:
1084                 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
1085                 put_fs_long(sl->mode,(long *)arg);
1086                 return(0);
1087         case SIOCSIFENCAP:
1088                 err=verify_area(VERIFY_READ,arg,sizeof(long));
1089                 sl->mode=get_fs_long((long *)arg);
1090 #ifdef CONFIG_AX25              
1091                 if(sl->mode & SL_MODE_AX25)
1092                 {
1093                         sl->dev->addr_len=7;    /* sizeof an AX.25 addr */
1094                         sl->dev->hard_header_len=17;    /* We don't do digipeaters */
1095                         sl->dev->type=3;                /* AF_AX25 not an AF_INET device */
1096                 }
1097                 else
1098                 {
1099                         sl->dev->addr_len=0;    /* No mac addr in slip mode */
1100                         sl->dev->hard_header_len=0;
1101                         sl->dev->type=0;
1102                 }
1103 #endif          
1104                 return(0);
1105         case SIOCSIFHWADDR:
1106 #ifdef CONFIG_AX25      
1107                 return sl_set_mac_address(sl->dev,arg);
1108 #endif
1109         default:
1110                 return(-EINVAL);
1111   }
1112   return(-EINVAL);
1113 }
1114 
1115 
1116 /* Initialize the SLIP driver.  Called by DDI. */
1117 int
1118 slip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1119 {
1120   struct slip *sl;
1121   int i;
1122 #ifdef CONFIG_AX25  
1123   static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1124   static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1125 #endif
1126 
1127   sl = &sl_ctrl[dev->base_addr];
1128 
1129   if (already++ == 0) {
1130         printk("SLIP: version %s (%d channels)\n",
1131                                 SLIP_VERSION, SL_NRUNIT);
1132         printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1133 #ifdef CONFIG_AX25
1134         printk("AX25: KISS encapsulation enabled\n");
1135 #endif  
1136         /* Fill in our LDISC request block. */
1137         sl_ldisc.flags  = 0;
1138         sl_ldisc.open   = slip_open;
1139         sl_ldisc.close  = slip_close;
1140         sl_ldisc.read   = NULL;
1141         sl_ldisc.write  = NULL;
1142         sl_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
1143                                    unsigned int, unsigned long)) slip_ioctl;
1144         sl_ldisc.select = NULL;
1145         sl_ldisc.handler = slip_recv;
1146         if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
1147                 printk("ERROR: %d\n", i);
1148   }
1149 
1150   /* Set up the "SLIP Control Block". */
1151   sl_initialize(sl, dev);
1152 
1153   /* Clear all statistics. */
1154   sl->rcount            = 0;                    /* SLIP receiver count  */
1155   sl->rpacket           = 0;                    /* #frames received     */
1156   sl->roverrun          = 0;                    /* "overrun" counter    */
1157   sl->spacket           = 0;                    /* #frames sent out     */
1158   sl->sbusy             = 0;                    /* "xmit busy" counter  */
1159   sl->errors            = 0;                    /* not used at present  */
1160 
1161   /* Finish setting up the DEVICE info. */
1162   dev->mtu              = SL_MTU;
1163   dev->hard_start_xmit  = sl_xmit;
1164   dev->open             = sl_open;
1165   dev->stop             = sl_close;
1166   dev->hard_header      = sl_header;
1167   dev->add_arp          = sl_add_arp;
1168   dev->type_trans       = sl_type_trans;
1169   dev->get_stats        = sl_get_stats;
1170 #ifdef HAVE_SET_MAC_ADDR
1171 #ifdef CONFIG_AX25
1172   dev->set_mac_address  = sl_set_mac_address;
1173 #endif
1174 #endif
1175   dev->hard_header_len  = 0;
1176   dev->addr_len         = 0;
1177   dev->type             = 0;
1178 #ifdef CONFIG_AX25  
1179   memcpy(dev->broadcast,ax25_bcast,7);          /* Only activated in AX.25 mode */
1180   memcpy(dev->dev_addr,ax25_test,7);            /*    ""      ""       ""    "" */
1181 #endif  
1182   dev->queue_xmit       = dev_queue_xmit;
1183   dev->rebuild_header   = sl_rebuild_header;
1184   for (i = 0; i < DEV_NUMBUFFS; i++)
1185                 dev->buffs[i] = NULL;
1186 
1187   /* New-style flags. */
1188   dev->flags            = 0;
1189   dev->family           = AF_INET;
1190   dev->pa_addr          = 0;
1191   dev->pa_brdaddr       = 0;
1192   dev->pa_mask          = 0;
1193   dev->pa_alen          = sizeof(unsigned long);
1194 
1195   return(0);
1196 }

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