tftp.c revision 3c2389b23b02aeda241ecb294e50b4522128e276
/* $Id$ */
/** @file
* NAT - TFTP server.
*/
/*
* Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*
* This code is based on:
*
* 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 *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 tftp_session *spt,
{
struct mbuf *m;
int n = 0;
if (!m)
return -1;
m->m_data += if_maxlinkhdr;
return 0;
}
struct tftp_session *spt,
{
struct mbuf *m;
int nobytes;
if (!m)
return -1;
m->m_data += if_maxlinkhdr;
nobytes = 2;
- 514
+ 3
- sizeof(struct ip)
- sizeof(struct udphdr);
return 0;
}
struct tftp_session *spt,
{
struct mbuf *m;
int nobytes;
if (block_nr < 1)
return -1;
if (!m)
return -1;
m->m_data += if_maxlinkhdr;
if (nobytes < 0)
{
/* send "file not found" error back */
return -1;
}
- (512 - nobytes)
- sizeof(struct ip)
- sizeof(struct udphdr);
if (nobytes == 512)
else
return 0;
}
{
struct tftp_session *spt;
int s, k, n;
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 */
{
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;
}
}
return;
}
}
}
{
int s;
if (s < 0)
return;
{
/* XXX */
}
}
{
{
case TFTP_RRQ:
break;
case TFTP_ACK:
break;
}
}