Example #1
0
int main(int argc, char *argv[])
{
	int ret;
	u16 seq;
	struct network_url url;
	struct network_client client;
	struct ping_send_package pkg;
	struct icmp_header *icmp = &pkg.icmp;
	struct ping_header *ping = &pkg.ping;

	assert(argc > 1);

	url.protocol = "icmp";
	url.hostname = argv[1];
	url.port = NETWORK_PORT_INVALID;
	url.pathname = NULL;

	ret = network_client_open(&client, &url, 0);
	if (ret < 0) {
		pr_red_info("network_client_open");
		return ret;
	}

	cavan_pthread_run(ping_recv_thread, &client);

	ping->id = getpid();
	icmp->type = 8;
	icmp->code = 0;

	for (seq = 1; ; seq++) {
		ssize_t wrlen;

		ping->seq = seq;
		pkg.time = clock_gettime_ns_mono();
		icmp->checksum = 0;
		icmp->checksum = mem_checksum16(&pkg, sizeof(pkg));

		wrlen = client.send(&client, &pkg, sizeof(pkg));
		if (wrlen != sizeof(pkg)) {
			pr_red_info("client.send");
			break;
		}

		msleep(500);
	}

	network_client_close(&client);

	return 0;
}
Example #2
0
static int ftp_server_receive_file1(struct network_client *client, const struct network_url *url, int fd)
{
	int ret;

	ret = ftp_create_data_link(client, url);
	if (ret < 0)
	{
		pr_red_info("ftp_create_data_link");
		return ret;
	}

	ret = network_client_recv_file(client, fd, 0);

	network_client_close(client);

	return ret;
}
Example #3
0
static int app_network_client_main(int argc, char *argv[])
{
	int ret;
	struct network_client client;

	assert(argc > 1);

	ret = network_client_open2(&client, argv[1], CAVAN_NET_FLAG_WAIT);
	if (ret < 0) {
		pr_red_info("network_client_open2");
		return ret;
	}

	ret = app_network_cmdline(&client);

	network_client_close(&client);

	return ret;
}
Example #4
0
static void ftp_service_close_connect(struct cavan_dynamic_service *service, void *conn)
{
	network_client_close(conn);
}
Example #5
0
static int ftp_service_cmdline(struct cavan_ftp_service *service, struct network_client *client)
{
	int fd;
	int ret;
	u32 command;
	char file_type;
	const char *reply;
	char rep_pasv[64];
	struct pollfd pfds[2];
	enum cavan_ftp_state state;
	struct network_url data_url;
	ssize_t wrlen, rdlen, replen;
	struct network_client data_link;
	struct network_service data_service;
	char abs_path[1024], curr_path[1024];
	char cmd_buff[1024], rep_buff[1024], *cmd_arg, *cmd_end;

	file_type = 0;
	data_link.sockfd = -1;
	data_service.sockfd = -1;
	network_url_init(&data_url, "tcp", NULL, 0, NULL);

	replen = 0;
	reply = "220 Cavan ftp server ready.\r\n";

	state = FTP_STATE_READY;
	text_copy(curr_path, service->home);

	pfds[0].fd = -1;
	pfds[1].fd = client->sockfd;
	pfds[0].events = pfds[1].events = POLLIN;

	while (1)
	{
		if (replen == 0)
		{
			replen = strlen(reply);
		}

#if FTP_DEBUG
		println("reply = %s", reply);
#endif

		wrlen = client->send(client, reply, replen);
		if (wrlen < 0)
		{
			pr_red_info("inet_send_text");
			goto out_close_data_link;
		}

		replen = 0;
		reply = rep_buff;

label_poll:
		ret = poll(pfds, NELEM(pfds), FTP_TIMEOUT_MS);
		if (ret < 1)
		{
			if (ret < 0)
			{
				pr_error_info("poll");
				goto out_close_data_link;
			}

			goto label_poll;
		}

		if (pfds[0].revents == POLLIN)
		{
			if (data_link.sockfd >= 0)
			{
				network_client_close(&data_link);
			}

			ret = network_service_accept(&data_service, &data_link);
			if (ret < 0)
			{
				pr_red_info("network_service_accept");
				goto out_network_service_close;
			}

			if (pfds[1].revents != POLLIN)
			{
				goto label_poll;
			}
		}

		rdlen = client->recv(client, cmd_buff, sizeof(cmd_buff) - 1);
		if (rdlen < 3)
		{
			goto out_close_data_link;
		}

		for (cmd_end = cmd_buff + rdlen - 1; cmd_end > cmd_buff && byte_is_lf(*cmd_end); cmd_end--);

		*++cmd_end = 0;

		for (cmd_arg = cmd_buff; cmd_arg < cmd_end && !byte_is_space(*cmd_arg); cmd_arg++);

		while ( cmd_arg < cmd_end && byte_is_space(*cmd_arg))
		{
			*cmd_arg++ = 0;
		}

#if FTP_DEBUG
		println("command = `%s', args = `%s'", cmd_buff, cmd_arg);
#endif

		command = *(u32 *) cmd_buff;

		switch (command)
		{
		case FTP_BUILD_CMD('q', 'u', 'i', 't'):
		case FTP_BUILD_CMD('Q', 'U', 'I', 'T'):
			network_client_send_text(client, "221 Goodbye.\r\n");
			return 0;

		case FTP_BUILD_CMD('u', 's', 'e', 'r'):
		case FTP_BUILD_CMD('U', 'S', 'E', 'R'):
			if (state < FTP_STATE_USER_RECVED)
			{
				state = FTP_STATE_USER_RECVED;
				reply = "331 Please input password.\r\n";
			}
			else
			{
				reply = "331 Any password will do.\r\n";
			}

			break;

		case FTP_BUILD_CMD('p', 'a', 's', 's'):
		case FTP_BUILD_CMD('P', 'A', 'S', 'S'):
			if (state < FTP_STATE_USER_RECVED)
			{
				reply = "530 Please input username.\r\n";
			}
			else if (state < FTP_STATE_LOGINED)
			{
				state = FTP_STATE_LOGINED;
				reply = "230 User login successfull.\r\n";
			}
			else
			{
				reply = "230 Alreay logged in.\r\n";
			}

			break;

		default:
			if (state < FTP_STATE_LOGINED)
			{
				if (state < FTP_STATE_USER_RECVED)
				{
					reply = "530 Please login with USER and PASS.\r\n";
				}
				else
				{
					reply = "530 Please login with PASS.\r\n";
				}

				break;
			}

			switch (command)
			{
			case FTP_BUILD_CMD('p', 'o', 'r', 't'):
			case FTP_BUILD_CMD('P', 'O', 'R', 'T'):
			{
				int temp[6];

				ret = sscanf(cmd_arg, "%d,%d,%d,%d,%d,%d", temp, temp + 1, temp + 2, temp + 3, temp + 4, temp + 5);
				if (ret == 6)
				{
					snprintf(data_url.memory, sizeof(data_url.memory), "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
					data_url.hostname = data_url.memory;
					data_url.port = temp[4] << 8 | temp[5];
					reply = "200 PORT command complete.\r\n";
				}
				else
				{
					reply = "501 Argument error.\r\n";
				}

				break;
			}

			case FTP_BUILD_CMD('o', 'p', 't', 's'):
			case FTP_BUILD_CMD('O', 'P', 'T', 'S'):
				reply = "200 OPTS command complete.\r\n";
				break;

			case FTP_BUILD_CMD('p', 'w', 'd', 0):
			case FTP_BUILD_CMD('P', 'W', 'D', 0):
			case FTP_BUILD_CMD('x', 'p', 'w', 'd'):
			case FTP_BUILD_CMD('X', 'P', 'W', 'D'):
				replen = snprintf(rep_buff, sizeof(rep_buff), "257 \"%s\"\r\n", curr_path);
				break;

			case FTP_BUILD_CMD('t', 'y', 'p', 'e'):
			case FTP_BUILD_CMD('T', 'Y', 'P', 'E'):
				reply = "200 TYPE commnd complete.\r\n";
				file_type = cmd_buff[5];
				break;

			case FTP_BUILD_CMD('s', 'y', 's', 't'):
			case FTP_BUILD_CMD('S', 'Y', 'S', 'T'):
				reply = "215 UNIX Type L8.\r\n";
				break;

			case FTP_BUILD_CMD('c', 'w', 'd', 0):
			case FTP_BUILD_CMD('C', 'W', 'D', 0):
			case FTP_BUILD_CMD('x', 'c', 'w', 'd'):
			case FTP_BUILD_CMD('X', 'C', 'W', 'D'):
				if (*cmd_arg)
				{
					ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path));
					if (access(abs_path, F_OK) < 0)
					{
						reply = "550 Failed to change directory.\r\n";
						break;
					}

					prettify_pathname_base(abs_path, curr_path, sizeof(curr_path));
				}
				else
				{
					text_copy(curr_path, service->home);
				}

				reply = "250 CWD commnd complete.\r\n";
				break;

			case FTP_BUILD_CMD('l', 'i', 's', 't'):
			case FTP_BUILD_CMD('L', 'I', 'S', 'T'):
				if (data_link.sockfd < 0 && data_url.port == 0)
				{
					reply = "550 Please run PORT or PASV first.\r\n";
					break;
				}

				fd = ftp_list_directory1(curr_path, file_type == 'I' ? "\n" : "\r\n");
				if (fd < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 List directory failed: %s.\r\n", strerror(errno));
					break;
				}

				wrlen = network_client_send_text(client, "150 List directory complete.\r\n");
				if (wrlen < 0)
				{
					pr_red_info("ftp_send_text");
					close(fd);
					goto out_close_data_link;
				}

				ret = ftp_server_send_file1(&data_link, &data_url, fd);
				close(fd);

				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 Send list failed: %s.\r\n", strerror(errno));
				}
				else
				{
					reply = "226 List send complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('s', 'i', 'z', 'e'):
			case FTP_BUILD_CMD('S', 'I', 'Z', 'E'):
			{
				struct stat st;

				if (*cmd_arg == 0 || stat(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)), &st))
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 get file size failed: %s.\r\n", strerror(errno));
				}
				else
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "213 %" PRINT_FORMAT_OFF "\r\n", st.st_size);
				}

				break;
			}

			case FTP_BUILD_CMD('r', 'e', 't', 'r'):
			case FTP_BUILD_CMD('R', 'E', 'T', 'R'):
				fd = open(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)), O_RDONLY);
				if (fd < 0)
				{
					reply = "550 Open file failed.\r\n";
					break;
				}

				wrlen = network_client_send_text(client, "125 Starting transfer\r\n");
				if (wrlen < 0)
				{
					pr_red_info("network_client_send_text");
					close(fd);
					goto out_close_data_link;
				}

				ret = ftp_server_send_file1(&data_link, &data_url, fd);
				close(fd);

				if (ret < 0)
				{
					reply = "550 Send file failed.\r\n";
				}
				else
				{
					reply = "226 Transfer complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('s', 't', 'o', 'r'):
			case FTP_BUILD_CMD('S', 'T', 'O', 'R'):
				fd = open(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)), O_WRONLY | O_CREAT, 0777);
				if (fd < 0)
				{
					reply = "550 Open file failed.\r\n";
					break;
				}

				wrlen = network_client_send_text(client, "125 Starting transfer\r\n");
				if (wrlen < 0)
				{
					pr_error_info("ftp_send_text");
					close(fd);
					goto out_close_data_link;
				}

				ret = ftp_server_receive_file1(&data_link, &data_url, fd);
				close(fd);

				if (ret < 0)
				{
					reply = "550 Receive file failed.\r\n";
				}
				else
				{
					reply = "226 Transfer complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('p', 'a', 's', 'v'):
			case FTP_BUILD_CMD('P', 'A', 'S', 'V'):
				if (data_service.sockfd < 0)
				{
					ret = ftp_data_service_open(&data_service, client, rep_pasv, sizeof(rep_pasv));
					if (ret < 0)
					{
						pr_red_info("ftp_data_service_open");
						return ret;
					}

					replen = ret;
					pfds[0].fd = data_service.sockfd;
				}

				reply = rep_pasv;
				break;

			case FTP_BUILD_CMD('d', 'e', 'l', 'e'):
			case FTP_BUILD_CMD('D', 'E', 'L', 'E'):
				ret = remove(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)));
				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 remove %s failed: %s.\r\n", cmd_arg, strerror(errno));
				}
				else
				{
					reply = "200 DELE command complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('r', 'm', 'd', 0):
			case FTP_BUILD_CMD('R', 'M', 'D', 0):
				ret = rmdir(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)));
				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 remove %s failed: %s.\r\n", cmd_arg, strerror(errno));
				}
				else
				{
					reply = "200 DELE command complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('m', 'k', 'd', 0):
			case FTP_BUILD_CMD('M', 'K', 'D', 0):
				ret = mkdir(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)), 0777);
				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 create directory %s failed: %s.\r\n", cmd_arg, strerror(errno));
				}
				else
				{
					reply = "200 MKD command complete.\r\n";
				}

				break;

			case FTP_BUILD_CMD('m', 'd', 't', 'm'):
			case FTP_BUILD_CMD('M', 'D', 'T', 'M'):
			{
				struct stat st;

				ret = stat(ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path)), &st);
				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 get file stat failed: %s.\r\n", strerror(errno));
				}
				else
				{
					struct tm ti;

					if (localtime_r((time_t *) &st.st_atime, &ti) == NULL)
					{
						replen = snprintf(rep_buff, sizeof(rep_buff), "550 get localtime failed: %s.\r\n", strerror(errno));
					}
					else
					{
						replen = snprintf(rep_buff, sizeof(rep_buff), "213 %04d%02d%02d%02d%02d%02d\r\n", \
							ti.tm_year + 1900, ti.tm_mon + 1, ti.tm_mday, ti.tm_hour, ti.tm_min, ti.tm_sec);
					}
				}

				break;
			}

			case FTP_BUILD_CMD('n', 'o', 'o', 'p'):
			case FTP_BUILD_CMD('N', 'O', 'O', 'P'):
				reply = "200 NOOP commnd complete.\r\n";
				break;

			case FTP_BUILD_CMD('r', 'n', 'f', 'r'):
			case FTP_BUILD_CMD('R', 'N', 'F', 'R'):
			{
				char rnfr_path[1024];

				ftp_get_abs_path(curr_path, cmd_arg, rnfr_path, sizeof(rnfr_path));
				reply = "350 RNFR command complete.\r\n";
				break;
			}

			case FTP_BUILD_CMD('r', 'n', 't', 'o'):
			case FTP_BUILD_CMD('R', 'N', 'T', 'O'):
			{
				char rnfr_path[1024];

				ftp_get_abs_path(curr_path, cmd_arg, abs_path, sizeof(abs_path));
				ret = rename(rnfr_path, abs_path);
				if (ret < 0)
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "550 Rename %s to %s failed[%s].\r\n", rnfr_path, abs_path, strerror(errno));
				}
				else
				{
					replen = snprintf(rep_buff, sizeof(rep_buff), "250 Rename %s to %s successfully.\r\n", rnfr_path, abs_path);
				}

				break;
			}

			case FTP_BUILD_CMD('s', 'i', 't', 'e'):
			case FTP_BUILD_CMD('S', 'I', 'T', 'E'):
				command = *(u32 *) cmd_arg;
				switch (command)
				{
				case FTP_BUILD_CMD('h', 'e', 'l', 'p'):
				case FTP_BUILD_CMD('H', 'E', 'L', 'P'):
					reply = "214 UNMASK HELP\r\n";
					break;

				default:
					goto label_unsupport_command;
				}

				break;

			case FTP_BUILD_CMD('f', 'e', 'a', 't'):
			case FTP_BUILD_CMD('F', 'E', 'A', 'T'):
				reply = "211 MDTM SIZE PASV PORT RNTO MKD RMD DELE RETR STOR\r\n";
				break;

			default:
