Changeset 0041cd6d in mainline


Ignore:
Timestamp:
2013-04-20T09:03:34Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9d8bd3ac
Parents:
ccb5165
Message:

Attempt decoding response (no pointer support).

Location:
uspace/srv/net/dnsres
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/dnsres/dns_msg.c

    rccb5165 r0041cd6d  
    3737#include <byteorder.h>
    3838#include <errno.h>
     39#include <macros.h>
    3940#include <stdint.h>
    4041#include <stdlib.h>
     
    109110}
    110111
     112static int dns_name_decode(uint8_t *buf, size_t size, char **rname,
     113    size_t *act_size)
     114{
     115        uint8_t *bp;
     116        size_t bsize;
     117        size_t lsize;
     118        size_t i;
     119
     120        bp = buf;
     121        bsize = min(size, DNS_NAME_MAX_SIZE);
     122
     123        while (true) {
     124                if (bsize == 0) {
     125                        return EINVAL;
     126                }
     127
     128
     129                lsize = *bp;
     130                ++bp;
     131                --bsize;
     132
     133                if (lsize == 0)
     134                        break;
     135
     136                if (bp != buf + 1)
     137                        printf(".");
     138
     139                if ((lsize & 0xc0) == 0xc0) {
     140                        /* Pointer */
     141                        printf("compression not supported!\n");
     142                        return EINVAL;
     143                }
     144
     145                if (lsize > bsize) {
     146                        return EINVAL;
     147                }
     148
     149                for (i = 0; i < lsize; i++) {
     150                        printf("%c", *bp);
     151                        ++bp;
     152                        --bsize;
     153                }
     154        }
     155
     156        printf("\n");
     157
     158        *act_size = bp - buf;
     159        return EOK;
     160}
     161
     162/** Decode unaligned big-endian 16-bit integer */
     163static uint16_t dns_uint16_t_decode(uint8_t *buf, size_t buf_size)
     164{
     165        assert(buf_size >= 2);
     166
     167        return ((uint16_t)buf[0] << 8) + buf[1];
     168}
     169
     170/** Encode unaligned big-endian 16-bit integer */
    111171static void dns_uint16_t_encode(uint16_t w, uint8_t *buf, size_t buf_size)
    112172{
     
    116176        if (buf != NULL && buf_size >= 2)
    117177                buf[1] = w & 0xff;
     178}
     179
     180/** Decode unaligned big-endian 32-bit integer */
     181static uint16_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
     182{
     183        assert(buf_size >= 4);
     184
     185        return ((uint32_t)buf[0] << 24) +
     186            ((uint32_t)buf[1] << 16) +
     187            ((uint32_t)buf[2] << 8) +
     188            buf[0];
    118189}
    119190
     
    144215        di += sizeof(uint16_t);
    145216
     217        return EOK;
     218}
     219
     220static int dns_question_decode(uint8_t *buf, size_t buf_size,
     221    dns_question_t **rquestion, size_t *act_size)
     222{
     223        dns_question_t *question;
     224        size_t name_size;
     225        int rc;
     226
     227        question = calloc(1, sizeof (dns_question_t));
     228        if (question == NULL)
     229                return ENOMEM;
     230
     231        printf("decode name..\n");
     232        rc = dns_name_decode(buf, buf_size, &question->qname, &name_size);
     233        if (rc != EOK) {
     234                printf("error decoding name..\n");
     235                free(question);
     236                return ENOMEM;
     237        }
     238
     239        printf("ok decoding name..\n");
     240        if (name_size + 2 * sizeof(uint16_t) > buf_size) {
     241                printf("name_size + 2 * 2 = %d >  buf_size = %d\n",
     242                    name_size + 2 * sizeof(uint16_t), buf_size);
     243                free(question);
     244                return EINVAL;
     245        }
     246
     247        question->qtype = dns_uint16_t_decode(buf + name_size, buf_size - name_size);
     248        question->qclass = dns_uint16_t_decode(buf + sizeof(uint16_t) + name_size,
     249            buf_size - sizeof(uint16_t) - name_size);
     250        *act_size = name_size + 2 * sizeof(uint16_t);
     251
     252        *rquestion = question;
     253        return EOK;
     254}
     255
     256static int dns_rr_decode(uint8_t *buf, size_t buf_size,
     257    dns_rr_t **retrr, size_t *act_size)
     258{
     259        dns_rr_t *rr;
     260        size_t name_size;
     261        uint8_t *bp;
     262        size_t bsz;
     263        size_t rdlength;
     264        int rc;
     265
     266        rr = calloc(1, sizeof (dns_rr_t));
     267        if (rr == NULL)
     268                return ENOMEM;
     269
     270        printf("decode name..\n");
     271        rc = dns_name_decode(buf, buf_size, &rr->name, &name_size);
     272        if (rc != EOK) {
     273                printf("error decoding name..\n");
     274                free(rr);
     275                return ENOMEM;
     276        }
     277
     278        printf("ok decoding name..\n");
     279        if (name_size + 2 * sizeof(uint16_t) > buf_size) {
     280                printf("name_size + 2 * 2 = %d >  buf_size = %d\n",
     281                    name_size + 2 * sizeof(uint16_t), buf_size);
     282                free(rr->name);
     283                free(rr);
     284                return EINVAL;
     285        }
     286
     287        bp = buf + name_size;
     288        bsz = buf_size - name_size;
     289
     290        if (bsz < 3 * sizeof(uint16_t) + sizeof(uint32_t)) {
     291                free(rr->name);
     292                free(rr);
     293                return EINVAL;
     294        }
     295
     296        rr->rtype = dns_uint16_t_decode(bp, bsz);
     297        bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     298
     299        rr->rclass = dns_uint16_t_decode(bp, bsz);
     300        bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     301
     302        rr->ttl = dns_uint32_t_decode(bp, bsz);
     303        bp += sizeof(uint32_t); bsz -= sizeof(uint32_t);
     304
     305        rdlength = dns_uint16_t_decode(bp, bsz);
     306        bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     307
     308        if (rdlength > bsz) {
     309                free(rr->name);
     310                free(rr);
     311                return EINVAL;
     312        }
     313
     314        rr->rdata_size = rdlength;
     315        rr->rdata = calloc(1, sizeof(rdlength));
     316        if (rr->rdata == NULL) {
     317                free(rr->name);
     318                free(rr);
     319                return ENOMEM;
     320        }
     321
     322        memcpy(rr->rdata, bp, rdlength);
     323        bp += rdlength;
     324        bsz -= rdlength;
     325
     326        *act_size = bp - buf;
     327        *retrr = rr;
    146328        return EOK;
    147329}
     
    207389}
    208390
     391int dns_message_decode(void *data, size_t size, dns_message_t **rmsg)
     392{
     393        dns_message_t *msg;
     394        dns_header_t *hdr;
     395        uint8_t *dp;
     396        size_t dsize;
     397        size_t field_size;
     398        dns_question_t *question;
     399        dns_rr_t *rr;
     400        size_t qd_count;
     401        size_t an_count;
     402        size_t i;
     403        int rc;
     404
     405        msg = calloc(1, sizeof(dns_message_t));
     406        if (msg == NULL)
     407                return ENOMEM;
     408
     409        if (size < sizeof(dns_header_t))
     410                return EINVAL;
     411
     412        hdr = data;
     413
     414        msg->id = uint16_t_be2host(hdr->id);
     415        msg->qr = BIT_RANGE_EXTRACT(uint16_t, OPB_QR, OPB_QR, hdr->opbits);
     416        msg->opcode = BIT_RANGE_EXTRACT(uint16_t, OPB_OPCODE_h, OPB_OPCODE_l,
     417            hdr->opbits);
     418        msg->aa = BIT_RANGE_EXTRACT(uint16_t, OPB_AA, OPB_AA, hdr->opbits);
     419        msg->tc = BIT_RANGE_EXTRACT(uint16_t, OPB_TC, OPB_TC, hdr->opbits);
     420        msg->rd = BIT_RANGE_EXTRACT(uint16_t, OPB_RD, OPB_RD, hdr->opbits);
     421        msg->ra = BIT_RANGE_EXTRACT(uint16_t, OPB_RA, OPB_RA, hdr->opbits);
     422        msg->rcode = BIT_RANGE_EXTRACT(uint16_t, OPB_RCODE_h, OPB_RCODE_l,
     423            hdr->opbits);
     424
     425        list_initialize(&msg->question);
     426        list_initialize(&msg->answer);
     427        list_initialize(&msg->authority);
     428        list_initialize(&msg->additional);
     429
     430        dp = (uint8_t *)data + sizeof(dns_header_t);
     431        dsize = size - sizeof(dns_header_t);
     432
     433        qd_count = uint16_t_be2host(hdr->qd_count);
     434        printf("qd_count = %d\n", (int)qd_count);
     435
     436        for (i = 0; i < qd_count; i++) {
     437                printf("decode question..\n");
     438                rc = dns_question_decode(dp, dsize, &question, &field_size);
     439                if (rc != EOK) {
     440                        printf("error decoding question\n");
     441                        goto error;
     442                }
     443                printf("ok decoding question\n");
     444
     445                dp += field_size;
     446                dsize -= field_size;
     447        }
     448
     449        an_count = uint16_t_be2host(hdr->an_count);
     450        printf("an_count = %d\n", an_count);
     451
     452        for (i = 0; i < an_count; i++) {
     453                printf("decode answer..\n");
     454                rc = dns_rr_decode(dp, dsize, &rr, &field_size);
     455                if (rc != EOK) {
     456                        printf("error decoding answer\n");
     457                        goto error;
     458                }
     459                printf("ok decoding answer\n");
     460
     461                dp += field_size;
     462                dsize -= field_size;
     463        }
     464
     465        printf("ns_count = %d\n", uint16_t_be2host(hdr->ns_count));
     466        printf("ar_count = %d\n", uint16_t_be2host(hdr->ar_count));
     467
     468        *rmsg = msg;
     469        return EOK;
     470error:
     471        /* XXX Destroy message */
     472        return rc;
     473}
     474
    209475/** @}
    210476 */
  • uspace/srv/net/dnsres/dns_msg.h

    rccb5165 r0041cd6d  
    4444
    4545extern int dns_message_encode(dns_message_t *, void **, size_t *);
     46extern int dns_message_decode(void *, size_t, dns_message_t **);
    4647
    4748#endif
  • uspace/srv/net/dnsres/transport.c

    rccb5165 r0041cd6d  
    6060        struct sockaddr_in src_addr;
    6161        socklen_t src_addr_size;
     62        size_t recv_size;
    6263        int fd;
     64        int i;
    6365
    6466        addr.sin_family = AF_INET;
     
    101103        }
    102104
    103         printf("received %d bytes\n", (int)rc);
     105        recv_size = (size_t)rc;
     106
     107        printf("received %d bytes\n", (int)recv_size);
     108        for (i = 0; i < (int)recv_size; i++) {
     109                if (recv_buf[i] >= 32 && recv_buf[i] < 127)
     110                        printf("%c", recv_buf[i]);
     111                else
     112                        printf("?");
     113        }
     114        printf("\n");
    104115
    105116        printf("close socket\n");
     
    108119        free(req_data);
    109120
    110         resp = NULL;
     121        rc = dns_message_decode(recv_buf, recv_size, &resp);
     122        if (rc != EOK)
     123                return EIO;
     124
    111125        *rresp = resp;
    112126        return EOK;
Note: See TracChangeset for help on using the changeset viewer.