📄 sock.c
字号:
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 + -