Răsfoiți Sursa

[更新] 支持 AF_UNIX 类型套接字

liukangcc 3 ani în urmă
părinte
comite
61da26a7ce

+ 105 - 0
bsp/qemu-vexpress-a9/drivers/drv_loopback.c

@@ -0,0 +1,105 @@
+#include <board.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <automac.h>
+#include <netif/ethernetif.h>
+#include <lwipopts.h>
+
+#include "mmu.h"
+
+static struct eth_device lo_emac = {0};
+rt_uint8_t enetaddr[6];         /* MAC address  */
+
+static rt_err_t loop_emac_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t loop_emac_control(rt_device_t dev, int cmd, void *args)
+{
+    switch(cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get MAC address */
+        if(args) rt_memcpy(args, enetaddr, 6);
+        else return -RT_ERROR;
+        break;
+
+    default :
+        break;
+    }
+    return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops loop_emac_ops = 
+{
+    loop_emac_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    loop_emac_control
+};
+#endif
+
+struct pbuf *lo_emac_rx(rt_device_t dev)
+{
+    struct pbuf* p = RT_NULL;
+
+    return p;
+}
+
+rt_err_t lo_emac_tx(rt_device_t dev, struct pbuf* p)
+{
+    return 0;
+}
+
+void lo_eth_device_linkchange(struct eth_device* dev, rt_bool_t up)
+{
+    rt_uint32_t level;
+
+    RT_ASSERT(dev != RT_NULL);
+
+    level = rt_hw_interrupt_disable();
+    dev->link_changed = 0x01;
+    if (up == RT_TRUE)
+        dev->link_status = 0x01;
+    else
+        dev->link_status = 0x00;
+    rt_hw_interrupt_enable(level);
+}
+
+int lo_emac_hw_init(void)
+{
+    /* test MAC address */
+    enetaddr[0] = AUTOMAC0 + 1;
+    enetaddr[1] = AUTOMAC1 + 1;
+    enetaddr[2] = AUTOMAC2 + 1;
+    enetaddr[3] = AUTOMAC3 + 1;
+    enetaddr[4] = AUTOMAC4 + 1;
+    enetaddr[5] = AUTOMAC5 + 1;
+
+#ifdef RT_USING_DEVICE_OPS
+    lo_emac.parent.ops        = &loop_emac_ops;
+#else
+    lo_emacparent.init        = loop_emac_init;
+    lo_emac.parent.open       = RT_NULL;
+    lo_emac.parent.close      = RT_NULL;
+    lo_emac.parent.read       = RT_NULL;
+    lo_emac.parent.write      = RT_NULL;
+    lo_emac.parent.control    = loop_emac_control;
+#endif
+    lo_emac.parent.user_data  = RT_NULL;
+    lo_emac.eth_rx     = RT_NULL;
+    lo_emac.eth_tx     = lo_emac_tx;
+
+    extern rt_err_t af_unix_eth_device_init(struct eth_device * dev, const char *name);
+    /* register ETH device */
+    af_unix_eth_device_init(&lo_emac, "lo");
+
+    lo_eth_device_linkchange(&lo_emac, RT_TRUE);
+
+    return 0;
+}
+INIT_APP_EXPORT(lo_emac_hw_init);

+ 16 - 0
components/lwp/lwp_syscall.c

@@ -2639,6 +2639,14 @@ int sys_bind(int socket, const struct musl_sockaddr *name, socklen_t namelen)
     {
         return -EFAULT;
     }
+
+#ifdef SAL_USING_AF_UNIX
+    if (name->sa_family  == AF_UNIX)
+    {
+        namelen = sizeof(struct sockaddr);
+    }
+#endif /* SAL_USING_AF_UNIX */
+
     lwp_get_from_user(&kname, (void *)name, namelen);
 
     sockaddr_tolwip(&kname, &sa);
@@ -2764,6 +2772,14 @@ int sys_connect(int socket, const struct musl_sockaddr *name, socklen_t namelen)
     {
         return -EFAULT;
     }
+
+#ifdef SAL_USING_AF_UNIX
+    if (name->sa_family  == AF_UNIX)
+    {
+        namelen = sizeof(struct sockaddr);
+    }
+#endif /* SAL_USING_AF_UNIX */
+
     lwp_get_from_user(&kname, (void *)name, namelen);
 
     sockaddr_tolwip(&kname, &sa);

+ 5 - 0
components/net/Kconfig

@@ -41,6 +41,11 @@ config RT_USING_SAL
             help
                 Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
 
+        config SAL_USING_AF_UNIX
+            bool "Enable support AF_UNIX socket"
+            default n
+            select LWIP_NETIF_LINK_CALLBACK
+
         if !SAL_USING_POSIX
 
             config SAL_SOCKETS_NUM

+ 2 - 0
components/net/lwip-2.0.2/src/include/lwip/sockets.h

@@ -210,12 +210,14 @@ struct linger {
 
 
 #define AF_UNSPEC       0
+#define AF_UNIX         1
 #define AF_INET         2
 #if LWIP_IPV6
 #define AF_INET6        10
 #else /* LWIP_IPV6 */
 #define AF_INET6        AF_UNSPEC
 #endif /* LWIP_IPV6 */
+#define PF_UNIX         AF_UNIX
 #define PF_INET         AF_INET
 #define PF_INET6        AF_INET6
 #define PF_UNSPEC       AF_UNSPEC

+ 155 - 0
components/net/lwip-2.0.2/src/netif/ethernetif.c

@@ -595,6 +595,161 @@ void eth_device_deinit(struct eth_device *dev)
     rt_free(netif);
 }
 
+#ifdef SAL_USING_AF_UNIX /* create loopback netdev */
+static err_t af_unix_eth_netif_device_init(struct netif *netif)
+{
+    struct eth_device *ethif;
+
+    ethif = (struct eth_device*)netif->state;
+    if (ethif != RT_NULL)
+    {
+        rt_device_t device;
+
+#ifdef RT_USING_NETDEV
+    /* network interface device register */
+    netdev_add(netif);
+#endif /* RT_USING_NETDEV */
+
+        /* get device object */
+        device = (rt_device_t) ethif;
+        if (rt_device_init(device) != RT_EOK)
+        {
+            return ERR_IF;
+        }
+
+        /* copy device flags to netif flags */
+        netif->flags = (ethif->flags & 0xff);
+        netif->mtu = ETHERNET_MTU;
+        
+        /* set output */
+        netif->output       = etharp_output;
+
+#if LWIP_IPV6
+        netif->output_ip6 = ethip6_output;
+        netif->ip6_autoconfig_enabled = 1;
+        netif_create_ip6_linklocal_address(netif, 1);
+
+#if LWIP_IPV6_MLD
+        netif->flags |= NETIF_FLAG_MLD6;
+
+        /*
+        * For hardware/netifs that implement MAC filtering.
+        * All-nodes link-local is handled by default, so we must let the hardware know
+        * to allow multicast packets in.
+        * Should set mld_mac_filter previously. */
+        if (netif->mld_mac_filter != NULL)
+        {
+            ip6_addr_t ip6_allnodes_ll;
+            ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
+            netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
+        }
+#endif /* LWIP_IPV6_MLD */
+
+#endif /* LWIP_IPV6 */
+
+        /* set default netif */
+        if (netif_default == RT_NULL)
+            netif_set_default(ethif->netif);
+
+        /* set interface up */
+        netif_set_up(ethif->netif);
+
+
+        if (ethif->flags & ETHIF_LINK_PHYUP)
+        {
+            /* set link_up for this netif */
+            netif_set_link_up(ethif->netif);
+        }
+
+        return ERR_OK;
+    }
+
+    return ERR_IF;
+}
+
+/* Keep old drivers compatible in RT-Thread */
+rt_err_t af_unix_eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags)
+{
+    struct netif* netif;
+#if LWIP_NETIF_HOSTNAME
+#define LWIP_HOSTNAME_LEN 16
+    char *hostname = RT_NULL;
+    netif = (struct netif*) rt_calloc (1, sizeof(struct netif) + LWIP_HOSTNAME_LEN);
+#else
+    netif = (struct netif*) rt_calloc (1, sizeof(struct netif));
+#endif
+    if (netif == RT_NULL)
+    {
+        rt_kprintf("malloc netif failed\n");
+        return -RT_ERROR;
+    }
+
+    /* set netif */
+    dev->netif = netif;
+    /* device flags, which will be set to netif flags when initializing */
+    dev->flags = flags;
+    /* link changed status of device */
+    dev->link_changed = 0x00;
+    dev->parent.type = RT_Device_Class_NetIf;
+    /* register to RT-Thread device manager */
+    rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
+    rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO);
+
+    /* set name */
+    netif->name[0] = name[0];
+    netif->name[1] = name[1];
+
+    /* set hw address to 6 */
+    netif->hwaddr_len   = 6;
+    /* maximum transfer unit */
+    netif->mtu          = ETHERNET_MTU;
+
+    /* set linkoutput */
+    netif->linkoutput   = ethernetif_linkoutput;
+        
+    /* get hardware MAC address */
+    rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
+
+#if LWIP_NETIF_HOSTNAME
+    /* Initialize interface hostname */
+    hostname = (char *)netif + sizeof(struct netif);
+    rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]);
+    netif->hostname = hostname;
+#endif /* LWIP_NETIF_HOSTNAME */
+
+    /* if tcp thread has been started up, we add this netif to the system */
+    if (rt_thread_find("tcpip") != RT_NULL)
+    {
+        ip4_addr_t ipaddr, netmask, gw;
+// set loopback ip
+        ipaddr.addr = inet_addr("127.0.0.1");
+        gw.addr = inet_addr("255.0.0.0");
+        netmask.addr = inet_addr("127.0.0.1");
+
+        netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, af_unix_eth_netif_device_init, tcpip_input);
+    }
+
+#ifdef RT_USING_NETDEV
+    /* network interface device flags synchronize */
+    netdev_flags_sync(netif);
+#endif /* RT_USING_NETDEV */
+
+    return RT_EOK;
+}
+
+rt_err_t af_unix_eth_device_init(struct eth_device * dev, const char *name)
+{
+    rt_uint16_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+#if LWIP_IGMP
+    /* IGMP support */
+    flags |= NETIF_FLAG_IGMP;
+#endif
+
+    return af_unix_eth_device_init_with_flag(dev, name, flags);
+}
+#endif /* SAL_USING_AF_UNIX */
+
 #ifndef LWIP_NO_RX_THREAD
 rt_err_t eth_device_ready(struct eth_device* dev)
 {

+ 11 - 0
components/net/sal_socket/include/sal_socket.h

@@ -71,11 +71,13 @@ typedef uint16_t in_port_t;
 #define  SOL_SOCKET     0xfff    /* options for socket level */
 
 #define AF_UNSPEC       0
+#define AF_UNIX         1
 #define AF_INET         2
 #define AF_INET6        10
 #define AF_CAN          29  /* Controller Area Network      */
 #define AF_AT           45  /* AT socket */
 #define AF_WIZ          46  /* WIZnet socket */
+#define PF_UNIX         AF_UNIX
 #define PF_INET         AF_INET
 #define PF_INET6        AF_INET6
 #define PF_UNSPEC       AF_UNSPEC
@@ -161,6 +163,15 @@ struct sockaddr
     char           sa_data[14];
 };
 
