You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/10/27 23:00:33 UTC

incubator-mynewt-core git commit: native_sockets; move to a separate package, from underneath mn_socket. This so that it can have init function automatically called from sysinit.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop a6fdc0c2f -> 5b0c58e49


native_sockets; move to a separate package, from underneath mn_socket.
This so that it can have init function automatically called from sysinit.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/5b0c58e4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/5b0c58e4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/5b0c58e4

Branch: refs/heads/develop
Commit: 5b0c58e49108bdca0f7db1e773742ce407c68a97
Parents: a6fdc0c
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Oct 27 15:58:25 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Oct 27 15:58:25 2016 -0700

----------------------------------------------------------------------
 apps/ocf_sample/src/main.c                      |  10 -
 apps/slinky_oic/src/main.c                      |   9 -
 hw/bsp/native/pkg.yml                           |   2 +
 .../include/mn_socket/arch/sim/native_sock.h    |  33 -
 net/ip/mn_socket/src/arch/sim/native_itf.c      | 212 ------
 net/ip/mn_socket/src/arch/sim/native_sock.c     | 753 -------------------
 .../mn_socket/src/arch/sim/native_sock_priv.h   |  40 -
 net/ip/mn_socket/test/src/mn_sock_test.c        |   1 -
 net/ip/mn_socket/test/src/mn_sock_test.h        |   1 -
 net/ip/mn_socket/test/src/mn_sock_util.c        |   1 -
 .../mn_socket/test/src/testcases/socket_tests.c |   1 -
 net/ip/native_sockets/pkg.yml                   |  33 +
 net/ip/native_sockets/src/native_itf.c          | 212 ++++++
 net/ip/native_sockets/src/native_sock.c         | 752 ++++++++++++++++++
 net/ip/native_sockets/src/native_sock_priv.h    |  40 +
 15 files changed, 1039 insertions(+), 1061 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/apps/ocf_sample/src/main.c
----------------------------------------------------------------------
diff --git a/apps/ocf_sample/src/main.c b/apps/ocf_sample/src/main.c
index dffe4d2..c1f1b4c 100644
--- a/apps/ocf_sample/src/main.c
+++ b/apps/ocf_sample/src/main.c
@@ -29,11 +29,6 @@
 #include <shell/shell.h>
 #endif
 
-#if (MYNEWT_VAL(OC_TRANSPORT_IP) == 1)
-#include "mn_socket/mn_socket.h"
-#include "mn_socket/arch/sim/native_sock.h"
-#endif
-
 #if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)
 #include "host/ble_hs.h"
 #include "ocf_sample.h"
@@ -284,11 +279,6 @@ main(int argc, char **argv)
     /* Initialize OS */
     sysinit();
 
-#if (MYNEWT_VAL(OC_TRANSPORT_IP) == 1)
-    rc = native_sock_init();
-    assert(rc == 0);
-#endif
-
 #if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)
     ocf_ble_init();
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/apps/slinky_oic/src/main.c
----------------------------------------------------------------------
diff --git a/apps/slinky_oic/src/main.c b/apps/slinky_oic/src/main.c
index ca27d6c..b45f1f4 100755
--- a/apps/slinky_oic/src/main.c
+++ b/apps/slinky_oic/src/main.c
@@ -39,10 +39,6 @@
 #include <reboot/log_reboot.h>
 #include <os/os_time.h>
 
-#if (MYNEWT_VAL(OC_TRANSPORT_IP) == 1)
-#include <mn_socket/arch/sim/native_sock.h>
-#endif
-
 #ifdef ARCH_sim
 #include <mcu/mcu_sim.h>
 #endif
@@ -273,11 +269,6 @@ main(int argc, char **argv)
 
     log_reboot(HARD_REBOOT);
 
