Getting error while wrting code for UCI in openwrt - c

I was trying to write code for UCI which can read the users UCI config file but the code is throwing following error
make[4]: Entering directory '/home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld'
ccache_cc -Os -pipe -g3 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -fmacro-prefix-map=/home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld=helloworld -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -Wl,--build-id -I/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/usr/include -I/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/include/fortify -I/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/include -c helloworld.c
ccache_cc -L/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/usr/lib -L/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib -znow -zrelro -lubus -lubox helloworld.o -o helloworld
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib/gcc/x86_64-openwrt-linux-musl/11.2.0/../../../../x86_64-openwrt-linux-musl/bin/ld: helloworld.o: in function `config__':
/home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld/helloworld.c:47: undefined reference to `uci_alloc_context'
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib/gcc/x86_64-openwrt-linux-musl/11.2.0/../../../../x86_64-openwrt-linux-musl/bin/ld: /home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld/helloworld.c:49: undefined reference to `uci_load'
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib/gcc/x86_64-openwrt-linux-musl/11.2.0/../../../../x86_64-openwrt-linux-musl/bin/ld: helloworld.o: in function `uci_lookup_section':
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/target-x86_64_musl/usr/include/uci.h:654: undefined reference to `uci_lookup_next'
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib/gcc/x86_64-openwrt-linux-musl/11.2.0/../../../../x86_64-openwrt-linux-musl/bin/ld: /home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/target-x86_64_musl/usr/include/uci.h:654: undefined reference to `uci_lookup_next'
/home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/toolchain-x86_64_gcc-11.2.0_musl/lib/gcc/x86_64-openwrt-linux-musl/11.2.0/../../../../x86_64-openwrt-linux-musl/bin/ld: helloworld.o: in function `config__':
/home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld/helloworld.c:55: undefined reference to `uci_free_context'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:3: helloworld] Error 1
make[4]: Leaving directory '/home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld'
make[3]: *** [Makefile:94: /home/krishanudev/iowrtFinal/iopsyswrt/build_dir/target-x86_64_musl/helloworld/.built] Error 2
make[3]: Leaving directory '/home/krishanudev/iowrtFinal/iopsyswrt/package/helloworld'
time: package/helloworld/compile#0.70#0.09#0.79
ERROR: package/helloworld failed to build.
make[2]: *** [package/Makefile:116: package/helloworld/compile] Error 1
make[2]: Leaving directory '/home/krishanudev/iowrtFinal/iopsyswrt'
make[1]: *** [package/Makefile:110: /home/krishanudev/iowrtFinal/iopsyswrt/staging_dir/target-x86_64_musl/stamp/.package_compile] Error 2
make[1]: Leaving directory '/home/krishanudev/iowrtFinal/iopsyswrt'
make: *** [/home/krishanudev/iowrtFinal/iopsyswrt/include/toplevel.mk:237: world] Error 2
The output expected from the below code is nothing but just echoing the ubus calls value.
How to make ubus call
ubus call test hello "{'id':10, 'msg':'Hello World'}"
Expected Output
root#10f23b40deec:/# ubus call test hello "{'id':10, 'msg':'Hello World'}"
{
"message": "test received a message: Hello World"
}
CODE
#include <unistd.h>
#include <uci.h>
#include <uci_blob.h>
#include <libubox/blobmsg_json.h>
#include "libubus.h"
#include <stdlib.h>
static struct ubus_context *ctx;
static struct ubus_subscriber test_event;
static struct blob_buf b;
/*
Enum created to have policy ordered with names
*/
enum {
HELLO_ID,
HELLO_MSG,
__HELLO_MAX
};
/*
Policy stuff, what elements we will return in the JSON
*/
static const struct blobmsg_policy hello_policy[] = {
[HELLO_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
[HELLO_MSG] = { .name = "msg", .type = BLOBMSG_TYPE_STRING },
};
/*
The request???
*/
struct hello_request {
struct ubus_request_data req;
struct uloop_timeout timeout;
char data[];
};
/*
*
* UCI
*
*/
static int config__(void)
{
struct uci_context *context = NULL;
struct uci_package *package = NULL;
struct uci_section *section = NULL;
context = uci_alloc_context();
uci_load(context, "users", &package);
const char *option = NULL;
section = uci_lookup_section(context, package, "user");
option = uci_lookup_option_string(context, section, "remote_access");
uci_free_context(context);
int res = atoi(option);
return res;
}
/*
*/
static void test_hello_reply(struct uloop_timeout *t)
{
fprintf(stderr, "test_hello_reply Start\n");
struct hello_request *req = container_of(t, struct hello_request, timeout);
blob_buf_init(&b, 0);
char *ch = "message";
blobmsg_add_string(&b, ch , req->data);
ubus_send_reply(ctx, &req->req, b.head);
ubus_complete_deferred_request(ctx, &req->req, 0);
free(req);
fprintf(stderr, "test_hello_reply End\n");
}
/**
The hello callback is this one.
#param ctx - The context??
#param obj - The...??
#param req -
#param method - The name of the method that wants to be called
#param msg -
*/
static int test_hello(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct hello_request *hreq;
struct blob_attr *tb[__HELLO_MAX];
const char *format = "%s received a message: %s";
const char *msgstr = "(unknown)";
fprintf(stderr, "test_hello Start\n");
blobmsg_parse(hello_policy, ARRAY_SIZE(hello_policy), tb, blob_data(msg), blob_len(msg));
if (tb[HELLO_MSG])
msgstr = blobmsg_data(tb[HELLO_MSG]);
hreq = calloc(1, sizeof(*hreq) + strlen(format) + strlen(obj->name) + strlen(msgstr) + 1);
sprintf(hreq->data, format, obj->name, msgstr);
ubus_defer_request(ctx, req, &hreq->req);
printf("helloooooo");
hreq->timeout.cb = test_hello_reply;
uloop_timeout_set(&hreq->timeout, 1000);
fprintf(stderr, "test_hello End\n");
return 0;
}
enum {
WATCH_ID,
WATCH_COUNTER,
__WATCH_MAX
};
static const struct blobmsg_policy watch_policy[__WATCH_MAX] = {
[WATCH_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
[WATCH_COUNTER] = { .name = "counter", .type = BLOBMSG_TYPE_INT32 },
};
static void
test_handle_remove(struct ubus_context *ctx, struct ubus_subscriber *s,
uint32_t id)
{
fprintf(stderr, "test_handle_remove Start\n");
fprintf(stderr, "Object %08x went away\n", id);
fprintf(stderr, "test_handle_remove End\n");
}
/*
When a method is called, displays method and params
*/
static int
test_notify(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
#if 0
char *str;
str = blobmsg_format_json(msg, true);
fprintf(stderr, "Received notification '%s': %s\n", method, str);
free(str);
#endif
fprintf(stderr, "test_notify Start\n");
fprintf(stderr, "test_notify End\n");
return 0;
}
static int test_watch(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
fprintf(stderr, "test_watch Start\n");
struct blob_attr *tb[__WATCH_MAX];
int ret;
blobmsg_parse(watch_policy, __WATCH_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[WATCH_ID])
return UBUS_STATUS_INVALID_ARGUMENT;
test_event.remove_cb = test_handle_remove; // Action on remove
test_event.cb = test_notify; // Say which is the objective for calls
ret = ubus_subscribe(ctx, &test_event, blobmsg_get_u32(tb[WATCH_ID]));
fprintf(stderr, "Watching object %08x: %s\n", blobmsg_get_u32(tb[WATCH_ID]), ubus_strerror(ret));
fprintf(stderr, "test_watch End\n");
return ret;
}
static const struct ubus_method test_methods[] = {
UBUS_METHOD("hello", test_hello, hello_policy),
UBUS_METHOD("watch", test_watch, watch_policy),
};
static struct ubus_object_type test_object_type =
UBUS_OBJECT_TYPE("test", test_methods);
static struct ubus_object test_object = {
.name = "test",
.type = &test_object_type,
.methods = test_methods,
.n_methods = ARRAY_SIZE(test_methods),
};
static void server_main(void)
{
fprintf(stderr, "server_main Start\n");
int ret;
ret = ubus_add_object(ctx, &test_object);
if (ret)
fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
ret = ubus_register_subscriber(ctx, &test_event);
if (ret)
fprintf(stderr, "Failed to add watch handler: %s\n", ubus_strerror(ret));
uloop_run();
fprintf(stderr, "server_main End\n");
}
int main(int argc, char **argv)
{
const char *ubus_socket = NULL;
int ch;
config__();
while ((ch = getopt(argc, argv, "cs:")) != -1) {
switch (ch) {
case 's':
ubus_socket = optarg;
break;
default:
break;
}
}
argc -= optind;
argv += optind;
uloop_init();
ctx = ubus_connect(ubus_socket);
if (!ctx) {
fprintf(stderr, "Failed to connect to ubus\n");
return -1;
}
ubus_add_uloop(ctx);
server_main();
ubus_free(ctx);
uloop_done();
return 0;
}

Related

How to add function for mqtt server authentication

How can I add the functions for username and password to authen mqtt broker.
The original file has not section for authentication. How can I adding function for username and password in authentication mqtt server?
This file has mqtt.h that is sitting parameters (such as hotsname, port, etc.). and I have added parameter for username and password in mqtt.h following this
struct mqtt_handle_s {
// Public members
char *host;
int port;
char *username;
char *password;
char *client_id;
mqtt_on_connect_t on_connect;
mqtt_on_message_t on_message;
// Private members
struct mosquitto *client;
char *topic_list;
size_t topic_size;
};
and then how can I adding the function for running that parameter to using in mqtt server authentication?
the main code is following..
#mqtt.c full code.
#if defined(_WIN32)
#include <windows.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "app_log.h"
#include "mqtt.h"
// Check if libmosquitto version is at least 1.5.7
#if LIBMOSQUITTO_VERSION_NUMBER < 1005007
#warning Untested libmosquitto version!
#endif
#define QOS 1
#define KEEPALIVE_INTERVAL_SEC 30
#define LOOP_TIMEOUT_MS 1
#define LOG_MASK MOSQ_LOG_NONE
static void mqtt_on_connect(struct mosquitto *mosq, void *obj, int rc);
static void mqtt_on_disconnect(struct mosquitto *mosq, void *obj, int rc);
static void mqtt_on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message);
static void mqtt_on_log(struct mosquitto *mosq, void *obj, int level, const char *str);
static const char * mqtt_err2str(int rc);
mqtt_status_t mqtt_init(mqtt_handle_t *handle)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc = MOSQ_ERR_ERRNO; // return code if mosquitto_new() fails
struct mosquitto *mosq;
mosquitto_lib_init();
mosq = mosquitto_new(handle->client_id, true, handle);
if (mosq != NULL) {
mosquitto_connect_callback_set(mosq, mqtt_on_connect);
mosquitto_disconnect_callback_set(mosq, mqtt_on_disconnect);
mosquitto_message_callback_set(mosq, mqtt_on_message);
mosquitto_log_callback_set(mosq, mqtt_on_log);
rc = mosquitto_connect(mosq, handle->host, handle->port, KEEPALIVE_INTERVAL_SEC);
}
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT init failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_CONNECT;
handle->client = NULL;
if (mosq != NULL) {
mosquitto_destroy(mosq);
}
} else {
handle->client = mosq;
}
handle->topic_list = NULL;
handle->topic_size = 0;
return ret;
}
mqtt_status_t mqtt_publish(mqtt_handle_t *handle, const char *topic, const char *payload)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
int mid;
if (handle->client != NULL) {
rc = mosquitto_publish(handle->client, &mid, topic, strlen(payload), payload, QOS, false);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT publish attempt failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_PUBLISH;
}
} else {
ret = MQTT_ERROR_PUBLISH;
}
return ret;
}
mqtt_status_t mqtt_step(mqtt_handle_t *handle)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
if (handle->client != NULL) {
rc = mosquitto_loop(handle->client, LOOP_TIMEOUT_MS, 1);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT loop failed: '%s'\n", mqtt_err2str(rc));
ret = MQTT_ERROR_STEP;
}
} else {
ret = MQTT_ERROR_STEP;
}
return ret;
}
mqtt_status_t mqtt_subscribe(mqtt_handle_t *handle, const char *topic)
{
mqtt_status_t ret = MQTT_SUCCESS;
int rc;
size_t topic_size;
if (handle->client != NULL) {
// Try to subscribe to topic.
rc = mosquitto_subscribe(handle->client, NULL, topic, QOS);
if ((rc != MOSQ_ERR_SUCCESS) && (rc != MOSQ_ERR_NO_CONN)) {
app_log("MQTT subscribe attempt failed to topic '%s': '%s'\n", topic, mqtt_err2str(rc));
ret = MQTT_ERROR_SUBSCRIBE;
}
// Append topic to topic list.
topic_size = strlen(topic) + 1;
handle->topic_list = realloc(handle->topic_list, handle->topic_size + topic_size);
if (handle->topic_list == NULL) {
app_log("MQTT failed to append topic to topic list.\n");
ret = MQTT_ERROR_SUBSCRIBE;
} else {
strcpy(&handle->topic_list[handle->topic_size], topic);
handle->topic_size += topic_size;
}
} else {
ret = MQTT_ERROR_SUBSCRIBE;
}
return ret;
}
mqtt_status_t mqtt_deinit(mqtt_handle_t *handle)
{
int rc;
if (handle->client != NULL) {
rc = mosquitto_disconnect(handle->client);
if (rc != MOSQ_ERR_SUCCESS) {
app_log("MQTT failed to disconnect: '%s', continue deinit.\n", mqtt_err2str(rc));
}
mosquitto_destroy(handle->client);
mosquitto_lib_cleanup();
if (handle->topic_list != NULL) {
free(handle->topic_list);
}
}
return MQTT_SUCCESS;
}
static void mqtt_on_connect(struct mosquitto *mosq, void *obj, int rc)
{
mqtt_handle_t *handle = (mqtt_handle_t *)obj;
size_t topic_start = 0;
char *topic;
int ret = MOSQ_ERR_SUCCESS;
app_log("MQTT connect status '%s'\n", mosquitto_connack_string(rc));
if (rc == 0) {
if (handle->on_connect != NULL) {
handle->on_connect(handle);
}
while (topic_start < handle->topic_size) {
topic = &handle->topic_list[topic_start];
ret = mosquitto_subscribe(mosq, NULL, topic, QOS);
topic_start += strlen(topic) + 1;
if (ret != MOSQ_ERR_SUCCESS) {
app_log("MQTT subscribe attempt failed to topic '%s': '%s'\n", topic, mqtt_err2str(ret));
}
}
}
}
static void mqtt_on_disconnect(struct mosquitto *mosq, void *obj, int rc)
{
int ret;
app_log("MQTT disconnected with reason '%d'\n", rc);
if (rc != 0) {
ret = mosquitto_reconnect(mosq);
app_log("MQTT reconnection attempt with status '%s'\n", mqtt_err2str(ret));
}
}
static void mqtt_on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
mqtt_handle_t *handle = (mqtt_handle_t *)obj;
char *payload;
if (handle->on_message != NULL) {
payload = malloc(message->payloadlen + 1);
if (NULL == payload) {
app_log("MQTT failed to allocate payload buffer.\n");
} else {
memcpy(payload, message->payload, message->payloadlen);
// Make sure that payload is NULL terminated.
payload[message->payloadlen] = 0;
handle->on_message(handle, message->topic, payload);
free(payload);
}
}
}
static void mqtt_on_log(struct mosquitto *mosq, void *obj, int level, const char *str)
{
if (level & LOG_MASK) {
app_log("MQTT log (%d): %s\n", level, str);
}
}
#if defined(_WIN32)
static const char * mqtt_err2str(int rc)
{
char *ret = NULL;
static char err_str[256];
if (MOSQ_ERR_ERRNO == rc) {
// Make sure to have a default output if FormatMessage fails
// or if error code is not available in errno.
strncpy(err_str, "Unknown system error", sizeof(err_str));
if (errno != 0) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, // dwFlags
NULL, // lpSource
errno, // dwMessageId
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
err_str, // lpBuffer
sizeof(err_str), // nSize
NULL); // Arguments
}
// Make sure that err_str is NULL terminated.
err_str[sizeof(err_str) - 1] = 0;
ret = err_str;
} else {
ret = (char *)mosquitto_strerror(rc);
}
return ret;
}
#else
static const char * mqtt_err2str(int rc)
{
return (MOSQ_ERR_ERRNO == rc) ? strerror(errno) : mosquitto_strerror(rc);
}
#endif // _WIN32

Get PID of XDP hook in userspace

I am using a multi-producer single-consumer implementation on the user side to handle incoming data from a eBPF map from an XDP hook.
However, in order to do this, I need to limit the number of cores the XDP hook can use to send information to the user-space by one. From what I understand, the only way to do this is by setting its affinity in manner like this:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
CPU_SET(2, &mask);
sched_setaffinity(-1, sizeof(mask), &mask);
However, I do not know how to obtain the PID for my hook so that I can do this.
I am using a BPF_MAP_TYPE_PERF_EVENT_ARRAY, and I hook the kern code via bpf_prog_load_xattr and bpf_set_link_xdp_fd.
Here is the function that loads the hook.
static int do_attach(int idx, int fd, const char *name, __u32 xdp_flags)
{
struct bpf_prog_info info = {};
__u32 info_len = sizeof(info);
int err;
err = bpf_set_link_xdp_fd(idx, fd, xdp_flags);
if (err < 0) {
printf("ERROR: failed to attach program to %s\n", name);
return err;
}
err = bpf_obj_get_info_by_fd(fd, &info, &info_len);
if (err) {
printf("can't get prog info - %s\n", strerror(errno));
return err;
}
prog_id = info.id;
return err;
}
And here is where it gets used.
int main(int argc, char **argv)
{
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP,
};
int prog_fd, map_fd;
struct bpf_object *obj;
struct bpf_map *map;
char filename[256];
int ret, err, i;
int numcpus = bpf_num_possible_cpus();
struct config cfg = {
.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
.ifindex = -1,
};
strncpy(cfg.filename, default_filename, sizeof(cfg.filename));
/* Cmdline options can change these */
parse_cmdline_args(argc, argv, long_options, &cfg, __doc__);
/* Required option */
if (cfg.ifindex == -1) {
fprintf(stderr, "ERR: required option --dev missing\n");
usage(argv[0], __doc__, long_options, (argc == 1));
return EXIT_FAIL_OPTION;
}
if (setrlimit(RLIMIT_MEMLOCK, &r)) {
perror("setrlimit(RLIMIT_MEMLOCK)");
return 1;
}
snprintf(filename, sizeof(filename), "xdp_sample_pkts_kern.o");
prog_load_attr.file = filename;
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
return 1;
if (!prog_fd) {
printf("load_bpf_file: %s\n", strerror(errno));
return 1;
}
map = bpf_map__next(NULL, obj);
if (!map) {
printf("finding a map in obj file failed\n");
return 1;
}
map_fd = bpf_map__fd(map);
err = do_attach(cfg.ifindex, prog_fd, cfg.ifname, cfg.xdp_flags);
if (err)
return err;
if (signal(SIGINT, sig_handler) ||
signal(SIGHUP, sig_handler) ||
signal(SIGTERM, sig_handler)) {
perror("signal");
return 1;
}
test_bpf_perf_event(map_fd, numcpus);
for (i = 0; i < numcpus; i++)
if (perf_event_mmap_header(pmu_fds[i], &headers[i]) < 0)
return 1;
pd = pcap_open_dead(DLT_EN10MB, 65535);
if (!pd)
goto out;
pdumper = pcap_dump_open(pd, cfg.filename);
if (!pdumper)
goto out;
ret = perf_event_poller_multi(pmu_fds, headers, numcpus,
print_bpf_output, &done);
pcap_dump_close(pdumper);
pcap_close(pd);
out:
do_detach(cfg.ifindex, cfg.ifname);
printf("\n%u packet samples stored in %s\n", pcap_pkts, cfg.filename);
return ret;
}

How to insert a ramfs module into linux kernel

I want to compile source code of a very simple file system--ramfs. But when I inserted the module into Linux kernel 3.10 I got a problem:
could not insert module myramfs.ko: Device or resource busy
I don't know which step I did wrong。The following is my code.
source code:ramfs
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/string.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#define RAMFS_DEFAULT_MODE 0755
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/ramfs.h>
const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
.write_begin = simple_write_begin,
.write_end = simple_write_end,
.set_page_dirty = __set_page_dirty_no_writeback,
};
const struct file_operations ramfs_file_operations = {
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.fsync = noop_fsync,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
.llseek = generic_file_llseek,
};
const struct inode_operations ramfs_file_inode_operations = {
.setattr = simple_setattr,
.getattr = simple_getattr,
};
static const struct super_operations ramfs_ops;
static const struct inode_operations ramfs_dir_inode_operations;
static struct backing_dev_info ramfs_backing_dev_info = {
.name = "ramfs",
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK |
BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
};
struct inode *ramfs_get_inode(struct super_block *sb,
const struct inode *dir, umode_t mode, dev_t dev)
{
struct inode * inode = new_inode(sb);
if (inode) {
inode->i_ino = get_next_ino();
inode_init_owner(inode, dir, mode);
inode->i_mapping->a_ops = &ramfs_aops;
inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
mapping_set_unevictable(inode->i_mapping);
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);
break;
case S_IFREG:
inode->i_op = &ramfs_file_inode_operations;
inode->i_fop = &ramfs_file_operations;
break;
case S_IFDIR:
inode->i_op = &ramfs_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode);
break;
case S_IFLNK:
inode->i_op = &page_symlink_inode_operations;
break;
}
}
return inode;
}
/*
* File creation. Allocate an inode, and we're done..
*/
/* SMP-safe */
static int
ramfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{
struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev);
int error = -ENOSPC;
if (inode) {
d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */
error = 0;
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
}
return error;
}
static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
{
int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);
if (!retval)
inc_nlink(dir);
return retval;
}
static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
{
return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);
}
static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
{
struct inode *inode;
int error = -ENOSPC;
inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
if (inode) {
int l = strlen(symname)+1;
error = page_symlink(inode, symname, l);
if (!error) {
d_instantiate(dentry, inode);
dget(dentry);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
} else
iput(inode);
}
return error;
}
static const struct inode_operations ramfs_dir_inode_operations = {
.create = ramfs_create,
.lookup = simple_lookup,
.link = simple_link,
.unlink = simple_unlink,
.symlink = ramfs_symlink,
.mkdir = ramfs_mkdir,
.rmdir = simple_rmdir,
.mknod = ramfs_mknod,
.rename = simple_rename,
};
static const struct super_operations ramfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
.show_options = generic_show_options,
};
struct ramfs_mount_opts {
umode_t mode;
};
enum {
Opt_mode,
Opt_err
};
static const match_table_t tokens = {
{Opt_mode, "mode=%o"},
{Opt_err, NULL}
};
struct ramfs_fs_info {
struct ramfs_mount_opts mount_opts;
};
static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
{
substring_t args[MAX_OPT_ARGS];
int option;
int token;
char *p;
opts->mode = RAMFS_DEFAULT_MODE;
while ((p = strsep(&data, ",")) != NULL) {
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_mode:
if (match_octal(&args[0], &option))
return -EINVAL;
opts->mode = option & S_IALLUGO;
break;
/*
* We might like to report bad mount options here;
* but traditionally ramfs has ignored all mount options,
* and as it is used as a !CONFIG_SHMEM simple substitute
* for tmpfs, better continue to ignore other mount options.
*/
}
}
return 0;
}
int ramfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct ramfs_fs_info *fsi;
struct inode *inode;
int err;
save_mount_options(sb, data);
fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
sb->s_fs_info = fsi;
if (!fsi)
return -ENOMEM;
err = ramfs_parse_options(data, &fsi->mount_opts);
if (err)
return err;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = RAMFS_MAGIC;
sb->s_op = &ramfs_ops;
sb->s_time_gran = 1;
inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
sb->s_root = d_make_root(inode);
if (!sb->s_root)
return -ENOMEM;
return 0;
}
struct dentry *ramfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_nodev(fs_type, flags, data, ramfs_fill_super);
}
static struct dentry *rootfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
}
static void ramfs_kill_sb(struct super_block *sb)
{
kfree(sb->s_fs_info);
kill_litter_super(sb);
}
static struct file_system_type ramfs_fs_type = {
.name = "ramfs",
.mount = ramfs_mount,
.kill_sb = ramfs_kill_sb,
.fs_flags = FS_USERNS_MOUNT,
};
static struct file_system_type rootfs_fs_type = {
.name = "rootfs",
.mount = rootfs_mount,
.kill_sb = kill_litter_super,
};
int __init init_ramfs_fs(void)
{
return register_filesystem(&ramfs_fs_type);
}
module_init(init_ramfs_fs)
int __init init_rootfs(void)
{
int err;
err = bdi_init(&ramfs_backing_dev_info);
if (err)
return err;
err = register_filesystem(&rootfs_fs_type);
if (err)
bdi_destroy(&ramfs_backing_dev_info);
return err;
}
Makefile:
ifneq ($(KERNELRELEASE),)
obj-m := myramfs.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers *.unsigned

