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

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