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

📄 sock.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 5 页
字号:
1521         case FIOGETOWN:
1522         case SIOCGPGRP:
1523                 if (sk) {
1524                         err=verify_area(VERIFY_WRITE,(void *) arg, sizeof(long));
1525                         if(err)
1526                                 return err;
1527                         put_fs_long(sk->proc,(int *)arg);
1528                 }
1529                 return(0);
1530 #if 0   /* FIXME: */
1531         case SIOCATMARK:
1532                 printk("AF_INET: ioctl(SIOCATMARK, 0x%08X)\n",(void *) arg);
1533                 return(-EINVAL);
1534 #endif
1535 
1536         case DDIOCSDBG:
1537                 return(dbg_ioctl((void *) arg, DBG_INET));
1538 
1539         case SIOCADDRT: case SIOCADDRTOLD:
1540         case SIOCDELRT: case SIOCDELRTOLD:
1541                 return(rt_ioctl(cmd,(void *) arg));
1542 
1543         case SIOCDARP:
1544         case SIOCGARP:
1545         case SIOCSARP:
1546                 return(arp_ioctl(cmd,(void *) arg));
1547 
1548         case IP_SET_DEV:
1549         case SIOCGIFCONF:
1550         case SIOCGIFFLAGS:
1551         case SIOCSIFFLAGS:
1552         case SIOCGIFADDR:
1553         case SIOCSIFADDR:
1554         case SIOCGIFDSTADDR:
1555         case SIOCSIFDSTADDR:
1556         case SIOCGIFBRDADDR:
1557         case SIOCSIFBRDADDR:
1558         case SIOCGIFNETMASK:
1559         case SIOCSIFNETMASK:
1560         case SIOCGIFMETRIC:
1561         case SIOCSIFMETRIC:
1562         case SIOCGIFMEM:
1563         case SIOCSIFMEM:
1564         case SIOCGIFMTU:
1565         case SIOCSIFMTU:
1566         case SIOCSIFLINK:
1567         case SIOCGIFHWADDR:
1568                 return(dev_ioctl(cmd,(void *) arg));
1569 
1570         default:
1571                 if (!sk || !sk->prot->ioctl) return(-EINVAL);
1572                 return(sk->prot->ioctl(sk, cmd, arg));
1573   }
1574   /*NOTREACHED*/
1575   return(0);
1576 }
1577 
1578 
1579 struct sk_buff *
1580 sock_wmalloc(struct sock *sk, unsigned long size, int force,
1581              int priority)
1582 {
1583   if (sk) {
1584         if (sk->wmem_alloc + size < sk->sndbuf || force) {
1585                 struct sk_buff * c = alloc_skb(size, priority);
1586                 if (c) {
1587                         cli();
1588                         sk->wmem_alloc+= size;
1589                         sti();
1590                 }
1591                 return c;
1592         }
1593         DPRINTF((DBG_INET, "sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
1594                                                 sk, size, force, priority));
1595         return(NULL);
1596   }
1597   return(alloc_skb(size, priority));
1598 }
1599 
1600 
1601 struct sk_buff *
1602 sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
1603 {
1604   if (sk) {
1605         if (sk->rmem_alloc + size < sk->rcvbuf || force) {
1606                 struct sk_buff *c = alloc_skb(size, priority);
1607                 if (c) {
1608                         cli();
1609                         sk->rmem_alloc += size;
1610                         sti();
1611                 }
1612                 return(c);
1613         }
1614         DPRINTF((DBG_INET, "sock_rmalloc(%X,%d,%d,%d) returning NULL\n",
1615                                                 sk,size,force, priority));
1616         return(NULL);
1617   }
1618   return(alloc_skb(size, priority));
1619 }
1620 
1621 
1622 unsigned long
1623 sock_rspace(struct sock *sk)
1624 {
1625   int amt;
1626 
1627   if (sk != NULL) {
1628         if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW) return(0);
1629         amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
1630         if (amt < 0) return(0);
1631         return(amt);
1632   }
1633   return(0);
1634 }
1635 
1636 
1637 unsigned long
1638 sock_wspace(struct sock *sk)
1639 {
1640   if (sk != NULL) {
1641         if (sk->shutdown & SEND_SHUTDOWN) return(0);
1642         if (sk->wmem_alloc >= sk->sndbuf) return(0);
1643         return(sk->sndbuf-sk->wmem_alloc );
1644   }
1645   return(0);
1646 }
1647 
1648 
1649 void
1650 sock_wfree(struct sock *sk, void *mem, unsigned long size)
1651 {
1652   DPRINTF((DBG_INET, "sock_wfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));
1653 
1654   IS_SKB(mem);
1655   kfree_skbmem(mem, size);
1656   if (sk) {
1657         sk->wmem_alloc -= size;
1658 
1659         /* In case it might be waiting for more memory. */
1660         if (!sk->dead) sk->write_space(sk);
1661         if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {
1662                 DPRINTF((DBG_INET,
1663                         "recovered lost memory, sock = %X\n", sk));
1664         }
1665         return;
1666   }
1667 }
1668 
1669 
1670 void
1671 sock_rfree(struct sock *sk, void *mem, unsigned long size)
1672 {
1673   DPRINTF((DBG_INET, "sock_rfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));
1674   IS_SKB(mem);
1675   kfree_skbmem(mem, size);
1676   if (sk) {
1677         sk->rmem_alloc -= size;
1678         if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {
1679                 DPRINTF((DBG_INET,
1680                         "recovered lot memory, sock = %X\n", sk));
1681         }
1682   }
1683 }
1684 
1685 
1686 /*
1687  * This routine must find a socket given a TCP or UDP header.
1688  * Everyhting is assumed to be in net order.
1689  */
1690 struct sock *get_sock(struct proto *prot, unsigned short num,
1691                                 unsigned long raddr,
1692                                 unsigned short rnum, unsigned long laddr)
1693 {
1694   struct sock *s;
1695   unsigned short hnum;
1696 
1697   hnum = ntohs(num);
1698   DPRINTF((DBG_INET, "get_sock(prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n",
1699           prot, num, raddr, rnum, laddr));
1700 
1701   /*
1702    * SOCK_ARRAY_SIZE must be a power of two.  This will work better
1703    * than a prime unless 3 or more sockets end up using the same
1704    * array entry.  This should not be a problem because most
1705    * well known sockets don't overlap that much, and for
1706    * the other ones, we can just be careful about picking our
1707    * socket number when we choose an arbitrary one.
1708    */
1709   for(s = prot->sock_array[hnum & (SOCK_ARRAY_SIZE - 1)];
1710       s != NULL; s = s->next) 
1711   {
1712         if (s->num != hnum) 
1713                 continue;
1714         if(s->dead && (s->state == TCP_CLOSE))
1715                 continue;
1716         if(prot == &udp_prot)
1717                 return s;
1718         if(ip_addr_match(s->daddr,raddr)==0)
1719                 continue;
1720         if (s->dummy_th.dest != rnum && s->dummy_th.dest != 0) 
1721                 continue;
1722         if(ip_addr_match(s->saddr,laddr) == 0)
1723                 continue;
1724         return(s);
1725   }
1726   return(NULL);
1727 }
1728 
1729 
1730 void release_sock(struct sock *sk)
1731 {
1732   if (!sk) {
1733         printk("sock.c: release_sock sk == NULL\n");
1734         return;
1735   }
1736   if (!sk->prot) {
1737 /*      printk("sock.c: release_sock sk->prot == NULL\n"); */
1738         return;
1739   }
1740 
1741   if (sk->blog) return;
1742 
1743   /* See if we have any packets built up. */
1744   cli();
1745   sk->inuse = 1;
1746   while(sk->back_log != NULL) {
1747         struct sk_buff *skb;
1748 
1749         sk->blog = 1;
1750         skb =(struct sk_buff *)sk->back_log;
1751         DPRINTF((DBG_INET, "release_sock: skb = %X:\n", skb));
1752         if (skb->next != skb) {
1753                 sk->back_log = skb->next;
1754                 skb->prev->next = skb->next;
1755                 skb->next->prev = skb->prev;
1756         } else {
1757                 sk->back_log = NULL;
1758         }
1759         sti();
1760         DPRINTF((DBG_INET, "sk->back_log = %X\n", sk->back_log));
1761         if (sk->prot->rcv) sk->prot->rcv(skb, skb->dev, sk->opt,
1762                                          skb->saddr, skb->len, skb->daddr, 1,
1763 
1764         /* Only used for/by raw sockets. */
1765         (struct inet_protocol *)sk->pair); 
1766         cli();
1767   }
1768   sk->blog = 0;
1769   sk->inuse = 0;
1770   sti();
1771   if (sk->dead && sk->state == TCP_CLOSE) {
1772         /* Should be about 2 rtt's */
1773         reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
1774   }
1775 }
1776 
1777 
1778 static int
1779 inet_fioctl(struct inode *inode, struct file *file,
1780          unsigned int cmd, unsigned long arg)
1781 {
1782   int minor, ret;
1783 
1784   /* Extract the minor number on which we work. */
1785   minor = MINOR(inode->i_rdev);
1786   if (minor != 0) return(-ENODEV);
1787 
1788   /* Now dispatch on the minor device. */
1789   switch(minor) {
1790         case 0:         /* INET */
1791                 ret = inet_ioctl(NULL, cmd, arg);
1792                 break;
1793         case 1:         /* IP */
1794                 ret = ip_ioctl(NULL, cmd, arg);
1795                 break;
1796         case 2:         /* ICMP */
1797                 ret = icmp_ioctl(NULL, cmd, arg);
1798                 break;
1799         case 3:         /* TCP */
1800                 ret = tcp_ioctl(NULL, cmd, arg);
1801                 break;
1802         case 4:         /* UDP */
1803                 ret = udp_ioctl(NULL, cmd, arg);
1804                 break;
1805         default:
1806                 ret = -ENODEV;
1807   }
1808 
1809   return(ret);
1810 }
1811 
1812 
1813 
1814 
1815 static struct file_operations inet_fops = {
1816   NULL,         /* LSEEK        */
1817   NULL,         /* READ         */
1818   NULL,         /* WRITE        */
1819   NULL,         /* READDIR      */
1820   NULL,         /* SELECT       */
1821   inet_fioctl,  /* IOCTL        */
1822   NULL,         /* MMAP         */
1823   NULL,         /* OPEN         */
1824   NULL          /* CLOSE        */
1825 };
1826 
1827 
1828 static struct proto_ops inet_proto_ops = {
1829   AF_INET,
1830 
1831   inet_create,
1832   inet_dup,
1833   inet_release,
1834   inet_bind,
1835   inet_connect,
1836   inet_socketpair,
1837   inet_accept,
1838   inet_getname, 
1839   inet_read,
1840   inet_write,
1841   inet_select,
1842   inet_ioctl,
1843   inet_listen,
1844   inet_send,
1845   inet_recv,
1846   inet_sendto,
1847   inet_recvfrom,
1848   inet_shutdown,
1849   inet_setsockopt,
1850   inet_getsockopt,
1851   inet_fcntl,
1852 };
1853 
1854 extern unsigned long seq_offset;
1855 
1856 /* Called by ddi.c on kernel startup.  */
1857 void inet_proto_init(struct ddi_proto *pro)
1858 {
1859   struct inet_protocol *p;
1860   int i;
1861 
1862   printk("Swansea University Computer Society Net2Debugged [1.30]\n");
1863   /* Set up our UNIX VFS major device. */
1864   if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) {
1865         printk("%s: cannot register major device %d!\n",
1866                                         pro->name, AF_INET_MAJOR);
1867         return;
1868   }
1869 
1870   /* Tell SOCKET that we are alive... */
1871   (void) sock_register(inet_proto_ops.family, &inet_proto_ops);
1872 
1873   seq_offset = CURRENT_TIME*250;
1874 
1875   /* Add all the protocols. */
1876   for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
1877         tcp_prot.sock_array[i] = NULL;
1878         udp_prot.sock_array[i] = NULL;
1879         raw_prot.sock_array[i] = NULL;
1880   }
1881   printk("IP Protocols: ");
1882   for(p = inet_protocol_base; p != NULL;) {
1883         struct inet_protocol *tmp;
1884 
1885         tmp = (struct inet_protocol *) p->next;
1886         inet_add_protocol(p);
1887         printk("%s%s",p->name,tmp?", ":"\n");
1888         p = tmp;
1889   }
1890 
1891   /* Initialize the DEV module. */
1892   dev_init();
1893 
1894   /* Initialize the "Buffer Head" pointers. */
1895   bh_base[INET_BH].routine = inet_bh;
1896 }
1897 

⌨️ 快捷键说明

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