Changeset 87e5658c in mainline


Ignore:
Timestamp:
2012-02-27T00:03:26Z (12 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.

Location:
uspace/srv/ethip
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/ethip/Makefile

    r081971b r87e5658c  
    3131
    3232SOURCES = \
     33        arp.c \
    3334        ethip.c \
    3435        ethip_nic.c \
  • uspace/srv/ethip/ethip.c

    r081971b r87e5658c  
    4545#include <stdlib.h>
    4646
     47#include "arp.h"
    4748#include "ethip.h"
    4849#include "ethip_nic.h"
     
    204205        }
    205206
    206         log_msg(LVL_DEBUG, " - construct SDU");
    207         sdu.lsrc.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 1;
    208         sdu.ldest.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 4;
    209         sdu.data = frame.data;
    210         sdu.size = frame.size;
    211         log_msg(LVL_DEBUG, " - call iplink_ev_recv");
    212         rc = iplink_ev_recv(&nic->iplink, &sdu);
     207        switch (frame.etype_len) {
     208        case ETYPE_ARP:
     209                arp_received(nic, &frame);
     210                break;
     211        case ETYPE_IP:
     212                log_msg(LVL_DEBUG, " - construct SDU");
     213                sdu.lsrc.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 1;
     214                sdu.ldest.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 4;
     215                sdu.data = frame.data;
     216                sdu.size = frame.size;
     217                log_msg(LVL_DEBUG, " - call iplink_ev_recv");
     218                rc = iplink_ev_recv(&nic->iplink, &sdu);
     219                break;
     220        default:
     221                log_msg(LVL_DEBUG, "Unknown ethertype %" PRIu16,
     222                    frame.etype_len);
     223        }
    213224
    214225        free(frame.data);
  • uspace/srv/ethip/ethip.h

    r081971b r87e5658c  
    7474} eth_frame_t;
    7575
     76/** ARP opcode */
     77typedef enum {
     78        /** Request */
     79        aop_request,
     80        /** Reply */
     81        aop_reply
     82} arp_opcode_t;
     83
     84/** ARP packet (for 48-bit MAC addresses and IPv4)
     85 *
     86 * Internal representation
     87 */
     88typedef struct {
     89        /** Opcode */
     90        arp_opcode_t opcode;
     91        /** Sender hardware address */
     92        mac48_addr_t sender_hw_addr;
     93        /** Sender protocol address */
     94        iplink_srv_addr_t sender_proto_addr;
     95        /** Target hardware address */
     96        mac48_addr_t target_hw_addr;
     97        /** Target protocol address */
     98        iplink_srv_addr_t target_proto_addr;
     99} arp_eth_packet_t;
     100
    76101extern int ethip_iplink_init(ethip_nic_t *);
    77102extern int ethip_received(iplink_srv_t *, void *, size_t);
    78 
    79103
    80104#endif
  • 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 */
  • uspace/srv/ethip/pdu.h

    r081971b r87e5658c  
    4040#include "ethip.h"
    4141
    42 int eth_pdu_encode(eth_frame_t *frame, void **rdata, size_t *rsize);
    43 int eth_pdu_decode(void *data, size_t size, eth_frame_t *frame);
     42extern int eth_pdu_encode(eth_frame_t *, void **, size_t *);
     43extern int eth_pdu_decode(void *, size_t, eth_frame_t *);
     44extern int arp_pdu_encode(arp_eth_packet_t *, void **, size_t *);
     45extern int arp_pdu_decode(void *, size_t, arp_eth_packet_t *);
    4446
    4547#endif
  • uspace/srv/ethip/std.h

    r081971b r87e5658c  
    4040#include <sys/types.h>
    4141
     42#define ETH_ADDR_SIZE 6
     43#define IPV4_ADDR_SIZE 4
     44#define ETH_FRAME_MIN_SIZE 60
     45
    4246/** Ethernet frame header */
    4347typedef struct {
    4448        /** Destination Address */
    45         uint8_t dest[6];
     49        uint8_t dest[ETH_ADDR_SIZE];
    4650        /** Source Address */
    47         uint8_t src[6];
     51        uint8_t src[ETH_ADDR_SIZE];
    4852        /** Ethertype or Length */
    4953        uint16_t etype_len;
    5054} eth_header_t;
    5155
     56/** ARP packet format (for 48-bit MAC addresses and IPv4) */
     57typedef struct {
     58        /** Hardware address space */
     59        uint16_t hw_addr_space;
     60        /** Protocol address space */
     61        uint16_t proto_addr_space;
     62        /** Hardware address size */
     63        uint8_t hw_addr_size;
     64        /** Protocol address size */
     65        uint8_t proto_addr_size;
     66        /** Opcode */
     67        uint16_t opcode;
     68        /** Sender hardware address */
     69        uint8_t sender_hw_addr[ETH_ADDR_SIZE];
     70        /** Sender protocol address */
     71        uint32_t sender_proto_addr;
     72        /** Target hardware address */
     73        uint8_t target_hw_addr[ETH_ADDR_SIZE];
     74        /** Target protocol address */
     75        uint32_t target_proto_addr;
     76} __attribute__((packed)) arp_eth_packet_fmt_t;
     77
     78enum arp_opcode_fmt {
     79        AOP_REQUEST = 1,
     80        AOP_REPLY   = 2
     81};
     82
     83enum arp_hw_addr_space {
     84        AHRD_ETHERNET = 1
     85};
     86
    5287/** IP Ethertype */
    53 #define ETYPE_IP        0x0800
     88enum ether_type {
     89        ETYPE_ARP = 0x0806,
     90        ETYPE_IP  = 0x0800
     91};
    5492
    55 #define ETH_FRAME_MIN_SIZE 60
    5693
    5794#endif
Note: See TracChangeset for help on using the changeset viewer.