Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/dhcp/transport.c

    r58e8646 re3811c9  
    3636
    3737#include <bitops.h>
    38 #include <errno.h>
    3938#include <inet/addr.h>
    4039#include <inet/dnsr.h>
     
    4241#include <io/log.h>
    4342#include <loc.h>
     43#include <net/in.h>
     44#include <net/inet.h>
     45#include <net/socket.h>
    4446#include <stdio.h>
    4547#include <stdlib.h>
     
    6567} dhcp_offer_t;
    6668
    67 static void dhcp_recv_msg(udp_assoc_t *, udp_rmsg_t *);
    68 static void dhcp_recv_err(udp_assoc_t *, udp_rerr_t *);
    69 static void dhcp_link_state(udp_assoc_t *, udp_link_state_t);
    70 
    71 static udp_cb_t dhcp_transport_cb = {
    72         .recv_msg = dhcp_recv_msg,
    73         .recv_err = dhcp_recv_err,
    74         .link_state = dhcp_link_state
    75 };
     69static int dhcp_recv_fibril(void *);
    7670
    7771int dhcp_send(dhcp_transport_t *dt, void *msg, size_t size)
    7872{
    79         inet_ep_t ep;
     73        struct sockaddr_in addr;
    8074        int rc;
    8175
    82         inet_ep_init(&ep);
    83         ep.port = dhcp_server_port;
    84         inet_addr_set(addr32_broadcast_all_hosts, &ep.addr);
     76        addr.sin_family = AF_INET;
     77        addr.sin_port = htons(dhcp_server_port);
     78        addr.sin_addr.s_addr = htonl(addr32_broadcast_all_hosts);
    8579
    86         rc = udp_assoc_send_msg(dt->assoc, &ep, msg, size);
     80        rc = sendto(dt->fd, msg, size, 0,
     81            (struct sockaddr *)&addr, sizeof(addr));
    8782        if (rc != EOK) {
    88                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed sending message");
     83                log_msg(LOG_DEFAULT, LVL_ERROR, "Sending failed");
    8984                return rc;
    9085        }
     
    9388}
    9489
    95 static void dhcp_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)
     90static int dhcp_recv_msg(dhcp_transport_t *dt, void **rmsg, size_t *rsize)
    9691{
    97         dhcp_transport_t *dt;
    98         size_t s;
     92        struct sockaddr_in src_addr;
     93        socklen_t src_addr_size;
     94        size_t recv_size;
    9995        int rc;
    10096
    101         log_msg(LOG_DEFAULT, LVL_NOTE, "dhcp_recv_msg()");
    102 
    103         dt = (dhcp_transport_t *)udp_assoc_userptr(assoc);
    104         s = udp_rmsg_size(rmsg);
    105         if (s > MAX_MSG_SIZE)
    106                 s = MAX_MSG_SIZE; /* XXX */
    107 
    108         rc = udp_rmsg_read(rmsg, 0, msgbuf, s);
    109         if (rc != EOK) {
    110                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error receiving message.");
    111                 return;
     97        if (dt->fd < 0) {
     98                /* Terminated */
     99                return EIO;
    112100        }
    113101
    114         log_msg(LOG_DEFAULT, LVL_NOTE, "dhcp_recv_msg() - call recv_cb");
    115         dt->recv_cb(dt->cb_arg, msgbuf, s);
    116 }
     102        src_addr_size = sizeof(src_addr);
     103        rc = recvfrom(dt->fd, msgbuf, MAX_MSG_SIZE, 0,
     104            (struct sockaddr *)&src_addr, &src_addr_size);
     105        if (rc < 0) {
     106                log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom failed (%d)", rc);
     107                return rc;
     108        }
    117109
    118 static void dhcp_recv_err(udp_assoc_t *assoc, udp_rerr_t *rerr)
    119 {
    120         log_msg(LOG_DEFAULT, LVL_WARN, "Ignoring ICMP error");
    121 }
     110        recv_size = (size_t)rc;
     111        *rmsg = msgbuf;
     112        *rsize = recv_size;
    122113
    123 static void dhcp_link_state(udp_assoc_t *assoc, udp_link_state_t ls)
    124 {
    125         log_msg(LOG_DEFAULT, LVL_NOTE, "Link state change");
     114        return EOK;
    126115}
    127116
     
    129118    dhcp_recv_cb_t recv_cb, void *arg)
    130119{
    131         udp_t *udp = NULL;
    132         udp_assoc_t *assoc = NULL;
    133         inet_ep2_t epp;
     120        int fd;
     121        struct sockaddr_in laddr;
     122        int fid;
    134123        int rc;
    135124
    136         log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_transport_init()");
     125        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcptransport_init()");
    137126
    138         inet_ep2_init(&epp);
    139         epp.local.addr.version = ip_v4;
    140         epp.local.port = dhcp_client_port;
    141         epp.local_link = link_id;
     127        laddr.sin_family = AF_INET;
     128        laddr.sin_port = htons(dhcp_client_port);
     129        laddr.sin_addr.s_addr = INADDR_ANY;
    142130
    143         rc = udp_create(&udp);
     131        fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     132        if (fd < 0) {
     133                rc = EIO;
     134                goto error;
     135        }
     136
     137        log_msg(LOG_DEFAULT, LVL_DEBUG, "Bind socket.");
     138        rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    144139        if (rc != EOK) {
    145140                rc = EIO;
     
    147142        }
    148143
    149         rc = udp_assoc_create(udp, &epp, &dhcp_transport_cb, dt, &assoc);
     144        log_msg(LOG_DEFAULT, LVL_DEBUG, "Set socket options");
     145        rc = setsockopt(fd, SOL_SOCKET, SO_IPLINK, &link_id, sizeof(link_id));
    150146        if (rc != EOK) {
    151147                rc = EIO;
     
    153149        }
    154150
    155         rc = udp_assoc_set_nolocal(assoc);
    156         if (rc != EOK) {
    157                 rc = EIO;
     151        dt->fd = fd;
     152        dt->recv_cb = recv_cb;
     153        dt->cb_arg = arg;
     154
     155        fid = fibril_create(dhcp_recv_fibril, dt);
     156        if (fid == 0) {
     157                rc = ENOMEM;
    158158                goto error;
    159159        }
    160160
    161         dt->udp = udp;
    162         dt->assoc = assoc;
    163         dt->recv_cb = recv_cb;
    164         dt->cb_arg = arg;
     161        dt->recv_fid = fid;
     162        fibril_add_ready(fid);
    165163
    166164        return EOK;
    167165error:
    168         udp_assoc_destroy(assoc);
    169         udp_destroy(udp);
     166        closesocket(fd);
    170167        return rc;
    171168}
     
    173170void dhcp_transport_fini(dhcp_transport_t *dt)
    174171{
    175         udp_assoc_destroy(dt->assoc);
    176         udp_destroy(dt->udp);
     172        closesocket(dt->fd);
     173        dt->fd = -1;
     174}
     175
     176static int dhcp_recv_fibril(void *arg)
     177{
     178        dhcp_transport_t *dt = (dhcp_transport_t *)arg;
     179        void *msg;
     180        size_t size = (size_t) -1;
     181        int rc;
     182
     183        while (true) {
     184                rc = dhcp_recv_msg(dt, &msg, &size);
     185                if (rc != EOK)
     186                        break;
     187
     188                assert(size != (size_t) -1);
     189
     190                dt->recv_cb(dt->cb_arg, msg, size);
     191        }
     192
     193        return EOK;
    177194}
    178195
Note: See TracChangeset for help on using the changeset viewer.