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

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