Changeset 87e5658c in mainline for uspace/srv/ethip/pdu.c


Ignore:
Timestamp:
2012-02-27T00:03:26Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
962f03b
Parents:
081971b
Message:

Prototype ARP responder.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/ethip/pdu.c

    r081971b r87e5658c  
    140140}
    141141
     142/** Encode ARP PDU. */
     143int arp_pdu_encode(arp_eth_packet_t *packet, void **rdata, size_t *rsize)
     144{
     145        void *data;
     146        size_t size;
     147        arp_eth_packet_fmt_t *pfmt;
     148        uint16_t fopcode;
     149
     150        log_msg(LVL_DEBUG, "arp_pdu_encode()");
     151
     152        size = sizeof(arp_eth_packet_fmt_t);
     153
     154        data = calloc(size, 1);
     155        if (data == NULL)
     156                return ENOMEM;
     157
     158        pfmt = (arp_eth_packet_fmt_t *)data;
     159
     160        switch (packet->opcode) {
     161        case aop_request: fopcode = AOP_REQUEST; break;
     162        case aop_reply: fopcode = AOP_REPLY; break;
     163        default:
     164                assert(false);
     165                fopcode = 0;
     166        }
     167
     168        pfmt->hw_addr_space = host2uint16_t_be(AHRD_ETHERNET);
     169        pfmt->proto_addr_space = host2uint16_t_be(ETYPE_IP);
     170        pfmt->hw_addr_size = ETH_ADDR_SIZE;
     171        pfmt->proto_addr_size = IPV4_ADDR_SIZE;
     172        pfmt->opcode = host2uint16_t_be(fopcode);
     173        mac48_encode(&packet->sender_hw_addr, pfmt->sender_hw_addr);
     174        pfmt->sender_proto_addr =
     175            host2uint32_t_be(packet->sender_proto_addr.ipv4);
     176        mac48_encode(&packet->target_hw_addr, pfmt->target_hw_addr);
     177        pfmt->target_proto_addr =
     178            host2uint32_t_be(packet->target_proto_addr.ipv4);
     179
     180        *rdata = data;
     181        *rsize = size;
     182        return EOK;
     183}
     184
     185/** Decode ARP PDU. */
     186int arp_pdu_decode(void *data, size_t size, arp_eth_packet_t *packet)
     187{
     188        arp_eth_packet_fmt_t *pfmt;
     189
     190        log_msg(LVL_DEBUG, "arp_pdu_decode()");
     191
     192        if (size < sizeof(arp_eth_packet_fmt_t)) {
     193                log_msg(LVL_DEBUG, "ARP PDU too short (%zu)", size);
     194                return EINVAL;
     195        }
     196
     197        pfmt = (arp_eth_packet_fmt_t *)data;
     198
     199        if (uint16_t_be2host(pfmt->hw_addr_space) != AHRD_ETHERNET) {
     200                log_msg(LVL_DEBUG, "HW address space != %u (%" PRIu16 ")",
     201                    AHRD_ETHERNET, uint16_t_be2host(pfmt->hw_addr_space));
     202                return EINVAL;
     203        }
     204
     205        if (uint16_t_be2host(pfmt->proto_addr_space) != ETYPE_IP) {
     206                log_msg(LVL_DEBUG, "Proto address space != %u (%" PRIu16 ")",
     207                    ETYPE_IP, uint16_t_be2host(pfmt->proto_addr_space));
     208                return EINVAL;
     209        }
     210
     211        if (pfmt->hw_addr_size != ETH_ADDR_SIZE) {
     212                log_msg(LVL_DEBUG, "HW address size != %zu (%zu)",
     213                    (size_t)ETH_ADDR_SIZE, (size_t)pfmt->hw_addr_size);
     214                return EINVAL;
     215        }
     216
     217        if (pfmt->proto_addr_size != IPV4_ADDR_SIZE) {
     218                log_msg(LVL_DEBUG, "Proto address size != %zu (%zu)",
     219                    (size_t)IPV4_ADDR_SIZE, (size_t)pfmt->proto_addr_size);
     220                return EINVAL;
     221        }
     222
     223        switch (uint16_t_be2host(pfmt->opcode)) {
     224        case AOP_REQUEST: packet->opcode = aop_request; break;
     225        case AOP_REPLY: packet->opcode = aop_reply; break;
     226        default:
     227                log_msg(LVL_DEBUG, "Invalid ARP opcode (%" PRIu16 ")",
     228                    uint16_t_be2host(pfmt->opcode));
     229                return EINVAL;
     230        }
     231
     232        mac48_decode(pfmt->sender_hw_addr, &packet->sender_hw_addr);
     233        packet->sender_proto_addr.ipv4 =
     234            uint32_t_be2host(pfmt->sender_proto_addr);
     235        mac48_decode(pfmt->target_hw_addr, &packet->target_hw_addr);
     236        packet->target_proto_addr.ipv4 =
     237            uint32_t_be2host(pfmt->target_proto_addr);
     238        log_msg(LVL_DEBUG, "packet->tpa = %x\n", pfmt->target_proto_addr);
     239
     240        return EOK;
     241}
     242
     243
    142244/** @}
    143245 */
Note: See TracChangeset for help on using the changeset viewer.