How to send single channel scan request to libnl, and receive single channel scan completion response for corresponding channel

I am sending single SSID and frequency to libnl for scanning, but i got multiple scan result along with my requested SSID and frequency,But i need single scan result (only for requested SSID), how to achieve this. Kindly help me , i am sending my code also.This code will run.
Compile: gcc -g -o scan scantesthandler.c -L /usr/lib/i386-linux-gnu/libnl.so -lnl
Run with debug log: NLCB=debug ./scan
#include<assert.h>
#include<errno.h>
#include<ifaddrs.h>
#include<netdb.h>
#include<stddef.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/rtnetlink.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <netlink/cache.h>
#include <netlink/socket.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <stdlib.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netlink/route/link.h>
#include <linux/nl80211.h>
static int expectedId;
static int ifIndex;
struct wpa_scan_res
{
unsigned char bssid[6];
int freq;
};
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
{
int *ret = arg;
*ret = err->error;
return NL_SKIP;
}
static int finish_handler(struct nl_msg *msg, void *arg)
{
int *ret = arg;
*ret = 0;
return NL_SKIP;
}
static int ack_handler(struct nl_msg *msg, void *arg)
{
int *err = arg;
*err = 0;
return NL_STOP;
}
static int bss_info_handler(struct nl_msg *msg, void *arg)
{
printf("\nFunction: %s, Line: %d\n",__FUNCTION__,__LINE__);
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *bss[NL80211_BSS_MAX + 1];
static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
[NL80211_BSS_TSF] = { .type = NLA_U64 },
[NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
[NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
[NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
[NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
[NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
[NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
[NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
};
struct wpa_scan_res *r = NULL;
r = (struct wpa_scan_res*)malloc(sizeof(struct wpa_scan_res));
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb[NL80211_ATTR_BSS])
return NL_SKIP;
if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
bss_policy))
return NL_SKIP;
if (bss[NL80211_BSS_BSSID])
memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),6);
if (bss[NL80211_BSS_FREQUENCY])
r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
printf("\nFrequency: %d ,BSSID: %2x:%2x:%2x:%2x:%2x:%2x",r->freq,r->bssid[0],r->bssid[1],r->bssid[2],r->bssid[3],r->bssid[4],r->bssid[5]);
return NL_SKIP;
}
static struct nl_msg* nl80211_scan_common(uint8_t cmd, int expectedId)
{
const char* ssid = "amitssid";
int ret;
struct nl_msg *msg;
int err;
size_t i;
int flags = 0,ifIndex;
msg = nlmsg_alloc();
if (!msg)
return NULL;
// setup the message
if(NULL==genlmsg_put(msg, 0, 0, expectedId, 0, flags, cmd, 0))
{
printf("\nError return genlMsg_put\n");
}
else
{
printf("\nSuccess genlMsg_put\n");
}
ifIndex = if_nametoindex("wlan1");
if(nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifIndex) < 0)
{
goto fail;
}
struct nl_msg *ssids = nlmsg_alloc();
if(nla_put(ssids, 1,strlen(ssid) ,ssid) <0)
{
nlmsg_free(ssids);
goto fail;
}
err = nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS,ssids);
nlmsg_free(ssids);
if (err < 0)
goto fail;
struct nl_msg *freqs = nlmsg_alloc();
if( nla_put_u32(freqs,1 ,2437) < 0) //amitssid
{
printf("\nnla_put_fail\n");
goto fail;
}
else
{
printf("\nnla_put_u32 pass\n");
}
//add message attributes
if(nla_put_nested(msg, NL80211_FREQUENCY_ATTR_FREQ,freqs) < 0)
{
printf("\nnla_put_nested failing:\n");
}
else
{
printf("\nnla_put_nested pass\n");
}
nlmsg_free(freqs);
if (err < 0)
goto fail;
return msg;
nla_put_failure:
printf("\nnla_put_failure\n");
nlmsg_free(msg);
return NULL;
fail:
nlmsg_free(msg);
return NULL;
}
int main(int argc, char** argv)
{
struct nl_msg *msg= NULL;
int ret = -1;
struct nl_cb *cb = NULL;
int err = -ENOMEM;
int returnvalue,getret;
int ifIndex, callbackret=-1;
struct nl_sock* sk = (void*)nl_handle_alloc();
if(sk == NULL)
{
printf("\nmemory error\n");
return;
}
cb = nl_cb_alloc(NL_CB_CUSTOM);
if(cb == NULL)
{
printf("\nfailed to allocate netlink callback\n");
}
enum nl80211_commands cmd;
if(genl_connect((void*)sk))
{
printf("\nConnected failed\n");
return;
}
//find the nl80211 driverID
expectedId = genl_ctrl_resolve((void*)sk, "nl80211");
if(expectedId < 0)
{
printf("\nnegative error code returned\n");
return;
}
else
{
printf("\ngenl_ctrl_resolve returned:%d\n",expectedId);
}
msg = nl80211_scan_common(NL80211_CMD_TRIGGER_SCAN, expectedId);
if (!msg)
{
printf("\nmsgbal:\n");
return -1;
}
err = nl_send_auto_complete((void*)sk, msg);
if (err < 0)
goto out;
else
{
printf("\nSent successfully\n");
}
err = 1;
nl_cb_err(cb,NL_CB_CUSTOM,error_handler,&err);
nl_cb_set(cb,NL_CB_FINISH,NL_CB_CUSTOM,finish_handler,&err);
nl_cb_set(cb,NL_CB_ACK,NL_CB_CUSTOM,ack_handler,&err);
callbackret = nl_cb_set(cb,NL_CB_VALID,NL_CB_CUSTOM,bss_info_handler,&err);
if(callbackret < 0)
{
printf("\n*************CallbackRet failed:***************** %d\n",callbackret);
}
else
{
printf("\n*************CallbackRet pass:***************** %d\n",callbackret);
}
returnvalue=nl_recvmsgs((void*)sk,cb);
printf("\n returnval:%d\n",returnvalue);
nlmsg_free(msg);
msg = NULL;
msg = nlmsg_alloc();
if (!msg)
return -1;
if(NULL==genlmsg_put(msg, 0, 0, expectedId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0))
{
printf("\nError return genlMsg_put\n");
}
else
{
printf("\nSuccess genlMsg_put\n");
}
ifIndex = if_nametoindex("wlan1");
printf("\nGet Scaninterface returned :%d\n",ifIndex);
nla_put_u32(msg,NL80211_ATTR_IFINDEX,ifIndex);
err = nl_send_auto_complete((void*)sk,msg);
if(err < 0) goto out;
err = 1;
getret= nl_recvmsgs((void*)sk,cb);
printf("\nGt Scan resultreturn:%d\n",getret);
out:
nlmsg_free(msg);
return err;
nla_put_failure:
printf("\nnla_put_failure\n");
nlmsg_free(msg);
return err;
}
You can just copy and paste this code on your system and run it.
As far as I know (and have seen) the scan command and result is dependent upon the vendor's device driver. One thing for certain there is no option to scan for a specific ssid; instead what you can do is to get all the scan result and loop through to check whether the ssid is in the list or not (wpa_supplicant uses this mechanism to match network configuration with scan result).
Now for the frequency, it should be possible to scan only a certain channel if the device driver has that functionality. But generally scan command scans all channel and returns the SSID (think your network-manager; it shows all the available SSID found for a scan command. which is essentially posted by device driver via cfg80211).

Emit signal is not happening in bluez dbus

I wrote some basic code to access the "start inquiry" bluez functionality by using dbus api's. Start Inquiry is happening that I could saw on hcidump. But I am not receiving any signal from the dbus which is "DeviceFound". I have tried lot. I tried to use different dbus tools like d-feet, dbus-monitor, bustle but I couln't got any clue.
Below is my written code. Anyone please tell me why this code is not working.
#include <stdio.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <glib.h>
struct generic_data {
unsigned int refcount;
GSList *interfaces;
char *introspect;
};
static void unregister(DBusConnection *connection, void *user_data)
{
}
static DBusHandlerResult filter_func(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
printf("Signal is called \n");
if (dbus_message_is_signal(message, "org.bluez.Adapter",
"DeviceFound"))
{
const char *adapter, *bdaddr;
char *name;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
dbus_message_iter_get_basic(&iter, &bdaddr);
printf("Finally found device address is %s\n", bdaddr);
}
}
static DBusObjectPathVTable generic_table = {
.unregister_function = unregister,
.message_function = filter_func,
};
int main(int argc, char **argv) {
DBusConnection *conn;
DBusError error;
DBusMessage *msg, *reply,*signal;
dbus_bool_t hcid_exists,start;
DBusMessageIter reply_iter;
const char *name,*address;
char *adapter, *match;
DBusMessageIter iter;
struct generic_data *data;
va_list var_args;
static GMainLoop *loop = NULL;
conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
dbus_error_init(&error);
hcid_exists = dbus_bus_name_has_owner(conn, "org.bluez", &error);
if(hcid_exists)
printf("good news hurrey\n");
/* Get the default adapter */
msg = dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "DefaultAdapter");
if (msg == NULL) {
dbus_connection_unref(conn);
return FALSE;
}
reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
dbus_message_unref(msg);
if (dbus_error_is_set(&error))
{
dbus_connection_unref(conn);
}
dbus_message_iter_init(reply, &reply_iter);
if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_OBJECT_PATH)
{
dbus_message_unref(reply);
dbus_connection_unref(conn);
return FALSE;
}
dbus_message_iter_get_basic(&reply_iter, &adapter);
adapter = g_strdup(adapter);
//printf("Ohhhh gooood finally got adapter name %s\n",adapter);
dbus_message_unref(reply);
data = g_new0(struct generic_data, 1);
if (!dbus_connection_register_object_path(conn,adapter,&generic_table, data)) {
g_free(data->introspect);
g_free(data);
return FALSE;
}
if (!dbus_connection_add_filter(conn, filter_func, data, g_free))
{
g_free(adapter);
dbus_connection_unref(conn);
return FALSE;
}
if(conn!=NULL)
msg = dbus_message_new_method_call("org.bluez",adapter,"org.bluez.Adapter", "StartDiscovery");
else
printf("conn is failed\n");
if(msg!=NULL)
start = dbus_connection_send_with_reply(conn, msg,NULL,-1);
else
printf("msg is failed\n");
if(start)
{
//printf("Main llop hasd tp start\n");
loop = g_main_loop_new(NULL, TRUE);
g_main_loop_run(loop);
}
dbus_message_unref(msg);
dbus_message_unref(reply);
dbus_connection_close(conn);
return 0;
}

Resources