Commit 1f697db9c3c22d3768175dbd70e7d5a68638e7b7
1 parent
47d5d01a
Add OACK support to slirp TFTP server, by Anthony Liguori.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2440 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
84 additions
and
0 deletions
slirp/tftp.c
@@ -120,6 +120,45 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, | @@ -120,6 +120,45 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, | ||
120 | return bytes_read; | 120 | return bytes_read; |
121 | } | 121 | } |
122 | 122 | ||
123 | +static int tftp_send_oack(struct tftp_session *spt, | ||
124 | + const char *key, uint32_t value, | ||
125 | + struct tftp_t *recv_tp) | ||
126 | +{ | ||
127 | + struct sockaddr_in saddr, daddr; | ||
128 | + struct mbuf *m; | ||
129 | + struct tftp_t *tp; | ||
130 | + int n = 0; | ||
131 | + | ||
132 | + m = m_get(); | ||
133 | + | ||
134 | + if (!m) | ||
135 | + return -1; | ||
136 | + | ||
137 | + memset(m->m_data, 0, m->m_size); | ||
138 | + | ||
139 | + m->m_data += if_maxlinkhdr; | ||
140 | + tp = (void *)m->m_data; | ||
141 | + m->m_data += sizeof(struct udpiphdr); | ||
142 | + | ||
143 | + tp->tp_op = htons(TFTP_OACK); | ||
144 | + n += sprintf(tp->x.tp_buf + n, "%s", key) + 1; | ||
145 | + n += sprintf(tp->x.tp_buf + n, "%u", value) + 1; | ||
146 | + | ||
147 | + saddr.sin_addr = recv_tp->ip.ip_dst; | ||
148 | + saddr.sin_port = recv_tp->udp.uh_dport; | ||
149 | + | ||
150 | + daddr.sin_addr = spt->client_ip; | ||
151 | + daddr.sin_port = spt->client_port; | ||
152 | + | ||
153 | + m->m_len = sizeof(struct tftp_t) - 514 + n - | ||
154 | + sizeof(struct ip) - sizeof(struct udphdr); | ||
155 | + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); | ||
156 | + | ||
157 | + return 0; | ||
158 | +} | ||
159 | + | ||
160 | + | ||
161 | + | ||
123 | static int tftp_send_error(struct tftp_session *spt, | 162 | static int tftp_send_error(struct tftp_session *spt, |
124 | u_int16_t errorcode, const char *msg, | 163 | u_int16_t errorcode, const char *msg, |
125 | struct tftp_t *recv_tp) | 164 | struct tftp_t *recv_tp) |
@@ -273,6 +312,8 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) | @@ -273,6 +312,8 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) | ||
273 | return; | 312 | return; |
274 | } | 313 | } |
275 | 314 | ||
315 | + k += 6; /* skipping octet */ | ||
316 | + | ||
276 | /* do sanity checks on the filename */ | 317 | /* do sanity checks on the filename */ |
277 | 318 | ||
278 | if ((spt->filename[0] != '/') | 319 | if ((spt->filename[0] != '/') |
@@ -297,6 +338,48 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) | @@ -297,6 +338,48 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) | ||
297 | return; | 338 | return; |
298 | } | 339 | } |
299 | 340 | ||
341 | + if (src[n - 1] != 0) { | ||
342 | + tftp_send_error(spt, 2, "Access violation", tp); | ||
343 | + return; | ||
344 | + } | ||
345 | + | ||
346 | + while (k < n) { | ||
347 | + const char *key, *value; | ||
348 | + | ||
349 | + key = src + k; | ||
350 | + k += strlen(key) + 1; | ||
351 | + | ||
352 | + if (k >= n) { | ||
353 | + tftp_send_error(spt, 2, "Access violation", tp); | ||
354 | + return; | ||
355 | + } | ||
356 | + | ||
357 | + value = src + k; | ||
358 | + k += strlen(value) + 1; | ||
359 | + | ||
360 | + if (strcmp(key, "tsize") == 0) { | ||
361 | + int tsize = atoi(value); | ||
362 | + struct stat stat_p; | ||
363 | + | ||
364 | + if (tsize == 0 && tftp_prefix) { | ||
365 | + char buffer[1024]; | ||
366 | + int len; | ||
367 | + | ||
368 | + len = snprintf(buffer, sizeof(buffer), "%s/%s", | ||
369 | + tftp_prefix, spt->filename); | ||
370 | + | ||
371 | + if (stat(buffer, &stat_p) == 0) | ||
372 | + tsize = stat_p.st_size; | ||
373 | + else { | ||
374 | + tftp_send_error(spt, 1, "File not found", tp); | ||
375 | + return; | ||
376 | + } | ||
377 | + } | ||
378 | + | ||
379 | + tftp_send_oack(spt, "tsize", tsize, tp); | ||
380 | + } | ||
381 | + } | ||
382 | + | ||
300 | tftp_send_data(spt, 1, tp); | 383 | tftp_send_data(spt, 1, tp); |
301 | } | 384 | } |
302 | 385 |
slirp/tftp.h