diff options
-rw-r--r-- | libnl_2/.gitignore | 2 | ||||
-rw-r--r-- | libnl_2/Android.mk | 39 | ||||
-rw-r--r-- | libnl_2/README | 88 | ||||
-rw-r--r-- | libnl_2/attr.c | 239 | ||||
-rw-r--r-- | libnl_2/cache.c | 37 | ||||
-rw-r--r-- | libnl_2/dbg.c | 12 | ||||
-rw-r--r-- | libnl_2/genl/family.c | 44 | ||||
-rw-r--r-- | libnl_2/genl/genl.c | 302 | ||||
-rw-r--r-- | libnl_2/handlers.c | 90 | ||||
-rw-r--r-- | libnl_2/msg.c | 150 | ||||
-rw-r--r-- | libnl_2/netlink.c | 273 | ||||
-rw-r--r-- | libnl_2/object.c | 33 | ||||
-rw-r--r-- | libnl_2/socket.c | 141 |
13 files changed, 0 insertions, 1450 deletions
diff --git a/libnl_2/.gitignore b/libnl_2/.gitignore deleted file mode 100644 index d4ca744..0000000 --- a/libnl_2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -include/netlink/version.h.in -cscope.* diff --git a/libnl_2/Android.mk b/libnl_2/Android.mk deleted file mode 100644 index 3721fc6..0000000 --- a/libnl_2/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -####################################### -# * Netlink cache not implemented -# * Library is not thread safe -####################################### - -LOCAL_PATH := $(call my-dir) - - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - attr.c \ - cache.c \ - genl/genl.c \ - genl/family.c \ - handlers.c \ - msg.c \ - netlink.c \ - object.c \ - socket.c \ - dbg.c - -LOCAL_C_INCLUDES += \ - external/libnl-headers - -# Static Library -LOCAL_MODULE := libnl_2 -LOCAL_MODULE_TAGS := optional -LOCAL_32_BIT_ONLY := true -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES := -LOCAL_WHOLE_STATIC_LIBRARIES:= libnl_2 -LOCAL_SHARED_LIBRARIES:= liblog -LOCAL_MODULE := libnl_2 -LOCAL_MODULE_TAGS := optional -LOCAL_32_BIT_ONLY := true -include $(BUILD_SHARED_LIBRARY) diff --git a/libnl_2/README b/libnl_2/README deleted file mode 100644 index 14db6db..0000000 --- a/libnl_2/README +++ /dev/null @@ -1,88 +0,0 @@ -Netlink Protocol Library - -This library is a clean room re-implementation of libnl 2.0 and -re-licensed under Apache 2.0. It was developed primarily to support -wpa_supplicant. However, with additional development can be extended -to support other netlink applications. - -Netlink Protocol Format (RFC3549) - -+-----------------+-+-------------------+-+ -|Netlink Message |P| Generic Netlink |P| -| Header |A| Message Header |A| -|(struct nlmsghdr)|D|(struct genlmsghdr)|D| -+-----------------+-+-------------------+-+-------------+ -|len:4|type:2|flags:2|seq:4 pid:4|cmd:1|ver:1|reserved:2| -+--------------------------------+----------------------+ -+-----------------+-+-----------------+-+-----------------+-+-----------------+-+---+ -|Netlink Attribute|P|Netlink Attribute|P|Netlink Attribute|P|Netlink Attribute|P|...| -| #0 Header |A| #0 Payload |A| #1 Header |A| #1 Payload |A| | -| (struct nlattr) |D| (void) |D| (struct nlattr) |D| (void) |D| | -+-----------------+-+-----------------+-+-----------------+-+-----------------+-+---+ -|len:2(==4+payload)|type:2|payload|pad| -+-------------------------+-------+---+ - -NETLINK OVERVIEW - -* Each netlink message consists of a bitstream with a netlink header. -* After this header a second header *can* be used specific to the netlink - family in use. This library was tested using the generic netlink - protocol defined by struct genlmsghdr to support nl80211. -* After the header(s) netlink attributes can be appended to the message - which hold can hold basic types such as unsigned integers and strings. -* Attributes can also be nested. This is accomplished by calling "nla_nest_start" - which creates an empty attribute with nest attributes as its payload. Then to - close the nest, "nla_nest_end" is called. -* All data structures in this implementation are byte-aligned (Currently 4 bytes). -* Acknowledgements (ACKs) are sent as NLMSG_ERROR netlink message types (0x2) and - have an error value of 0. - -KNOWN ISSUES - - GENERAL - * Not tested for thread safety - - Android.mk - * No dynamic library because of netlink cache not implemented and - not tested for thread safety - - attr.c - * nla_parse - does not use nla_policy argument - - cache.c - * netlink cache not implemented and only supports one netlink family id - which is stored in the nl_cache pointer instead of an actual cache - - netlink.c - * nl_recvmsgs - does not support nl_cb_overwrite_recv() - * nl_recv - sets/unsets asynchronous socket flag - -SOURCE FILES - -* Android.mk - Android makefile -* README - This file -* attr.c - Netlink attributes -* cache.c - Netlink cache -* genl/family.c - Generic netlink family id -* genl/genl.c - Generic netlink -* handlers.c - Netlink callbacks -* msg.c - Netlink messages construction -* netlink.c - Netlink socket communication -* object.c - libnl object wrapper -* socket.c - Netlink kernel socket utils - -IMPORTANT HEADER FILES - NOTE: These are based on the the origin GPL libnl headers - -* netlink-types.h - Contains many important structs for libnl - to represent netlink objects -* netlink/netlink-kernel.h - Netlink kernel headers and field constants. -* netlink/msg.h - macros for iterating over netlink messages -* netlink/attr.h - netlink attribute constants, iteration macros and setters - -REFERENCES - -* nl80211.h -* netlink_types.h -* $LINUX_KERNEL/net/wireless/nl80211.c -* http://www.infradead.org/~tgr/libnl/doc-3.0/index.html -* http://www.netfilter.org/projects/libmnl/doxygen/index.html diff --git a/libnl_2/attr.c b/libnl_2/attr.c deleted file mode 100644 index 2ef7590..0000000 --- a/libnl_2/attr.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <errno.h> -#include "netlink/netlink.h" -#include "netlink/msg.h" -#include "netlink/attr.h" -#include "netlink-types.h" - -/* Return payload of string attribute. */ -char *nla_get_string(struct nlattr *nla) -{ - return (char *) nla_data(nla); -} - -/* Return payload of 16 bit integer attribute. */ -uint16_t nla_get_u16(struct nlattr *nla) -{ - return *((uint16_t *) nla_data(nla)); -} - -/* Return payload of 32 bit integer attribute. */ -uint32_t nla_get_u32(struct nlattr *nla) -{ - return *((uint32_t *) nla_data(nla)); -} - -/* Return value of 8 bit integer attribute. */ -uint8_t nla_get_u8(struct nlattr *nla) -{ - return *((uint8_t *) nla_data(nla)); -} - -/* Return payload of uint64_t attribute. */ -uint64_t nla_get_u64(struct nlattr *nla) -{ - uint64_t tmp; - nla_memcpy(&tmp, nla, sizeof(tmp)); - return tmp; -} - -/* Head of payload */ -void *nla_data(const struct nlattr *nla) -{ - return (void *) ((char *) nla + NLA_HDRLEN); -} - -/* Return length of the payload . */ -int nla_len(const struct nlattr *nla) -{ - return nla->nla_len - NLA_HDRLEN; -} - -int nla_padlen(int payload) -{ - return NLA_ALIGN(payload) - payload; -} - -/* Start a new level of nested attributes. */ -struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype) -{ - struct nlattr *start = (struct nlattr *)nlmsg_tail(msg->nm_nlh); - int rc; - - rc = nla_put(msg, attrtype, 0, NULL); - if (rc < 0) - return NULL; - - return start; -} - -/* Finalize nesting of attributes. */ -int nla_nest_end(struct nl_msg *msg, struct nlattr *start) -{ - /* Set attribute size */ - start->nla_len = (unsigned char *)nlmsg_tail(nlmsg_hdr(msg)) - - (unsigned char *)start; - return 0; -} - -/* Return next attribute in a stream of attributes. */ -struct nlattr *nla_next(const struct nlattr *nla, int *remaining) -{ - struct nlattr *next_nla = NULL; - if (nla->nla_len >= sizeof(struct nlattr) && - nla->nla_len <= *remaining){ - next_nla = (struct nlattr *) \ - ((char *) nla + NLA_ALIGN(nla->nla_len)); - *remaining = *remaining - NLA_ALIGN(nla->nla_len); - } - - return next_nla; - -} - -/* Check if the attribute header and payload can be accessed safely. */ -int nla_ok(const struct nlattr *nla, int remaining) -{ - return remaining > 0 && - nla->nla_len >= sizeof(struct nlattr) && - sizeof(struct nlattr) <= (unsigned int) remaining && - nla->nla_len <= remaining; -} - -/* Create attribute index based on a stream of attributes. */ -/* NOTE: Policy not used ! */ -int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, - int len, struct nla_policy *policy) -{ - struct nlattr *pos; - int rem; - - /* First clear table */ - memset(tb, 0, (maxtype + 1) * sizeof(struct nlattr *)); - - nla_for_each_attr(pos, head, len, rem) { - int type = nla_type(pos); - - if ((type <= maxtype) && (type != 0)) - tb[type] = pos; - } - - return 0; -} - - -/* Create attribute index based on nested attribute. */ -int nla_parse_nested(struct nlattr *tb[], int maxtype, - struct nlattr *nla, struct nla_policy *policy) -{ - return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); -} - - -/* Add a unspecific attribute to netlink message. */ -int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data) -{ - struct nlattr *nla; - - /* Reserve space and init nla header */ - nla = nla_reserve(msg, attrtype, datalen); - if (nla) { - memcpy(nla_data(nla), data, datalen); - return 0; - } - - return -EINVAL; -} - -/* Add 8 bit integer attribute to netlink message. */ -int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value) -{ - return nla_put(msg, attrtype, sizeof(uint8_t), &value); -} - -/* Add 16 bit integer attribute to netlink message. */ -int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value) -{ - return nla_put(msg, attrtype, sizeof(uint16_t), &value); -} - -/* Add 32 bit integer attribute to netlink message. */ -int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value) -{ - return nla_put(msg, attrtype, sizeof(uint32_t), &value); -} - -/* Add 64 bit integer attribute to netlink message. */ -int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value) -{ - return nla_put(msg, attrtype, sizeof(uint64_t), &value); -} - -/* Add nested attributes to netlink message. */ -/* Takes the attributes found in the nested message and appends them - * to the message msg nested in a container of the type attrtype. The - * nested message may not have a family specific header */ -int nla_put_nested(struct nl_msg *msg, int attrtype, struct nl_msg *nested) -{ - int rc; - - rc = nla_put(msg, attrtype, nlmsg_attrlen(nlmsg_hdr(nested), 0), - nlmsg_attrdata(nlmsg_hdr(nested), 0)); - return rc; - -} - -/* Return type of the attribute. */ -int nla_type(const struct nlattr *nla) -{ - return (int)nla->nla_type & NLA_TYPE_MASK; -} - -/* Reserves room for an attribute in specified netlink message and fills - * in the attribute header (type,length). Return NULL if insufficient space */ -struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int data_len) -{ - - struct nlattr *nla; - const unsigned int NEW_SIZE = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + - NLA_ALIGN(NLA_HDRLEN + data_len); - - /* Check enough space for attribute */ - if (NEW_SIZE > msg->nm_size) - return NULL; - - nla = (struct nlattr *)nlmsg_tail(msg->nm_nlh); - nla->nla_type = attrtype; - nla->nla_len = NLA_HDRLEN + data_len; - memset((unsigned char *)nla + nla->nla_len, 0, nla_padlen(data_len)); - msg->nm_nlh->nlmsg_len = NEW_SIZE; - return nla; -} - -/* Copy attribute payload to another memory area. */ -int nla_memcpy(void *dest, struct nlattr *src, int count) -{ - if (!src || !dest) - return 0; - if (count > nla_len(src)) - count = nla_len(src); - memcpy(dest, nla_data(src), count); - return count; -} diff --git a/libnl_2/cache.c b/libnl_2/cache.c deleted file mode 100644 index c21974d..0000000 --- a/libnl_2/cache.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include "netlink/cache.h" -#include "netlink/object.h" - -void nl_cache_free(struct nl_cache *cache) -{ - -} - -void nl_cache_clear(struct nl_cache *cache) -{ - -} - -void nl_cache_remove(struct nl_object *obj) -{ - -} - - diff --git a/libnl_2/dbg.c b/libnl_2/dbg.c deleted file mode 100644 index 9764de6..0000000 --- a/libnl_2/dbg.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "netlink/netlink.h" -#include <android/log.h> - -void libnl_printf(int level, char *format, ...) -{ - va_list ap; - - level = ANDROID_LOG_ERROR; - va_start(ap, format); - __android_log_vprint(level, "libnl_2", format, ap); - va_end(ap); -} diff --git a/libnl_2/genl/family.c b/libnl_2/genl/family.c deleted file mode 100644 index 1beee6e..0000000 --- a/libnl_2/genl/family.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include "netlink-types.h" - -static struct genl_family *genl_family_find_byname(const char *name) -{ - return NULL; -} - -/* Release reference and none outstanding */ -void genl_family_put(struct genl_family *family) -{ - family->ce_refcnt--; - if (family->ce_refcnt <= 0) - free(family); -} - -unsigned int genl_family_get_id(struct genl_family *family) -{ - const int NO_FAMILY_ID = 0; - - if (!family) - return NO_FAMILY_ID; - else - return family->gf_id; - -} - diff --git a/libnl_2/genl/genl.c b/libnl_2/genl/genl.c deleted file mode 100644 index 1a39c6a..0000000 --- a/libnl_2/genl/genl.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <linux/netlink.h> -#include <netlink/genl/ctrl.h> -#include <netlink/genl/family.h> -#include "netlink-types.h" - -/* Get head of attribute data. */ -struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen) -{ - return (struct nlattr *) \ - ((char *) gnlh + GENL_HDRLEN + NLMSG_ALIGN(hdrlen)); - -} - -/* Get length of attribute data. */ -int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen) -{ - struct nlattr *nla; - struct nlmsghdr *nlh; - - nla = genlmsg_attrdata(gnlh, hdrlen); - nlh = (struct nlmsghdr *) ((char *) gnlh - NLMSG_HDRLEN); - return (char *) nlmsg_tail(nlh) - (char *) nla; -} - -/* Add generic netlink header to netlink message. */ -void *genlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, int family, - int hdrlen, int flags, uint8_t cmd, uint8_t version) -{ - int new_size; - struct nlmsghdr *nlh; - struct timeval tv; - struct genlmsghdr *gmh; - - /* Make sure nl_msg has enough space */ - new_size = NLMSG_HDRLEN + GENL_HDRLEN + hdrlen; - if ((sizeof(struct nl_msg) + new_size) > msg->nm_size) - goto fail; - - /* Fill in netlink header */ - nlh = msg->nm_nlh; - nlh->nlmsg_len = new_size; - nlh->nlmsg_type = family; - nlh->nlmsg_pid = getpid(); - nlh->nlmsg_flags = flags | NLM_F_REQUEST | NLM_F_ACK; - - /* Get current time for sequence number */ - if (gettimeofday(&tv, NULL)) - nlh->nlmsg_seq = 1; - else - nlh->nlmsg_seq = (int) tv.tv_sec; - - /* Setup genlmsghdr in new message */ - gmh = (struct genlmsghdr *) ((char *)nlh + NLMSG_HDRLEN); - gmh->cmd = (__u8) cmd; - gmh->version = version; - - return gmh; -fail: - return NULL; - -} - -/* Socket has already been alloced to connect it to kernel? */ -int genl_connect(struct nl_sock *sk) -{ - return nl_connect(sk, NETLINK_GENERIC); - -} - -int genl_ctrl_alloc_cache(struct nl_sock *sock, struct nl_cache **result) -{ - int rc = -1; - int nl80211_genl_id = -1; - char sendbuf[sizeof(struct nlmsghdr)+sizeof(struct genlmsghdr)]; - struct nlmsghdr nlmhdr; - struct genlmsghdr gmhhdr; - struct iovec sendmsg_iov; - struct msghdr msg; - int num_char; - const int RECV_BUF_SIZE = getpagesize(); - char *recvbuf; - struct iovec recvmsg_iov; - int nl80211_flag = 0, nlm_f_multi = 0, nlmsg_done = 0; - struct nlmsghdr *nlh; - - /* REQUEST GENERIC NETLINK FAMILY ID */ - /* Message buffer */ - nlmhdr.nlmsg_len = sizeof(sendbuf); - nlmhdr.nlmsg_type = NETLINK_GENERIC; - nlmhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP; - nlmhdr.nlmsg_seq = sock->s_seq_next; - nlmhdr.nlmsg_pid = sock->s_local.nl_pid; - - /* Generic netlink header */ - memset(&gmhhdr, 0, sizeof(gmhhdr)); - gmhhdr.cmd = CTRL_CMD_GETFAMILY; - gmhhdr.version = CTRL_ATTR_FAMILY_ID; - - /* Combine netlink and generic netlink headers */ - memcpy(&sendbuf[0], &nlmhdr, sizeof(nlmhdr)); - memcpy(&sendbuf[0]+sizeof(nlmhdr), &gmhhdr, sizeof(gmhhdr)); - - /* Create IO vector with Netlink message */ - sendmsg_iov.iov_base = &sendbuf; - sendmsg_iov.iov_len = sizeof(sendbuf); - - /* Socket message */ - msg.msg_name = (void *) &sock->s_peer; - msg.msg_namelen = sizeof(sock->s_peer); - msg.msg_iov = &sendmsg_iov; - msg.msg_iovlen = 1; /* Only sending one iov */ - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - /* Send message and verify sent */ - num_char = sendmsg(sock->s_fd, &msg, 0); - if (num_char == -1) - return -errno; - - /* RECEIVE GENL CMD RESPONSE */ - - /* Create receive iov buffer */ - recvbuf = (char *) malloc(RECV_BUF_SIZE); - - /* Attach to iov */ - recvmsg_iov.iov_base = recvbuf; - recvmsg_iov.iov_len = RECV_BUF_SIZE; - - msg.msg_iov = &recvmsg_iov; - msg.msg_iovlen = 1; - - /***************************************************************/ - /* Receive message. If multipart message, keep receiving until */ - /* message type is NLMSG_DONE */ - /***************************************************************/ - - do { - - int recvmsg_len, nlmsg_rem; - - /* Receive message */ - memset(recvbuf, 0, RECV_BUF_SIZE); - recvmsg_len = recvmsg(sock->s_fd, &msg, 0); - - /* Make sure receive successful */ - if (recvmsg_len < 0) { - rc = -errno; - goto error_recvbuf; - } - - /* Parse nlmsghdr */ - nlmsg_for_each_msg(nlh, (struct nlmsghdr *) recvbuf, \ - recvmsg_len, nlmsg_rem) { - struct nlattr *nla; - int nla_rem; - - /* Check type */ - switch (nlh->nlmsg_type) { - case NLMSG_DONE: - goto return_genl_id; - break; - case NLMSG_ERROR: - - /* Should check nlmsgerr struct received */ - fprintf(stderr, "Receive message error\n"); - goto error_recvbuf; - case NLMSG_OVERRUN: - fprintf(stderr, "Receive data partly lost\n"); - goto error_recvbuf; - case NLMSG_MIN_TYPE: - case NLMSG_NOOP: - break; - default: - break; - } - - - - /* Check flags */ - if (nlh->nlmsg_flags & NLM_F_MULTI) - nlm_f_multi = 1; - else - nlm_f_multi = 0; - - if (nlh->nlmsg_type & NLMSG_DONE) - nlmsg_done = 1; - else - nlmsg_done = 0; - - /* Iteratve over attributes */ - nla_for_each_attr(nla, - nlmsg_attrdata(nlh, GENL_HDRLEN), - nlmsg_attrlen(nlh, GENL_HDRLEN), - nla_rem){ - - /* If this family is nl80211 */ - if (nla->nla_type == CTRL_ATTR_FAMILY_NAME && - !strcmp((char *)nla_data(nla), - "nl80211")) - nl80211_flag = 1; - - /* Save the family id */ - else if (nl80211_flag && - nla->nla_type == CTRL_ATTR_FAMILY_ID) { - nl80211_genl_id = - *((int *)nla_data(nla)); - nl80211_flag = 0; - } - - } - - } - - } while (nlm_f_multi && !nlmsg_done); - -return_genl_id: - /* Return family id as cache pointer */ - *result = (struct nl_cache *) nl80211_genl_id; - rc = 0; -error_recvbuf: - free(recvbuf); -error: - return rc; -} - -/* Checks the netlink cache to find family reference by name string */ -/* NOTE: Caller needs to call genl_family_put() when done with * - * returned object */ -struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache, \ - const char *name) -{ - struct genl_family *gf = (struct genl_family *) \ - malloc(sizeof(struct genl_family)); - if (!gf) - goto fail; - memset(gf, 0, sizeof(*gf)); - - /* Add ref */ - gf->ce_refcnt++; - - /* Overriding cache pointer as family id for now */ - gf->gf_id = (uint16_t) ((uint32_t) cache); - strncpy(gf->gf_name, name, GENL_NAMSIZ); - - return gf; -fail: - return NULL; - -} - -int genl_ctrl_resolve(struct nl_sock *sk, const char *name) -{ - struct nl_cache *cache = NULL; - struct genl_family *gf = NULL; - int id = -1; - - /* Hack to support wpa_supplicant */ - if (strcmp(name, "nlctrl") == 0) - return NETLINK_GENERIC; - - if (strcmp(name, "nl80211") != 0) { - fprintf(stderr, "%s is not supported\n", name); - return id; - } - - if (!genl_ctrl_alloc_cache(sk, &cache)) { - gf = genl_ctrl_search_by_name(cache, name); - if (gf) - id = genl_family_get_id(gf); - } - - if (gf) - genl_family_put(gf); - if (cache) - nl_cache_free(cache); - - return id; -} diff --git a/libnl_2/handlers.c b/libnl_2/handlers.c deleted file mode 100644 index 48dcab4..0000000 --- a/libnl_2/handlers.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <malloc.h> -#include "netlink-types.h" -#include "netlink/handlers.h" - -/* Allocate a new callback handle. */ -struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) -{ - struct nl_cb *cb; - - cb = (struct nl_cb *) malloc(sizeof(struct nl_cb)); - if (cb == NULL) - goto fail; - memset(cb, 0, sizeof(*cb)); - - return nl_cb_get(cb); -fail: - return NULL; -} - -/* Clone an existing callback handle */ -struct nl_cb *nl_cb_clone(struct nl_cb *orig) -{ - struct nl_cb *new_cb; - - new_cb = nl_cb_alloc(NL_CB_DEFAULT); - if (new_cb == NULL) - goto fail; - - /* Copy original and set refcount to 1 */ - memcpy(new_cb, orig, sizeof(*orig)); - new_cb->cb_refcnt = 1; - - return new_cb; -fail: - return NULL; -} - -/* Set up a callback. */ -int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, \ - nl_recvmsg_msg_cb_t func, void *arg) -{ - cb->cb_set[type] = func; - cb->cb_args[type] = arg; - return 0; -} - - - -/* Set up an error callback. */ -int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, \ - nl_recvmsg_err_cb_t func, void *arg) -{ - cb->cb_err = func; - cb->cb_err_arg = arg; - return 0; - -} - -struct nl_cb *nl_cb_get(struct nl_cb *cb) -{ - cb->cb_refcnt++; - return cb; -} - -void nl_cb_put(struct nl_cb *cb) -{ - if (!cb) - return; - cb->cb_refcnt--; - if (cb->cb_refcnt <= 0) - free(cb); -} diff --git a/libnl_2/msg.c b/libnl_2/msg.c deleted file mode 100644 index 1303e8a..0000000 --- a/libnl_2/msg.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <malloc.h> -#include <unistd.h> -#include <sys/socket.h> -#include <linux/netlink.h> -#include "netlink-types.h" - -/* Allocate a new netlink message with the default maximum payload size. */ -struct nl_msg *nlmsg_alloc(void) -{ - /* Whole page will store nl_msg + nlmsghdr + genlmsghdr + payload */ - const int page_sz = getpagesize(); - struct nl_msg *nm; - struct nlmsghdr *nlh; - - /* Netlink message */ - nm = (struct nl_msg *) malloc(page_sz); - if (!nm) - goto fail; - - /* Netlink message header pointer */ - nlh = (struct nlmsghdr *) ((char *) nm + sizeof(struct nl_msg)); - - /* Initialize */ - memset(nm, 0, page_sz); - nm->nm_size = page_sz; - - nm->nm_src.nl_family = AF_NETLINK; - nm->nm_src.nl_pid = getpid(); - - nm->nm_dst.nl_family = AF_NETLINK; - nm->nm_dst.nl_pid = 0; /* Kernel */ - - /* Initialize and add to netlink message */ - nlh->nlmsg_len = NLMSG_HDRLEN; - nm->nm_nlh = nlh; - - /* Add to reference count and return nl_msg */ - nlmsg_get(nm); - return nm; -fail: - return NULL; -} - -/* Return pointer to message payload. */ -void *nlmsg_data(const struct nlmsghdr *nlh) -{ - return (char *) nlh + NLMSG_HDRLEN; -} - -/* Add reference count to nl_msg */ -void nlmsg_get(struct nl_msg *nm) -{ - nm->nm_refcnt++; -} - -/* Release a reference from an netlink message. */ -void nlmsg_free(struct nl_msg *nm) -{ - if (nm) { - nm->nm_refcnt--; - if (nm->nm_refcnt <= 0) - free(nm); - } - -} - -/* Return actual netlink message. */ -struct nlmsghdr *nlmsg_hdr(struct nl_msg *n) -{ - return n->nm_nlh; -} - -/* Return head of attributes data / payload section */ -struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen) -{ - unsigned char *data = nlmsg_data(nlh); - return (struct nlattr *)(data + NLMSG_ALIGN(hdrlen)); -} - -/* Returns pointer to end of netlink message */ -void *nlmsg_tail(const struct nlmsghdr *nlh) -{ - return (void *)((char *)nlh + NLMSG_ALIGN(nlh->nlmsg_len)); -} - -/* Next netlink message in message stream */ -struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) -{ - struct nlmsghdr *next_nlh = NULL; - int len = nlmsg_len(nlh); - - len = NLMSG_ALIGN(len); - if (*remaining > 0 && - len <= *remaining && - len >= (int) sizeof(struct nlmsghdr)) { - next_nlh = (struct nlmsghdr *)((char *)nlh + len); - *remaining -= len; - } - - return next_nlh; -} - -int nlmsg_datalen(const struct nlmsghdr *nlh) -{ - return nlh->nlmsg_len - NLMSG_HDRLEN; -} - -/* Length of attributes data */ -int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) -{ - return nlmsg_datalen(nlh) - NLMSG_ALIGN(hdrlen); -} - -/* Length of netlink message */ -int nlmsg_len(const struct nlmsghdr *nlh) -{ - return nlh->nlmsg_len; -} - -/* Check if the netlink message fits into the remaining bytes */ -int nlmsg_ok(const struct nlmsghdr *nlh, int rem) -{ - return rem >= (int)sizeof(struct nlmsghdr) && - rem >= nlmsg_len(nlh) && - nlmsg_len(nlh) >= (int) sizeof(struct nlmsghdr) && - nlmsg_len(nlh) <= (rem); -} - -int nlmsg_padlen(int payload) -{ - return NLMSG_ALIGN(payload) - payload; -} diff --git a/libnl_2/netlink.c b/libnl_2/netlink.c deleted file mode 100644 index ee3d600..0000000 --- a/libnl_2/netlink.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/socket.h> -#include "netlink-types.h" - -#define NL_BUFFER_SZ (32768U) - -/* Checks message for completeness and sends it out */ -int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg) -{ - struct nlmsghdr *nlh = msg->nm_nlh; - struct timeval tv; - - if (!nlh) { - int errsv = errno; - fprintf(stderr, "Netlink message header is NULL!\n"); - return -errsv; - } - - /* Complete the nl_msg header */ - if (gettimeofday(&tv, NULL)) - nlh->nlmsg_seq = 1; - else - nlh->nlmsg_seq = (int) tv.tv_sec; - nlh->nlmsg_pid = sk->s_local.nl_pid; - nlh->nlmsg_flags |= NLM_F_REQUEST | NLM_F_ACK; - - return nl_send(sk, msg); -} - -/* Receives a netlink message, allocates a buffer in *buf and stores - * the message content. The peer's netlink address is stored in - * *nla. The caller is responsible for freeing the buffer allocated in - * *buf if a positive value is returned. Interrupted system calls are - * handled by repeating the read. The input buffer size is determined - * by peeking before the actual read is done */ -int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla, \ - unsigned char **buf, struct ucred **creds) -{ - int rc = -1; - int sk_flags; - int RECV_BUF_SIZE = getpagesize(); - int errsv; - struct iovec recvmsg_iov; - struct msghdr msg; - - /* Allocate buffer */ - *buf = (unsigned char *) malloc(RECV_BUF_SIZE); - if (!(*buf)) { - rc = -ENOMEM; - goto fail; - } - - /* Prepare to receive message */ - recvmsg_iov.iov_base = *buf; - recvmsg_iov.iov_len = RECV_BUF_SIZE; - - msg.msg_name = (void *) &sk->s_peer; - msg.msg_namelen = sizeof(sk->s_peer); - msg.msg_iov = &recvmsg_iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - /* Make non blocking and then restore previous setting */ - sk_flags = fcntl(sk->s_fd, F_GETFL, 0); - fcntl(sk->s_fd, F_SETFL, O_NONBLOCK); - rc = recvmsg(sk->s_fd, &msg, 0); - errsv = errno; - fcntl(sk->s_fd, F_SETFL, sk_flags); - - if (rc < 0) { - rc = -errsv; - free(*buf); - *buf = NULL; - } - -fail: - return rc; -} - -/* Receive a set of messages from a netlink socket */ -/* NOTE: Does not currently support callback replacements!!! */ -int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb) -{ - struct sockaddr_nl nla; - struct ucred *creds; - - int rc, cb_rc = NL_OK, done = 0; - - do { - unsigned char *buf; - int i, rem, flags; - struct nlmsghdr *nlh; - struct nlmsgerr *nlme; - struct nl_msg *msg; - - done = 0; - rc = nl_recv(sk, &nla, &buf, &creds); - if (rc < 0) - break; - - nlmsg_for_each_msg(nlh, (struct nlmsghdr *) buf, rc, rem) { - - if (rc <= 0 || cb_rc == NL_STOP) - break; - - /* Check for callbacks */ - - msg = (struct nl_msg *) malloc(sizeof(struct nl_msg)); - memset(msg, 0, sizeof(*msg)); - msg->nm_nlh = nlh; - - /* Check netlink message type */ - - switch (msg->nm_nlh->nlmsg_type) { - case NLMSG_ERROR: /* Used for ACK too */ - /* Certainly we should be doing some - * checking here to make sure this - * message is intended for us */ - nlme = nlmsg_data(msg->nm_nlh); - if (nlme->error == 0) - msg->nm_nlh->nlmsg_flags |= NLM_F_ACK; - - rc = nlme->error; - cb_rc = cb->cb_err(&nla, nlme, cb->cb_err_arg); - nlme = NULL; - break; - - case NLMSG_DONE: - done = 1; - - case NLMSG_OVERRUN: - case NLMSG_NOOP: - default: - break; - }; - - for (i = 0; i <= NL_CB_TYPE_MAX; i++) { - - if (cb->cb_set[i]) { - switch (i) { - case NL_CB_VALID: - if (rc > 0) - cb_rc = cb->cb_set[i](msg, cb->cb_args[i]); - break; - - case NL_CB_FINISH: - if ((msg->nm_nlh->nlmsg_flags & NLM_F_MULTI) && - (msg->nm_nlh->nlmsg_type & NLMSG_DONE)) - cb_rc = cb->cb_set[i](msg, cb->cb_args[i]); - - break; - - case NL_CB_ACK: - if (msg->nm_nlh->nlmsg_flags & NLM_F_ACK) - cb_rc = cb->cb_set[i](msg, cb->cb_args[i]); - - break; - default: - break; - } - } - } - - free(msg); - if (done) - break; - } - free(buf); - buf = NULL; - - if (done) - break; - } while (rc > 0 && cb_rc != NL_STOP); - -success: -fail: - return rc; -} - -/* Send raw data over netlink socket */ -int nl_send(struct nl_sock *sk, struct nl_msg *msg) -{ - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct iovec msg_iov; - - /* Create IO vector with Netlink message */ - msg_iov.iov_base = nlh; - msg_iov.iov_len = nlh->nlmsg_len; - - return nl_send_iovec(sk, msg, &msg_iov, 1); -} - -/* Send netlink message */ -int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, - struct iovec *iov, unsigned iovlen) -{ - int rc; - - /* Socket message */ - struct msghdr mh = { - .msg_name = (void *) &sk->s_peer, - .msg_namelen = sizeof(sk->s_peer), - .msg_iov = iov, - .msg_iovlen = iovlen, - .msg_control = NULL, - .msg_controllen = 0, - .msg_flags = 0 - }; - - /* Send message and verify sent */ - rc = nl_sendmsg(sk, (struct nl_msg *) &mh, 0); - if (rc < 0) - fprintf(stderr, "Error sending netlink message: %d\n", errno); - return rc; - -} - -/* Send netlink message with control over sendmsg() message header */ -int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) -{ - return sendmsg(sk->s_fd, (struct msghdr *) msg, (int) hdr); -} - -/* Create and connect netlink socket */ -int nl_connect(struct nl_sock *sk, int protocol) -{ - struct sockaddr addr; - socklen_t addrlen; - int rc; - - /* Create RX socket */ - sk->s_fd = socket(PF_NETLINK, SOCK_RAW, protocol); - if (sk->s_fd < 0) - return -errno; - - /* Set size of RX and TX buffers */ - if (nl_socket_set_buffer_size(sk, NL_BUFFER_SZ, NL_BUFFER_SZ) < 0) - return -errno; - - /* Bind RX socket */ - rc = bind(sk->s_fd, (struct sockaddr *)&sk->s_local, \ - sizeof(sk->s_local)); - if (rc < 0) - return -errno; - addrlen = sizeof(addr); - getsockname(sk->s_fd, &addr, &addrlen); - - return 0; - -} diff --git a/libnl_2/object.c b/libnl_2/object.c deleted file mode 100644 index c53accf..0000000 --- a/libnl_2/object.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include "netlink-types.h" - -void nl_object_put(struct nl_object *obj) -{ - obj->ce_refcnt--; - if (!obj->ce_refcnt) - nl_object_free(obj); -} - -void nl_object_free(struct nl_object *obj) -{ - nl_cache_remove(obj); -} - - diff --git a/libnl_2/socket.c b/libnl_2/socket.c deleted file mode 100644 index e94eb9e..0000000 --- a/libnl_2/socket.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed 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. - */ - -/* NOTICE: This is a clean room re-implementation of libnl */ - -#include <errno.h> -#include <unistd.h> -#include <malloc.h> -#include <sys/time.h> -#include <sys/socket.h> -#include "netlink-types.h" - -/* Join group */ -int nl_socket_add_membership(struct nl_sock *sk, int group) -{ - return setsockopt(sk->s_fd, SOL_NETLINK, - NETLINK_ADD_MEMBERSHIP, &group, sizeof(group)); -} - -/* Allocate new netlink socket. */ -static struct nl_sock *_nl_socket_alloc(void) -{ - struct nl_sock *sk; - struct timeval tv; - struct nl_cb *cb; - - sk = (struct nl_sock *) malloc(sizeof(struct nl_sock)); - if (!sk) - return NULL; - memset(sk, 0, sizeof(*sk)); - - /* Get current time */ - - if (gettimeofday(&tv, NULL)) - goto fail; - else - sk->s_seq_next = (int) tv.tv_sec; - - /* Create local socket */ - sk->s_local.nl_family = AF_NETLINK; - sk->s_local.nl_pid = 0; /* Kernel fills in pid */ - sk->s_local.nl_groups = 0; /* No groups */ - - /* Create peer socket */ - sk->s_peer.nl_family = AF_NETLINK; - sk->s_peer.nl_pid = 0; /* Kernel */ - sk->s_peer.nl_groups = 0; /* No groups */ - - return sk; -fail: - free(sk); - return NULL; -} - -/* Allocate new netlink socket. */ -struct nl_sock *nl_socket_alloc(void) -{ - struct nl_sock *sk = _nl_socket_alloc(); - struct nl_cb *cb; - - if (!sk) - return NULL; - - cb = nl_cb_alloc(NL_CB_DEFAULT); - if (!cb) - goto cb_fail; - sk->s_cb = cb; - return sk; -cb_fail: - free(sk); - return NULL; -} - -/* Allocate new socket with custom callbacks. */ -struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb) -{ - struct nl_sock *sk = _nl_socket_alloc(); - - if (!sk) - return NULL; - - sk->s_cb = cb; - nl_cb_get(cb); - - return sk; -} - -/* Free a netlink socket. */ -void nl_socket_free(struct nl_sock *sk) -{ - nl_cb_put(sk->s_cb); - close(sk->s_fd); - free(sk); -} - -/* Sets socket buffer size of netlink socket */ -int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) -{ - if (setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF, \ - &rxbuf, (socklen_t) sizeof(rxbuf))) - goto error; - - if (setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF, \ - &txbuf, (socklen_t) sizeof(txbuf))) - goto error; - - return 0; -error: - return -errno; - -} - -int nl_socket_get_fd(struct nl_sock *sk) -{ - return sk->s_fd; -} - -void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) -{ - nl_cb_put(sk->s_cb); - sk->s_cb = cb; - nl_cb_get(cb); -} - -struct nl_cb *nl_socket_get_cb(struct nl_sock *sk) -{ - return nl_cb_get(sk->s_cb); -} |