Changes in uspace/srv/net/dhcp/transport.c [58e8646:e3811c9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dhcp/transport.c
r58e8646 re3811c9 36 36 37 37 #include <bitops.h> 38 #include <errno.h>39 38 #include <inet/addr.h> 40 39 #include <inet/dnsr.h> … … 42 41 #include <io/log.h> 43 42 #include <loc.h> 43 #include <net/in.h> 44 #include <net/inet.h> 45 #include <net/socket.h> 44 46 #include <stdio.h> 45 47 #include <stdlib.h> … … 65 67 } dhcp_offer_t; 66 68 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 }; 69 static int dhcp_recv_fibril(void *); 76 70 77 71 int dhcp_send(dhcp_transport_t *dt, void *msg, size_t size) 78 72 { 79 inet_ep_t ep;73 struct sockaddr_in addr; 80 74 int rc; 81 75 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); 85 79 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)); 87 82 if (rc != EOK) { 88 log_msg(LOG_DEFAULT, LVL_ERROR, " Failed sending message");83 log_msg(LOG_DEFAULT, LVL_ERROR, "Sending failed"); 89 84 return rc; 90 85 } … … 93 88 } 94 89 95 static void dhcp_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)90 static int dhcp_recv_msg(dhcp_transport_t *dt, void **rmsg, size_t *rsize) 96 91 { 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; 99 95 int rc; 100 96 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; 112 100 } 113 101 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 } 117 109 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; 122 113 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; 126 115 } 127 116 … … 129 118 dhcp_recv_cb_t recv_cb, void *arg) 130 119 { 131 udp_t *udp = NULL;132 udp_assoc_t *assoc = NULL;133 in et_ep2_t epp;120 int fd; 121 struct sockaddr_in laddr; 122 int fid; 134 123 int rc; 135 124 136 log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp _transport_init()");125 log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcptransport_init()"); 137 126 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; 142 130 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)); 144 139 if (rc != EOK) { 145 140 rc = EIO; … … 147 142 } 148 143 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)); 150 146 if (rc != EOK) { 151 147 rc = EIO; … … 153 149 } 154 150 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; 158 158 goto error; 159 159 } 160 160 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); 165 163 166 164 return EOK; 167 165 error: 168 udp_assoc_destroy(assoc); 169 udp_destroy(udp); 166 closesocket(fd); 170 167 return rc; 171 168 } … … 173 170 void dhcp_transport_fini(dhcp_transport_t *dt) 174 171 { 175 udp_assoc_destroy(dt->assoc); 176 udp_destroy(dt->udp); 172 closesocket(dt->fd); 173 dt->fd = -1; 174 } 175 176 static 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; 177 194 } 178 195
Note:
See TracChangeset
for help on using the changeset viewer.