-#if (MYNEWT_VAL(OC_TRANSPORT_IP) == 1)
-    rc = native_sock_init();
-    assert(rc == 0);
-#endif
-
 #if MYNEWT_VAL(SPLIT_LOADER)
     {
         void *entry;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/hw/bsp/native/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/bsp/native/pkg.yml b/hw/bsp/native/pkg.yml
index 471610f..fe821e1 100644
--- a/hw/bsp/native/pkg.yml
+++ b/hw/bsp/native/pkg.yml
@@ -31,6 +31,8 @@ pkg.deps:
     - hw/mcu/native
     - hw/drivers/uart/uart_hal
     - sys/flash_map
+    - net/ip/native_sockets
 
 pkg.deps.BLE_DEVICE:
     - hw/drivers/nimble/native
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/include/mn_socket/arch/sim/native_sock.h
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/include/mn_socket/arch/sim/native_sock.h b/net/ip/mn_socket/include/mn_socket/arch/sim/native_sock.h
deleted file mode 100644
index 6fc2946..0000000
--- a/net/ip/mn_socket/include/mn_socket/arch/sim/native_sock.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef __NATIVE_SOCK_H_
-#define __NATIVE_SOCK_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int native_sock_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __NATIVE_SOCK_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/src/arch/sim/native_itf.c
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/src/arch/sim/native_itf.c b/net/ip/mn_socket/src/arch/sim/native_itf.c
deleted file mode 100644
index eb60154..0000000
--- a/net/ip/mn_socket/src/arch/sim/native_itf.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#include <ifaddrs.h>
-#include <net/if.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include "mn_socket/mn_socket.h"
-#include "native_sock_priv.h"
-
-static uint8_t
-itf_flags(int if_flags)
-{
-    uint8_t flags;
-
-    flags = 0;
-
-    if ((if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) {
-        flags |= MN_ITF_F_UP;
-    }
-    if (if_flags & IFF_MULTICAST) {
-        flags |= MN_ITF_F_MULTICAST;
-    }
-    return flags;
-}
-
-int
-native_sock_itf_getnext(struct mn_itf *mi)
-{
-    int prev_idx, cur_idx;
-    struct ifaddrs *ifap;
-    struct ifaddrs *ifa;
-    int rc;
-
-    if (mi->mif_name[0] == '\0') {
-        prev_idx = 0;
-    } else {
-        prev_idx = mi->mif_idx;
-    }
-    mi->mif_idx = UCHAR_MAX;
-    rc = getifaddrs(&ifap);
-    if (rc < 0) {
-        rc = native_sock_err_to_mn_err(errno);
-        return rc;
-    }
-
-    rc = MN_ENOBUFS;
-    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-        cur_idx = if_nametoindex(ifa->ifa_name);
-        if (cur_idx <= prev_idx || cur_idx >= mi->mif_idx) {
-            continue;
-        }
-        strncpy(mi->mif_name, ifa->ifa_name, sizeof(mi->mif_name));
-        mi->mif_idx = cur_idx;
-        mi->mif_flags = itf_flags(ifa->ifa_flags);
-        rc = 0;
-    }
-    freeifaddrs(ifap);
-    return rc;
-}
-
-static int
-addrcmp(uint8_t fam1, void *addr1, uint8_t fam2, void *addr2, int alen)
-{
-    if (fam1 != fam2) {
-        return fam1 - fam2;
-    }
-    return memcmp(addr1, addr2, alen);
-}
-
-static int
-plen(void *addr, int alen)
-{
-    int i;
-    int j;
-    uint8_t b;
-
-    for (i = 0; i < alen; i++) {
-        b = ((uint8_t *)addr)[i];
-        if (b == 0xff) {
-            continue;
-        }
-        for (j = 0; j < 7; j++) {
-            if ((b & (0x80 >> j)) == 0) {
-                return i * 8 + j;
-            }
-        }
-    }
-    return alen * 8;
-}
-
-int
-native_sock_itf_addr(int idx, uint32_t *addr)
-{
-    struct ifaddrs *ifap;
-    struct ifaddrs *ifa;
-    struct sockaddr_in *sin;
-    int rc;
-
-    rc = getifaddrs(&ifap);
-    if (rc < 0) {
-        rc = native_sock_err_to_mn_err(errno);
-        return rc;
-    }
-
-    rc = MN_EADDRNOTAVAIL;
-    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-        if (if_nametoindex(ifa->ifa_name) != idx) {
-            continue;
-        }
-        if (ifa->ifa_addr->sa_family == AF_INET) {
-            sin = (struct sockaddr_in *)ifa->ifa_addr;
-            *addr = sin->sin_addr.s_addr;
-            rc = 0;
-            break;
-        }
-    }
-    freeifaddrs(ifap);
-    return rc;
-}
-
-int
-native_sock_itf_addr_getnext(struct mn_itf *mi, struct mn_itf_addr *mia)
-{
-    struct ifaddrs *ifap;
-    struct ifaddrs *ifa;
-    struct sockaddr_in *sin;
-    struct sockaddr_in6 *sin6;
-    int rc;
-    uint8_t prev_family;
-    uint8_t prev_addr[16];
-
-    rc = getifaddrs(&ifap);
-    if (rc < 0) {
-        rc = native_sock_err_to_mn_err(errno);
-        return rc;
-    }
-
-    prev_family = mia->mifa_family;
-    memcpy(prev_addr, &mia->mifa_addr, sizeof(mia->mifa_addr));
-    mia->mifa_family = UCHAR_MAX;
-    memset(&mia->mifa_addr, 0xff, sizeof(mia->mifa_addr));
-
-    rc = MN_ENOBUFS;
-
-    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-        if (if_nametoindex(ifa->ifa_name) != mi->mif_idx) {
-            continue;
-        }
-        if (ifa->ifa_addr->sa_family == AF_INET) {
-            sin = (struct sockaddr_in *)ifa->ifa_addr;
-            if (addrcmp(MN_AF_INET, &sin->sin_addr,
-                prev_family, prev_addr,
-                sizeof(struct in_addr)) <= 0) {
-                continue;
-            }
-            if (addrcmp(MN_AF_INET, &sin->sin_addr,
-                mia->mifa_family, &mia->mifa_addr,
-                sizeof(struct in_addr)) >= 0) {
-                continue;
-            }
-            mia->mifa_family = MN_AF_INET;
-            memcpy(&mia->mifa_addr, &sin->sin_addr, sizeof(struct in_addr));
-
-            sin = (struct sockaddr_in *)ifa->ifa_netmask;
-            mia->mifa_plen = plen(&sin->sin_addr, sizeof(struct in_addr));
-        } else if (ifa->ifa_addr->sa_family == AF_INET6) {
-            sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
-            if (addrcmp(MN_AF_INET6, &sin6->sin6_addr,
-                prev_family, prev_addr,
-                sizeof(struct in6_addr)) <= 0) {
-                continue;
-            }
-            if (addrcmp(MN_AF_INET6, &sin6->sin6_addr,
-                mia->mifa_family, &mia->mifa_addr,
-                sizeof(struct in6_addr)) >= 0) {
-                continue;
-            }
-            mia->mifa_family = MN_AF_INET6;
-            memcpy(&mia->mifa_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
-
-            sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
-            mia->mifa_plen = plen(&sin6->sin6_addr, sizeof(struct in6_addr));
-        } else {
-            continue;
-        }
-        rc = 0;
-    }
-    freeifaddrs(ifap);
-    return rc;
-}
-
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/src/arch/sim/native_sock.c
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/src/arch/sim/native_sock.c b/net/ip/mn_socket/src/arch/sim/native_sock.c
deleted file mode 100644
index 55e06f3..0000000
--- a/net/ip/mn_socket/src/arch/sim/native_sock.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#include <sys/socket.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <poll.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-
-#include <os/os.h>
-#include <os/os_mbuf.h>
-#include "mn_socket/mn_socket.h"
-#include "mn_socket/mn_socket_ops.h"
-
-#include "mn_socket/arch/sim/native_sock.h"
-#include "native_sock_priv.h"
-
-#define NATIVE_SOCK_MAX 8
-#define NATIVE_SOCK_MAX_UDP 2048
-#define NATIVE_SOCK_POLL_ITVL (OS_TICKS_PER_SEC / 5)
-#define SOCK_STACK_SZ   4096
-#define SOCK_PRIO       2
-
-static int native_sock_create(struct mn_socket **sp, uint8_t domain,
-  uint8_t type, uint8_t proto);
-static int native_sock_close(struct mn_socket *);
-static int native_sock_connect(struct mn_socket *, struct mn_sockaddr *);
-static int native_sock_bind(struct mn_socket *, struct mn_sockaddr *);
-static int native_sock_listen(struct mn_socket *, uint8_t qlen);
-static int native_sock_sendto(struct mn_socket *, struct os_mbuf *,
-  struct mn_sockaddr *);
-static int native_sock_recvfrom(struct mn_socket *, struct os_mbuf **,
-  struct mn_sockaddr *);
-static int native_sock_getsockopt(struct mn_socket *, uint8_t level,
-  uint8_t name, void *val);
-static int native_sock_setsockopt(struct mn_socket *, uint8_t level,
-  uint8_t name, void *val);
-
-static int native_sock_getsockname(struct mn_socket *, struct mn_sockaddr *);
-static int native_sock_getpeername(struct mn_socket *, struct mn_sockaddr *);
-
-static struct native_sock {
-    struct mn_socket ns_sock;
-    int ns_fd;
-    unsigned int ns_poll:1;
-    unsigned int ns_listen:1;
-    uint8_t ns_type;
-    uint8_t ns_pf;
-    struct os_sem ns_sem;
-    STAILQ_HEAD(, os_mbuf_pkthdr) ns_rx;
-    struct os_mbuf *ns_tx;
-} native_socks[NATIVE_SOCK_MAX];
-
-static struct native_sock_state {
-    struct pollfd poll_fds[NATIVE_SOCK_MAX];
-    int poll_fd_cnt;
-    struct os_mutex mtx;
-    struct os_task task;
-} native_sock_state;
-
-static const struct mn_socket_ops native_sock_ops = {
-    .mso_create = native_sock_create,
-    .mso_close = native_sock_close,
-
-    .mso_bind = native_sock_bind,
-    .mso_connect = native_sock_connect,
-    .mso_listen = native_sock_listen,
-
-    .mso_sendto = native_sock_sendto,
-    .mso_recvfrom = native_sock_recvfrom,
-
-    .mso_getsockopt = native_sock_getsockopt,
-    .mso_setsockopt = native_sock_setsockopt,
-
-    .mso_getsockname = native_sock_getsockname,
-    .mso_getpeername = native_sock_getpeername,
-
-    .mso_itf_getnext = native_sock_itf_getnext,
-    .mso_itf_addr_getnext = native_sock_itf_addr_getnext
-};
-
-static struct native_sock *
-native_get_sock(void)
-{
-    int i;
-    struct native_sock *ns;
-
-    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
-        if (native_socks[i].ns_fd < 0) {
-            ns = &native_socks[i];
-            ns->ns_poll = 0;
-            ns->ns_listen = 0;
-            return ns;
-        }
-    }
-    return NULL;
-}
-
-static struct native_sock *
-native_find_sock(int fd)
-{
-    int i;
-
-    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
-        if (native_socks[i].ns_fd == fd) {
-            return &native_socks[i];
-        }
-    }
-    return NULL;
-}
-
-static void
-native_sock_poll_rebuild(struct native_sock_state *nss)
-{
-    struct native_sock *ns;
-    int i;
-    int j;
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    for (i = 0, j = 0; i < NATIVE_SOCK_MAX; i++) {
-        ns = &native_socks[i];
-        if (ns->ns_fd < 0) {
-            continue;
-        }
-        if (!ns->ns_poll) {
-            continue;
-        }
-        nss->poll_fds[j].fd = ns->ns_fd;
-        nss->poll_fds[j].events = POLLIN;
-        nss->poll_fds[j].revents = 0;
-        j++;
-    }
-    nss->poll_fd_cnt = j;
-    os_mutex_release(&nss->mtx);
-}
-
-int
-native_sock_err_to_mn_err(int err)
-{
-    switch (err) {
-    case 0:
-        return 0;
-    case EAGAIN:
-    case EINPROGRESS:
-        return MN_EAGAIN;
-    case ENOTCONN:
-        return MN_ENOTCONN;
-    case ETIMEDOUT:
-        return MN_ETIMEDOUT;
-    case ENOMEM:
-        return MN_ENOBUFS;
-    case EADDRINUSE:
-        return MN_EADDRINUSE;
-    case EADDRNOTAVAIL:
-        return MN_EADDRNOTAVAIL;
-    default:
-        return MN_EINVAL;
-    }
-}
-
-static int
-native_sock_mn_addr_to_addr(struct mn_sockaddr *ms, struct sockaddr *sa,
-  int *sa_len)
-{
-    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
-    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
-
-    switch (ms->msa_family) {
-    case MN_AF_INET:
-        sin->sin_family = AF_INET;
-#ifndef MN_LINUX
-        sin->sin_len = sizeof(*sin);
-#endif
-        sin->sin_addr.s_addr = msin->msin_addr.s_addr;
-        sin->sin_port = msin->msin_port;
-        *sa_len = sizeof(*sin);
-        break;
-    case MN_AF_INET6:
-        sin6->sin6_family = AF_INET6;
-#ifndef MN_LINUX
-        sin6->sin6_len = sizeof(*sin6);
-#endif
-        sin6->sin6_port = msin6->msin6_port;
-        sin6->sin6_flowinfo = msin6->msin6_flowinfo;
-        memcpy(&sin6->sin6_addr, &msin6->msin6_addr, sizeof(msin6->msin6_addr));
-        sin6->sin6_scope_id = msin6->msin6_scope_id;
-        *sa_len = sizeof(*sin6);
-        break;
-    default:
-        return MN_EPROTONOSUPPORT;
-    }
-    return 0;
-}
-
-static int
-native_sock_addr_to_mn_addr(struct sockaddr *sa, struct mn_sockaddr *ms)
-{
-    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
-    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
-    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-
-    switch (sa->sa_family) {
-    case AF_INET:
-        msin->msin_family = MN_AF_INET;
-        msin->msin_len = sizeof(*msin);
-        msin->msin_addr.s_addr = sin->sin_addr.s_addr;
-        msin->msin_port = sin->sin_port;
-        break;
-    case AF_INET6:
-        msin6->msin6_family = MN_AF_INET6;
-        msin6->msin6_len = sizeof(*msin6);
-        msin6->msin6_port = sin6->sin6_port;
-        msin6->msin6_flowinfo = sin6->sin6_flowinfo;
-        memcpy(&msin6->msin6_addr, &sin6->sin6_addr, sizeof(msin6->msin6_addr));
-        msin6->msin6_scope_id = sin6->sin6_scope_id;
-        break;
-    default:
-        return MN_EPROTONOSUPPORT;
-    }
-    return 0;
-}
-
-static int
-native_sock_create(struct mn_socket **sp, uint8_t domain,
-  uint8_t type, uint8_t proto)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct native_sock *ns;
-    int idx;
-
-    switch (domain) {
-    case MN_PF_INET:
-        domain = PF_INET;
-        break;
-    case MN_PF_INET6:
-        domain = PF_INET6;
-        break;
-    default:
-        return MN_EPROTONOSUPPORT;
-    }
-
-    switch (type) {
-    case MN_SOCK_DGRAM:
-        type = SOCK_DGRAM;
-        break;
-    case MN_SOCK_STREAM:
-        type = SOCK_STREAM;
-        break;
-    case 0:
-        break;
-    default:
-        return MN_EPROTONOSUPPORT;
-    }
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    ns = native_get_sock();
-    if (!ns) {
-        os_mutex_release(&nss->mtx);
-        return MN_ENOBUFS;
-    }
-    os_sem_init(&ns->ns_sem, 0);
-    idx = socket(domain, type, proto);
-    ns->ns_fd = idx;
-    ns->ns_pf = domain;
-    ns->ns_type = type;
-    os_mutex_release(&nss->mtx);
-    if (idx < 0) {
-        return MN_ENOBUFS;
-    }
-    *sp = &ns->ns_sock;
-    return 0;
-}
-
-static int
-native_sock_close(struct mn_socket *s)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct native_sock *ns = (struct native_sock *)s;
-    struct os_mbuf_pkthdr *m;
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    close(ns->ns_fd);
-    ns->ns_fd = -1;
-
-    /*
-     * When socket is closed, we must free all mbufs which might be
-     * queued in it.
-     */
-    while ((m = STAILQ_FIRST(&ns->ns_rx))) {
-        STAILQ_REMOVE_HEAD(&ns->ns_rx, omp_next);
-        os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(m));
-    }
-    native_sock_poll_rebuild(nss);
-    os_mutex_release(&nss->mtx);
-    return 0;
-}
-
-static int
-native_sock_connect(struct mn_socket *s, struct mn_sockaddr *addr)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    int rc;
-    int sa_len;
-
-    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
-    if (rc) {
-        return rc;
-    }
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    if (connect(ns->ns_fd, sa, sa_len)) {
-        rc = errno;
-        os_mutex_release(&nss->mtx);
-        return native_sock_err_to_mn_err(rc);
-    }
-    ns->ns_poll = 1;
-    native_sock_poll_rebuild(nss);
-    os_mutex_release(&nss->mtx);
-    mn_socket_writable(s, 0);
-    return 0;
-}
-
-static int
-native_sock_bind(struct mn_socket *s, struct mn_sockaddr *addr)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    int rc;
-    int sa_len;
-    int val = 1;
-
-    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
-    if (rc) {
-        return rc;
-    }
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    if (ns->ns_type == SOCK_STREAM) {
-        rc = setsockopt(ns->ns_fd, SOL_SOCKET, SO_REUSEADDR, &val,
-          sizeof(val));
-        if (rc) {
-            goto err;
-        }
-    }
-    rc = ioctl(ns->ns_fd, FIONBIO, (char *)&val);
-    if (rc) {
-        goto err;
-    }
-    if (bind(ns->ns_fd, sa, sa_len)) {
-        goto err;
-    }
-    if (ns->ns_type == SOCK_DGRAM) {
-        ns->ns_poll = 1;
-        native_sock_poll_rebuild(nss);
-    }
-    os_mutex_release(&nss->mtx);
-    return 0;
-err:
-    rc = errno;
-    os_mutex_release(&nss->mtx);
-    return native_sock_err_to_mn_err(rc);
-}
-
-static int
-native_sock_listen(struct mn_socket *s, uint8_t qlen)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct native_sock *ns = (struct native_sock *)s;
-    int rc;
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    if (listen(ns->ns_fd, qlen)) {
-        rc = errno;
-        os_mutex_release(&nss->mtx);
-        return native_sock_err_to_mn_err(rc);
-    }
-    ns->ns_poll = 1;
-    ns->ns_listen = 1;
-    native_sock_poll_rebuild(nss);
-    os_mutex_release(&nss->mtx);
-    return 0;
-}
-
-/*
- * TX routine for stream sockets (TCP). The data to send is pointed
- * by ns_tx.
- * Keep sending mbufs until socket says that it can't take anymore.
- * then wait for send event notification before continuing.
- */
-static int
-native_sock_stream_tx(struct native_sock *ns, int notify)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    struct os_mbuf *m;
-    struct os_mbuf *n;
-    int rc;
-
-    rc = 0;
-
-    os_mutex_pend(&nss->mtx, OS_TIMEOUT_NEVER);
-    while (ns->ns_tx && rc == 0) {
-        m = ns->ns_tx;
-        n = SLIST_NEXT(m, om_next);
-        rc = write(ns->ns_fd, m->om_data, m->om_len);
-        if (rc == m->om_len) {
-            ns->ns_tx = n;
-            os_mbuf_free(m);
-            rc = 0;
-        } else {
-            rc = errno;
-        }
-    }
-    os_mutex_release(&nss->mtx);
-    if (rc) {
-        if (rc == EAGAIN) {
-            rc = 0;
-        } else {
-            rc = native_sock_err_to_mn_err(rc);
-        }
-    }
-    if (notify) {
-        if (ns->ns_tx == NULL) {
-            mn_socket_writable(&ns->ns_sock, 0);
-        } else {
-            mn_socket_writable(&ns->ns_sock, rc);
-        }
-    }
-    return rc;
-}
-
-static int
-native_sock_sendto(struct mn_socket *s, struct os_mbuf *m,
-  struct mn_sockaddr *addr)
-{
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
-    struct os_mbuf *o;
-    int sa_len;
-    int off;
-    int rc;
-
-    if (ns->ns_type == SOCK_DGRAM) {
-        rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
-        if (rc) {
-            return rc;
-        }
-        off = 0;
-        for (o = m; o; o = SLIST_NEXT(o, om_next)) {
-            if (off + o->om_len > sizeof(tmpbuf)) {
-                return MN_ENOBUFS;
-            }
-            os_mbuf_copydata(o, 0, o->om_len, &tmpbuf[off]);
-            off += o->om_len;
-        }
-        rc = sendto(ns->ns_fd, tmpbuf, off, 0, sa, sa_len);
-        if (rc != off) {
-            return native_sock_err_to_mn_err(errno);
-        }
-        os_mbuf_free_chain(m);
-        return 0;
-    } else {
-        if (ns->ns_tx) {
-            return MN_EAGAIN;
-        }
-        ns->ns_tx = m;
-
-        rc = native_sock_stream_tx(ns, 0);
-        return rc;
-    }
-}
-
-static int
-native_sock_recvfrom(struct mn_socket *s, struct os_mbuf **mp,
-  struct mn_sockaddr *addr)
-{
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
-    struct os_mbuf *m;
-    socklen_t slen;
-    int rc;
-
-    slen = sizeof(ss);
-    if (ns->ns_type == SOCK_DGRAM) {
-        rc = recvfrom(ns->ns_fd, tmpbuf, sizeof(tmpbuf), 0, sa, &slen);
-    } else {
-        rc = getpeername(ns->ns_fd, sa, &slen);
-        if (rc == 0) {
-            rc = read(ns->ns_fd, tmpbuf, sizeof(tmpbuf));
-        }
-    }
-    if (rc < 0) {
-        return native_sock_err_to_mn_err(errno);
-    }
-    if (ns->ns_type == SOCK_STREAM && rc == 0) {
-        mn_socket_readable(&ns->ns_sock, MN_ECONNABORTED);
-        ns->ns_poll = 0;
-        native_sock_poll_rebuild(&native_sock_state);
-        return MN_ECONNABORTED;
-    }
-
-    m = os_msys_get_pkthdr(rc, 0);
-    if (!m) {
-        return MN_ENOBUFS;
-    }
-    os_mbuf_copyinto(m, 0, tmpbuf, rc);
-    *mp = m;
-    if (addr) {
-        native_sock_addr_to_mn_addr(sa, addr);
-    }
-    return 0;
-}
-
-static int
-native_sock_getsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
-  void *val)
-{
-    return MN_EPROTONOSUPPORT;
-}
-
-static int
-native_sock_setsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
-  void *val)
-{
-    struct native_sock *ns = (struct native_sock *)s;
-    int rc;
-    uint32_t val32;
-    struct group_req greq;
-    struct sockaddr_in *sin;
-    struct sockaddr_in6 *sin6;
-    struct mn_mreq *mreq;
-
-    if (level == MN_SO_LEVEL) {
-        switch (name) {
-        case MN_MCAST_JOIN_GROUP:
-        case MN_MCAST_LEAVE_GROUP:
-            mreq = val;
-            memset(&greq, 0, sizeof(greq));
-            greq.gr_interface = mreq->mm_idx;
-            if (mreq->mm_family == MN_AF_INET) {
-                sin = (struct sockaddr_in *)&greq.gr_group;
-#ifndef MN_LINUX
-                sin->sin_len = sizeof(*sin);
-#endif
-                sin->sin_family = AF_INET;
-                memcpy(&sin->sin_addr, &mreq->mm_addr, sizeof(struct in_addr));
-                level = IPPROTO_IP;
-            } else {
-                sin6 = (struct sockaddr_in6 *)&greq.gr_group;
-#ifndef MN_LINUX
-                sin6->sin6_len = sizeof(*sin6);
-#endif
-                sin6->sin6_family = AF_INET6;
-                memcpy(&sin6->sin6_addr, &mreq->mm_addr,
-                  sizeof(struct in6_addr));
-                level = IPPROTO_IPV6;
-            }
-
-            if (name == MN_MCAST_JOIN_GROUP) {
-                name = MCAST_JOIN_GROUP;
-            } else {
-                name = MCAST_LEAVE_GROUP;
-            }
-            rc = setsockopt(ns->ns_fd, level, name, &greq, sizeof(greq));
-            if (rc) {
-                return native_sock_err_to_mn_err(errno);
-            }
-            return 0;
-        case MN_MCAST_IF:
-            if (ns->ns_pf == AF_INET) {
-                level = IPPROTO_IP;
-                name = IP_MULTICAST_IF;
-                rc = native_sock_itf_addr(*(int *)val, &val32);
-                if (rc) {
-                    return rc;
-                }
-            } else {
-                level = IPPROTO_IPV6;
-                name = IPV6_MULTICAST_IF;
-                val32 = *(uint32_t *)val;
-            }
-            rc = setsockopt(ns->ns_fd, level, name, &val32, sizeof(val32));
-            if (rc) {
-                return native_sock_err_to_mn_err(errno);
-            }
-            return 0;
-        }
-    }
-    return MN_EPROTONOSUPPORT;
-}
-
-static int
-native_sock_getsockname(struct mn_socket *s, struct mn_sockaddr *addr)
-{
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    socklen_t len;
-    int rc;
-
-    len = sizeof(struct sockaddr_storage);
-    rc = getsockname(ns->ns_fd, sa, &len);
-    if (rc) {
-        return native_sock_err_to_mn_err(errno);
-    }
-    rc = native_sock_addr_to_mn_addr(sa, addr);
-    if (rc) {
-        return rc;
-    }
-    return 0;
-}
-
-static int
-native_sock_getpeername(struct mn_socket *s, struct mn_sockaddr *addr)
-{
-    struct native_sock *ns = (struct native_sock *)s;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    socklen_t len;
-    int rc;
-
-    len = sizeof(struct sockaddr_storage);
-    rc = getpeername(ns->ns_fd, sa, &len);
-    if (rc) {
-        return native_sock_err_to_mn_err(errno);
-    }
-    rc = native_sock_addr_to_mn_addr(sa, addr);
-    if (rc) {
-        return rc;
-    }
-    return 0;
-}
-
-/*
- * XXX should do this task with SIGIO as well.
- */
-static void
-socket_task(void *arg)
-{
-    struct native_sock_state *nss = arg;
-    struct native_sock *ns, *new_ns;
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = (struct sockaddr *)&ss;
-    int i;
-    socklen_t slen;
-    int rc;
-
-    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    while (1) {
-        os_mutex_release(&nss->mtx);
-        os_time_delay(NATIVE_SOCK_POLL_ITVL);
-        os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-        if (nss->poll_fd_cnt) {
-            rc = poll(nss->poll_fds, nss->poll_fd_cnt, 0);
-        } else {
-            rc = 0;
-        }
-        if (rc == 0) {
-            continue;
-        }
-        for (i = 0; i < nss->poll_fd_cnt; i++) {
-            if (!nss->poll_fds[i].revents) {
-                continue;
-            }
-            nss->poll_fds[i].revents = 0;
-            ns = native_find_sock(nss->poll_fds[i].fd);
-            assert(ns);
-            if (ns->ns_listen) {
-                new_ns = native_get_sock();
-                if (!new_ns) {
-                    continue;
-                }
-                slen = sizeof(ss);
-                new_ns->ns_fd = accept(ns->ns_fd, sa, &slen);
-                if (new_ns->ns_fd < 0) {
-                    continue;
-                }
-                new_ns->ns_type = ns->ns_type;
-                new_ns->ns_sock.ms_ops = &native_sock_ops;
-                os_mutex_release(&nss->mtx);
-                if (mn_socket_newconn(&ns->ns_sock, &new_ns->ns_sock)) {
-                    /*
-                     * should close
-                     */
-                }
-                os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-                new_ns->ns_poll = 1;
-                native_sock_poll_rebuild(nss);
-            } else {
-                mn_socket_readable(&ns->ns_sock, 0);
-            }
-        }
-    }
-}
-
-int
-native_sock_init(void)
-{
-    struct native_sock_state *nss = &native_sock_state;
-    int i;
-    os_stack_t *sp;
-
-    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
-        native_socks[i].ns_fd = -1;
-        STAILQ_INIT(&native_socks[i].ns_rx);
-    }
-    sp = malloc(sizeof(os_stack_t) * SOCK_STACK_SZ);
-    if (!sp) {
-        return -1;
-    }
-    os_mutex_init(&nss->mtx);
-    i = os_task_init(&nss->task, "socket", socket_task, &native_sock_state,
-      SOCK_PRIO, OS_WAIT_FOREVER, sp, SOCK_STACK_SZ);
-    if (i) {
-        return -1;
-    }
-    i = mn_socket_ops_reg(&native_sock_ops);
-    if (i) {
-        return -1;
-    }
-
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/src/arch/sim/native_sock_priv.h
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/src/arch/sim/native_sock_priv.h b/net/ip/mn_socket/src/arch/sim/native_sock_priv.h
deleted file mode 100644
index 907af71..0000000
--- a/net/ip/mn_socket/src/arch/sim/native_sock_priv.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef __NATIVE_SOCK_PRIV_H_
-#define __NATIVE_SOCK_PRIV_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct mn_itf;
-struct mn_itf_addr;
-
-int native_sock_itf_getnext(struct mn_itf *);
-int native_sock_itf_addr_getnext(struct mn_itf *, struct mn_itf_addr *);
-int native_sock_itf_addr(int idx, uint32_t *addr);
-
-int native_sock_err_to_mn_err(int err);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/test/src/mn_sock_test.c
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/test/src/mn_sock_test.c b/net/ip/mn_socket/test/src/mn_sock_test.c
index 9ae6041..92b489a 100644
--- a/net/ip/mn_socket/test/src/mn_sock_test.c
+++ b/net/ip/mn_socket/test/src/mn_sock_test.c
@@ -26,7 +26,6 @@
 #include "testutil/testutil.h"
 
 #include "mn_socket/mn_socket.h"
