1 //#include <sys/param.h> 2 #include <stdio.h> 3 4 #include <net/if.h> 5 #include <netinet/in.h> 6 #include <sys/param.h> 7 #include <sys/errno.h> 8 #include <sys/linker.h> 9 #include <sys/ioctl.h> 10 #include <sys/nv.h> 11 #include <sys/socket.h> 12 #include <sys/sockio.h> 13 14 #include <atf-c.h> 15 16 #define OVPN_NEW_PEER _IO ('D', 1) 17 18 static nvlist_t * 19 fake_sockaddr(void) 20 { 21 uint32_t addr = htonl(INADDR_LOOPBACK); 22 nvlist_t *nvl; 23 24 nvl = nvlist_create(0); 25 26 nvlist_add_number(nvl, "af", AF_INET); 27 nvlist_add_binary(nvl, "address", &addr, 4); 28 nvlist_add_number(nvl, "port", 1024); 29 30 return (nvl); 31 } 32 33 static char ovpn_ifname[IFNAMSIZ]; 34 static int ovpn_fd; 35 36 static int 37 create_interface(int fd) 38 { 39 int ret; 40 struct ifreq ifr; 41 42 bzero(&ifr, sizeof(ifr)); 43 44 /* Create ovpnx first, then rename it. */ 45 snprintf(ifr.ifr_name, IFNAMSIZ, "ovpn"); 46 ret = ioctl(fd, SIOCIFCREATE2, &ifr); 47 if (ret) 48 return (ret); 49 50 snprintf(ovpn_ifname, IFNAMSIZ, "%s", ifr.ifr_name); 51 printf("Created %s\n", ovpn_ifname); 52 53 return (0); 54 } 55 56 static void 57 destroy_interface(int fd) 58 { 59 int ret; 60 struct ifreq ifr; 61 62 if (ovpn_ifname[0] == 0) 63 return; 64 65 printf("Destroy %s\n", ovpn_ifname); 66 67 bzero(&ifr, sizeof(ifr)); 68 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", ovpn_ifname); 69 70 ret = ioctl(fd, SIOCIFDESTROY, &ifr); 71 if (ret) 72 atf_tc_fail("Failed to destroy interface"); 73 74 ovpn_ifname[0] = 0; 75 } 76 77 ATF_TC_WITH_CLEANUP(tcp); 78 ATF_TC_HEAD(tcp, tc) 79 { 80 atf_tc_set_md_var(tc, "require.user", "root"); 81 } 82 83 ATF_TC_BODY(tcp, tc) 84 { 85 struct ifdrv drv; 86 struct sockaddr_in sock_in; 87 int ret; 88 nvlist_t *nvl; 89 90 /* Ensure the module is loaded. */ 91 if (kldfind("if_ovpn") == -1 && errno == ENOENT) 92 atf_tc_skip("if_ovpn not loaded"); 93 94 ovpn_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); 95 96 /* Kick off a connect so there's a local address set, which we need for 97 * ovpn_new_peer() to get to the critical point. */ 98 bzero(&sock_in, sizeof(sock_in)); 99 sock_in.sin_family = AF_INET; 100 sock_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 101 sock_in.sin_port = htons(1024); 102 connect(ovpn_fd, (struct sockaddr *)&sock_in, sizeof(sock_in)); 103 104 ret = create_interface(ovpn_fd); 105 if (ret) 106 atf_tc_fail("Failed to create interface"); 107 108 nvl = nvlist_create(0); 109 110 nvlist_add_number(nvl, "peerid", 0); 111 nvlist_add_number(nvl, "fd", ovpn_fd); 112 nvlist_add_nvlist(nvl, "remote", fake_sockaddr()); 113 114 bzero(&drv, sizeof(drv)); 115 snprintf(drv.ifd_name, IFNAMSIZ, "%s", ovpn_ifname); 116 drv.ifd_cmd = OVPN_NEW_PEER; 117 drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len); 118 119 ret = ioctl(ovpn_fd, SIOCSDRVSPEC, &drv); 120 ATF_CHECK_EQ(ret, -1); 121 ATF_CHECK_EQ(errno, EPROTOTYPE); 122 } 123 124 ATF_TC_CLEANUP(tcp, tc) 125 { 126 destroy_interface(ovpn_fd); 127 close(ovpn_fd); 128 } 129 130 ATF_TP_ADD_TCS(tp) 131 { 132 ATF_TP_ADD_TC(tp, tcp); 133 134 return (atf_no_error()); 135 } 136