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