Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/device/device/generic/trusty/dhcp/common/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 8 kB image not shown  

Quelle  message.cpp

  Sprache: C
 

/*
 * Copyright 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 "message.h"
#include "dhcp.h"

#include <string.h>

#include <vector>

static uint32_t sNextTransactionId = 1;

// The default lease time in seconds
static const uint32_t kDefaultLeaseTime = 10 * 60;

// The parameters that the client would like to receive from the server
static const uint8_t kRequestParameters[] = {
    OPT_SUBNET_MASK, OPT_GATEWAY, OPT_DNS, OPT_BROADCAST_ADDR,
    OPT_LEASE_TIME,  OPT_T1,      OPT_T2,  OPT_MTU};

Message::Message() {
    memset(&dhcpData, 0sizeof(dhcpData));
    mSize = 0;
}

Message::Message(const uint8_t* data, size_t size) {
    if (size <= sizeof(dhcpData)) {
        memcpy(&dhcpData, data, size);
        mSize = size;
    } else {
        memset(&dhcpData, 0sizeof(dhcpData));
        mSize = 0;
    }
}

Message Message::discover(const uint8_t (&sourceMac)[ETH_ALEN]) {
    Message message(OP_BOOTREQUEST, sourceMac, static_cast<uint8_t>(DHCPDISCOVER));

    message.addOption(OPT_PARAMETER_LIST, kRequestParameters);
    message.endOptions();

    return message;
}

Message Message::request(const uint8_t (&sourceMac)[ETH_ALEN], in_addr_t requestAddress,
                         in_addr_t serverAddress) {

    Message message(OP_BOOTREQUEST, sourceMac, static_cast<uint8_t>(DHCPREQUEST));

    message.addOption(OPT_PARAMETER_LIST, kRequestParameters);
    message.addOption(OPT_REQUESTED_IP, requestAddress);
    message.addOption(OPT_SERVER_ID, serverAddress);
    message.endOptions();

    return message;
}

Message Message::offer(const Message& sourceMessage, in_addr_t serverAddress,
                       in_addr_t offeredAddress, in_addr_t offeredNetmask, in_addr_t offeredGateway,
                       const in_addr_t* offeredDnsServers, size_t numOfferedDnsServers) {

    uint8_t macAddress[ETH_ALEN];
    memcpy(macAddress, sourceMessage.dhcpData.chaddr, sizeof(macAddress));
    Message message(OP_BOOTREPLY, macAddress, static_cast<uint8_t>(DHCPOFFER));

    message.dhcpData.xid = sourceMessage.dhcpData.xid;
    message.dhcpData.flags = sourceMessage.dhcpData.flags;
    message.dhcpData.yiaddr = offeredAddress;
    message.dhcpData.giaddr = sourceMessage.dhcpData.giaddr;

    message.addOption(OPT_SERVER_ID, serverAddress);
    message.addOption(OPT_LEASE_TIME, kDefaultLeaseTime);
    message.addOption(OPT_SUBNET_MASK, offeredNetmask);
    message.addOption(OPT_GATEWAY, offeredGateway);
    message.addOption(OPT_DNS, offeredDnsServers, numOfferedDnsServers * sizeof(in_addr_t));

    message.endOptions();

    return message;
}

Message Message::ack(const Message& sourceMessage, in_addr_t serverAddress,
                     in_addr_t offeredAddress, in_addr_t offeredNetmask, in_addr_t offeredGateway,
                     const in_addr_t* offeredDnsServers, size_t numOfferedDnsServers) {
    uint8_t macAddress[ETH_ALEN];
    memcpy(macAddress, sourceMessage.dhcpData.chaddr, sizeof(macAddress));
    Message message(OP_BOOTREPLY, macAddress, static_cast<uint8_t>(DHCPACK));

    message.dhcpData.xid = sourceMessage.dhcpData.xid;
    message.dhcpData.flags = sourceMessage.dhcpData.flags;
    message.dhcpData.yiaddr = offeredAddress;
    message.dhcpData.giaddr = sourceMessage.dhcpData.giaddr;

    message.addOption(OPT_SERVER_ID, serverAddress);
    message.addOption(OPT_LEASE_TIME, kDefaultLeaseTime);
    message.addOption(OPT_SUBNET_MASK, offeredNetmask);
    message.addOption(OPT_GATEWAY, offeredGateway);
    message.addOption(OPT_DNS, offeredDnsServers, numOfferedDnsServers * sizeof(in_addr_t));

    message.endOptions();

    return message;
}

Message Message::nack(const Message& sourceMessage, in_addr_t serverAddress) {
    uint8_t macAddress[ETH_ALEN];
    memcpy(macAddress, sourceMessage.dhcpData.chaddr, sizeof(macAddress));
    Message message(OP_BOOTREPLY, macAddress, static_cast<uint8_t>(DHCPNAK));

    message.dhcpData.xid = sourceMessage.dhcpData.xid;
    message.dhcpData.flags = sourceMessage.dhcpData.flags;
    message.dhcpData.giaddr = sourceMessage.dhcpData.giaddr;

    message.addOption(OPT_SERVER_ID, serverAddress);
    message.endOptions();

    return message;
}

bool Message::isValidDhcpMessage(uint8_t expectedOp, uint32_t expectedXid) const {
    if (!isValidDhcpMessage(expectedOp)) {
        return false;
    }
    // Only look for message with a matching transaction ID
    if (dhcpData.xid != expectedXid) {
        return false;
    }
    return true;
}

bool Message::isValidDhcpMessage(uint8_t expectedOp) const {
    // Require that there is at least enough options for the DHCP cookie
    if (dhcpData.options + 4 > end()) {
        return false;
    }

    if (dhcpData.op != expectedOp) {
        return false;
    }
    if (dhcpData.htype != HTYPE_ETHER) {
        return false;
    }
    if (dhcpData.hlen != ETH_ALEN) {
        return false;
    }

    // Need to have the correct cookie in the options
    if (dhcpData.options[0] != OPT_COOKIE1) {
        return false;
    }
    if (dhcpData.options[1] != OPT_COOKIE2) {
        return false;
    }
    if (dhcpData.options[2] != OPT_COOKIE3) {
        return false;
    }
    if (dhcpData.options[3] != OPT_COOKIE4) {
        return false;
    }

    return true;
}

size_t Message::optionsSize() const {
    auto options = reinterpret_cast<const uint8_t*>(&dhcpData.options);
    const uint8_t* msgEnd = end();
    if (msgEnd <= options) {
        return 0;
    }
    return msgEnd - options;
}

uint8_t Message::type() const {
    uint8_t length = 0;
    const uint8_t* opt = getOption(OPT_MESSAGE_TYPE, &length);
    if (opt && length == 1) {
        return *opt;
    }
    return 0;
}

in_addr_t Message::serverId() const {
    uint8_t length = 0;
    const uint8_t* opt = getOption(OPT_SERVER_ID, &length);
    if (opt && length == 4) {
        return *reinterpret_cast<const in_addr_t*>(opt);
    }
    return 0;
}

in_addr_t Message::requestedIp() const {
    uint8_t length = 0;
    const uint8_t* opt = getOption(OPT_REQUESTED_IP, &length);
    if (opt && length == 4) {
        return *reinterpret_cast<const in_addr_t*>(opt);
    }
    return 0;
}

Message::Message(uint8_t operation, const uint8_t (&macAddress)[ETH_ALEN], uint8_t type) {
    memset(&dhcpData, 0sizeof(dhcpData));

    dhcpData.op = operation;
    dhcpData.htype = HTYPE_ETHER;
    dhcpData.hlen = ETH_ALEN;
    dhcpData.hops = 0;

    dhcpData.flags = htons(FLAGS_BROADCAST);

    dhcpData.xid = htonl(sNextTransactionId++);

    memcpy(dhcpData.chaddr, macAddress, ETH_ALEN);

    uint8_t* opts = dhcpData.options;

    *opts++ = OPT_COOKIE1;
    *opts++ = OPT_COOKIE2;
    *opts++ = OPT_COOKIE3;
    *opts++ = OPT_COOKIE4;

    *opts++ = OPT_MESSAGE_TYPE;
    *opts++ = 1;
    *opts++ = type;

    updateSize(opts);
}

void Message::addOption(uint8_t type, const void* data, uint8_t size) {
    uint8_t* opts = nextOption();

    *opts++ = type;
    *opts++ = size;
    memcpy(opts, data, size);
    opts += size;

    updateSize(opts);
}

void Message::endOptions() {
    uint8_t* opts = nextOption();

    *opts++ = OPT_END;

    updateSize(opts);
}

const uint8_t* Message::getOption(uint8_t expectedOptCode, uint8_t* length) const {
    size_t optsSize = optionsSize();
    for (size_t i = 4; i + 2 < optsSize;) {
        uint8_t optCode = dhcpData.options[i];
        uint8_t optLen = dhcpData.options[i + 1];
        const uint8_t* opt = dhcpData.options + i + 2;

        if (optCode == OPT_END) {
            return nullptr;
        }
        if (optCode == expectedOptCode) {
            *length = optLen;
            return opt;
        }
        i += 2 + optLen;
    }
    return nullptr;
}

uint8_t* Message::nextOption() {
    return reinterpret_cast<uint8_t*>(&dhcpData) + size();
}

void Message::updateSize(uint8_t* optionsEnd) {
    mSize = optionsEnd - reinterpret_cast<uint8_t*>(&dhcpData);
}

Messung V0.5 in Prozent
C=93 H=96 G=94

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.