+/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
+struct sockaddr_un
+{
+    uint8_t        sa_len;
+    sa_family_t    sa_family;
+    char sun_path[108];         /* Path name.  */
+};
+
+
 #if NETDEV_IPV4
 /* members are in network byte order */
 struct sockaddr_in

+ 29 - 0
components/net/sal_socket/socket/net_sockets.c

@@ -80,6 +80,17 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen)
 {
     int socket = dfs_net_getsocket(s);
 
+#ifdef SAL_USING_AF_UNIX
+    struct sockaddr_in server_addr = {0};
+    if (name->sa_family == AF_UNIX)
+    {
+        server_addr.sin_family = AF_INET;
+        server_addr.sin_port = htons(514);
+        server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+        return sal_bind(socket, (struct sockaddr *)&server_addr, namelen);
+    }
+#endif /* SAL_USING_AF_UNIX */
+
     return sal_bind(socket, name, namelen);
 }
 RTM_EXPORT(bind);
@@ -154,6 +165,17 @@ int connect(int s, const struct sockaddr *name, socklen_t namelen)
 {
     int socket = dfs_net_getsocket(s);
 
+#ifdef SAL_USING_AF_UNIX
+    struct sockaddr_in server_addr = {0};
+    if (name->sa_family == AF_UNIX)
+    {
+        server_addr.sin_family = AF_INET;
+        server_addr.sin_port = htons(514);
+        server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+        return sal_connect(socket, (struct sockaddr *)&server_addr, namelen);
+    }
+#endif /* SAL_USING_AF_UNIX */
+
     return sal_connect(socket, name, namelen);
 }
 RTM_EXPORT(connect);
@@ -225,6 +247,13 @@ int socket(int domain, int type, int protocol)
         return -1;
     }
 
+#ifdef SAL_USING_AF_UNIX
+    if (domain == AF_UNIX)
+    {
+        domain = AF_INET;
+    }
+#endif /* SAL_USING_AF_UNIX */
+
     /* create socket  and then put it to the dfs_fd */
     socket = sal_socket(domain, type, protocol);
     if (socket >= 0)