static int nl80211_init(void) { int err; state.nl_sock = nl_socket_alloc(); if (!state.nl_sock) { LOG_ERR_("Failed to allocate netlink socket.\n"); return -ENOMEM; } nl_socket_set_buffer_size(state.nl_sock, 8192, 8192); if (genl_connect(state.nl_sock)) { LOG_ERR_("Failed to connect to generic netlink.\n"); err = -ENOLINK; goto out_handle_destroy; } state.nl80211_id = genl_ctrl_resolve(state.nl_sock, "nl80211"); if (state.nl80211_id < 0) { LOG_ERR_("nl80211 not found.\n"); err = -ENOENT; goto out_handle_destroy; } return 0; out_handle_destroy: nl_socket_free(state.nl_sock); return err; }
int main(int argc, char* argv[]) { etix::tool::logger::get_instance("cameradar"); auto args = parse_cmdline(argc, argv); if (not args.first) return EXIT_FAILURE; print_version(); // configure file configuration path auto conf_path = std::string{}; if (not args.second.exist("-c")) { conf_path = etix::cameradar::default_configuration_path; LOG_WARN_("No custom path set, trying to use default path: " + conf_path, "main"); } else { conf_path = args.second["-c"]; } if (not args.second.exist("-l")) { etix::tool::logger::get_instance("cameradar").set_level(etix::tool::loglevel::INFO); LOG_INFO_("No log level set, using log level 2 (ignoring DEBUG)", "main"); } else { try { int level = std::stoi(args.second["-l"]); etix::tool::logger::get_instance("cameradar") .set_level(static_cast<etix::tool::loglevel>(level)); } catch (...) { LOG_ERR_("Invalid log level format, log level should be 1, 2, 4, 5 or 6", "main"); return EXIT_FAILURE; } } // Try to load the configuration auto conf = cmrdr::load(conf_path); if (not conf.first) { return EXIT_FAILURE; } LOG_INFO_("Configuration successfully loaded", "main"); // If one of the path is invalid, exit auto paths_ok = check_storage_path(conf.second.thumbnail_storage_path); if (not paths_ok) { return EXIT_FAILURE; } // Here we should get the cache manager but for now we will juste // make a dumb cache manager auto plug = std::make_shared<etix::cameradar::cache_manager>(conf.second.cache_manager_path, conf.second.cache_manager_name); if (not plug->make_instance()) { LOG_ERR_(std::string("Invalid cache manager "), "cameradar"); return false; } LOG_INFO_("Launching Cameradar, press CTRL+C to gracefully stop", "main"); etix::cameradar::dispatcher disp(conf.second, plug, args); disp.run(); LOG_WARN_("See ya !", "cameradar"); return EXIT_SUCCESS; }
static int validate_nla_stream(uint8_t *buf, size_t buflen) { struct nlattr *cur_attr; int remaining, attr_cnt = 0; cur_attr = (struct nlattr *) buf; remaining = buflen; while (nla_ok(cur_attr, remaining)) { attr_cnt++; cur_attr = nla_next(cur_attr, &remaining); } if (!attr_cnt) { LOG_ERR_("No valid attributes found in the input!\n"); return -EINVAL; } if (remaining) LOG_WARN_("%d invalid bytes at the end detected of the" " input. Skipping these..\n", remaining); LOG_NOTICE_("Found %d attributes in the input stream\n", attr_cnt); return 0; }
// Check if a folder exists, is readable and writable bool check_folder(const std::string& path) { struct stat sb; if ((stat(path.c_str(), &sb) == 0) && (S_ISDIR(sb.st_mode)) && (sb.st_mode & S_IRUSR) && (sb.st_mode & S_IWUSR)) { LOG_INFO_("Folder " + path + " is available and has sufficient rights", "main"); return true; } LOG_ERR_("Folder " + path + " has insufficient rights, please check your configuration", "main"); return false; }
static int do_listen_events(void) { struct nl_cb *cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb) { LOG_ERR_("failed to allocate netlink callbacks\n"); return -ENOMEM; } /* no sequence checking for multicast messages */ nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL); for (;;) nl_recvmsgs(state.nl_sock, cb); nl_cb_put(cb); return 0; }
static int send_recv_nlcmd(void *nla, size_t nla_len) { int err, nla_offset = 0; struct nl_cb *cb; struct nl_cb *s_cb; struct nl_msg *msg; if (cur_cmd <= NL80211_CMD_UNSPEC) { LOG_ERR_("Unsupported nl command: %d\n", cur_cmd); return 1; } if (devidx_set) /* Since devidx is a uint32_t the attribute will consume 8 * bytes. The nla input stream must be appended after this * attribute. */ nla_offset = 8; LOG_DBG_("%s: Allocating %d bytes for nlmsg\n", __func__, nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN); msg = nlmsg_alloc_size(nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN); if (!msg) { LOG_ERR_("failed to allocate netlink message\n"); return 2; } cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); s_cb = nl_cb_alloc((log_level > LOG_WARNING) ? NL_CB_DEBUG : NL_CB_DEFAULT); if (!cb || !s_cb) { LOG_ERR_("failed to allocate netlink callbacks\n"); err = 2; goto out; } genlmsg_put(msg, 0, 0, state.nl80211_id, 0, 0, cur_cmd, 0); if (devidx_set) { LOG_DBG_("%s: Adding devidx %d attribute\n", __func__, devidx); if (dev_by_phy) NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx); else NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); } add_nla_stream_to_msg(msg, nla, nla_len); nl_socket_set_cb(state.nl_sock, s_cb); err = nl_send_auto_complete(state.nl_sock, msg); if (err < 0) { LOG_ERR_("nl_send_auto_complete %d\n", err); goto out; } 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); nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL); while (err > 0) nl_recvmsgs(state.nl_sock, cb); out: nl_cb_put(cb); nl_cb_put(s_cb); nlmsg_free(msg); return err; nla_put_failure: LOG_ERR_("building message failed\n"); return 2; }