Exemple #1
0
int
tftp_upcall(PACKET pkt, void * data)
{
   struct tfconn * cn;
   struct udp * pup;

   /* get pointer to UDP header */
   pup = (struct udp *)pkt->nb_prot;
   pup -= 1;

   /* Find tftp session this packet is for. */
   if (data == TFTPSERVER)    /* tftp server connection */
   {
#ifdef TFTP_SERVER
      int err;
      /* call server for new session here */
      err = tfshnd(pkt->fhost, pup->ud_srcp, pkt->nb_prot);
#endif /* TFTP_SERVER */
      udp_free(pkt);
     /* do not return an error to the udp layer */
   }
   else  /* TFTP server child connection */
   {
      cn = (struct tfconn *)data;
      if (cn->tf_fhost != pkt->fhost)   /* sanity check */
      {
         dtrap();
         return ENP_NOT_MINE;
      }

      if (cn->tf_inbuf.udp_use)
      {
         dtrap(); /* ever happen? */
      }

      cn->tf_inbuf.data = pkt->nb_prot;
      cn->tf_inbuf.dlen = pkt->nb_plen;
      cn->tf_inbuf.udp_use = (void*)pkt;

      tftprcv(cn, pup->ud_srcp);    /* process the packet */

      if (cn->tf_inbuf.udp_use)     /* pkt may be freed in upcall */
      {
         udp_free(pkt);
         cn->tf_inbuf.udp_use = (PACKET)NULL;
      }
   }

   return 0;
}
Exemple #2
0
extern int send_rescueack(unsigned short no, unsigned short lo)
{
	ebuf_t *buf = NULL;
	int acksocket;
	char tftpnull;
	int res, i;

	/*
	 * Open a UDP socket to the TFTP server
	 */
	acksocket = udp_socket(UDP_PROTO_TFTP);
	res = udp_bind(acksocket, 69);
	if (res < 0) {
		return res;
	}
	udp_connect(acksocket, ackport);
	for (i = 0; i < 1; i++) {
		buf = udp_alloc();
		if (!buf)
			return -1;
		/*
		 * Send the data
		 */
		ebuf_append_u16_be(buf, no);
		ebuf_append_u16_be(buf, lo);
		ebuf_append_bytes(buf,&tftpnull, 0);
		udp_send(acksocket ,buf, tftpipto);
	}
	if (buf)
		udp_free(buf);
	udp_close(acksocket);
	return 0;
}
Exemple #3
0
void
tftp_udpbuffer(struct tfconn *cn, int size)
{
   PACKET pkt;

   if (cn->tf_outbuf.udp_use)
   {
      pkt = (PACKET)cn->tf_outbuf.udp_use;
      if (pkt->nb_plen >= (unsigned)size)
      {
         /* recycle existing buffer */
         pkt->nb_prot = (char *)cn->tf_outbuf.data;
         return;
      }
      else
      {
         udp_free(pkt);       /* old packet was too small */
      }
   }

   pkt = udp_alloc(size, 0);
   if (!pkt) /* alloc failed, clear outbuf pointers */
   {
      cn->tf_outbuf.data = NULL;
      cn->tf_outbuf.dlen = 0;
      cn->tf_outbuf.udp_use = NULL;
   }
   else  /* return buffer pointer */
   {
      cn->tf_outbuf.data = pkt->nb_prot;
      cn->tf_outbuf.dlen =  size;
      cn->tf_outbuf.udp_use = (void *)pkt;   /* so we can find struct later */
   }
}
Exemple #4
0
void
udp_free_client(struct udp_client *cl)
{
    udp_free(cl);
    free(cl);

    return;
}
Exemple #5
0
void
tftp_udpfree(struct tfconn *cn)
{
   PACKET pkt;

   pkt = (PACKET)cn->tf_outbuf.udp_use;
#ifdef ZEROCOPY_API
   pkt->inuse = 1;   /* free this copy - "unclone" it */
#endif
   udp_free(pkt);
   cn->tf_outbuf.udp_use = NULL;
   cn->tf_outbuf.data = NULL;
}
Exemple #6
0
void
cmd_udp_read(int fd, short which, void *arg)
{
	struct udp_con *con = arg;
	u_char buf[2048];
	ssize_t len;

	TRACE(fd, len = read(fd, buf, sizeof(buf)));
	if (len == -1) {
		if (errno == EINTR || errno == EAGAIN)
			goto again;
	}
	if (len <= 0) {
		udp_free(con);
		return;
	}

	udp_send(con, buf, len);

 again:
	cmd_trigger_read(&con->cmd, 1);
}
struct udp_client *
udp_register_client(void)
{
    struct udp_client *cl;

    cl = calloc(sizeof(*cl), 1);
    if (!cl)
        return cl;

    cl->cl_buf = calloc(UDP_MSG_DEFAULT_SIZE, 1);
    if (!cl->cl_buf)
        goto exit_register;
    cl->cl_buf_len = UDP_MSG_DEFAULT_SIZE;
    cl->cl_sock = -1;

    return cl;
exit_register:
    if (cl)
        udp_free(cl);

    return NULL;
}
Exemple #8
0
void
cmd_udp_eread(int fd, short which, void *arg)
{
	extern FILE *honeyd_servicefp;
	struct udp_con *con = arg;
	char line[1024];
	int nread;
	struct command *cmd = &con->cmd;

	TRACE(fd, nread = read(fd, line, sizeof(line)));

	if (nread <= 0) {
		udp_free(con);
		return;
	}

	if (nread == sizeof(line))
		nread--;
	line[nread] = '\0';
	
	honeyd_log_service(honeyd_servicefp, IP_PROTO_UDP, &con->conhdr, line);

	event_add(&cmd->peread, NULL);
}
static int _tftpd_open(tftp_info_t *info,char *hostname,char *filename,int mode)
{
    ebuf_t *buf = NULL;
    uint16_t type;
    int res;
    int retries;
    char ch = 0;

    /*
     * Open a UDP socket
     */    

    info->tftp_socket = udp_socket(UDP_PROTO_TFTP);
    info->tftp_lastblock = 0;
    info->tftp_error = 0;
    info->tftp_filemode = mode;

    /*
     * Listen for requests
     */

    res = udp_bind(info->tftp_socket,UDP_PROTO_TFTP);
    if (res < 0) return res;

    res = CFE_ERR_TIMEOUT;

    for (retries = 0; retries < tftp_max_retries; retries++) {
	while (console_status()) {
	    console_read(&ch,1);
	    if (ch == 3) break;
	}
	if (ch == 3) {
	    res = CFE_ERR_INTR;
	    break;
	}

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_recv_timeout);
	if (buf == NULL) continue;

	/*
	 * Process the request
	 */

	ebuf_get_u16_be(buf,type);

	switch (type) {
	    case TFTP_OP_RRQ:
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		memcpy(info->tftp_ipaddr,buf->eb_usrptr,IP_ADDR_LEN);
		info->tftp_blknum = 1;
		info->tftp_blklen = 0;
		res = 0;
		break;

	    case TFTP_OP_WRQ:
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		memcpy(info->tftp_ipaddr,buf->eb_usrptr,IP_ADDR_LEN);
		info->tftp_blknum = 0;
		res = _tftp_readmore(info);
		break;

	    default:
		/* 
		 * we aren't expecting any of these messages
		 */
		res = CFE_ERR_PROTOCOLERR;
		break;
	}

	udp_free(buf);
	break;
    }

    if (res) {
	udp_close(info->tftp_socket);
	info->tftp_socket = -1;
    }

    return res;
}
static int _tftp_writemore(tftp_info_t *info)
{
    ebuf_t *buf;
    uint16_t cmd,block,error;
    int retries;

    /*
     * If we've already written the last block, there is no more
     */

    if (info->tftp_lastblock) return 1;
    if (info->tftp_error) return CFE_ERR_TIMEOUT;

    /*
     * Otherwise, send a block
     */

    for (retries = 0; retries < tftp_max_retries; retries++) {

	buf = udp_alloc();
	if (!buf) return -1;

	/*
	 * Send the data
	 */

	ebuf_append_u16_be(buf,TFTP_OP_DATA);
	ebuf_append_u16_be(buf,info->tftp_blknum);
	ebuf_append_bytes(buf,info->tftp_data,info->tftp_blklen);
	udp_send(info->tftp_socket,buf,info->tftp_ipaddr);

	/*
	 * Wait for some response, retransmitting as necessary
	 */

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_recv_timeout);
	if (buf == NULL) continue;

	/*
	 * Got a response, make sure it's right
	 */

	ebuf_get_u16_be(buf,cmd);

	if (cmd == TFTP_OP_ERROR) {
	    ebuf_get_u16_be(buf,error);
	    xprintf("TFTP write error %d: %s\n",error,ebuf_ptr(buf));
	    info->tftp_error = 1;
	    info->tftp_lastblock = 1;
	    udp_free(buf);
	    return CFE_ERR_IOERR;
	    }

	if (cmd != TFTP_OP_ACK) {
	    udp_free(buf);
	    continue;
	    }

	ebuf_get_u16_be(buf,block);
	if (block != (info->tftp_blknum)) {
	    udp_free(buf);
	    continue;
	    }

	/*
	 * It's the correct response.  Update the block #
	 */

	info->tftp_blknum++;
	if (info->tftp_blklen != TFTP_BLOCKSIZE) info->tftp_lastblock = 1;
	udp_free(buf);
	break;
	}

    /*
     * If we had some failure, mark the stream with an error
     */

    if (retries == tftp_max_retries) {
	info->tftp_error = 1;
	return CFE_ERR_TIMEOUT;
	}

    return 0;
}
static int _tftp_readmore(tftp_info_t *info)
{
    ebuf_t *buf;
    uint16_t cmd,block;
    int retries;

    /*
     * If we've already read the last block, there is no more
     */

    if (info->tftp_lastblock) return 1;
    if (info->tftp_error) return CFE_ERR_TIMEOUT;

    /*
     * Otherwise, ack the current block so another one will come
     */

    for (retries = 0; retries < tftp_max_retries; retries++) {

	buf = udp_alloc();
	if (!buf) return -1;

	/*
	 * Send the ack
	 */

	ebuf_append_u16_be(buf,TFTP_OP_ACK);
	ebuf_append_u16_be(buf,info->tftp_blknum);
	udp_send(info->tftp_socket,buf,info->tftp_ipaddr);

	/*
	 * Wait for some response, retransmitting as necessary
	 */

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_recv_timeout);
	if (buf == NULL) continue;

	/*
	 * Got a response, make sure it's right
	 */

	ebuf_get_u16_be(buf,cmd);
	if (cmd != TFTP_OP_DATA) {
	    udp_free(buf);
	    continue;
	    }

	ebuf_get_u16_be(buf,block);
	if (block != (info->tftp_blknum+1)) {
	    udp_free(buf);
	    continue;
	    }

	/*
	 * It's the correct response.  Copy the user data
	 */

	info->tftp_blknum = block;
	info->tftp_blklen = ebuf_length(buf);
	ebuf_get_bytes(buf,info->tftp_data,ebuf_length(buf));
	udp_free(buf);
	break;
	}

    /*
     * If the block is less than 512 bytes long, it's the EOF block.
     */

    if (retries == tftp_max_retries) {
	info->tftp_error = 1;
	return CFE_ERR_TIMEOUT;
	}

    if (info->tftp_blklen < TFTP_BLOCKSIZE) {
	info->tftp_lastblock = 1;		/* EOF */
	}

    return 0;
}
static int _tftp_open(tftp_info_t *info,char *hostname,char *filename,int mode)
{
    ebuf_t *buf = NULL;
    const char *datamode = "octet";
    uint16_t type,error,block;
    int res;
    int retries;

    /*
     * Look up the remote host's IP address
     */

    res = dns_lookup(hostname,info->tftp_ipaddr);
    if (res < 0) return res;

    /*
     * Open a UDP socket to the TFTP server
     */    

    info->tftp_socket = udp_socket(UDP_PROTO_TFTP);
    info->tftp_lastblock = 0;
    info->tftp_error = 0;
    info->tftp_filemode = mode;

    /*
     * Try to send the RRQ packet to open the file
     */

    for (retries = 0; retries < tftp_max_retries; retries++) {

	buf = udp_alloc();
	if (!buf) break;

	if (info->tftp_filemode == FILE_MODE_READ) {
	    ebuf_append_u16_be(buf,TFTP_OP_RRQ);	/* read file */
	    }
	else {
	    ebuf_append_u16_be(buf,TFTP_OP_WRQ);	/* write file */
	    }
	ebuf_append_bytes(buf,filename,strlen(filename)+1);
	ebuf_append_bytes(buf,datamode,strlen(datamode)+1);

	udp_send(info->tftp_socket,buf,info->tftp_ipaddr);

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_rrq_timeout);
	if (buf) break;
	}

    /*
     * If we got no response, bail now.
     */

    if (!buf) {
	udp_close(info->tftp_socket);
	info->tftp_socket = -1;
	return CFE_ERR_TIMEOUT;
	}

    /*
     * Otherwise, process the response.
     */

    ebuf_get_u16_be(buf,type);

    switch (type) {
	case TFTP_OP_ACK:
	    /*
	     * Acks are what we get back on a WRQ command,
	     * but are otherwise unexpected.
	     */
	    if (info->tftp_filemode == FILE_MODE_WRITE) {
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		info->tftp_blknum = 1;
		info->tftp_blklen = 0;
		udp_free(buf);
		return 0;
		break;
		}
	    /* fall through */
	case TFTP_OP_RRQ:
	case TFTP_OP_WRQ:
	default:
	    /* 
	     * we aren't expecting any of these messages
	     */
	    udp_free(buf);
	    udp_close(info->tftp_socket);
	    info->tftp_socket = -1;
	    return CFE_ERR_PROTOCOLERR;

	case TFTP_OP_ERROR:
	    ebuf_get_u16_be(buf,error);
	    xprintf("TFTP error %d: %s\n",error,ebuf_ptr(buf));
	    udp_free(buf);
	    udp_close(info->tftp_socket);
	    info->tftp_socket = -1;
	    return CFE_ERR_PROTOCOLERR;

	case TFTP_OP_DATA:
	    /*
	     * Yay, we've got data!  Store the first block.
	     */
	    ebuf_get_u16_be(buf,block);
	    udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
	    info->tftp_blknum = block;
	    info->tftp_blklen = ebuf_length(buf);
	    ebuf_get_bytes(buf,info->tftp_data,ebuf_length(buf));
	    udp_free(buf);
	    if (info->tftp_blklen < TFTP_BLOCKSIZE) {
		info->tftp_lastblock = 1;		/* EOF */
		}
	    return 0;
	    break;
	    
	}
}
Exemple #13
0
int psock_close(FAR struct socket *psock)
{
  int err;

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* We perform the uIP close operation only if this is the last count on the socket.
   * (actually, I think the socket crefs only takes the values 0 and 1 right now).
   */

  if (psock->s_crefs <= 1)
    {
      /* Perform uIP side of the close depending on the protocol type */

      switch (psock->s_type)
        {
#ifdef CONFIG_NET_PKT
          case SOCK_RAW:
            {
              FAR struct pkt_conn_s *conn = psock->s_conn;

              /* Is this the last reference to the connection structure (there
               * could be more if the socket was dup'ed).
               */

              if (conn->crefs <= 1)
                {
                  /* Yes... free the connection structure */

                  conn->crefs = 0;          /* No more references on the connection */
                  pkt_free(psock->s_conn);  /* Free uIP resources */
                }
              else
                {
                  /* No.. Just decrement the reference count */

                  conn->crefs--;
                }
            }
            break;
#endif

#ifdef CONFIG_NET_TCP
          case SOCK_STREAM:
            {
              FAR struct tcp_conn_s *conn = psock->s_conn;

              /* Is this the last reference to the connection structure (there
               * could be more if the socket was dup'ed).
               */

              if (conn->crefs <= 1)
                {
                  /* Yes... then perform the disconnection now */

                  tcp_unlisten(conn);                /* No longer accepting connections */
                  conn->crefs = 0;                   /* Discard our reference to the connection */
                  err = netclose_disconnect(psock);  /* Break any current connections */
                  if (err < 0)
                    {
                      /* This would normally occur only if there is a timeout
                       * from a lingering close.
                       */

                      goto errout_with_psock;
                    }
                }
              else
                {
                  /* No.. Just decrement the reference count */

                  conn->crefs--;
                }
            }
            break;
#endif

#ifdef CONFIG_NET_UDP
          case SOCK_DGRAM:
            {
              FAR struct udp_conn_s *conn = psock->s_conn;

              /* Is this the last reference to the connection structure (there
               * could be more if the socket was dup'ed).
               */

              if (conn->crefs <= 1)
                {
                  /* Yes... free the connection structure */

                  conn->crefs = 0;          /* No more references on the connection */
                  udp_free(psock->s_conn);  /* Free uIP resources */
                }
              else
                {
                  /* No.. Just decrement the reference count */

                  conn->crefs--;
                }
            }
            break;
#endif

          default:
            err = EBADF;
            goto errout;
        }
    }

  /* Then release our reference on the socket structure containing the connection */

  sock_release(psock);
  return OK;

#ifdef CONFIG_NET_TCP
errout_with_psock:
  sock_release(psock);
#endif

errout:
  set_errno(err);
  return ERROR;
}
Exemple #14
0
int psock_close(FAR struct socket *psock)
{
  int err;

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* We perform the uIP close operation only if this is the last count on
   * the socket. (actually, I think the socket crefs only takes the values
   * 0 and 1 right now).
   *
   * It is possible for a psock to have no connection, e.g. a TCP socket
   * waiting in accept.
   */

  if (psock->s_crefs <= 1 && psock->s_conn != NULL)
    {
      /* Perform uIP side of the close depending on the protocol type */

      switch (psock->s_type)
        {
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)
          case SOCK_STREAM:
            {
#ifdef CONFIG_NET_LOCAL_STREAM
#ifdef CONFIG_NET_TCP
              if (psock->s_domain == PF_LOCAL)
#endif
                {
                  /* Release our reference to the local connection structure */

                  local_close(psock);
                }
#endif /* CONFIG_NET_LOCAL_STREAM */

#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL_STREAM
              else
#endif
                {
                  FAR struct tcp_conn_s *conn = psock->s_conn;

                  /* Is this the last reference to the connection structure
                   * (there could be more if the socket was dup'ed).
                   */

                  if (conn->crefs <= 1)
                    {
                      /* Yes... then perform the disconnection now */

                      tcp_unlisten(conn); /* No longer accepting connections */
                      conn->crefs = 0;    /* Discard our reference to the connection */

                      /* Break any current connections */

                      err = netclose_disconnect(psock);
                      if (err < 0)
                        {
                          /* This would normally occur only if there is a
                           * timeout from a lingering close.
                           */

                          goto errout_with_psock;
                        }

                      /* Stop the network monitor */

                      net_stopmonitor(conn);
                    }
                  else
                    {
                      /* No.. Just decrement the reference count */

                      conn->crefs--;
                    }
                }
#endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */
            }
            break;
#endif

#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
          case SOCK_DGRAM:
            {
#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
              if (psock->s_domain == PF_LOCAL)
#endif
                {
                  /* Release our reference to the local connection structure */

                  local_close(psock);
                }
#endif /* CONFIG_NET_LOCAL_DGRAM */

#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
              else
#endif
                {
                  FAR struct udp_conn_s *conn = psock->s_conn;

                  /* Is this the last reference to the connection structure
                   * (there could be more if the socket was dup'ed).
                   */

                  if (conn->crefs <= 1)
                    {
                      /* Yes... free the connection structure */

                      conn->crefs = 0;
                      udp_free(psock->s_conn);
                    }
                  else
                    {
                      /* No.. Just decrement the reference count */

                      conn->crefs--;
                    }
                }
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */
            }
            break;
#endif

#ifdef CONFIG_NET_PKT
          case SOCK_RAW:
            {
              FAR struct pkt_conn_s *conn = psock->s_conn;

              /* Is this the last reference to the connection structure (there
               * could be more if the socket was dup'ed).
               */

              if (conn->crefs <= 1)
                {
                  /* Yes... free the connection structure */

                  conn->crefs = 0;          /* No more references on the connection */
                  pkt_free(psock->s_conn);  /* Free uIP resources */
                }
              else
                {
                  /* No.. Just decrement the reference count */

                  conn->crefs--;
                }
            }
            break;
#endif

          default:
            err = EBADF;
            goto errout;
        }
    }

  /* Then release our reference on the socket structure containing the connection */

  sock_release(psock);
  return OK;

