root/net/inet/dev.c

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

DEFINITIONS

This source file includes following definitions.
  1. min
  2. get_mask
  3. ip_addr_match
  4. chk_addr
  5. my_addr
  6. dev_add_pack
  7. dev_remove_pack
  8. dev_get
  9. dev_check
  10. dev_open
  11. dev_close
  12. dev_queue_xmit
  13. netif_rx
  14. dev_rint
  15. dev_transmit
  16. in_inet_bh
  17. inet_bh
  18. dev_tint
  19. dev_ifconf
  20. sprintf_stats
  21. dev_get_info
  22. bad_mask
  23. dev_ifsioc
  24. dev_ioctl
  25. dev_init

   1 /*
   2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3  *              operating system.  INET is implemented using the  BSD Socket
   4  *              interface as the means of communication with the user level.
   5  *
   6  *              Interface (streams) handling functions.
   7  *
   8  * Version:     @(#)dev.c       1.0.19  05/31/93
   9  *
  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *              Mark Evans, <evansmp@uhura.aston.ac.uk>
  13  * 
  14  * Fixes:       
  15  *              Alan Cox:       check_addr returns a value for a wrong subnet
  16  *                              ie not us but don't forward this!
  17  *              Alan Cox:       block timer if the inet_bh handler is running
  18  *              Alan Cox:       generic queue code added. A lot neater now
  19  *              C.E.Hawkins:    SIOCGIFCONF only reports 'upped' interfaces
  20  *              C.E.Hawkins:    IFF_PROMISC support
  21  *              Alan Cox:       Supports Donald Beckers new hardware 
  22  *                              multicast layer, but not yet multicast lists.
  23  *              Alan Cox:       ip_addr_match problems with class A/B nets.
  24  *              C.E.Hawkins     IP 0.0.0.0 and also same net route fix. [FIXME: Ought to cause ICMP_REDIRECT]
  25  *              Alan Cox:       Removed bogus subnet check now the subnet code
  26  *                              a) actually works for all A/B nets
  27  *                              b) doesn't forward off the same interface.
  28  *              Alan Cox:       Multiple extra protocols
  29  *              Alan Cox:       Fixed ifconfig up of dud device setting the up flag
  30  *              Alan Cox:       Fixed verify_area errors
  31  *              Alan Cox:       Removed IP_SET_DEV as per Fred's comment. I hope this doesn't give
  32  *                              anything away 8)
  33  *
  34  *              This program is free software; you can redistribute it and/or
  35  *              modify it under the terms of the GNU General Public License
  36  *              as published by the Free Software Foundation; either version
  37  *              2 of the License, or (at your option) any later version.
  38  */
  39 #include <asm/segment.h>
  40 #include <asm/system.h>
  41 #include <asm/bitops.h>
  42 #include <linux/config.h>
  43 #include <linux/types.h>
  44 #include <linux/kernel.h>
  45 #include <linux/sched.h>
  46 #include <linux/string.h>
  47 #include <linux/mm.h>
  48 #include <linux/socket.h>
  49 #include <linux/sockios.h>
  50 #include <linux/in.h>
  51 #include <linux/errno.h>
  52 #include <linux/interrupt.h>
  53 #include <linux/if_ether.h>
  54 #include "inet.h"
  55 #include "dev.h"
  56 #include "eth.h"
  57 #include "ip.h"
  58 #include "route.h"
  59 #include "protocol.h"
  60 #include "tcp.h"
  61 #include "skbuff.h"
  62 #include "sock.h"
  63 #include "arp.h"
  64 #ifdef CONFIG_AX25
  65 #include "ax25.h"
  66 #endif
  67 
  68 
  69 #ifdef CONFIG_IPX
  70 
  71 static struct packet_type ipx_8023_type = {
  72   NET16(ETH_P_802_3),
  73   0,
  74   ipx_rcv,
  75   NULL,
  76   NULL
  77 };
  78 
  79 static struct packet_type ipx_packet_type = {
  80   NET16(ETH_P_IPX),
  81   0,
  82   ipx_rcv,
  83   NULL,
  84   &ipx_8023_type
  85 };
  86 
  87 #endif
  88 
  89 #ifdef CONFIG_AX25
  90 
  91 static struct packet_type ax25_packet_type = {
  92   NET16(ETH_P_AX25),
  93   0,
  94   ax25_rcv,
  95   NULL,
  96 #ifdef CONFIG_IPX
  97   &ipx_packet_type
  98 #else
  99   NULL
 100 #endif
 101 };
 102 #endif
 103 
 104 
 105 static struct packet_type arp_packet_type = {
 106   NET16(ETH_P_ARP),
 107   0,            /* copy */
 108   arp_rcv,
 109   NULL,
 110 #ifdef CONFIG_IPX
 111 #ifndef CONFIG_AX25
 112   &ipx_packet_type
 113 #else
 114   &ax25_packet_type
 115 #endif
 116 #else
 117 #ifdef CONFIG_AX25
 118   &ax25_packet_type
 119 #else
 120   NULL          /* next */
 121 #endif
 122 #endif
 123 };
 124 
 125 
 126 static struct packet_type ip_packet_type = {
 127   NET16(ETH_P_IP),
 128   0,            /* copy */
 129   ip_rcv,
 130   NULL,
 131   &arp_packet_type
 132 };
 133    
 134 
 135 struct packet_type *ptype_base = &ip_packet_type;
 136 static struct sk_buff *volatile backlog = NULL;
 137 static int backlog_size = 0;
 138 static unsigned long ip_bcast = 0;
 139 
 140 
 141 /* Return the lesser of the two values. */
 142 static unsigned long
 143 min(unsigned long a, unsigned long b)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145   if (a < b) return(a);
 146   return(b);
 147 }
 148 
 149 
 150 /* Determine a default network mask, based on the IP address. */
 151 static unsigned long
 152 get_mask(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154   unsigned long dst;
 155 
 156   if (addr == 0L) 
 157         return(0L);     /* special case */
 158 
 159   dst = ntohl(addr);
 160   if (IN_CLASSA(dst)) 
 161         return(htonl(IN_CLASSA_NET));
 162   if (IN_CLASSB(dst)) 
 163         return(htonl(IN_CLASSB_NET));
 164   if (IN_CLASSC(dst)) 
 165         return(htonl(IN_CLASSC_NET));
 166   
 167   /* Something else, probably a subnet. */
 168   return(0);
 169 }
 170 
 171 
 172 int
 173 ip_addr_match(unsigned long me, unsigned long him)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   int i;
 176   unsigned long mask=0xFFFFFFFF;
 177   DPRINTF((DBG_DEV, "ip_addr_match(%s, ", in_ntoa(me)));
 178   DPRINTF((DBG_DEV, "%s)\n", in_ntoa(him)));
 179 
 180   if (me == him) 
 181         return(1);
 182   for (i = 0; i < 4; i++, me >>= 8, him >>= 8, mask >>= 8) {
 183         if ((me & 0xFF) != (him & 0xFF)) {
 184                 /*
 185                  * The only way this could be a match is for
 186                  * the rest of addr1 to be 0 or 255.
 187                  */
 188                 if (me != 0 && me != mask) return(0);
 189                 return(1);
 190         }
 191   }
 192   return(1);
 193 }
 194 
 195 
 196 /* Check the address for our address, broadcasts, etc. */
 197 int chk_addr(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         struct device *dev;
 200         unsigned long mask;
 201 
 202         /* Accept both `all ones' and `all zeros' as BROADCAST. */
 203         if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
 204                 return IS_BROADCAST;
 205 
 206         mask = get_mask(addr);
 207 
 208         /* Accept all of the `loopback' class A net. */
 209         if ((addr & mask) == htonl(0x7F000000L))
 210                 return IS_MYADDR;
 211 
 212         /* OK, now check the interface addresses. */
 213         for (dev = dev_base; dev != NULL; dev = dev->next) {
 214                 if (!(dev->flags & IFF_UP))
 215                         continue;
 216                 if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
 217                         return IS_MYADDR;
 218                 /* Is it the exact IP address? */
 219                 if (addr == dev->pa_addr)
 220                         return IS_MYADDR;
 221                 /* Is it our broadcast address? */
 222                 if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
 223                         return IS_BROADCAST;
 224                 /* Nope. Check for a subnetwork broadcast. */
 225                 if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) {
 226                         if ((addr & ~dev->pa_mask) == 0)
 227                                 return IS_BROADCAST;
 228                         if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
 229                                 return IS_BROADCAST;
 230                 }
 231                 /* Nope. Check for Network broadcast. */
 232                 if (((addr ^ dev->pa_addr) & mask) == 0) {
 233                         if ((addr & ~mask) == 0)
 234                                 return IS_BROADCAST;
 235                         if ((addr & ~mask) == ~mask)
 236                                 return IS_BROADCAST;
 237                 }
 238         }
 239         return 0;               /* no match at all */
 240 }
 241 
 242 
 243 /*
 244  * Retrieve our own address.
 245  * Because the loopback address (127.0.0.1) is already recognized
 246  * automatically, we can use the loopback interface's address as
 247  * our "primary" interface.  This is the addressed used by IP et
 248  * al when it doesn't know which address to use (i.e. it does not
 249  * yet know from or to which interface to go...).
 250  */
 251 unsigned long
 252 my_addr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 253 {
 254   struct device *dev;
 255 
 256   for (dev = dev_base; dev != NULL; dev = dev->next) {
 257         if (dev->flags & IFF_LOOPBACK) return(dev->pa_addr);
 258   }
 259   return(0);
 260 }
 261 
 262 
 263 static int dev_nit=0; /* Number of network taps running */
 264 
 265 /* Add a protocol ID to the list.  This will change soon. */
 266 void
 267 dev_add_pack(struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 268 {
 269   struct packet_type *p1;
 270   pt->next = ptype_base;
 271 
 272   /* Don't use copy counts on ETH_P_ALL. Instead keep a global
 273      count of number of these and use it and pt->copy to decide
 274      copies */
 275   pt->copy=0;
 276   if(pt->type==NET16(ETH_P_ALL))
 277         dev_nit++;      /* I'd like a /dev/nit too one day 8) */
 278   else
 279   {
 280         /* See if we need to copy it. */
 281         for (p1 = ptype_base; p1 != NULL; p1 = p1->next) {
 282                 if (p1->type == pt->type) {
 283                         pt->copy = 1;
 284                         break;
 285                 }
 286           }
 287   }
 288   
 289   /*
 290    *    NIT taps must go at the end or inet_bh will leak!
 291    */
 292    
 293   if(pt->type==NET16(ETH_P_ALL))
 294   {
 295         pt->next=NULL;
 296         if(ptype_base==NULL)
 297                 ptype_base=pt;
 298         else
 299         {
 300                 for(p1=ptype_base;p1->next!=NULL;p1=p1->next);
 301                 p1->next=pt;
 302         }
 303   }
 304   else
 305         ptype_base = pt;
 306 }
 307 
 308 
 309 /* Remove a protocol ID from the list.  This will change soon. */
 310 void
 311 dev_remove_pack(struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313   struct packet_type *lpt, *pt1;
 314 
 315   if (pt->type == NET16(ETH_P_ALL))
 316         dev_nit--;
 317   if (pt == ptype_base) {
 318         ptype_base = pt->next;
 319         return;
 320   }
 321 
 322   lpt = NULL;
 323   for (pt1 = ptype_base; pt1->next != NULL; pt1 = pt1->next) {
 324         if (pt1->next == pt ) {
 325                 cli();
 326                 if (!pt->copy && lpt) 
 327                         lpt->copy = 0;
 328                 pt1->next = pt->next;
 329                 sti();
 330                 return;
 331         }
 332 
 333         if (pt1->next -> type == pt ->type && pt->type != NET16(ETH_P_ALL)) {
 334                 lpt = pt1->next;
 335         }
 336   }
 337 }
 338 
 339 
 340 /* Find an interface in the list. This will change soon. */
 341 struct device *
 342 dev_get(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 343 {
 344   struct device *dev;
 345 
 346   for (dev = dev_base; dev != NULL; dev = dev->next) {
 347         if (strcmp(dev->name, name) == 0) 
 348                 return(dev);
 349   }
 350   return(NULL);
 351 }
 352 
 353 
 354 /* Find an interface that can handle addresses for a certain address. */
 355 struct device * dev_check(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 356 {
 357         struct device *dev;
 358 
 359         for (dev = dev_base; dev; dev = dev->next) {
 360                 if (!(dev->flags & IFF_UP))
 361                         continue;
 362                 if (!(dev->flags & IFF_POINTOPOINT))
 363                         continue;
 364                 if (addr != dev->pa_dstaddr)
 365                         continue;
 366                 return dev;
 367         }
 368         for (dev = dev_base; dev; dev = dev->next) {
 369                 if (!(dev->flags & IFF_UP))
 370                         continue;
 371                 if (dev->flags & IFF_POINTOPOINT)
 372                         continue;
 373                 if (dev->pa_mask & (addr ^ dev->pa_addr))
 374                         continue;
 375                 return dev;
 376         }
 377         return NULL;
 378 }
 379 
 380 
 381 /* Prepare an interface for use. */
 382 int
 383 dev_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 384 {
 385   int ret = 0;
 386 
 387   if (dev->open) 
 388         ret = dev->open(dev);
 389   if (ret == 0) 
 390         dev->flags |= (IFF_UP | IFF_RUNNING);
 391 
 392   return(ret);
 393 }
 394 
 395 
 396 /* Completely shutdown an interface. */
 397 int
 398 dev_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 399 {
 400   if (dev->flags != 0) {
 401         int ct=0;
 402         dev->flags = 0;
 403         if (dev->stop) 
 404                 dev->stop(dev);
 405         rt_flush(dev);
 406         dev->pa_addr = 0;
 407         dev->pa_dstaddr = 0;
 408         dev->pa_brdaddr = 0;
 409         dev->pa_mask = 0;
 410         /* Purge any queued packets when we down the link */
 411         while(ct<DEV_NUMBUFFS)
 412         {
 413                 struct sk_buff *skb;
 414                 while((skb=skb_dequeue(&dev->buffs[ct]))!=NULL)
 415                         if(skb->free)
 416                                 kfree_skb(skb,FREE_WRITE);
 417                 ct++;
 418         }
 419   }
 420 
 421   return(0);
 422 }
 423 
 424 
 425 /* Send (or queue for sending) a packet. */
 426 void
 427 dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
     /* [previous][next][first][last][top][bottom][index][help] */
 428 {
 429   int where = 0;                /* used to say if the packet should go  */
 430                                 /* at the front or the back of the      */
 431                                 /* queue.                               */
 432 
 433   DPRINTF((DBG_DEV, "dev_queue_xmit(skb=%X, dev=%X, pri = %d)\n",
 434                                                         skb, dev, pri));
 435 
 436   if (dev == NULL) {
 437         printk("dev.c: dev_queue_xmit: dev = NULL\n");
 438         return;
 439   }
 440  
 441   IS_SKB(skb);
 442     
 443   skb->dev = dev;
 444   if (skb->next != NULL) {
 445         /* Make sure we haven't missed an interrupt. */
 446         dev->hard_start_xmit(NULL, dev);
 447         return;
 448   }
 449 
 450   if (pri < 0) {
 451         pri = -pri-1;
 452         where = 1;
 453   }
 454 
 455   if (pri >= DEV_NUMBUFFS) {
 456         printk("bad priority in dev_queue_xmit.\n");
 457         pri = 1;
 458   }
 459 
 460   if (dev->hard_start_xmit(skb, dev) == 0) {
 461         return;
 462   }
 463 
 464   /* Put skb into a bidirectional circular linked list. */
 465   DPRINTF((DBG_DEV, "dev_queue_xmit dev->buffs[%d]=%X\n",
 466                                         pri, dev->buffs[pri]));
 467 
 468   /* Interrupts should already be cleared by hard_start_xmit. */
 469   cli();
 470   skb->magic = DEV_QUEUE_MAGIC;
 471   if(where)
 472         skb_queue_head(&dev->buffs[pri],skb);
 473   else
 474         skb_queue_tail(&dev->buffs[pri],skb);
 475   skb->magic = DEV_QUEUE_MAGIC;
 476   sti();
 477 }
 478 
 479 /*
 480  * Receive a packet from a device driver and queue it for the upper
 481  * (protocol) levels.  It always succeeds.
 482  */
 483 void
 484 netif_rx(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486   static int dropping = 0;
 487   /* Set any necessary flags. */
 488   skb->sk = NULL;
 489   skb->free = 1;
 490 
 491   /* check that we aren't oevrdoing things.. */
 492   if (!backlog_size)
 493         dropping = 0;
 494   else if (backlog_size > 100)
 495         dropping = 1;
 496   if (dropping) {
 497         kfree_skb(skb, FREE_READ);
 498         return;
 499   }
 500   /* and add it to the "backlog" queue. */
 501   IS_SKB(skb);
 502   skb_queue_tail(&backlog,skb);
 503   backlog_size++;
 504   
 505   /* If any packet arrived, mark it for processing. */
 506   if (backlog != NULL) mark_bh(INET_BH);
 507 
 508   return;
 509 }
 510 
 511 
 512 /*
 513  * The old interface to fetch a packet from a device driver.
 514  * This function is the base level entry point for all drivers that
 515  * want to send a packet to the upper (protocol) levels.  It takes
 516  * care of de-multiplexing the packet to the various modules based
 517  * on their protocol ID.
 518  *
 519  * Return values:       1 <- exit I can't do any more
 520  *                      0 <- feed me more (i.e. "done", "OK"). 
 521  */
 522 int
 523 dev_rint(unsigned char *buff, long len, int flags, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 524 {
 525   static int dropping = 0;
 526   struct sk_buff *skb = NULL;
 527   unsigned char *to;
 528   int amount, left;
 529   int len2;
 530 
 531   if (dev == NULL || buff == NULL || len <= 0) return(1);
 532   if (flags & IN_SKBUFF) {
 533         skb = (struct sk_buff *) buff;
 534   } else {
 535         if (dropping) {
 536           if (backlog != NULL)
 537               return(1);
 538           printk("INET: dev_rint: no longer dropping packets.\n");
 539           dropping = 0;
 540         }
 541 
 542         skb = alloc_skb(sizeof(*skb) + len, GFP_ATOMIC);
 543         if (skb == NULL) {
 544                 printk("dev_rint: packet dropped on %s (no memory) !\n",
 545                        dev->name);
 546                 dropping = 1;
 547                 return(1);
 548         }
 549         skb->mem_len = sizeof(*skb) + len;
 550         skb->mem_addr = (struct sk_buff *) skb;
 551 
 552         /* First we copy the packet into a buffer, and save it for later. */
 553         to = skb->data;
 554         left = len;
 555         len2 = len;
 556         while (len2 > 0) {
 557                 amount = min(len2, (unsigned long) dev->rmem_end -
 558                                                 (unsigned long) buff);
 559                 memcpy(to, buff, amount);
 560                 len2 -= amount;
 561                 left -= amount;
 562                 buff += amount;
 563                 to += amount;
 564                 if ((unsigned long) buff == dev->rmem_end)
 565                         buff = (unsigned char *) dev->rmem_start;
 566         }
 567   }
 568   skb->len = len;
 569   skb->dev = dev;
 570   skb->free = 1;
 571 
 572   netif_rx(skb);
 573   /* OK, all done. */
 574   return(0);
 575 }
 576 
 577 
 578 /* This routine causes all interfaces to try to send some data. */
 579 void
 580 dev_transmit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 581 {
 582   struct device *dev;
 583 
 584   for (dev = dev_base; dev != NULL; dev = dev->next) {
 585         if (!dev->tbusy) {
 586                 dev_tint(dev);
 587         }
 588   }
 589 }
 590 
 591 static volatile char in_bh = 0;
 592 
 593 int in_inet_bh()        /* Used by timer.c */
     /* [previous][next][first][last][top][bottom][index][help] */
 594 {
 595         return(in_bh==0?0:1);
 596 }
 597 
 598 /*
 599  * This function gets called periodically, to see if we can
 600  * process any data that came in from some interface.
 601  *
 602  */
 603 void
 604 inet_bh(void *tmp)
     /* [previous][next][first][last][top][bottom][index][help] */
 605 {
 606   struct sk_buff *skb;
 607   struct packet_type *ptype;
 608   unsigned short type;
 609   unsigned char flag = 0;
 610   int nitcount;
 611 
 612   /* Atomically check and mark our BUSY state. */
 613   if (set_bit(1, (void*)&in_bh))
 614       return;
 615 
 616   /* Can we send anything now? */
 617   dev_transmit();
 618   
 619   /* Any data left to process? */
 620   while((skb=skb_dequeue(&backlog))!=NULL)
 621   {
 622         backlog_size--;
 623         nitcount=dev_nit;
 624         flag=0;
 625         sti();
 626        /*
 627         * Bump the pointer to the next structure.
 628         * This assumes that the basic 'skb' pointer points to
 629         * the MAC header, if any (as indicated by its "length"
 630         * field).  Take care now!
 631         */
 632        skb->h.raw = skb->data + skb->dev->hard_header_len;
 633        skb->len -= skb->dev->hard_header_len;
 634 
 635        /*
 636         * Fetch the packet protocol ID.  This is also quite ugly, as
 637         * it depends on the protocol driver (the interface itself) to
 638         * know what the type is, or where to get it from.  The Ethernet
 639         * interfaces fetch the ID from the two bytes in the Ethernet MAC
 640         * header (the h_proto field in struct ethhdr), but drivers like
 641         * SLIP and PLIP have no alternative but to force the type to be
 642         * IP or something like that.  Sigh- FvK
 643         */
 644        type = skb->dev->type_trans(skb, skb->dev);
 645 
 646         /*
 647          * We got a packet ID.  Now loop over the "known protocols"
 648          * table (which is actually a linked list, but this will
 649          * change soon if I get my way- FvK), and forward the packet
 650          * to anyone who wants it.
 651          */
 652         for (ptype = ptype_base; ptype != NULL; ptype = ptype->next) {
 653                 if (ptype->type == type || ptype->type == NET16(ETH_P_ALL)) {
 654                         struct sk_buff *skb2;
 655 
 656                         if (ptype->type==NET16(ETH_P_ALL))
 657                                 nitcount--;
 658                         if (ptype->copy || nitcount) {  /* copy if we need to   */
 659                                 skb2 = alloc_skb(skb->mem_len, GFP_ATOMIC);
 660                                 if (skb2 == NULL) 
 661                                         continue;
 662                                 memcpy(skb2, (const void *) skb, skb->mem_len);
 663                                 skb2->mem_addr = skb2;
 664                                 skb2->h.raw = (unsigned char *)(
 665                                     (unsigned long) skb2 +
 666                                     (unsigned long) skb->h.raw -
 667                                     (unsigned long) skb
 668                                 );
 669                                 skb2->free = 1;
 670                         } else {
 671                                 skb2 = skb;
 672                         }
 673 
 674                         /* This used to be in the 'else' part, but then
 675                          * we don't have this flag set when we get a
 676                          * protocol that *does* require copying... -FvK
 677                          */
 678                         flag = 1;
 679 
 680                         /* Kick the protocol handler. */
 681                         ptype->func(skb2, skb->dev, ptype);
 682                 }
 683         }
 684 
 685         /*
 686          * That's odd.  We got an unknown packet.  Who's using
 687          * stuff like Novell or Amoeba on this network??
 688          */
 689         if (!flag) {
 690                 DPRINTF((DBG_DEV,
 691                         "INET: unknown packet type 0x%04X (ignored)\n", type));
 692                 skb->sk = NULL;
 693                 kfree_skb(skb, FREE_WRITE);
 694         }
 695 
 696         /* Again, see if we can transmit anything now. */
 697         dev_transmit();
 698         cli();
 699   }
 700   in_bh = 0;
 701   sti();
 702   dev_transmit();
 703 }
 704 
 705 
 706 /*
 707  * This routine is called when an device driver (i.e. an
 708  * interface) is * ready to transmit a packet.
 709  */
 710  
 711 void dev_tint(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 712 {
 713         int i;
 714         struct sk_buff *skb;
 715         
 716         for(i = 0;i < DEV_NUMBUFFS; i++) {
 717                 while((skb=skb_dequeue(&dev->buffs[i]))!=NULL)
 718                 {
 719                         skb->magic = 0;
 720                         skb->next = NULL;
 721                         skb->prev = NULL;
 722                         dev->queue_xmit(skb,dev,-i - 1);
 723                         if (dev->tbusy)
 724                                 return;
 725                 }
 726         }
 727 }
 728 
 729 
 730 /* Perform a SIOCGIFCONF call. */
 731 static int
 732 dev_ifconf(char *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 733 {
 734   struct ifconf ifc;
 735   struct ifreq ifr;
 736   struct device *dev;
 737   char *pos;
 738   int len;
 739   int err;
 740 
 741   /* Fetch the caller's info block. */
 742   err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifconf));
 743   if(err)
 744         return err;
 745   memcpy_fromfs(&ifc, arg, sizeof(struct ifconf));
 746   len = ifc.ifc_len;
 747   pos = ifc.ifc_buf;
 748   err=verify_area(VERIFY_WRITE, pos, len);
 749   if(err)
 750         return err;
 751 
 752   /* Loop over the interfaces, and write an info block for each. */
 753   for (dev = dev_base; dev != NULL; dev = dev->next) {
 754         if(!(dev->flags & IFF_UP))
 755                 continue;
 756         memset(&ifr, 0, sizeof(struct ifreq));
 757         strcpy(ifr.ifr_name, dev->name);
 758         (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
 759         (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
 760 
 761         /* Write this block to the caller's space. */
 762         memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
 763         pos += sizeof(struct ifreq);
 764         len -= sizeof(struct ifreq);
 765         if (len < sizeof(struct ifreq)) break;
 766   }
 767 
 768   /* All done.  Write the updated control block back to the caller. */
 769   ifc.ifc_len = (pos - ifc.ifc_buf);
 770   ifc.ifc_req = (struct ifreq *) ifc.ifc_buf;
 771   memcpy_tofs(arg, &ifc, sizeof(struct ifconf));
 772   return(pos - arg);
 773 }
 774 
 775 /* Print device statistics. */
 776 char *sprintf_stats(char *buffer, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 777 {
 778   char *pos = buffer;
 779   struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
 780 
 781   if (stats)
 782     pos += sprintf(pos, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
 783                    dev->name,
 784                    stats->rx_packets, stats->rx_errors,
 785                    stats->rx_dropped + stats->rx_missed_errors,
 786                    stats->rx_fifo_errors,
 787                    stats->rx_length_errors + stats->rx_over_errors
 788                    + stats->rx_crc_errors + stats->rx_frame_errors,
 789                    stats->tx_packets, stats->tx_errors, stats->tx_dropped,
 790                    stats->tx_fifo_errors, stats->collisions,
 791                    stats->tx_carrier_errors + stats->tx_aborted_errors
 792                    + stats->tx_window_errors + stats->tx_heartbeat_errors);
 793   else
 794       pos += sprintf(pos, "%6s: No statistics available.\n", dev->name);
 795 
 796   return pos;
 797 }
 798 
 799 /* Called from the PROCfs module. */
 800 int
 801 dev_get_info(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 802 {
 803   char *pos = buffer;
 804   struct device *dev;
 805 
 806   pos +=
 807       sprintf(pos,
 808               "Inter-|   Receive                  |  Transmit\n"
 809               " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
 810   for (dev = dev_base; dev != NULL; dev = dev->next) {
 811       pos = sprintf_stats(pos, dev);
 812   }
 813   return pos - buffer;
 814 }
 815 
 816 static inline int bad_mask(unsigned long mask, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 817 {
 818         if (addr & (mask = ~mask))
 819                 return 1;
 820         mask = ntohl(mask);
 821         if (mask & (mask+1))
 822                 return 1;
 823         return 0;
 824 }
 825 
 826 
 827 /* Perform the SIOCxIFxxx calls. */
 828 static int
 829 dev_ifsioc(void *arg, unsigned int getset)
     /* [previous][next][first][last][top][bottom][index][help] */
 830 {
 831   struct ifreq ifr;
 832   struct device *dev;
 833   int ret;
 834 
 835   /* Fetch the caller's info block. */
 836   int err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifreq));
 837   if(err)
 838         return err;
 839   memcpy_fromfs(&ifr, arg, sizeof(struct ifreq));
 840 
 841   /* See which interface the caller is talking about. */
 842   if ((dev = dev_get(ifr.ifr_name)) == NULL) return(-EINVAL);
 843 
 844   switch(getset) {
 845         case SIOCGIFFLAGS:
 846                 ifr.ifr_flags = dev->flags;
 847                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 848                 ret = 0;
 849                 break;
 850         case SIOCSIFFLAGS:
 851                 {
 852                   int old_flags = dev->flags;
 853                   dev->flags = ifr.ifr_flags & (
 854                         IFF_UP | IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
 855                         IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
 856                         IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI);
 857                         
 858                   if ( (old_flags & IFF_PROMISC) && ((dev->flags & IFF_PROMISC) == 0))
 859                         dev->set_multicast_list(dev,0,NULL);
 860                   if ( (dev->flags & IFF_PROMISC) && ((old_flags & IFF_PROMISC) == 0))
 861                         dev->set_multicast_list(dev,-1,NULL);
 862                   if ((old_flags & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
 863                         ret = dev_close(dev);
 864                   } else
 865                   {
 866                       ret = (! (old_flags & IFF_UP) && (dev->flags & IFF_UP))
 867                         ? dev_open(dev) : 0;
 868                       if(ret<0)
 869                         dev->flags&=~IFF_UP;    /* Didnt open so down the if */
 870                   }
 871                 }
 872                 break;
 873         case SIOCGIFADDR:
 874                 (*(struct sockaddr_in *)
 875                   &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
 876                 (*(struct sockaddr_in *)
 877                   &ifr.ifr_addr).sin_family = dev->family;
 878                 (*(struct sockaddr_in *)
 879                   &ifr.ifr_addr).sin_port = 0;
 880                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 881                 ret = 0;
 882                 break;
 883         case SIOCSIFADDR:
 884                 dev->pa_addr = (*(struct sockaddr_in *)
 885                                  &ifr.ifr_addr).sin_addr.s_addr;
 886                 dev->family = ifr.ifr_addr.sa_family;
 887                 dev->pa_mask = get_mask(dev->pa_addr);
 888                 dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
 889                 ret = 0;
 890                 break;
 891         case SIOCGIFBRDADDR:
 892                 (*(struct sockaddr_in *)
 893                   &ifr.ifr_broadaddr).sin_addr.s_addr = dev->pa_brdaddr;
 894                 (*(struct sockaddr_in *)
 895                   &ifr.ifr_broadaddr).sin_family = dev->family;
 896                 (*(struct sockaddr_in *)
 897                   &ifr.ifr_broadaddr).sin_port = 0;
 898                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 899                 ret = 0;
 900                 break;
 901         case SIOCSIFBRDADDR:
 902                 dev->pa_brdaddr = (*(struct sockaddr_in *)
 903                                     &ifr.ifr_broadaddr).sin_addr.s_addr;
 904                 ret = 0;
 905                 break;
 906         case SIOCGIFDSTADDR:
 907                 (*(struct sockaddr_in *)
 908                   &ifr.ifr_dstaddr).sin_addr.s_addr = dev->pa_dstaddr;
 909                 (*(struct sockaddr_in *)
 910                   &ifr.ifr_broadaddr).sin_family = dev->family;
 911                 (*(struct sockaddr_in *)
 912                   &ifr.ifr_broadaddr).sin_port = 0;
 913                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 914                 ret = 0;
 915                 break;
 916         case SIOCSIFDSTADDR:
 917                 dev->pa_dstaddr = (*(struct sockaddr_in *)
 918                                     &ifr.ifr_dstaddr).sin_addr.s_addr;
 919                 ret = 0;
 920                 break;
 921         case SIOCGIFNETMASK:
 922                 (*(struct sockaddr_in *)
 923                   &ifr.ifr_netmask).sin_addr.s_addr = dev->pa_mask;
 924                 (*(struct sockaddr_in *)
 925                   &ifr.ifr_netmask).sin_family = dev->family;
 926                 (*(struct sockaddr_in *)
 927                   &ifr.ifr_netmask).sin_port = 0;
 928                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 929                 ret = 0;
 930                 break;
 931         case SIOCSIFNETMASK: {
 932                 unsigned long mask = (*(struct sockaddr_in *)
 933                         &ifr.ifr_netmask).sin_addr.s_addr;
 934                 ret = -EINVAL;
 935                 if (bad_mask(mask,0))
 936                         break;
 937                 dev->pa_mask = mask;
 938                 ret = 0;
 939                 break;
 940         }
 941         case SIOCGIFMETRIC:
 942                 ifr.ifr_metric = dev->metric;
 943                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 944                 ret = 0;
 945                 break;
 946         case SIOCSIFMETRIC:
 947                 dev->metric = ifr.ifr_metric;
 948                 ret = 0;
 949                 break;
 950         case SIOCGIFMTU:
 951                 ifr.ifr_mtu = dev->mtu;
 952                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
 953                 ret = 0;
 954                 break;
 955         case SIOCSIFMTU:
 956                 dev->mtu = ifr.ifr_mtu;
 957                 ret = 0;
 958                 break;
 959         case SIOCGIFMEM:
 960                 printk("NET: ioctl(SIOCGIFMEM, 0x%08X)\n", (int)arg);
 961                 ret = -EINVAL;
 962                 break;
 963         case SIOCSIFMEM:
 964                 printk("NET: ioctl(SIOCSIFMEM, 0x%08X)\n", (int)arg);
 965                 ret = -EINVAL;
 966                 break;
 967         case SIOCGIFHWADDR:
 968                 memcpy(ifr.ifr_hwaddr,dev->dev_addr, MAX_ADDR_LEN);
 969                 memcpy_tofs(arg,&ifr,sizeof(struct ifreq));
 970                 ret=0;
 971                 break;
 972         default:
 973                 ret = -EINVAL;
 974   }
 975   return(ret);
 976 }
 977 
 978 
 979 /* This function handles all "interface"-type I/O control requests. */
 980 int
 981 dev_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 982 {
 983   struct iflink iflink;
 984   struct ddi_device *dev;
 985 
 986   switch(cmd) {
 987         case IP_SET_DEV:
 988                 printk("Your network configuration program needs upgrading.\n");
 989                 return -EINVAL;
 990 
 991         case SIOCGIFCONF:
 992                 (void) dev_ifconf((char *) arg);
 993                 return 0;
 994 
 995         case SIOCGIFFLAGS:
 996         case SIOCGIFADDR:
 997         case SIOCGIFDSTADDR:
 998         case SIOCGIFBRDADDR:
 999         case SIOCGIFNETMASK:
1000         case SIOCGIFMETRIC:
1001         case SIOCGIFMTU:
1002         case SIOCGIFMEM:
1003         case SIOCGIFHWADDR:
1004                 return dev_ifsioc(arg, cmd);
1005 
1006         case SIOCSIFFLAGS:
1007         case SIOCSIFADDR:
1008         case SIOCSIFDSTADDR:
1009         case SIOCSIFBRDADDR:
1010         case SIOCSIFNETMASK:
1011         case SIOCSIFMETRIC:
1012         case SIOCSIFMTU:
1013         case SIOCSIFMEM:
1014                 if (!suser())
1015                         return -EPERM;
1016                 return dev_ifsioc(arg, cmd);
1017 
1018         case SIOCSIFLINK:
1019                 if (!suser())
1020                         return -EPERM;
1021                 memcpy_fromfs(&iflink, arg, sizeof(iflink));
1022                 dev = ddi_map(iflink.id);
1023                 if (dev == NULL)
1024                         return -EINVAL;
1025 
1026                 /* Now allocate an interface and connect it. */
1027                 printk("AF_INET: DDI \"%s\" linked to stream \"%s\"\n",
1028                                                 dev->name, iflink.stream);
1029                 return 0;
1030 
1031         default:
1032                 return -EINVAL;
1033   }
1034 }
1035 
1036 
1037 /* Initialize the DEV module. */
1038 void
1039 dev_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1040 {
1041   struct device *dev, *dev2;
1042 
1043   /* Add the devices.
1044    * If the call to dev->init fails, the dev is removed
1045    * from the chain disconnecting the device until the
1046    * next reboot.
1047    */
1048   dev2 = NULL;
1049   for (dev = dev_base; dev != NULL; dev=dev->next) {
1050         if (dev->init && dev->init(dev)) {
1051                 if (dev2 == NULL) dev_base = dev->next;
1052                   else dev2->next = dev->next;
1053         } else {
1054                 dev2 = dev;
1055         }
1056   }
1057 
1058   /* Set up some IP addresses. */
1059   ip_bcast = in_aton("255.255.255.255");
1060 }

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