⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 3 页
字号:
699 {
700         int i;
701         struct sk_buff *skb;
702         
703         for(i = 0;i < DEV_NUMBUFFS; i++) {
704                 while((skb=skb_dequeue(&dev->buffs[i]))!=NULL)
705                 {
706                         skb->magic = 0;
707                         skb->next = NULL;
708                         skb->prev = NULL;
709                         dev->queue_xmit(skb,dev,-i - 1);
710                         if (dev->tbusy)
711                                 return;
712                 }
713         }
714 }
715 
716 
717 /* Perform a SIOCGIFCONF call. */
718 static int
719 dev_ifconf(char *arg)
720 {
721   struct ifconf ifc;
722   struct ifreq ifr;
723   struct device *dev;
724   char *pos;
725   int len;
726   int err;
727 
728   /* Fetch the caller's info block. */
729   err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifconf));
730   if(err)
731         return err;
732   memcpy_fromfs(&ifc, arg, sizeof(struct ifconf));
733   len = ifc.ifc_len;
734   pos = ifc.ifc_buf;
735 
736   /* Loop over the interfaces, and write an info block for each. */
737   for (dev = dev_base; dev != NULL; dev = dev->next) {
738         if(!(dev->flags & IFF_UP))
739                 continue;
740         memset(&ifr, 0, sizeof(struct ifreq));
741         strcpy(ifr.ifr_name, dev->name);
742         (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
743         (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
744 
745         /* Write this block to the caller's space. */
746         memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
747         pos += sizeof(struct ifreq);
748         len -= sizeof(struct ifreq);
749         if (len < sizeof(struct ifreq)) break;
750   }
751 
752   /* All done.  Write the updated control block back to the caller. */
753   ifc.ifc_len = (pos - ifc.ifc_buf);
754   ifc.ifc_req = (struct ifreq *) ifc.ifc_buf;
755   memcpy_tofs(arg, &ifc, sizeof(struct ifconf));
756   return(pos - arg);
757 }
758 
759 /* Print device statistics. */
760 char *sprintf_stats(char *buffer, struct device *dev)
761 {
762   char *pos = buffer;
763   struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
764 
765   if (stats)
766     pos += sprintf(pos, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
767                    dev->name,
768                    stats->rx_packets, stats->rx_errors,
769                    stats->rx_dropped + stats->rx_missed_errors,
770                    stats->rx_fifo_errors,
771                    stats->rx_length_errors + stats->rx_over_errors
772                    + stats->rx_crc_errors + stats->rx_frame_errors,
773                    stats->tx_packets, stats->tx_errors, stats->tx_dropped,
774                    stats->tx_fifo_errors, stats->collisions,
775                    stats->tx_carrier_errors + stats->tx_aborted_errors
776                    + stats->tx_window_errors + stats->tx_heartbeat_errors);
777   else
778       pos += sprintf(pos, "%6s: No statistics available.\n", dev->name);
779 
780   return pos;
781 }
782 
783 /* Called from the PROCfs module. */
784 int
785 dev_get_info(char *buffer)
786 {
787   char *pos = buffer;
788   struct device *dev;
789 
790   pos +=
791       sprintf(pos,
792               "Inter-|   Receive                  |  Transmit\n"
793               " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
794   for (dev = dev_base; dev != NULL; dev = dev->next) {
795       pos = sprintf_stats(pos, dev);
796   }
797   return pos - buffer;
798 }
799 
800 static inline int bad_mask(unsigned long mask, unsigned long addr)
801 {
802         if (addr & (mask = ~mask))
803                 return 1;
804         mask = ntohl(mask);
805         if (mask & (mask+1))
806                 return 1;
807         return 0;
808 }
809 
810 
811 /* Perform the SIOCxIFxxx calls. */
812 static int
813 dev_ifsioc(void *arg, unsigned int getset)
814 {
815   struct ifreq ifr;
816   struct device *dev;
817   int ret;
818 
819   /* Fetch the caller's info block. */
820   int err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifreq));
821   if(err)
822         return err;
823   memcpy_fromfs(&ifr, arg, sizeof(struct ifreq));
824 
825   /* See which interface the caller is talking about. */
826   if ((dev = dev_get(ifr.ifr_name)) == NULL) return(-EINVAL);
827 
828   switch(getset) {
829         case SIOCGIFFLAGS:
830                 ifr.ifr_flags = dev->flags;
831                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
832                 ret = 0;
833                 break;
834         case SIOCSIFFLAGS:
835                 {
836                   int old_flags = dev->flags;
837                   dev->flags = ifr.ifr_flags & (
838                         IFF_UP | IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
839                         IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
840                         IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI);
841                         
842                   if ( (old_flags & IFF_PROMISC) && ((dev->flags & IFF_PROMISC) == 0))
843                         dev->set_multicast_list(dev,0,NULL);
844                   if ( (dev->flags & IFF_PROMISC) && ((old_flags & IFF_PROMISC) == 0))
845                         dev->set_multicast_list(dev,-1,NULL);
846                   if ((old_flags & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
847                         ret = dev_close(dev);
848                   } else
849                   {
850                       ret = (! (old_flags & IFF_UP) && (dev->flags & IFF_UP))
851                         ? dev_open(dev) : 0;
852                       if(ret<0)
853                         dev->flags&=~IFF_UP;    /* Didnt open so down the if */
854                   }
855                 }
856                 break;
857         case SIOCGIFADDR:
858                 (*(struct sockaddr_in *)
859                   &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
860                 (*(struct sockaddr_in *)
861                   &ifr.ifr_addr).sin_family = dev->family;
862                 (*(struct sockaddr_in *)
863                   &ifr.ifr_addr).sin_port = 0;
864                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
865                 ret = 0;
866                 break;
867         case SIOCSIFADDR:
868                 dev->pa_addr = (*(struct sockaddr_in *)
869                                  &ifr.ifr_addr).sin_addr.s_addr;
870                 dev->family = ifr.ifr_addr.sa_family;
871                 dev->pa_mask = get_mask(dev->pa_addr);
872                 dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
873                 ret = 0;
874                 break;
875         case SIOCGIFBRDADDR:
876                 (*(struct sockaddr_in *)
877                   &ifr.ifr_broadaddr).sin_addr.s_addr = dev->pa_brdaddr;
878                 (*(struct sockaddr_in *)
879                   &ifr.ifr_broadaddr).sin_family = dev->family;
880                 (*(struct sockaddr_in *)
881                   &ifr.ifr_broadaddr).sin_port = 0;
882                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
883                 ret = 0;
884                 break;
885         case SIOCSIFBRDADDR:
886                 dev->pa_brdaddr = (*(struct sockaddr_in *)
887                                     &ifr.ifr_broadaddr).sin_addr.s_addr;
888                 ret = 0;
889                 break;
890         case SIOCGIFDSTADDR:
891                 (*(struct sockaddr_in *)
892                   &ifr.ifr_dstaddr).sin_addr.s_addr = dev->pa_dstaddr;
893                 (*(struct sockaddr_in *)
894                   &ifr.ifr_broadaddr).sin_family = dev->family;
895                 (*(struct sockaddr_in *)
896                   &ifr.ifr_broadaddr).sin_port = 0;
897                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
898                 ret = 0;
899                 break;
900         case SIOCSIFDSTADDR:
901                 dev->pa_dstaddr = (*(struct sockaddr_in *)
902                                     &ifr.ifr_dstaddr).sin_addr.s_addr;
903                 ret = 0;
904                 break;
905         case SIOCGIFNETMASK:
906                 (*(struct sockaddr_in *)
907                   &ifr.ifr_netmask).sin_addr.s_addr = dev->pa_mask;
908                 (*(struct sockaddr_in *)
909                   &ifr.ifr_netmask).sin_family = dev->family;
910                 (*(struct sockaddr_in *)
911                   &ifr.ifr_netmask).sin_port = 0;
912                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
913                 ret = 0;
914                 break;
915         case SIOCSIFNETMASK: {
916                 unsigned long mask = (*(struct sockaddr_in *)
917                         &ifr.ifr_netmask).sin_addr.s_addr;
918                 ret = -EINVAL;
919                 if (bad_mask(mask,0))
920                         break;
921                 dev->pa_mask = mask;
922                 ret = 0;
923                 break;
924         }
925         case SIOCGIFMETRIC:
926                 ifr.ifr_metric = dev->metric;
927                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
928                 ret = 0;
929                 break;
930         case SIOCSIFMETRIC:
931                 dev->metric = ifr.ifr_metric;
932                 ret = 0;
933                 break;
934         case SIOCGIFMTU:
935                 ifr.ifr_mtu = dev->mtu;
936                 memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
937                 ret = 0;
938                 break;
939         case SIOCSIFMTU:
940                 dev->mtu = ifr.ifr_mtu;
941                 ret = 0;
942                 break;
943         case SIOCGIFMEM:
944                 printk("NET: ioctl(SIOCGIFMEM, 0x%08X)\n", (int)arg);
945                 ret = -EINVAL;
946                 break;
947         case SIOCSIFMEM:
948                 printk("NET: ioctl(SIOCSIFMEM, 0x%08X)\n", (int)arg);
949                 ret = -EINVAL;
950                 break;
951         case SIOCGIFHWADDR:
952                 memcpy(ifr.ifr_hwaddr,dev->dev_addr, MAX_ADDR_LEN);
953                 memcpy_tofs(arg,&ifr,sizeof(struct ifreq));
954                 ret=0;
955                 break;
956         default:
957                 ret = -EINVAL;
958   }
959   return(ret);
960 }
961 
962 
963 /* This function handles all "interface"-type I/O control requests. */
964 int
965 dev_ioctl(unsigned int cmd, void *arg)
966 {
967   struct iflink iflink;
968   struct ddi_device *dev;
969 
970   switch(cmd) {
971         case IP_SET_DEV:
972                 printk("Your network configuration program needs upgrading.\n");
973                 return -EINVAL;
974 
975         case SIOCGIFCONF:
976                 (void) dev_ifconf((char *) arg);
977                 return 0;
978 
979         case SIOCGIFFLAGS:
980         case SIOCGIFADDR:
981         case SIOCGIFDSTADDR:
982         case SIOCGIFBRDADDR:
983         case SIOCGIFNETMASK:
984         case SIOCGIFMETRIC:
985         case SIOCGIFMTU:
986         case SIOCGIFMEM:
987         case SIOCGIFHWADDR:
988                 return dev_ifsioc(arg, cmd);
989 
990         case SIOCSIFFLAGS:
991         case SIOCSIFADDR:
992         case SIOCSIFDSTADDR:
993         case SIOCSIFBRDADDR:
994         case SIOCSIFNETMASK:
995         case SIOCSIFMETRIC:
996         case SIOCSIFMTU:
997         case SIOCSIFMEM:
998                 if (!suser())
999                         return -EPERM;
1000                 return dev_ifsioc(arg, cmd);
1001 
1002         case SIOCSIFLINK:
1003                 if (!suser())
1004                         return -EPERM;
1005                 memcpy_fromfs(&iflink, arg, sizeof(iflink));
1006                 dev = ddi_map(iflink.id);
1007                 if (dev == NULL)
1008                         return -EINVAL;
1009 
1010                 /* Now allocate an interface and connect it. */
1011                 printk("AF_INET: DDI \"%s\" linked to stream \"%s\"\n",
1012                                                 dev->name, iflink.stream);
1013                 return 0;
1014 
1015         default:
1016                 return -EINVAL;
1017   }
1018 }
1019 
1020 
1021 /* Initialize the DEV module. */
1022 void
1023 dev_init(void)
1024 {
1025   struct device *dev, *dev2;
1026 
1027   /* Add the devices.
1028    * If the call to dev->init fails, the dev is removed
1029    * from the chain disconnecting the device until the
1030    * next reboot.
1031    */
1032   dev2 = NULL;
1033   for (dev = dev_base; dev != NULL; dev=dev->next) {
1034         if (dev->init && dev->init(dev)) {
1035                 if (dev2 == NULL) dev_base = dev->next;
1036                   else dev2->next = dev->next;
1037         } else {
1038                 dev2 = dev;
1039         }
1040   }
1041 
1042   /* Set up some IP addresses. */
1043   ip_bcast = in_aton("255.255.255.255");
1044 }
1045 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -