Пример #1
0
static int
tcp_write(tcpcon_t *tc, const void *data, size_t len)
{
#ifdef MSG_NOSIGNAL
  return netSend(tc->fd, data, len, MSG_NOSIGNAL) != len ? ECONNRESET : 0;
#else
  return netSend(tc->fd, data, len, 0           ) != len ? ECONNRESET : 0;
#endif
}
Пример #2
0
// returns 0 on success and a (negative) error number on failure
int socketSendData(JsNetwork *net, JsVar *connection, int sckt, JsVar **sendData) {
    char *buf = alloca(net->chunkSize); // allocate on stack

    assert(!jsvIsEmptyString(*sendData));

    size_t bufLen = httpStringGet(*sendData, buf, net->chunkSize);
    int num = netSend(net, sckt, buf, bufLen);
    if (num < 0) return num; // an error occurred
    // Now cut what we managed to send off the beginning of sendData
    if (num > 0) {
        JsVar *newSendData = 0;
        if (num < (int)jsvGetStringLength(*sendData)) {
            // we didn't send all of it... cut out what we did send
            newSendData = jsvNewFromStringVar(*sendData, (size_t)num, JSVAPPENDSTRINGVAR_MAXLENGTH);
        } else {
            // we sent all of it! Issue a drain event, unless we want to close, then we shouldn't
            // callback for more data
            bool wantClose = jsvGetBoolAndUnLock(jsvObjectGetChild(connection,HTTP_NAME_CLOSE,0));
            if (!wantClose) {
                jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_DRAIN, &connection, 1);
            }
            newSendData = jsvNewFromEmptyString();
        }
        jsvUnLock(*sendData);
        *sendData = newSendData;
    }

    return 0;
}
Пример #3
0
void debugPrintf(const char* fmt, ...)
{
	char buffer[0x800];
	va_list arg;
	va_start(arg, fmt);
	vsnprintf(buffer, sizeof(buffer), fmt, arg);
	va_end(arg);
	netSend(SocketFD, buffer, strlen(buffer), 0);
}
Пример #4
0
// Attempt to send buffer on an established client connection, returns true if it sent something
bool telnetSendBuf(JsNetwork *net) {
  if (tnSrv.sock == 0 || tnSrv.cliSock == 0) return false;

  // if we have nothing buffered, that's it
  if (tnSrv.txBufLen == 0) return false;

  // try to send the tx buffer
  int sent = netSend(net, tnSrv.cliSock, tnSrv.txBuf, tnSrv.txBufLen);
  if (sent == tnSrv.txBufLen) {
    tnSrv.txBufLen = 0;
  } else if (sent > 0) {
    // shift remaining chars up in the buffer
    memmove(tnSrv.txBuf, tnSrv.txBuf+sent, (size_t)(tnSrv.txBufLen-sent));
    tnSrv.txBufLen -= (uint16_t)sent;
  } else if (sent < 0) {
    telnetRelease(net);
  }
  if (sent != 0) {
    //printf("tnSrv: sent sock=%d, %d bytes, %d left\n", tnSrv.sock, sent, tnSrv.txBufLen);
  }
  return sent != 0;
}
Пример #5
0
/**
 * Sends an ARP request for an ARP table entry over a network interface. 
 * @param entry ARP table entry
 * @return OK if packet was sent, otherwise SYSERR
 */
syscall arpSendRqst(struct arpEntry *entry)
{
    struct netif *netptr = NULL;
    struct packet *pkt = NULL;
    struct arpPkt *arp = NULL;
    int result;

    /* Error check pointers */
    if (NULL == entry)
    {
        return SYSERR;
    }

    ARP_TRACE("Sending ARP request");

    /* Setup pointer to network interface */
    netptr = entry->nif;

    /* Obtain a buffer for the packet */
    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        ARP_TRACE("Failed to acquire packet buffer");
        return SYSERR;
    }

    /* Place ARP header at end of packet buffer */
    pkt->nif = netptr;
    pkt->len =
        ARP_CONST_HDR_LEN + netptr->hwaddr.len * 2 + netptr->ip.len * 2;
    pkt->curr -= pkt->len;
    arp = (struct arpPkt *)pkt->curr;

    /* Fill in ARP header */
    arp->hwtype = hs2net(netptr->hwaddr.type);
    arp->prtype = hs2net(netptr->ip.type);
    arp->hwalen = netptr->hwaddr.len;
    arp->pralen = netptr->ip.len;
    arp->op = hs2net(ARP_OP_RQST);
    ARP_TRACE("Filled in types, lens, and op");
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], entry->praddr.addr,
           arp->pralen);
    ARP_TRACE("Filled in addrs");

    /* Send packet */
    result = netSend(pkt, &netptr->hwbrc, NULL, ETHER_TYPE_ARP);

    ARP_TRACE("Sent packet");

    /* Free buffer for the packet */
    if (SYSERR == netFreebuf(pkt))
    {
        ARP_TRACE("Failed to free packet buffer");
        return SYSERR;
    }

    /* Return result of netSend */
    return result;
}
Пример #6
0
ssize_t netSendPeerEvent(NetPath *netPath, const Octet *buf, UInteger16 length, TimeInternal* time)
{
    return netSend(buf, length, time, &netPath->peerMulticastAddr, netPath->eventPcb);
}
Пример #7
0
ssize_t netSendPeerGeneral(NetPath *netPath, const Octet *buf, UInteger16 length)
{
    return netSend(buf, length, NULL, &netPath->peerMulticastAddr, netPath->generalPcb);
}
Пример #8
0
/**
 * Tests the network interfaces.
 * @return OK when testing is complete
 */
thread test_netif(bool verbose)
{
    bool passed = TRUE;
    int i = 0;
    struct netaddr ip;
    struct netaddr mask;
    struct netaddr gate;
    struct netaddr hw;
    struct netaddr brc;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pkt;
    struct netif *netptr;
    uchar *data;

    enable();

    ip.type = NETADDR_IPv4;
    ip.len = IPv4_ADDR_LEN;
    ip.addr[0] = 192;
    ip.addr[1] = 168;
    ip.addr[2] = 1;
    ip.addr[3] = 6;

    mask.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;
    mask.addr[0] = 255;
    mask.addr[1] = 255;
    mask.addr[2] = 255;
    mask.addr[3] = 0;

    gate.type = NETADDR_IPv4;
    gate.len = IPv4_ADDR_LEN;
    gate.addr[0] = 192;
    gate.addr[1] = 168;
    gate.addr[2] = 1;
    gate.addr[3] = 1;

    brc.type = NETADDR_IPv4;
    brc.len = IPv4_ADDR_LEN;
    brc.addr[0] = 255;
    brc.addr[1] = 255;
    brc.addr[2] = 255;
    brc.addr[3] = 255;

    testPrint(verbose, "Open loopback ethernet device");
    failif((SYSERR == open(ELOOP)), "");

    testPrint(verbose, "Start network interface");
    if (SYSERR == netUp(ELOOP, &ip, &mask, &gate))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        for (i = 0; i < NNETIF; i++)
        {
            if ((NET_ALLOC == netiftab[i].state)
                && (ELOOP == netiftab[i].dev))
            {
                break;
            }
        }

        netptr = &netiftab[i];
        if ((i >= NNETIF)
            || (netptr->state != NET_ALLOC)
            || (netptr->mtu != ELOOP_MTU)
            || (netptr->linkhdrlen != ELOOP_LINKHDRSIZE)
            || (FALSE == netaddrequal(&netptr->ip, &ip))
            || (FALSE == netaddrequal(&netptr->mask, &mask))
            || (FALSE == netaddrequal(&netptr->gateway, &gate)))
        {
            failif(TRUE, "Incorrect structure setup");
        }
        else
        {
            for (i = 0; i < NET_NTHR; i++)
            {
                if (isbadtid(netptr->recvthr[i]))
                {
                    failif(TRUE, "Bad recvthr");
                    break;
                }
            }
            if (NET_NTHR == i)
            {
                failif(FALSE, "");
            }
        }
    }

    testPrint(verbose, "Stop network interface");
    failif((SYSERR == netDown(ELOOP)), "");

    testPrint(verbose, "Start network interface (no gateway)");
    failif((SYSERR == netUp(ELOOP, &ip, &mask, NULL)), "");
    for (i = 0; i < NNETIF; i++)
    {
        if ((NET_ALLOC == netiftab[i].state)
            && (ELOOP == netiftab[i].dev))
        {
            break;
        }
    }

    /* Kill receiver threads */
    netptr = &netiftab[i];
    for (i = 0; i < NET_NTHR; i++)
    {
        kill(netptr->recvthr[i]);
        netptr->recvthr[i] = BADTID;
    }

    testPrint(verbose, "Get packet buffer");
    pkt = netGetbuf();
    failif((SYSERR == (int)pkt), "");

    data = (uchar *)&_binary_data_testnetif_pcap_start;
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt->nif = netptr;
    pkt->len = phdr.caplen - netptr->linkhdrlen;
    pkt->curr = pkt->curr - pkt->len;
    memcpy(pkt->curr, data + netptr->linkhdrlen, pkt->len);

    hw.type = NETADDR_ETHERNET;
    hw.len = ETH_ADDR_LEN;
    hw.addr[0] = 0xAA;
    hw.addr[1] = 0xBB;
    hw.addr[2] = 0xCC;
    hw.addr[3] = 0xDD;
    hw.addr[4] = 0xEE;
    hw.addr[5] = 0xAA;

    testPrint(verbose, "Send packet (known hardware address)");
    if (SYSERR == netSend(pkt, &hw, NULL, ETHER_TYPE_ARP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        if ((SYSERR == read(netptr->dev, pkt, phdr.caplen))
            || (memcmp(pkt, data, phdr.caplen) != 0))
        {
            failif(TRUE, "Packet did not match");
        }
        else
        {
            failif(FALSE, "");
        }
    }

    testPrint(verbose, "Free packet buffer");
    failif((SYSERR == netFreebuf(pkt)), "");

    testPrint(verbose, "Stop network interface");
    failif(((SYSERR == netDown(ELOOP)) || (SYSERR == close(ELOOP))), "");

    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }

    return OK;
}
Пример #9
0
/**
 * Fragments packet into maximum transmission unit sized chunks.
 * @param pkt the packet to fragment
 * @return OK
 */
syscall ipv4SendFrag(struct packet *pkt, struct netaddr *nxthop)
{
    uint ihl;
    uchar *data;
    uint dRem = 0;              // The amount of data remaining to be fragmented
    ushort froff;
    ushort lastFlag;
    ushort dLen;

    // Incoming packet structures
    struct ipv4Pkt *ip;

    // Outgoing packet structures
    struct ipv4Pkt *outip;
    struct packet *outpkt;

    IPv4_TRACE("Declaration");

    if (NULL == pkt)
    {
        return SYSERR;
    }

    // Setup incoming packet structures
    ip = (struct ipv4Pkt *)pkt->curr;

    if (net2hs(ip->len) <= pkt->nif->mtu)
    {
        IPv4_TRACE("NetSend");

        if (netaddrequal(&pkt->nif->ipbrc, nxthop))
        {
            IPv4_TRACE("Subnet Broadcast");
            return netSend(pkt, &NETADDR_GLOBAL_ETH_BRC,
                           nxthop, ETHER_TYPE_IPv4);
        }
        return netSend(pkt, NULL, nxthop, ETHER_TYPE_IPv4);
    }

    // Verify header does not have DF
    if (net2hs(ip->flags_froff) & IPv4_FLAG_DF)
    {
        IPv4_TRACE("net2hs of froff");
        /* Send ICMP message */
        icmpDestUnreach(pkt, ICMP_FOFF_DFSET);
        return SYSERR;
    }

    ihl = (ip->ver_ihl & IPv4_IHL) * 4;
    data = ((uchar *)ip) + ihl;
    dRem = net2hs(ip->len) - ihl;
    froff = net2hs(ip->flags_froff) & IPv4_FROFF;
    lastFlag = net2hs(ip->flags_froff) & IPv4_FLAGS;

    // Length of data in this packet will be MTU - header length,
    //  rounded down to nearest multiple of 8 bytes.
    dLen = (pkt->nif->mtu - ihl) & ~0x7;

    pkt->len = ihl + dLen;
    ip->len = hs2net(pkt->len);

    // Set more fragments flag
    ip->flags_froff = IPv4_FLAG_MF & froff;
    ip->flags_froff = hs2net(ip->flags_froff);

    ip->chksum = 0;
    ip->chksum = netChksum((uchar *)ip, ihl);

    netSend(pkt, NULL, nxthop, ETHER_TYPE_IPv4);
    dRem -= dLen;
    data += dLen;
    froff += (dLen / 8);

    // Get memory from stack for outgoing fragment
    outpkt = netGetbuf();

    if (SYSERR == (int)outpkt)
    {
        IPv4_TRACE("allocating outpkt");
        return SYSERR;
    }

    // Set up outgoing packet pointers and variables
    outpkt->curr -= pkt->nif->mtu;
    outip = (struct ipv4Pkt *)outpkt->curr;
    outpkt->nif = pkt->nif;

    memcpy(outip, ip, IPv4_HDR_LEN);

    // While packet must be fragmented
    while (dRem > 0)
    {
        if (((dRem + 7) & ~0x7) > pkt->nif->mtu + IPv4_HDR_LEN)
        {
            dLen = (pkt->nif->mtu - IPv4_HDR_LEN) & ~0x7;
        }
        else
        {
            dLen = dRem;
        }
        // Copy data segment
        memcpy(outip->opts, data, dLen);

        // Set more fragments flag
        if (dLen == dRem)
        {
            outip->flags_froff = lastFlag & froff;
        }
        else
        {
            outip->flags_froff = IPv4_FLAG_MF & froff;
        }
        outip->flags_froff = hs2net(outip->flags_froff);

        // Update fields
        outip->len = hs2net(IPv4_HDR_LEN + dLen);
        outip->chksum = 0;
        outip->chksum = netChksum((uchar *)outip, IPv4_HDR_LEN);

        // Update outgoing packet length
        outpkt->len = net2hs(outip->len);

        // Send fragment
        netSend(outpkt, NULL, nxthop, ETHER_TYPE_IPv4);

        dRem -= dLen;
        data += dLen;
        froff += (dLen / 8);
    }

    IPv4_TRACE("freeing outpkt");
    netFreebuf(outpkt);
    return OK;
}
Пример #10
0
static void handleclient(u64 conn_s_p)
{
	// todo: clean up
	
	int conn_s = (int)conn_s_p;
	int list_s_data = -1;
	int conn_s_data = -1;
	int datareq = 0;
	
	char		cwd[256];
	char		rnfr[256];
	char		filename[256];
	char		user[32];
	u32		rest = 0;
	int		authd = 0;
	int		active = 1;
	Lv2FsFile	tempfd;
	char		buf[BUFFER_SIZE];

	char	buffer[1024];
	char	client_cmd[8][128];
	ssize_t	bytes;
	
	#if LOGIN_CHECK == 1
	// load password file
	char passwordcheck[33];
						
	// check if password file exists - if not, use default password
	if(exists(PASSWORD_FPATH) == 0)
	{
		Lv2FsFile fd;
		u64 read;
		
		lv2FsOpen(PASSWORD_FPATH, LV2_O_RDONLY, &fd, 0, NULL, 0);
		lv2FsRead(fd, passwordcheck, 32, &read);
		lv2FsClose(fd);
		
		if(strlen(passwordcheck) != 32)
		{
			strcpy(passwordcheck, LOGIN_PASSWORD);
		}
	}
	else
	{
		strcpy(passwordcheck, LOGIN_PASSWORD);
	}
	#endif
	
	// start directory
	strcpy(cwd, "/");
	
	// welcome message
	swritel(conn_s, "220-OpenPS3FTP by @jjolano\r\n");
	sprintf(buffer, "220 Version %s\r\n", VERSION);
	swritel(conn_s, buffer);
	
	while(exitapp == 0 && active && (bytes = sreadl(conn_s, buffer, 1024)) > 0)
	{
		// get rid of the newline at the end of the string
		buffer[strcspn(buffer, "\n")] = '\0';
		buffer[strcspn(buffer, "\r")] = '\0';
		
		// parse received string into array
		int parameter_count = 0;
		
		char *result = strtok(buffer, " ");
		
		strcpy(client_cmd[0], result);
		
		while(parameter_count < 7 && (result = strtok(NULL, " ")) != NULL)
		{
			parameter_count++;
			strcpy(client_cmd[parameter_count], result);
		}
		
		// identify the command
		int cmd_id;
		for(cmd_id = 0; cmd_id < client_cmds_count; cmd_id++)
		{
			if(strcasecmp(client_cmd[0], client_cmds[cmd_id]) == 0)
			{
				break;
			}
		}
		
		// execute command
		if(authd == 0)
		{
			// not logged in
			
			switch(cmd_id)
			{
				case 0: // USER
					#if LOGIN_CHECK == 1
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						strcpy(user, client_cmd[1]);
						sprintf(buffer, "331 User %s OK. Password required\r\n", user);
						swritel(conn_s, buffer);
					}
					else
					{
						swritel(conn_s, "501 Please provide a username\r\n");
					}
					#else
					sprintf(buffer, "331 User %s OK. Password (not really) required\r\n", user);
					swritel(conn_s, buffer);
					#endif
					break;
				case 1: // PASS
					#if LOGIN_CHECK == 1
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						// hash the password given
						char output[33];
						md5(output, client_cmd[1]);
					
						if(strcmp(user, LOGIN_USERNAME) == 0 && strcmp(output, passwordcheck) == 0)
						{
							swritel(conn_s, "230 Successful authentication\r\n");
							authd = 1;
						}
						else
						{
							swritel(conn_s, "430 Invalid username or password - \r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Invalid username or password\r\n");
					}
					#else
					swritel(conn_s, "230 Successful authentication\r\n");
					authd = 1;
					#endif
					break;
				case 2: // QUIT
					swritel(conn_s, "221 See you later\r\n");
					active = 0;
					break;
				default: swritel(conn_s, "530 You are not logged in\r\n");
			}
		}
		else
		{
			// logged in
			
			switch(cmd_id)
			{
				case 0: // USER
				case 1: // PASS
					swritel(conn_s, "530 You are already logged in\r\n");
					break;
				case 2: // QUIT
					swritel(conn_s, "221 See you later\r\n");
					active = 0;
					break;
				case 3: // PASV
					rest = 0;
				
					netSocketInfo snf;
				
					int ret = netGetSockInfo(conn_s, &snf, 1);
				
					if(ret >= 0 && snf.local_adr.s_addr != 0)
					{
						// assign a random port for passive mode
						srand(conn_s);
						
						int rand1 = (rand() % 251) + 4;
						int rand2 = rand() % 256;
						
						sprintf(buffer, "227 Entering Passive Mode (%u,%u,%u,%u,%i,%i)\r\n",
							(snf.local_adr.s_addr & 0xFF000000) >> 24,
							(snf.local_adr.s_addr & 0xFF0000) >> 16,
							(snf.local_adr.s_addr & 0xFF00) >> 8,
							(snf.local_adr.s_addr & 0xFF),
							rand1, rand2);
						
						short int pasvport = (rand1 * 256) + rand2;
						
						struct sockaddr_in servaddr;
						memset(&servaddr, 0, sizeof(servaddr));
						servaddr.sin_family      = AF_INET;
						servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
						servaddr.sin_port        = htons(pasvport);
						
						list_s_data = netSocket(AF_INET, SOCK_STREAM, 0);
						netBind(list_s_data, (struct sockaddr *) &servaddr, sizeof(servaddr));
						netListen(list_s_data, 1);
						
						swritel(conn_s, buffer);
						
						if((conn_s_data = netAccept(list_s_data, NULL, NULL)) == -1)
						{
							swritel(conn_s, "550 PASV command failed\r\n");
						}
						else
						{
							datareq = 1;
						}
						break;
					}
		
					swritel(conn_s, "550 PASV command failed\r\n");
					break;
				case 4: // PORT
					if(parameter_count == 1)
					{
						rest = 0;
						
						char connectinfo[32];
						strcpy(connectinfo, client_cmd[1]);
						
						char data[7][4];
						int i = 0;
						
						char *result = strtok(connectinfo, ",");
	
						strcpy(data[0], result);
	
						while(i < 6 && (result = strtok(NULL, ",")) != NULL)
						{
							i++;
							strcpy(data[i], result);
						}
					
						char conn_ipaddr[16];
						sprintf(conn_ipaddr, "%s.%s.%s.%s", data[0], data[1], data[2], data[3]);
						
						struct sockaddr_in servaddr;
						memset(&servaddr, 0, sizeof(servaddr));
						servaddr.sin_family	= AF_INET;
						servaddr.sin_port	= htons((atoi(data[4]) * 256) + atoi(data[5]));
						inet_pton(AF_INET, conn_ipaddr, &servaddr.sin_addr);
						
						conn_s_data = netSocket(AF_INET, SOCK_STREAM, 0);
					
						if(connect(conn_s_data, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
						{
							swritel(conn_s, "200 PORT command successful\r\n");
							datareq = 1;
						}
						else
						{
							swritel(conn_s, "550 PORT command failed\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 5: // SITE
					if(strcasecmp(client_cmd[1], "CHMOD") == 0)
					{
						int i;
						for(i = 4; i <= parameter_count; i++)
						{
							strcat(client_cmd[3], " ");
							strcat(client_cmd[3], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[3], cwd);
					
						char perms[4];
						sprintf(perms, "0%s", client_cmd[2]);
						
						if(lv2FsChmod(filename, S_IFMT | strtol(perms, NULL, 8)) == 0)
						{
							swritel(conn_s, "250 File permissions successfully set\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to set file permissions\r\n");
						}
					}
					else
					{
						swritel(conn_s, "500 Unrecognized SITE command\r\n");
					}
					break;
				case 6: // FEAT
					swritel(conn_s, "211- Extensions supported:\r\n");
				
					int i;
					for(i = 0; i < feat_cmds_count; i++)
					{
						sprintf(buffer, " %s\r\n", feat_cmds[i]);
						swritel(conn_s, buffer);
					}
				
					swritel(conn_s, "211 End.\r\n");
					break;
				case 7: // TYPE
					swritel(conn_s, "200 TYPE command successful\r\n");
					break;
				case 8: // REST
					if(parameter_count == 1)
					{
						rest = atoi(client_cmd[1]);
						swritel(conn_s, "350 REST command successful\r\n");
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 9: // RETR
					if(parameter_count >= 1)
					{
						if(conn_s_data == -1)
						{
							swritel(conn_s, "425 No data connection\r\n");
							break;
						}
					
						swritel(conn_s, "150 Opening data connection\r\n");

						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						u64 pos;
						u64 read = -1;
					
						Lv2FsFile fd;
					
						lv2FsOpen(filename, LV2_O_RDONLY, &fd, 0, NULL, 0);
						lv2FsLSeek64(fd, (s64)rest, SEEK_SET, &pos);
					
						if(fd >= 0)
						{
							while(lv2FsRead(fd, buf, BUFFER_SIZE - 1, &read) == 0 && read > 0)
							{
								netSend(conn_s_data, buf, read, 0);
							}
						
							if(read == 0)
							{
								swritel(conn_s, "226 Transfer complete\r\n");
							}
							else
							{
								swritel(conn_s, "426 Transfer failed\r\n");
							}
						}
						else
						{
							swritel(conn_s, "452 File access error\r\n");
						}
						
						lv2FsClose(fd);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 10: // PWD
					sprintf(buffer, "257 \"%s\" is the current directory\r\n", cwd);
					swritel(conn_s, buffer);
					break;
				case 11: // CWD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						strcpy(filename, client_cmd[1]);
						
						if(strcmp(filename, "../") == 0)
						{
							for(int i = strlen(cwd) - 2; i > 0; i--)
							{
								if(cwd[i] != '/')
								{
									cwd[i] = '\0';
								}
								else
								{
									break;
								}
							}
							
							sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
							swritel(conn_s, buffer);
							break;
						}
					
						if(filename[0] == '/')
						{
							strcpy(cwd, (strlen(filename) == 1) ? "/" : filename);
						}
						else
						{
							strcat(cwd, filename);
						}
					
						if(cwd[strlen(cwd) - 1] != '/')
						{
							strcat(cwd, "/");
						}
					
						if(isDir(cwd))
						{
							sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
						}
						else
						{
							sprintf(buffer, "550 Could not change directory: %s\r\n", cwd);
						}
					
						swritel(conn_s, buffer);
					}
					else
					{
						sprintf(buffer, "257 \"%s\" is the current directory\r\n", cwd);
						swritel(conn_s, buffer);
					}
					break;
				case 12: // CDUP
					for(int i = strlen(cwd) - 2; i > 0; i--)
					{
						if(cwd[i] != '/')
						{
							cwd[i] = '\0';
						}
						else
						{
							break;
						}
					}
				
					sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
					swritel(conn_s, buffer);
					break;
				case 13: // NLST
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(buffer, "%s\r\n", ent.d_name);
							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "451 Cannot access directory\r\n");
					}
				
					lv2FsCloseDir(tempfd);
					break;
				case 14: // LIST
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
						
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%b %d %Y", tm);
						
							sprintf(buffer, "%s%s%s%s%s%s%s%s%s%s 1 root root %lu %s %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"d":"-", 
								((entry.st_mode & S_IRUSR) != 0)?"r":"-",
								((entry.st_mode & S_IWUSR) != 0)?"w":"-",
								((entry.st_mode & S_IXUSR) != 0)?"x":"-",
								((entry.st_mode & S_IRGRP) != 0)?"r":"-",
								((entry.st_mode & S_IWGRP) != 0)?"w":"-",
								((entry.st_mode & S_IXGRP) != 0)?"x":"-",
								((entry.st_mode & S_IROTH) != 0)?"r":"-",
								((entry.st_mode & S_IWOTH) != 0)?"w":"-",
								((entry.st_mode & S_IXOTH) != 0)?"x":"-",
								(long unsigned int)entry.st_size, 
								timebuf, 
								ent.d_name);

							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "451 Cannot access directory\r\n");
					}
				
					lv2FsCloseDir(tempfd);
					break;
				case 15: // STOR
					if(parameter_count >= 1)
					{
						if(conn_s_data == -1)
						{
							swritel(conn_s, "425 No data connection\r\n");
							break;
						}
						
						swritel(conn_s, "150 Opening data connection\r\n");

						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						u64 pos;
						u64 read = -1;
						u64 write = -1;
						
						Lv2FsFile fd;
					
						lv2FsOpen(filename, LV2_O_WRONLY | LV2_O_CREAT, &fd, 0, NULL, 0);
						lv2FsChmod(filename, S_IFMT | 0666);
					
						lv2FsLSeek64(fd, (s32)rest, SEEK_SET, &pos);
						
						if(fd >= 0)
						{
							while((read = (u64)netRecv(conn_s_data, buf, BUFFER_SIZE - 1, MSG_WAITALL)) > 0)
							{
								lv2FsWrite(fd, buf, read, &write);
							
								if(write != read)
								{
									break;
								}
							}
							
							if(read == 0)
							{
								swritel(conn_s, "226 Transfer complete\r\n");
							}
							else
							{
								swritel(conn_s, "426 Transfer failed\r\n");
							}
						}
						else
						{
							swritel(conn_s, "452 File access error\r\n");
						}
						
						lv2FsClose(fd);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 16: // NOOP
					swritel(conn_s, "200 Zzzz...\r\n");
					break;
				case 17: // DELE
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						if(lv2FsUnlink(filename) == 0)
						{
							swritel(conn_s, "250 File successfully deleted\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to delete file\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 18: // MKD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsMkdir(filename, 0775) == 0)
						{
							swritel(conn_s, "250 Directory successfully created\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to create directory\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 19: // RMD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsRmdir(filename) == 0)
						{
							swritel(conn_s, "250 Directory successfully deleted\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to remove directory\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 20: // RNFR
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(rnfr, client_cmd[1], cwd);
					
						if(exists(rnfr) == 0)
						{
							swritel(conn_s, "350 RNFR successful - ready for destination\r\n");
						}
						else
						{
							swritel(conn_s, "550 RNFR failed - file does not exist\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 21: // RNTO
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsRename(rnfr, filename) == 0)
						{
							swritel(conn_s, "250 File successfully renamed\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to rename file\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 22: // SIZE
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						Lv2FsStat entry;
						
						if(lv2FsStat(filename, &entry) == 0)
						{
							sprintf(buffer, "213 %lu\r\n", (long unsigned int)entry.st_size);
						}
						else
						{
							sprintf(buffer, "550 Requested file doesn't exist\r\n");
						}
					
						swritel(conn_s, buffer);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 23: // SYST
					swritel(conn_s, "215 UNIX Type: L8\r\n");
					break;
				case 24: // HELP
					swritel(conn_s, "214 No help for you.\r\n");
					break;
				case 25: // PASSWD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						// hash the password given
						char output[33];
						md5(output, client_cmd[1]);
					
						Lv2FsFile fd;
						u64 written;
					
						lv2FsOpen(PASSWORD_FPATH, LV2_O_WRONLY | LV2_O_CREAT, &fd, 0, NULL, 0);
						lv2FsWrite(fd, output, 32, &written);
						lv2FsClose(fd);
					
						swritel(conn_s, "200 Password successfully changed\r\n");
					}
					else
					{
						swritel(conn_s, "501 Invalid password\r\n");
					}
					break;
				case 26: // MLSD
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%Y%m%d%H%M%S", tm);
						
							int permint = 0;

							permint +=	(((entry.st_mode & S_IRUSR) != 0)?400:0) +
									(((entry.st_mode & S_IWUSR) != 0)?200:0) +
									(((entry.st_mode & S_IXUSR) != 0)?100:0);
						
							permint +=	(((entry.st_mode & S_IRGRP) != 0)?40:0) +
									(((entry.st_mode & S_IWGRP) != 0)?20:0) +
									(((entry.st_mode & S_IXGRP) != 0)?10:0);
						
							permint +=	(((entry.st_mode & S_IROTH) != 0)?4:0) +
									(((entry.st_mode & S_IWOTH) != 0)?2:0) +
									(((entry.st_mode & S_IXOTH) != 0)?1:0);
						
							sprintf(buffer, "type=%s;size=%lu;modify=%s;UNIX.mode=0%i;UNIX.uid=root;UNIX.gid=root; %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"dir":"file", 
								(long unsigned int)entry.st_size, 
								timebuf, 
								permint,
								ent.d_name);
						
							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "501 Directory access error\r\n");
					}

					lv2FsCloseDir(tempfd);
					break;
				case 27: // MLST
					swritel(conn_s, "250- Listing directory");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
					
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%Y%m%d%H%M%S", tm);
						
							int permint = 0;

							permint +=	(((entry.st_mode & S_IRUSR) != 0)?400:0) +
									(((entry.st_mode & S_IWUSR) != 0)?200:0) +
									(((entry.st_mode & S_IXUSR) != 0)?100:0);
						
							permint +=	(((entry.st_mode & S_IRGRP) != 0)?40:0) +
									(((entry.st_mode & S_IWGRP) != 0)?20:0) +
									(((entry.st_mode & S_IXGRP) != 0)?10:0);
						
							permint +=	(((entry.st_mode & S_IROTH) != 0)?4:0) +
									(((entry.st_mode & S_IWOTH) != 0)?2:0) +
									(((entry.st_mode & S_IXOTH) != 0)?1:0);
						
							sprintf(buffer, " type=%s;size=%lu;modify=%s;UNIX.mode=0%i;UNIX.uid=root;UNIX.gid=root; %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"dir":"file", 
								(long unsigned int)entry.st_size, 
								timebuf, 
								permint,
								ent.d_name);
						
							swritel(conn_s, buffer);
						}
					}
				
					swritel(conn_s, "250 End\r\n");
				
					lv2FsCloseDir(tempfd);
					break;
				case 28: // EXITAPP
					swritel(conn_s, "221 Exiting OpenPS3FTP, bye\r\n");
					exitapp = 1;
					break;
				case 29: // TEST
					swritel(conn_s, "211-Listing parameters\r\n");
					sprintf(buffer, "211-Count: %i\r\n", parameter_count);
					swritel(conn_s, buffer);
					
					int tx;
					for(tx = 0; tx <= parameter_count; tx++)
					{
						sprintf(buffer, " %i:%s\r\n", tx, client_cmd[tx]);
						swritel(conn_s, buffer);
					}
					
					swritel(conn_s, "211 End\r\n");
					break;
				default: swritel(conn_s, "500 Unrecognized command\r\n");
			}
			
			if(datareq == 1)
			{
				datareq = 0;
			}
			else
			{
				// close any active data connections
				if(conn_s_data > -1)
				{
					netShutdown(conn_s_data, 2);
					netClose(conn_s_data);
					conn_s_data = -1;
				}
				
				if(list_s_data > -1)
				{
					netShutdown(list_s_data, 2);
					netClose(list_s_data);
					list_s_data = -1;
				}
			}
		}
	}
Пример #11
0
ssize_t netSendPeerEvent(NetPath *netPath, const octet_t *buf, int16_t  length, TimeInternal* time)
{
	return netSend(buf, length, time, &netPath->peerMulticastAddr, netPath->eventPcb);
}
Пример #12
0
ssize_t netSendPeerGeneral(NetPath *netPath, const octet_t *buf, int16_t  length)
{
	return netSend(buf, length, NULL, &netPath->peerMulticastAddr, netPath->generalPcb);
}