1 /* $NetBSD: npf_test_subr.c,v 1.6 2013/11/08 00:38:27 rmind Exp $ */ 2 3 /* 4 * NPF initialisation and handler routines. 5 * 6 * Public Domain. 7 */ 8 9 #include <sys/types.h> 10 #include <net/if.h> 11 #include <net/if_types.h> 12 13 #include "npf_impl.h" 14 #include "npf_test.h" 15 16 /* State of the current stream. */ 17 static npf_state_t cstream_state; 18 static void * cstream_ptr; 19 static bool cstream_retval; 20 21 static void npf_state_sample(npf_state_t *, bool); 22 23 void 24 npf_test_init(void) 25 { 26 npf_state_setsampler(npf_state_sample); 27 } 28 29 int 30 npf_test_load(const void *xml) 31 { 32 prop_dictionary_t npf_dict = prop_dictionary_internalize(xml); 33 return npfctl_reload(0, npf_dict); 34 } 35 36 ifnet_t * 37 npf_test_addif(const char *ifname, bool reg, bool verbose) 38 { 39 ifnet_t *ifp = if_alloc(IFT_OTHER); 40 41 /* 42 * This is a "fake" interface with explicitly set index. 43 * Note: test modules may not setup pfil(9) hooks and if_attach() 44 * may not trigger npf_ifmap_attach(), so we call it manually. 45 */ 46 strlcpy(ifp->if_xname, ifname, sizeof(ifp->if_xname)); 47 ifp->if_dlt = DLT_NULL; 48 ifp->if_index = 0; 49 if_attach(ifp); 50 if_alloc_sadl(ifp); 51 52 npf_ifmap_attach(ifp); 53 if (reg) { 54 npf_ifmap_register(ifname); 55 } 56 57 if (verbose) { 58 printf("+ Interface %s\n", ifname); 59 } 60 return ifp; 61 } 62 63 ifnet_t * 64 npf_test_getif(const char *ifname) 65 { 66 return ifunit(ifname); 67 } 68 69 /* 70 * State sampler - this routine is called from inside of NPF state engine. 71 */ 72 static void 73 npf_state_sample(npf_state_t *nst, bool retval) 74 { 75 /* Pointer will serve as an ID. */ 76 cstream_ptr = nst; 77 memcpy(&cstream_state, nst, sizeof(npf_state_t)); 78 cstream_retval = retval; 79 } 80 81 int 82 npf_test_statetrack(const void *data, size_t len, ifnet_t *ifp, 83 bool forw, int64_t *result) 84 { 85 struct mbuf *m; 86 int i = 0, error; 87 88 m = mbuf_getwithdata(data, len); 89 error = npf_packet_handler(NULL, &m, ifp, forw ? PFIL_OUT : PFIL_IN); 90 if (error) { 91 assert(m == NULL); 92 return error; 93 } 94 assert(m != NULL); 95 m_freem(m); 96 97 const int di = forw ? NPF_FLOW_FORW : NPF_FLOW_BACK; 98 npf_tcpstate_t *fstate = &cstream_state.nst_tcpst[di]; 99 npf_tcpstate_t *tstate = &cstream_state.nst_tcpst[!di]; 100 101 result[i++] = (intptr_t)cstream_ptr; 102 result[i++] = cstream_retval; 103 result[i++] = cstream_state.nst_state; 104 105 result[i++] = fstate->nst_end; 106 result[i++] = fstate->nst_maxend; 107 result[i++] = fstate->nst_maxwin; 108 result[i++] = fstate->nst_wscale; 109 110 result[i++] = tstate->nst_end; 111 result[i++] = tstate->nst_maxend; 112 result[i++] = tstate->nst_maxwin; 113 result[i++] = tstate->nst_wscale; 114 115 return 0; 116 } 117