// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This code is derived from the 'iw' source code.  The copyright and license
// of that code is as follows:
//
// Copyright (c) 2007, 2008  Johannes Berg
// Copyright (c) 2007  Andy Lutomirski
// Copyright (c) 2007  Mike Kershaw
// Copyright (c) 2008-2009  Luis R. Rodriguez
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include "shill/nl80211_socket.h"

#include <ctype.h>
#include <errno.h>

#include <net/if.h>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/genl.h>
#include <netlink/msg.h>
#include <netlink/netlink.h>

#include <iomanip>
#include <sstream>
#include <string>

#include <base/logging.h>

#include "shill/kernel_bound_nlmessage.h"
#include "shill/logging.h"
#include "shill/netlink_socket.h"
#include "shill/scope_logger.h"
#include "shill/user_bound_nlmessage.h"

using std::string;

namespace shill {

const char Nl80211Socket::kSocketFamilyName[] = "nl80211";

bool Nl80211Socket::Init() {
  if (!NetlinkSocket::Init()) {
    LOG(ERROR) << "NetlinkSocket didn't initialize.";
    return false;
  }

  nl80211_id_ = genl_ctrl_resolve(GetNlSock(), "nlctrl");
  if (nl80211_id_ < 0) {
    LOG(ERROR) << "nl80211 not found.";
    return false;
  }

  LOG(INFO) << "Nl80211Socket initialized successfully";
  return true;
}

bool Nl80211Socket::AddGroupMembership(const string &group_name) {
  int id = GetMulticastGroupId(group_name);
  if (id < 0) {
    LOG(ERROR) << "No Id for group " << group_name;
    return false;
  } else {
    int result = nl_socket_add_membership(GetNlSock(), id);
    if (result != 0) {
      LOG(ERROR) << "Failed call to 'nl_socket_add_membership': " << result;
      return false;
    }
  }
  LOG(INFO) << " Group " << group_name << " added successfully";
  return true;
}

int Nl80211Socket::OnAck(struct nl_msg *unused_msg, void *arg) {
  if (arg) {
    int *ret = reinterpret_cast<int *>(arg);
    *ret = 0;
  }
  return NL_STOP;  // Stop parsing and discard remainder of buffer.
}

int Nl80211Socket::OnError(struct sockaddr_nl *unused_nla, struct nlmsgerr *err,
                           void *arg) {
  int *ret = reinterpret_cast<int *>(arg);
  if (err) {
    if (ret)
      *ret = err->error;
    LOG(ERROR) << "Error(" << err->error << ") " << strerror(err->error);
  } else {
    if (ret)
      *ret = -1;
    LOG(ERROR) << "Error(<unknown>)";
  }
  return NL_STOP;  // Stop parsing and discard remainder of buffer.
}

int Nl80211Socket::OnFamilyResponse(struct nl_msg *msg, void *arg) {
  if (!msg) {
    LOG(ERROR) << "NULL |msg| parameter";
    return NL_SKIP;  // Skip current message, continue parsing buffer.
  }

  if (!arg) {
    LOG(ERROR) << "NULL |arg| parameter";
    return NL_SKIP;  // Skip current message, continue parsing buffer.
  }

  struct HandlerArgs *grp = reinterpret_cast<struct HandlerArgs *>(arg);
  struct nlattr *tb[CTRL_ATTR_MAX + 1];
  struct genlmsghdr *gnlh = reinterpret_cast<struct genlmsghdr *>(
      nlmsg_data(nlmsg_hdr(msg)));
  struct nlattr *mcgrp = NULL;
  int rem_mcgrp;

  nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);

  if (!tb[CTRL_ATTR_MCAST_GROUPS])
    return NL_SKIP;  // Skip current message, continue parsing buffer.

  // nla_for_each_nested(...)
  mcgrp = reinterpret_cast<nlattr *>(nla_data(tb[CTRL_ATTR_MCAST_GROUPS]));
  rem_mcgrp = nla_len(tb[CTRL_ATTR_MCAST_GROUPS]);
  bool found_one = false;
  for (; nla_ok(mcgrp, rem_mcgrp); mcgrp = nla_next(mcgrp, &(rem_mcgrp))) {
    struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];

    nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX,
        reinterpret_cast<nlattr *>(nla_data(mcgrp)), nla_len(mcgrp), NULL);

    if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]) {
      LOG(ERROR) << "No group name in 'group' message";
      continue;
    } else if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]) {
      LOG(ERROR) << "No group id in 'group' message";
      continue;
    }

    if (strncmp(reinterpret_cast<char *>(
        nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])),
          grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]))) {
      continue;
    }
    found_one = true;
    grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
    SLOG(WiFi, 6) << "GROUP '"
                  << reinterpret_cast<char *>(
                      nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]))
                  << "' has ID "
                  << grp->id;
    break;
  }
  if (!found_one) {
    LOG(ERROR) << "NO GROUP matched '"
               << grp->group
               << "', the one for which we were looking";
  }

  return NL_SKIP;  // Skip current message, continue parsing buffer.
}

int Nl80211Socket::GetMulticastGroupId(const string &group) {
  // Allocate and build the message.
  KernelBoundNlMessage message;
  if (!message.Init()) {
    LOG(ERROR) << "Couldn't initialize message";
    return -1;
  }

  if (!message.AddNetlinkHeader(NL_AUTO_PID, NL_AUTO_SEQ, GetFamilyId(), 0, 0,
                                CTRL_CMD_GETFAMILY, 0))
    return -1;

  int result = message.AddAttribute(CTRL_ATTR_FAMILY_NAME,
                                    GetSocketFamilyName().length() + 1,
                                    GetSocketFamilyName().c_str());
  if (result < 0) {
    LOG(ERROR) << "nla_put return error: " << result;
    return -1;
  }

  if (!message.Send(this)) {
    return -1;
  }

  // Wait for the response.

  NetlinkSocket::Callback netlink_callback;
  struct HandlerArgs grp(group.c_str(), -ENOENT);
  int status = 1;

  if (netlink_callback.Init()) {
    if (!netlink_callback.ErrHandler(NL_CB_CUSTOM, OnError, &status)) {
      return -1;
    }
    if (!netlink_callback.SetHandler(NL_CB_ACK, NL_CB_CUSTOM, OnAck, &status)) {
      return -1;
    }
    if (!netlink_callback.SetHandler(NL_CB_VALID, NL_CB_CUSTOM,
                                     OnFamilyResponse, &grp)) {
      return -1;
    }
  } else {
    LOG(ERROR) << "Couldn't initialize callback";
    return -1;
  }

  while (status > 0) {  // 'status' is set by the NL_CB_ACK handler.
    if (!GetMessagesUsingCallback(&netlink_callback)) {
      return -1;
    }
  }

  if (status != 0) {
    return -1;
  }

  return grp.id;
}

}  // namespace shill
