/* * Open a Port from Internet to a local process on FRITZ!Box * */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include "extern.h" #include "port_open.h" typedef unsigned char u8; typedef unsigned short u16; /* ---------------------------------------------------------------- */ /* ------- /dev/kdsld_misc */ /* ---------------------------------------------------------------- */ #pragma pack(1) struct kdslinterface_port_ipv4_open { unsigned traffic_class; u16 port; u8 protocol; u8 autoclose; }; struct kdslinterface_port_ipv4_close { unsigned traffic_class; u16 port; u8 protocol; }; struct kdslinterface_port_ipv6_open { unsigned traffic_class; u16 port; u8 protocol; u8 autoclose; }; struct kdslinterface_port_ipv6_close { unsigned traffic_class; u16 port; u8 protocol; }; #pragma pack() #define KDSLD_PORT_IPV4_OPEN _IOW('D',0x00, struct kdslinterface_port_ipv4_open) #define KDSLD_PORT_IPV4_CLOSE _IOW('D',0x01, struct kdslinterface_port_ipv4_close) #define KDSLD_PORT_IPV6_OPEN _IOW('D',0x02, struct kdslinterface_port_ipv6_open) #define KDSLD_PORT_IPV6_CLOSE _IOW('D',0x03, struct kdslinterface_port_ipv6_close) static int dev_open(void) { int fd = open("/dev/kdsld_misc", O_RDWR | O_NONBLOCK); if (fd >= 0) return fd; fd = open("/dev/kdsld_port", O_RDWR | O_NONBLOCK); return fd; } int OpenIPv4TCPPort(unsigned short port) { int ret; int fd = dev_open(); if (fd < 0) { Log(("OpenIPv4TCPPort devopen failed")); return -EBADF; } struct kdslinterface_port_ipv4_open args; memset(&args, 0, sizeof(args)); args.traffic_class = 0; args.protocol = IPPROTO_TCP; args.port = htons(port); args.autoclose = 1; ret = ioctl(fd, KDSLD_PORT_IPV4_OPEN, &args); if (ret != 0) ret = -errno; close(fd); Log(("OpenIPv4TCPPort port=%u ret=%d", port, ret)); return ret; } int CloseIPv4TCPPort(unsigned short port) { int ret; int fd = dev_open(); if (fd < 0) { Log(("CloseIPv4TCPPort dev open failed")); return -EBADF; } struct kdslinterface_port_ipv4_close args; memset(&args, 0, sizeof(args)); args.traffic_class = 0; args.protocol = IPPROTO_TCP; args.port = htons(port); ret = ioctl(fd, KDSLD_PORT_IPV4_CLOSE, &args); if (ret != 0) ret = -errno; close(fd); Log(("CloseIPv4TCPPort port=%u ret=%d", port, ret)); return ret; } #ifdef USE_IPV6 int OpenIPv6TCPPort(unsigned short port) { int ret; int fd = dev_open(); if (fd < 0) return -EBADF; struct kdslinterface_port_ipv6_open args; memset(&args, 0, sizeof(args)); args.traffic_class = 0; args.protocol = IPPROTO_TCP; args.port = htons(port); args.autoclose = 1; ret = ioctl(fd, KDSLD_PORT_IPV6_OPEN, &args); if (ret != 0) ret = -errno; close(fd); return ret; } int CloseIPv6TCPPort(unsigned short port) { int ret; int fd = dev_open(); if (fd < 0) return -EBADF; struct kdslinterface_port_ipv6_close args; memset(&args, 0, sizeof(args)); args.traffic_class = 0; args.protocol = IPPROTO_TCP; args.port = htons(port); ret = ioctl(fd, KDSLD_PORT_IPV6_CLOSE, &args); if (ret != 0) ret = -errno; close(fd); return ret; } #endif