#ifdef CONFIG_NET_TCP
errout_with_psock:
  sock_release(psock);
#endif

errout:
  set_errno(err);
  return ERROR;
}
Exemple #15
0
static int _tftpd_open(tftp_info_t *info,char *hostname,char *filename,int mode)
{
    ebuf_t *buf = NULL;
    uint16_t type;
    int res;
    int retries;
    char ch = 0;
#ifdef RESCUE_MODE
	uint8_t asuslink[13] = "ASUSSPACELINK";
	uint8_t maclink[13]="snxxxxxxxxxxx";
	unsigned char tftpmask[4] = { 0xff, 0xff, 0xff, 0x00 };
	int i;
	char tftpnull;
	uint8_t ipaddr[4] = { 0xc0, 0xa8, 0x01, 0x0c };
	uint8_t hwaddr[6] = { 0x00, 0xe0, 0x18, 0x00, 0x3e, 0xc4 };
#endif

    /*
     * Open a UDP socket
     */    

    info->tftp_socket = udp_socket(UDP_PROTO_TFTP);
    info->tftp_lastblock = 0;
    info->tftp_error = 0;
    info->tftp_filemode = mode;

    /*
     * Listen for requests
     */

    res = udp_bind(info->tftp_socket,UDP_PROTO_TFTP);
    if (res < 0) return res;

    res = CFE_ERR_TIMEOUT;

    for (retries = 0; retries < tftp_max_retries; retries++) {
	while (console_status()) {
	    console_read(&ch,1);
	    if (ch == 3) break;
	}
	if (ch == 3) {
	    res = CFE_ERR_INTR;
	    break;
	}

	buf = udp_recv_with_timeout(info->tftp_socket,tftp_recv_timeout);
	if (buf == NULL) continue;

	/*
	 * Process the request
	 */

	ebuf_get_u16_be(buf,type);

	switch (type) {
	    case TFTP_OP_RRQ:
#ifdef RESCUE_MODE
                         udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
                         ackport = buf->eb_usrdata;
                         memcpy(info->tftp_ipaddr,buf->eb_usrptr,IP_ADDR_LEN);
                         info->tftp_blknum = 1;
                         info->tftp_blklen = 0;
                         for (i=0; i<13; i++) {
                                if (buf->eb_ptr[i] != asuslink[i])
                                                break;
                         }
                         if (i==13) {
                                tftpipfrom[0]=buf->eb_ptr[16];
                                tftpipfrom[1]=buf->eb_ptr[15];
                                tftpipfrom[2]=buf->eb_ptr[14];
                                tftpipfrom[3]=buf->eb_ptr[13];
                                tftpipto[0]=buf->eb_usrptr[0];
                                tftpipto[1]=buf->eb_usrptr[1];
                                tftpipto[2]=buf->eb_usrptr[2];
                                tftpipto[3]=buf->eb_usrptr[3];
                                        net_setparam(NET_IPADDR,tftpipfrom);
                                        net_setparam(NET_NETMASK,tftpmask);
                                        net_setparam(NET_GATEWAY,tftpipfrom);
                                        ui_myshowifconfig();
                                        net_setnetvars();
                                        for (i=0; i<4; i++)
                                                ipaddr[i]=tftpipto[i];
                                        for (i=0; i<6; i++)
                                                hwaddr[i]=buf->eb_data[6+i];
                                        buf = udp_alloc();
                                        if (!buf) {
                                                res = CFE_ERR_TIMEOUT;
                                                break;
                                        }
                                        ebuf_append_u16_be(buf, 3);
                                        ebuf_append_u16_be(buf, 1);
                                        ebuf_append_bytes(buf,&tftpnull, 0);
                                        arp_delete(ipaddr);
                                        arp_add(ipaddr,hwaddr);
                                        udp_send(info->tftp_socket, buf, tftpipto);
                                }
                                else {
                                        for (i=0; i<13; i++) {
                                                if (buf->eb_ptr[i] != maclink[i])
                                                        break;
                                        }
                                        if (i==13) {
                                                tftpipfrom[0]=buf->eb_ptr[16];
                                                tftpipfrom[1]=buf->eb_ptr[15];
                                                tftpipfrom[2]=buf->eb_ptr[14];
                                                tftpipfrom[3]=buf->eb_ptr[13];
                                                tftpipto[0]=buf->eb_usrptr[0];
                                                tftpipto[1]=buf->eb_usrptr[1];
                                                tftpipto[2]=buf->eb_usrptr[2];
                                                tftpipto[3]=buf->eb_usrptr[3];
                                                net_setparam(NET_IPADDR,tftpipfrom);
                                                net_setparam(NET_NETMASK,tftpmask);
                                                net_setparam(NET_GATEWAY,tftpipfrom);
                                                ui_myshowifconfig();
                                                net_setnetvars();
                                                for (i=0; i<4; i++)
                                                        ipaddr[i]=tftpipto[i];
                                                for (i=0; i<6; i++)
                                                        hwaddr[i]=buf->eb_data[6+i];
                                                buf = udp_alloc();
                                                if (!buf) {
                                                        res = CFE_ERR_TIMEOUT;
                                                break;
                                        }
                                        ebuf_append_u16_be(buf, 3);
                                        ebuf_append_u16_be(buf, 1);
                                        ebuf_append_bytes(buf,&tftpnull, 0);
                                        arp_delete(ipaddr);
                                        arp_add(ipaddr,hwaddr);
                                        udp_send(info->tftp_socket, buf, tftpipto);
                                }
                        }
                        res = CFE_ERR_TIMEOUT;
#else
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		memcpy(info->tftp_ipaddr,buf->eb_usrptr,IP_ADDR_LEN);
		info->tftp_blknum = 1;
		info->tftp_blklen = 0;
		res = 0;
#endif
		break;

	    case TFTP_OP_WRQ:
		udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata);
		memcpy(info->tftp_ipaddr,buf->eb_usrptr,IP_ADDR_LEN);
		info->tftp_blknum = 0;
		res = _tftp_readmore(info);
		break;

	    default:
		/* 
		 * we aren't expecting any of these messages
		 */
		res = CFE_ERR_PROTOCOLERR;
		break;
	}

	udp_free(buf);
	break;
    }

    if (res) {
	udp_close(info->tftp_socket);
	info->tftp_socket = -1;
    }

    return res;
}