label_unsupport_command:
				pr_red_info("unsupport command: `%s'", cmd_buff);
				reply = "500 Unknown command.\r\n";
			}
		}
	}

out_close_data_link:
	if (data_link.sockfd >= 0)
	{
		network_client_close(&data_link);
	}
out_network_service_close:
	if (data_service.sockfd >= 0)
	{
		network_service_close(&data_service);
	}
	return 0;
}
Example #6
0
int ftp_client_run(struct network_url *url, const char *username, const char *password)
{
	int ret;
	char buff[1024], *p;
	ssize_t wrlen, rdlen;
	struct network_client client;

	ret = network_client_open(&client, url, 0);
	if (ret < 0)
	{
		pr_red_info("network_client_open");
		return ret;
	}

	ret = ftp_client_login(&client, username, password);
	if (ret < 0)
	{
		pr_red_info("ftp_client_login");
		return ret;
	}

	while (1)
	{
		while (1)
		{
			print("cavan-ftp> ");

			for (p = buff; (*p = getchar()) != '\n'; p++);

			if (p > buff)
			{
				p = text_copy(p, "\r\n");
				break;
			}
		}

		if (text_lhcmp("ls", buff) == 0)
		{
			println("list command");
			ftp_client_receive_file(&client, url->hostname, 6789);
		}
		else
		{
			wrlen = client.send(&client, buff, p - buff);
			if (wrlen < 0)
			{
				pr_red_info("inet_send");
				ret = wrlen;
				break;
			}
		}

		rdlen = client.recv(&client, buff, sizeof(buff));
		if (rdlen < 0)
		{
			pr_red_info("client.recv");
			ret = rdlen;
			break;
		}

		buff[rdlen] = 0;
		println("%s", buff);
	}

	network_client_close(&client);

	return ret;
}