tftp.c revision 44960a370fe9fdc75f1b3273518f2d06f67be80e
/*
* tftp.c - a simple, read-only tftp server for qemu
*
* Copyright (c) 2004 Magnus Damm <damm@opensource.se>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <slirp.h>
struct tftp_session {
int in_use;
unsigned char filename[TFTP_FILENAME_MAX];
int timestamp;
};
const char *tftp_prefix;
{
}
{
}
{
struct tftp_session *spt;
int k;
for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
spt = &tftp_sessions[k];
goto found;
/* sessions time out after 5 inactive seconds */
goto found;
}
return -1;
return k;
}
{
struct tftp_session *spt;
int k;
for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
spt = &tftp_sessions[k];
return k;
}
}
}
}
return -1;
}
{
int fd;
int bytes_read = 0;
char buffer[1024];
int n;
if (n >= sizeof(buffer))
return -1;
if (fd < 0) {
return -1;
}
if (len) {
}
return bytes_read;
}
{
struct mbuf *m;
int n = 0;
m = m_get();
if (!m)
return -1;
m->m_data += if_maxlinkhdr;
return 0;
}
{
struct mbuf *m;
int nobytes;
m = m_get();
if (!m) {
return -1;
}
m->m_data += if_maxlinkhdr;
#ifndef VBOX
#else /* VBOX */
#endif /* VBOX */
nobytes = 2;
return 0;
}
{
struct mbuf *m;
int nobytes;
if (block_nr < 1) {
return -1;
}
m = m_get();
if (!m) {
return -1;
}
m->m_data += if_maxlinkhdr;
if (nobytes < 0) {
m_free(m);
/* send "file not found" error back */
return -1;
}
if (nobytes == 512) {
}
else {
}
return 0;
}
{
struct tftp_session *spt;
int s, k, n;
s = tftp_session_allocate(tp);
if (s < 0) {
return;
}
spt = &tftp_sessions[s];
/* get name */
for (k = 0; k < n; k++) {
if (k < TFTP_FILENAME_MAX) {
}
else {
return;
}
if (src[k] == '\0') {
break;
}
}
if (k >= n) {
return;
}
k++;
/* check mode */
if ((n - k) < 6) {
return;
}
return;
}
k += 6; /* skipping octet */
/* do sanity checks on the filename */
#ifndef VBOX
#else /* VBOX */
#endif /* VBOX */
return;
}
/* only allow exported prefixes */
if (!tftp_prefix) {
return;
}
/* check if the file exists */
return;
}
if (src[n - 1] != 0) {
return;
}
while (k < n) {
if (k >= n) {
return;
}
if (tsize == 0 && tftp_prefix) {
char buffer[1024];
int len;
else {
return;
}
}
}
}
}
{
int s;
s = tftp_session_find(tp);
if (s < 0) {
return;
}
if (tftp_send_data(&tftp_sessions[s],
tp) < 0) {
return;
}
}
void tftp_input(struct mbuf *m)
{
case TFTP_RRQ:
break;
case TFTP_ACK:
break;
}
}