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 (void)kldload("if_ovpn"); 92 93 ovpn_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); 94 95 /* Kick off a connect so there's a local address set, which we need for 96 * ovpn_new_peer() to get to the critical point. */ 97 bzero(&sock_in, sizeof(sock_in)); 98 sock_in.sin_family = AF_INET; 99 sock_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 100 sock_in.sin_port = htons(1024); 101 connect(ovpn_fd, (struct sockaddr *)&sock_in, sizeof(sock_in)); 102 103 ret = create_interface(ovpn_fd); 104 if (ret) 105 atf_tc_fail("Failed to create interface"); 106 107 nvl = nvlist_create(0); 108 109 nvlist_add_number(nvl, "peerid", 0); 110 nvlist_add_number(nvl, "fd", ovpn_fd); 111 nvlist_add_nvlist(nvl, "remote", fake_sockaddr()); 112 113 bzero(&drv, sizeof(drv)); 114 snprintf(drv.ifd_name, IFNAMSIZ, "%s", ovpn_ifname); 115 drv.ifd_cmd = OVPN_NEW_PEER; 116 drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len); 117 118 ret = ioctl(ovpn_fd, SIOCSDRVSPEC, &drv); 119 ATF_CHECK_EQ(ret, -1); 120 ATF_CHECK_EQ(errno, EPROTOTYPE); 121 } 122 123 ATF_TC_CLEANUP(tcp, tc) 124 { 125 destroy_interface(ovpn_fd); 126 close(ovpn_fd); 127 } 128 129 ATF_TP_ADD_TCS(tp) 130 { 131 ATF_TP_ADD_TC(tp, tcp); 132 133 return (atf_no_error()); 134 } 135