-#include "mn_socket/arch/sim/native_sock.h"
 #include "mn_sock_test.h"
 
 #define TEST_STACK_SIZE 4096

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/test/src/mn_sock_test.h
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/test/src/mn_sock_test.h b/net/ip/mn_socket/test/src/mn_sock_test.h
index 82f0cde..785aca9 100644
--- a/net/ip/mn_socket/test/src/mn_sock_test.h
+++ b/net/ip/mn_socket/test/src/mn_sock_test.h
@@ -28,7 +28,6 @@
 #include "testutil/testutil.h"
 
 #include "mn_socket/mn_socket.h"
-#include "mn_socket/arch/sim/native_sock.h"
 
 #define TEST_STACK_SIZE 4096
 #define TEST_PRIO 22

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/test/src/mn_sock_util.c
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/test/src/mn_sock_util.c b/net/ip/mn_socket/test/src/mn_sock_util.c
index 68d49cf..aea436e 100644
--- a/net/ip/mn_socket/test/src/mn_sock_util.c
+++ b/net/ip/mn_socket/test/src/mn_sock_util.c
@@ -26,7 +26,6 @@
 #include "testutil/testutil.h"
 
 #include "mn_socket/mn_socket.h"
-#include "mn_socket/arch/sim/native_sock.h"
 
 struct os_sem test_sem;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/mn_socket/test/src/testcases/socket_tests.c
