/*
 * Copyright (C) 2017 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.
 */

#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#define LOG_TAG "Netd"
#include <cutils/log.h>

#include "NetdConstants.h"
#include "NetlinkCommands.h"

namespace android {
namespace net {

int openRtNetlinkSocket() {
    int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
    if (sock == -1) {
        return -errno;
    }
    if (connect(sock, reinterpret_cast<const sockaddr*>(&KERNEL_NLADDR),
                sizeof(KERNEL_NLADDR)) == -1) {
        return -errno;
    }
    return sock;
}

int recvNetlinkAck(int sock) {
    struct {
        nlmsghdr msg;
        nlmsgerr err;
    } response;

    int ret = recv(sock, &response, sizeof(response), 0);

    if (ret == -1) {
        ret = -errno;
        ALOGE("netlink recv failed (%s)", strerror(-ret));
        return ret;
    }

    if (ret != sizeof(response)) {
        ALOGE("bad netlink response message size (%d != %zu)", ret, sizeof(response));
        return -EBADMSG;
    }

    return response.err.error;  // Netlink errors are negative errno.
}

// Sends a netlink request and possibly expects an ack.
// |iov| is an array of struct iovec that contains the netlink message payload.
// The netlink header is generated by this function based on |action| and |flags|.
// Returns -errno if there was an error or if the kernel reported an error.
#ifdef __clang__
#if __has_feature(address_sanitizer)
__attribute__((optnone))
#endif
#endif
WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
                                          const NetlinkDumpCallback& callback) {
    nlmsghdr nlmsg = {
        .nlmsg_type = action,
        .nlmsg_flags = flags,
    };
    iov[0].iov_base = &nlmsg;
    iov[0].iov_len = sizeof(nlmsg);
    for (int i = 0; i < iovlen; ++i) {
        nlmsg.nlmsg_len += iov[i].iov_len;
    }

    int sock = openRtNetlinkSocket();
    if (sock < 0) {
        return sock;
    }


    int ret = 0;

    if (writev(sock, iov, iovlen) == -1) {
        ret = -errno;
        ALOGE("netlink socket connect/writev failed (%s)", strerror(-ret));
        close(sock);
        return ret;
    }

    if (flags & NLM_F_ACK) {
        ret = recvNetlinkAck(sock);
    }

    if ((flags & NLM_F_DUMP) && callback != nullptr) {
        ret = processNetlinkDump(sock, callback);
    }

    close(sock);

    return ret;
}

int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) {
    return sendNetlinkRequest(action, flags, iov, iovlen, nullptr);
}

int processNetlinkDump(int sock, const NetlinkDumpCallback& callback) {
    char buf[kNetlinkDumpBufferSize];

    ssize_t bytesread;
    do {
        bytesread = read(sock, buf, sizeof(buf));

        if (bytesread < 0) {
            return -errno;
        }

        uint32_t len = bytesread;
        for (nlmsghdr *nlh = reinterpret_cast<nlmsghdr *>(buf);
             NLMSG_OK(nlh, len);
             nlh = NLMSG_NEXT(nlh, len)) {
            switch (nlh->nlmsg_type) {
              case NLMSG_DONE:
                callback(nullptr);
                return 0;
              case NLMSG_ERROR: {
                nlmsgerr *err = reinterpret_cast<nlmsgerr *>(NLMSG_DATA(nlh));
                return err->error;
              }
              default:
                callback(nlh);
            }
        }
    } while (bytesread > 0);

    return 0;
}

}  // namespace net
}  // namespace android
