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

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