----------------------------------------------------------------------
diff --git a/net/ip/mn_socket/test/src/testcases/socket_tests.c b/net/ip/mn_socket/test/src/testcases/socket_tests.c
index 2550bf3..3a81cc8 100644
--- a/net/ip/mn_socket/test/src/testcases/socket_tests.c
+++ b/net/ip/mn_socket/test/src/testcases/socket_tests.c
@@ -21,7 +21,6 @@
 TEST_CASE(socket_tests)
 {
     sysinit();
-    native_sock_init();
 
     os_sem_init(&test_sem, 0);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/native_sockets/pkg.yml
----------------------------------------------------------------------
diff --git a/net/ip/native_sockets/pkg.yml b/net/ip/native_sockets/pkg.yml
new file mode 100644
index 0000000..003fd3f
--- /dev/null
+++ b/net/ip/native_sockets/pkg.yml
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/ip/native_sockets
+pkg.description: Socket interface for Mynewt, uses native sockets.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - socket
+    - IP
+
+pkg.deps:
+    - kernel/os
+    - net/ip/mn_socket
+
+pkg.init_function: native_sock_init
+pkg.init_stage: 2

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/native_sockets/src/native_itf.c
----------------------------------------------------------------------
diff --git a/net/ip/native_sockets/src/native_itf.c b/net/ip/native_sockets/src/native_itf.c
new file mode 100644
index 0000000..eb60154
--- /dev/null
+++ b/net/ip/native_sockets/src/native_itf.c
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "mn_socket/mn_socket.h"
+#include "native_sock_priv.h"
+
+static uint8_t
+itf_flags(int if_flags)
+{
+    uint8_t flags;
+
+    flags = 0;
+
+    if ((if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) {
+        flags |= MN_ITF_F_UP;
+    }
+    if (if_flags & IFF_MULTICAST) {
+        flags |= MN_ITF_F_MULTICAST;
+    }
+    return flags;
+}
+
+int
+native_sock_itf_getnext(struct mn_itf *mi)
+{
+    int prev_idx, cur_idx;
+    struct ifaddrs *ifap;
+    struct ifaddrs *ifa;
+    int rc;
+
+    if (mi->mif_name[0] == '\0') {
+        prev_idx = 0;
+    } else {
+        prev_idx = mi->mif_idx;
+    }
+    mi->mif_idx = UCHAR_MAX;
+    rc = getifaddrs(&ifap);
+    if (rc < 0) {
+        rc = native_sock_err_to_mn_err(errno);
+        return rc;
+    }
+
+    rc = MN_ENOBUFS;
+    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+        cur_idx = if_nametoindex(ifa->ifa_name);
+        if (cur_idx <= prev_idx || cur_idx >= mi->mif_idx) {
+            continue;
+        }
+        strncpy(mi->mif_name, ifa->ifa_name, sizeof(mi->mif_name));
+        mi->mif_idx = cur_idx;
+        mi->mif_flags = itf_flags(ifa->ifa_flags);
+        rc = 0;
+    }
+    freeifaddrs(ifap);
+    return rc;
+}
+
+static int
+addrcmp(uint8_t fam1, void *addr1, uint8_t fam2, void *addr2, int alen)
+{
+    if (fam1 != fam2) {
+        return fam1 - fam2;
+    }
+    return memcmp(addr1, addr2, alen);
+}
+
+static int
+plen(void *addr, int alen)
+{
+    int i;
+    int j;
+    uint8_t b;
+
+    for (i = 0; i < alen; i++) {
+        b = ((uint8_t *)addr)[i];
+        if (b == 0xff) {
+            continue;
+        }
+        for (j = 0; j < 7; j++) {
+            if ((b & (0x80 >> j)) == 0) {
+                return i * 8 + j;
+            }
+        }
+    }
+    return alen * 8;
+}
+
+int
+native_sock_itf_addr(int idx, uint32_t *addr)
+{
+    struct ifaddrs *ifap;
+    struct ifaddrs *ifa;
+    struct sockaddr_in *sin;
+    int rc;
+
+    rc = getifaddrs(&ifap);
+    if (rc < 0) {
+        rc = native_sock_err_to_mn_err(errno);
+        return rc;
+    }
+
+    rc = MN_EADDRNOTAVAIL;
+    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+        if (if_nametoindex(ifa->ifa_name) != idx) {
+            continue;
+        }
+        if (ifa->ifa_addr->sa_family == AF_INET) {
+            sin = (struct sockaddr_in *)ifa->ifa_addr;
+            *addr = sin->sin_addr.s_addr;
+            rc = 0;
+            break;
+        }
+    }
+    freeifaddrs(ifap);
+    return rc;
+}
+
+int
+native_sock_itf_addr_getnext(struct mn_itf *mi, struct mn_itf_addr *mia)
+{
+    struct ifaddrs *ifap;
+    struct ifaddrs *ifa;
+    struct sockaddr_in *sin;
+    struct sockaddr_in6 *sin6;
+    int rc;
+    uint8_t prev_family;
+    uint8_t prev_addr[16];
+
+    rc = getifaddrs(&ifap);
+    if (rc < 0) {
+        rc = native_sock_err_to_mn_err(errno);
+        return rc;
+    }
+
+    prev_family = mia->mifa_family;
+    memcpy(prev_addr, &mia->mifa_addr, sizeof(mia->mifa_addr));
+    mia->mifa_family = UCHAR_MAX;
+    memset(&mia->mifa_addr, 0xff, sizeof(mia->mifa_addr));
+
+    rc = MN_ENOBUFS;
+
+    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+        if (if_nametoindex(ifa->ifa_name) != mi->mif_idx) {
+            continue;
+        }
+        if (ifa->ifa_addr->sa_family == AF_INET) {
+            sin = (struct sockaddr_in *)ifa->ifa_addr;
+            if (addrcmp(MN_AF_INET, &sin->sin_addr,
+                prev_family, prev_addr,
+                sizeof(struct in_addr)) <= 0) {
+                continue;
+            }
+            if (addrcmp(MN_AF_INET, &sin->sin_addr,
+                mia->mifa_family, &mia->mifa_addr,
+                sizeof(struct in_addr)) >= 0) {
+                continue;
+            }
+            mia->mifa_family = MN_AF_INET;
+            memcpy(&mia->mifa_addr, &sin->sin_addr, sizeof(struct in_addr));
+
+            sin = (struct sockaddr_in *)ifa->ifa_netmask;
+            mia->mifa_plen = plen(&sin->sin_addr, sizeof(struct in_addr));
+        } else if (ifa->ifa_addr->sa_family == AF_INET6) {
+            sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+            if (addrcmp(MN_AF_INET6, &sin6->sin6_addr,
+                prev_family, prev_addr,
+                sizeof(struct in6_addr)) <= 0) {
+                continue;
+            }
+            if (addrcmp(MN_AF_INET6, &sin6->sin6_addr,
+                mia->mifa_family, &mia->mifa_addr,
+                sizeof(struct in6_addr)) >= 0) {
+                continue;
+            }
+            mia->mifa_family = MN_AF_INET6;
+            memcpy(&mia->mifa_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+
+            sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
+            mia->mifa_plen = plen(&sin6->sin6_addr, sizeof(struct in6_addr));
+        } else {
+            continue;
+        }
+        rc = 0;
+    }
+    freeifaddrs(ifap);
+    return rc;
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/native_sockets/src/native_sock.c
----------------------------------------------------------------------
diff --git a/net/ip/native_sockets/src/native_sock.c b/net/ip/native_sockets/src/native_sock.c
new file mode 100644
index 0000000..a4049f4
--- /dev/null
+++ b/net/ip/native_sockets/src/native_sock.c
@@ -0,0 +1,752 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <poll.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+
+#include <os/os.h>
+#include <os/os_mbuf.h>
+#include "mn_socket/mn_socket.h"
+#include "mn_socket/mn_socket_ops.h"
+
+#include "native_sock_priv.h"
+
+#define NATIVE_SOCK_MAX 8
+#define NATIVE_SOCK_MAX_UDP 2048
+#define NATIVE_SOCK_POLL_ITVL (OS_TICKS_PER_SEC / 5)
+#define SOCK_STACK_SZ   4096
+#define SOCK_PRIO       2
+
+static int native_sock_create(struct mn_socket **sp, uint8_t domain,
+  uint8_t type, uint8_t proto);
+static int native_sock_close(struct mn_socket *);
+static int native_sock_connect(struct mn_socket *, struct mn_sockaddr *);
+static int native_sock_bind(struct mn_socket *, struct mn_sockaddr *);
+static int native_sock_listen(struct mn_socket *, uint8_t qlen);
+static int native_sock_sendto(struct mn_socket *, struct os_mbuf *,
+  struct mn_sockaddr *);
+static int native_sock_recvfrom(struct mn_socket *, struct os_mbuf **,
+  struct mn_sockaddr *);
+static int native_sock_getsockopt(struct mn_socket *, uint8_t level,
+  uint8_t name, void *val);
+static int native_sock_setsockopt(struct mn_socket *, uint8_t level,
+  uint8_t name, void *val);
+
+static int native_sock_getsockname(struct mn_socket *, struct mn_sockaddr *);
+static int native_sock_getpeername(struct mn_socket *, struct mn_sockaddr *);
+
+static struct native_sock {
+    struct mn_socket ns_sock;
+    int ns_fd;
+    unsigned int ns_poll:1;
+    unsigned int ns_listen:1;
+    uint8_t ns_type;
+    uint8_t ns_pf;
+    struct os_sem ns_sem;
+    STAILQ_HEAD(, os_mbuf_pkthdr) ns_rx;
+    struct os_mbuf *ns_tx;
+} native_socks[NATIVE_SOCK_MAX];
+
+static struct native_sock_state {
+    struct pollfd poll_fds[NATIVE_SOCK_MAX];
+    int poll_fd_cnt;
+    struct os_mutex mtx;
+    struct os_task task;
+} native_sock_state;
+
+static const struct mn_socket_ops native_sock_ops = {
+    .mso_create = native_sock_create,
+    .mso_close = native_sock_close,
+
+    .mso_bind = native_sock_bind,
+    .mso_connect = native_sock_connect,
+    .mso_listen = native_sock_listen,
+
+    .mso_sendto = native_sock_sendto,
+    .mso_recvfrom = native_sock_recvfrom,
+
+    .mso_getsockopt = native_sock_getsockopt,
+    .mso_setsockopt = native_sock_setsockopt,
+
+    .mso_getsockname = native_sock_getsockname,
+    .mso_getpeername = native_sock_getpeername,
+
+    .mso_itf_getnext = native_sock_itf_getnext,
+    .mso_itf_addr_getnext = native_sock_itf_addr_getnext
+};
+
+static struct native_sock *
+native_get_sock(void)
+{
+    int i;
+    struct native_sock *ns;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        if (native_socks[i].ns_fd < 0) {
+            ns = &native_socks[i];
+            ns->ns_poll = 0;
+            ns->ns_listen = 0;
+            return ns;
+        }
+    }
+    return NULL;
+}
+
+static struct native_sock *
+native_find_sock(int fd)
+{
+    int i;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        if (native_socks[i].ns_fd == fd) {
+            return &native_socks[i];
+        }
+    }
+    return NULL;
+}
+
+static void
+native_sock_poll_rebuild(struct native_sock_state *nss)
+{
+    struct native_sock *ns;
+    int i;
+    int j;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    for (i = 0, j = 0; i < NATIVE_SOCK_MAX; i++) {
+        ns = &native_socks[i];
+        if (ns->ns_fd < 0) {
+            continue;
+        }
+        if (!ns->ns_poll) {
+            continue;
+        }
+        nss->poll_fds[j].fd = ns->ns_fd;
+        nss->poll_fds[j].events = POLLIN;
+        nss->poll_fds[j].revents = 0;
+        j++;
+    }
+    nss->poll_fd_cnt = j;
+    os_mutex_release(&nss->mtx);
+}
+
+int
+native_sock_err_to_mn_err(int err)
+{
+    switch (err) {
+    case 0:
+        return 0;
+    case EAGAIN:
+    case EINPROGRESS:
+        return MN_EAGAIN;
+    case ENOTCONN:
+        return MN_ENOTCONN;
+    case ETIMEDOUT:
+        return MN_ETIMEDOUT;
+    case ENOMEM:
+        return MN_ENOBUFS;
+    case EADDRINUSE:
+        return MN_EADDRINUSE;
+    case EADDRNOTAVAIL:
+        return MN_EADDRNOTAVAIL;
+    default:
+        return MN_EINVAL;
+    }
+}
+
+static int
+native_sock_mn_addr_to_addr(struct mn_sockaddr *ms, struct sockaddr *sa,
+  int *sa_len)
+{
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
+    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
+
+    switch (ms->msa_family) {
+    case MN_AF_INET:
+        sin->sin_family = AF_INET;
+#ifndef MN_LINUX
+        sin->sin_len = sizeof(*sin);
+#endif
+        sin->sin_addr.s_addr = msin->msin_addr.s_addr;
+        sin->sin_port = msin->msin_port;
+        *sa_len = sizeof(*sin);
+        break;
+    case MN_AF_INET6:
+        sin6->sin6_family = AF_INET6;
+#ifndef MN_LINUX
+        sin6->sin6_len = sizeof(*sin6);
+#endif
+        sin6->sin6_port = msin6->msin6_port;
+        sin6->sin6_flowinfo = msin6->msin6_flowinfo;
+        memcpy(&sin6->sin6_addr, &msin6->msin6_addr, sizeof(msin6->msin6_addr));
+        sin6->sin6_scope_id = msin6->msin6_scope_id;
+        *sa_len = sizeof(*sin6);
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+    return 0;
+}
+
+static int
+native_sock_addr_to_mn_addr(struct sockaddr *sa, struct mn_sockaddr *ms)
+{
+    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
+    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+    switch (sa->sa_family) {
+    case AF_INET:
+        msin->msin_family = MN_AF_INET;
+        msin->msin_len = sizeof(*msin);
+        msin->msin_addr.s_addr = sin->sin_addr.s_addr;
+        msin->msin_port = sin->sin_port;
+        break;
+    case AF_INET6:
+        msin6->msin6_family = MN_AF_INET6;
+        msin6->msin6_len = sizeof(*msin6);
+        msin6->msin6_port = sin6->sin6_port;
+        msin6->msin6_flowinfo = sin6->sin6_flowinfo;
+        memcpy(&msin6->msin6_addr, &sin6->sin6_addr, sizeof(msin6->msin6_addr));
+        msin6->msin6_scope_id = sin6->sin6_scope_id;
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+    return 0;
+}
+
+static int
+native_sock_create(struct mn_socket **sp, uint8_t domain,
+  uint8_t type, uint8_t proto)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns;
+    int idx;
+
+    switch (domain) {
+    case MN_PF_INET:
+        domain = PF_INET;
+        break;
+    case MN_PF_INET6:
+        domain = PF_INET6;
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+
+    switch (type) {
+    case MN_SOCK_DGRAM:
+        type = SOCK_DGRAM;
+        break;
+    case MN_SOCK_STREAM:
+        type = SOCK_STREAM;
+        break;
+    case 0:
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    ns = native_get_sock();
+    if (!ns) {
+        os_mutex_release(&nss->mtx);
+        return MN_ENOBUFS;
+    }
+    os_sem_init(&ns->ns_sem, 0);
+    idx = socket(domain, type, proto);
+    ns->ns_fd = idx;
+    ns->ns_pf = domain;
+    ns->ns_type = type;
+    os_mutex_release(&nss->mtx);
+    if (idx < 0) {
+        return MN_ENOBUFS;
+    }
+    *sp = &ns->ns_sock;
+    return 0;
+}
+
+static int
+native_sock_close(struct mn_socket *s)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct os_mbuf_pkthdr *m;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    close(ns->ns_fd);
+    ns->ns_fd = -1;
+
+    /*
+     * When socket is closed, we must free all mbufs which might be
+     * queued in it.
+     */
+    while ((m = STAILQ_FIRST(&ns->ns_rx))) {
+        STAILQ_REMOVE_HEAD(&ns->ns_rx, omp_next);
+        os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(m));
+    }
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    return 0;
+}
+
+static int
+native_sock_connect(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int rc;
+    int sa_len;
+
+    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
+    if (rc) {
+        return rc;
+    }
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (connect(ns->ns_fd, sa, sa_len)) {
+        rc = errno;
+        os_mutex_release(&nss->mtx);
+        return native_sock_err_to_mn_err(rc);
+    }
+    ns->ns_poll = 1;
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    mn_socket_writable(s, 0);
+    return 0;
+}
+
+static int
+native_sock_bind(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int rc;
+    int sa_len;
+    int val = 1;
+
+    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
+    if (rc) {
+        return rc;
+    }
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (ns->ns_type == SOCK_STREAM) {
+        rc = setsockopt(ns->ns_fd, SOL_SOCKET, SO_REUSEADDR, &val,
+          sizeof(val));
+        if (rc) {
+            goto err;
+        }
+    }
+    rc = ioctl(ns->ns_fd, FIONBIO, (char *)&val);
+    if (rc) {
+        goto err;
+    }
+    if (bind(ns->ns_fd, sa, sa_len)) {
+        goto err;
+    }
+    if (ns->ns_type == SOCK_DGRAM) {
+        ns->ns_poll = 1;
+        native_sock_poll_rebuild(nss);
+    }
+    os_mutex_release(&nss->mtx);
+    return 0;
+err:
+    rc = errno;
+    os_mutex_release(&nss->mtx);
+    return native_sock_err_to_mn_err(rc);
+}
+
+static int
+native_sock_listen(struct mn_socket *s, uint8_t qlen)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    int rc;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (listen(ns->ns_fd, qlen)) {
+        rc = errno;
+        os_mutex_release(&nss->mtx);
+        return native_sock_err_to_mn_err(rc);
+    }
+    ns->ns_poll = 1;
+    ns->ns_listen = 1;
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    return 0;
+}
+
+/*
+ * TX routine for stream sockets (TCP). The data to send is pointed
+ * by ns_tx.
+ * Keep sending mbufs until socket says that it can't take anymore.
+ * then wait for send event notification before continuing.
+ */
+static int
+native_sock_stream_tx(struct native_sock *ns, int notify)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct os_mbuf *m;
+    struct os_mbuf *n;
+    int rc;
+
+    rc = 0;
+
+    os_mutex_pend(&nss->mtx, OS_TIMEOUT_NEVER);
+    while (ns->ns_tx && rc == 0) {
+        m = ns->ns_tx;
+        n = SLIST_NEXT(m, om_next);
+        rc = write(ns->ns_fd, m->om_data, m->om_len);
+        if (rc == m->om_len) {
+            ns->ns_tx = n;
+            os_mbuf_free(m);
+            rc = 0;
+        } else {
+            rc = errno;
+        }
+    }
+    os_mutex_release(&nss->mtx);
+    if (rc) {
+        if (rc == EAGAIN) {
+            rc = 0;
+        } else {
+            rc = native_sock_err_to_mn_err(rc);
+        }
+    }
+    if (notify) {
+        if (ns->ns_tx == NULL) {
+            mn_socket_writable(&ns->ns_sock, 0);
+        } else {
+            mn_socket_writable(&ns->ns_sock, rc);
+        }
+    }
+    return rc;
+}
+
+static int
+native_sock_sendto(struct mn_socket *s, struct os_mbuf *m,
+  struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
+    struct os_mbuf *o;
+    int sa_len;
+    int off;
+    int rc;
+
+    if (ns->ns_type == SOCK_DGRAM) {
+        rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
+        if (rc) {
+            return rc;
+        }
+        off = 0;
+        for (o = m; o; o = SLIST_NEXT(o, om_next)) {
+            if (off + o->om_len > sizeof(tmpbuf)) {
+                return MN_ENOBUFS;
+            }
+            os_mbuf_copydata(o, 0, o->om_len, &tmpbuf[off]);
+            off += o->om_len;
+        }
+        rc = sendto(ns->ns_fd, tmpbuf, off, 0, sa, sa_len);
+        if (rc != off) {
+            return native_sock_err_to_mn_err(errno);
+        }
+        os_mbuf_free_chain(m);
+        return 0;
+    } else {
+        if (ns->ns_tx) {
+            return MN_EAGAIN;
+        }
+        ns->ns_tx = m;
+
+        rc = native_sock_stream_tx(ns, 0);
+        return rc;
+    }
+}
+
+static int
+native_sock_recvfrom(struct mn_socket *s, struct os_mbuf **mp,
+  struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
+    struct os_mbuf *m;
+    socklen_t slen;
+    int rc;
+
+    slen = sizeof(ss);
+    if (ns->ns_type == SOCK_DGRAM) {
+        rc = recvfrom(ns->ns_fd, tmpbuf, sizeof(tmpbuf), 0, sa, &slen);
+    } else {
+        rc = getpeername(ns->ns_fd, sa, &slen);
+        if (rc == 0) {
+            rc = read(ns->ns_fd, tmpbuf, sizeof(tmpbuf));
+        }
+    }
+    if (rc < 0) {
+        return native_sock_err_to_mn_err(errno);
+    }
+    if (ns->ns_type == SOCK_STREAM && rc == 0) {
+        mn_socket_readable(&ns->ns_sock, MN_ECONNABORTED);
+        ns->ns_poll = 0;
+        native_sock_poll_rebuild(&native_sock_state);
+        return MN_ECONNABORTED;
+    }
+
+    m = os_msys_get_pkthdr(rc, 0);
+    if (!m) {
+        return MN_ENOBUFS;
+    }
+    os_mbuf_copyinto(m, 0, tmpbuf, rc);
+    *mp = m;
+    if (addr) {
+        native_sock_addr_to_mn_addr(sa, addr);
+    }
+    return 0;
+}
+
+static int
+native_sock_getsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
+  void *val)
+{
+    return MN_EPROTONOSUPPORT;
+}
+
+static int
+native_sock_setsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
+  void *val)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    int rc;
+    uint32_t val32;
+    struct group_req greq;
+    struct sockaddr_in *sin;
+    struct sockaddr_in6 *sin6;
+    struct mn_mreq *mreq;
+
+    if (level == MN_SO_LEVEL) {
+        switch (name) {
+        case MN_MCAST_JOIN_GROUP:
+        case MN_MCAST_LEAVE_GROUP:
+            mreq = val;
+            memset(&greq, 0, sizeof(greq));
+            greq.gr_interface = mreq->mm_idx;
+            if (mreq->mm_family == MN_AF_INET) {
+                sin = (struct sockaddr_in *)&greq.gr_group;
+#ifndef MN_LINUX
+                sin->sin_len = sizeof(*sin);
+#endif
+                sin->sin_family = AF_INET;
+                memcpy(&sin->sin_addr, &mreq->mm_addr, sizeof(struct in_addr));
+                level = IPPROTO_IP;
+            } else {
+                sin6 = (struct sockaddr_in6 *)&greq.gr_group;
+#ifndef MN_LINUX
+                sin6->sin6_len = sizeof(*sin6);
+#endif
+                sin6->sin6_family = AF_INET6;
+                memcpy(&sin6->sin6_addr, &mreq->mm_addr,
+                  sizeof(struct in6_addr));
+                level = IPPROTO_IPV6;
+            }
+
+            if (name == MN_MCAST_JOIN_GROUP) {
+                name = MCAST_JOIN_GROUP;
+            } else {
+                name = MCAST_LEAVE_GROUP;
+            }
+            rc = setsockopt(ns->ns_fd, level, name, &greq, sizeof(greq));
+            if (rc) {
+                return native_sock_err_to_mn_err(errno);
+            }
+            return 0;
+        case MN_MCAST_IF:
+            if (ns->ns_pf == AF_INET) {
+                level = IPPROTO_IP;
+                name = IP_MULTICAST_IF;
+                rc = native_sock_itf_addr(*(int *)val, &val32);
+                if (rc) {
+                    return rc;
+                }
+            } else {
+                level = IPPROTO_IPV6;
+                name = IPV6_MULTICAST_IF;
+                val32 = *(uint32_t *)val;
+            }
+            rc = setsockopt(ns->ns_fd, level, name, &val32, sizeof(val32));
+            if (rc) {
+                return native_sock_err_to_mn_err(errno);
+            }
+            return 0;
+        }
+    }
+    return MN_EPROTONOSUPPORT;
+}
+
+static int
+native_sock_getsockname(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    socklen_t len;
+    int rc;
+
+    len = sizeof(struct sockaddr_storage);
+    rc = getsockname(ns->ns_fd, sa, &len);
+    if (rc) {
+        return native_sock_err_to_mn_err(errno);
+    }
+    rc = native_sock_addr_to_mn_addr(sa, addr);
+    if (rc) {
+        return rc;
+    }
+    return 0;
+}
+
+static int
+native_sock_getpeername(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    socklen_t len;
+    int rc;
+
+    len = sizeof(struct sockaddr_storage);
+    rc = getpeername(ns->ns_fd, sa, &len);
+    if (rc) {
+        return native_sock_err_to_mn_err(errno);
+    }
+    rc = native_sock_addr_to_mn_addr(sa, addr);
+    if (rc) {
+        return rc;
+    }
+    return 0;
+}
+
+/*
+ * XXX should do this task with SIGIO as well.
+ */
+static void
+socket_task(void *arg)
+{
+    struct native_sock_state *nss = arg;
+    struct native_sock *ns, *new_ns;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int i;
+    socklen_t slen;
+    int rc;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    while (1) {
+        os_mutex_release(&nss->mtx);
+        os_time_delay(NATIVE_SOCK_POLL_ITVL);
+        os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+        if (nss->poll_fd_cnt) {
+            rc = poll(nss->poll_fds, nss->poll_fd_cnt, 0);
+        } else {
+            rc = 0;
+        }
+        if (rc == 0) {
+            continue;
+        }
+        for (i = 0; i < nss->poll_fd_cnt; i++) {
+            if (!nss->poll_fds[i].revents) {
+                continue;
+            }
+            nss->poll_fds[i].revents = 0;
+            ns = native_find_sock(nss->poll_fds[i].fd);
+            assert(ns);
+            if (ns->ns_listen) {
+                new_ns = native_get_sock();
+                if (!new_ns) {
+                    continue;
+                }
+                slen = sizeof(ss);
+                new_ns->ns_fd = accept(ns->ns_fd, sa, &slen);
+                if (new_ns->ns_fd < 0) {
+                    continue;
+                }
+                new_ns->ns_type = ns->ns_type;
+                new_ns->ns_sock.ms_ops = &native_sock_ops;
+                os_mutex_release(&nss->mtx);
+                if (mn_socket_newconn(&ns->ns_sock, &new_ns->ns_sock)) {
+                    /*
+                     * should close
+                     */
+                }
+                os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+                new_ns->ns_poll = 1;
+                native_sock_poll_rebuild(nss);
+            } else {
+                mn_socket_readable(&ns->ns_sock, 0);
+            }
+        }
+    }
+}
+
+int
+native_sock_init(void)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    int i;
+    os_stack_t *sp;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        native_socks[i].ns_fd = -1;
+        STAILQ_INIT(&native_socks[i].ns_rx);
+    }
+    sp = malloc(sizeof(os_stack_t) * SOCK_STACK_SZ);
+    if (!sp) {
+        return -1;
+    }
+    os_mutex_init(&nss->mtx);
+    i = os_task_init(&nss->task, "socket", socket_task, &native_sock_state,
+      SOCK_PRIO, OS_WAIT_FOREVER, sp, SOCK_STACK_SZ);
+    if (i) {
+        return -1;
+    }
+    i = mn_socket_ops_reg(&native_sock_ops);
+    if (i) {
+        return -1;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5b0c58e4/net/ip/native_sockets/src/native_sock_priv.h
----------------------------------------------------------------------
diff --git a/net/ip/native_sockets/src/native_sock_priv.h b/net/ip/native_sockets/src/native_sock_priv.h
new file mode 100644
index 0000000..907af71
--- /dev/null
+++ b/net/ip/native_sockets/src/native_sock_priv.h
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __NATIVE_SOCK_PRIV_H_
+#define __NATIVE_SOCK_PRIV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct mn_itf;
+struct mn_itf_addr;
+
+int native_sock_itf_getnext(struct mn_itf *);
+int native_sock_itf_addr_getnext(struct mn_itf *, struct mn_itf_addr *);
+int native_sock_itf_addr(int idx, uint32_t *addr);
+
+int native_sock_err_to_mn_err(int err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif