Исходники tcpdrop под Solaris

В рассылке нашёл исходники автора Youzhong Yang. Привожу как есть, используйте на свой страх и риск.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <inet/tcp.h>
#include <arpa/inet.h>
#include <sys/socket_impl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
/* the following function is from illumos-gate:
http://src.illumos.org/source/xref/illumos-gate/usr/src/cmd/zoneadmd/vplat.c#3169
*/
static int
tcp_abort_conn(zoneid_t zoneid,
const struct sockaddr_storage *local, const struct sockaddr_storage *remote)
{
int fd;
struct strioctl ioc;
tcp_ioc_abort_conn_t conn;
int error;

	conn.ac_local = *local;
conn.ac_remote = *remote;
conn.ac_start = TCPS_SYN_SENT;
conn.ac_end = TCPS_TIME_WAIT;
conn.ac_zoneid = zoneid;

ioc.ic_cmd = TCP_IOC_ABORT_CONN;
ioc.ic_timout = -1; /* infinite timeout */
ioc.ic_len = sizeof (conn);
ioc.ic_dp = (char *)&conn;

if ((fd = open("/dev/tcp", O_RDONLY)) < 0) {
fprintf(stderr, "unable to open %s\n", "/dev/tcp");
return (-1);
}

error = ioctl(fd, I_STR, &ioc);
printf("ioctl = %d, errno = %d\n", error, errno);
(void) close(fd);
if (error == 0 || errno == ENOENT)/* ENOENT is not an error */
return (0);
return (-1);
}

void print_usage(char *argv[])
{
printf("USAGE:\n");
printf("    %s -l local_ip -s local_port -r remote_ip -d remote_port -z zone_id\n\n", argv[0]);
}

int main(int argc, char *argv[])
{
int c;
int ret;
char *s_local_ip, *s_remote_ip, *s_local_port, *s_remote_port, *s_zoneid;
struct in_addr local_ip, remote_ip;
int local_port, remote_port;
zoneid_t zoneid;
struct sockaddr_storage l, r;
struct sockaddr_in *local, *remote;
int error;

s_local_ip = "0.0.0.0";
s_remote_ip = "0.0.0.0";
s_local_port = "0";
s_remote_port = "0";
s_zoneid = "0";
local_ip.s_addr = INADDR_ANY;
remote_ip.s_addr = INADDR_ANY;
local_port = 0;
remote_port = 0;
zoneid = 0;

while ((c = getopt(argc, argv, ":l:s:r:d:z:")) != -1) {
switch(c) {
case 'l':
s_local_ip = optarg; break;
case 's':
s_local_port = optarg; break;
case 'r':
s_remote_ip = optarg; break;
case 'd':
s_remote_port = optarg; break;
case 'z':
s_zoneid = optarg; break;
case ':':
printf("-%c without arg\n", optopt);
exit(1);
break;
}
}

if(argc == 1) {
print_usage(argv);
exit(1);
}

ret = inet_pton(AF_INET, s_local_ip, &local_ip);
printf("inet_pton = %d, addr = 0x%x\n", ret, local_ip.s_addr);
if(ret != 1) {
print_usage(argv);
exit(1);
}

ret = inet_pton(AF_INET, s_remote_ip, &remote_ip);
printf("inet_pton = %d, addr = 0x%x\n", ret, remote_ip.s_addr);
if(ret != 1) {
print_usage(argv);
exit(1);
}

local_port = atoi(s_local_port);
remote_port = atoi(s_remote_port);
zoneid = atoi(s_zoneid);

printf("local ip = %s\n", s_local_ip);
printf("local port = %d\n", local_port);
printf("remote ip = %s\n", s_remote_ip);
printf("remote port = %d\n", remote_port);
printf("zone id = %d\n", zoneid);

bzero(&l, sizeof(*local));
local = (struct sockaddr_in *) &l;
local->sin_family = AF_INET;
local->sin_addr = local_ip;
local->sin_port = htons(local_port);

bzero(&r, sizeof(*remote));
remote = (struct sockaddr_in *) &r;
remote->sin_family = AF_INET;
remote->sin_addr = remote_ip;
remote->sin_port = htons(remote_port);

	error = tcp_abort_conn(zoneid, &l, &r);

	printf("tcp_abort_conn = %d\n", error);

	return 0;
}

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *