Line data Source code
1 : /* 2 : * Copyright (c) 2020 Cisco and/or its affiliates. 3 : * Licensed under the Apache License, Version 2.0 (the "License"); 4 : * you may not use this file except in compliance with the License. 5 : * You may obtain a copy of the License at: 6 : * 7 : * http://www.apache.org/licenses/LICENSE-2.0 8 : * 9 : * Unless required by applicable law or agreed to in writing, software 10 : * distributed under the License is distributed on an "AS IS" BASIS, 11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : * See the License for the specific language governing permissions and 13 : * limitations under the License. 14 : */ 15 : 16 : #ifndef included_vnet_mpcap_h 17 : #define included_vnet_mpcap_h 18 : 19 : #include <vnet/vnet.h> 20 : #include <vppinfra/mpcap.h> 21 : 22 : /** 23 : * @brief Add packet 24 : * 25 : * @param *pm - mpcap_main_t 26 : * @param time_now - f64 27 : * @param n_bytes_in_trace - u32 28 : * @param n_bytes_in_packet - u32 29 : * 30 : * @return Packet Data 31 : * 32 : */ 33 : static inline void * 34 15 : mpcap_add_packet (mpcap_main_t * pm, 35 : f64 time_now, u32 n_bytes_in_trace, u32 n_bytes_in_packet) 36 : { 37 : mpcap_packet_header_t *h; 38 : u8 *d; 39 : 40 : /* File already closed? */ 41 15 : if (PREDICT_FALSE (pm->flags & MPCAP_FLAG_INIT_DONE) == 0) 42 0 : return 0; 43 : 44 15 : d = pm->current_va; 45 15 : pm->current_va += sizeof (h[0]) + n_bytes_in_trace; 46 : 47 : /* Out of space? */ 48 15 : if (PREDICT_FALSE (pm->current_va >= pm->file_baseva + pm->max_file_size)) 49 0 : return 0; 50 15 : h = (void *) (d); 51 15 : h->time_in_sec = time_now; 52 15 : h->time_in_usec = 1e6 * (time_now - h->time_in_sec); 53 15 : h->n_packet_bytes_stored_in_file = n_bytes_in_trace; 54 15 : h->n_bytes_in_packet = n_bytes_in_packet; 55 15 : pm->n_packets_captured++; 56 15 : return h->data; 57 : } 58 : 59 : /** 60 : * @brief Add buffer (vlib_buffer_t) to the trace 61 : * 62 : * @param *pm - mpcap_main_t 63 : * @param *vm - vlib_main_t 64 : * @param time_now - f64 65 : * @param buffer_index - u32 66 : * @param n_bytes_in_trace - u32 67 : * 68 : */ 69 : static inline void 70 15 : mpcap_add_buffer (mpcap_main_t * pm, 71 : vlib_main_t * vm, 72 : f64 time_now, u32 buffer_index, u32 n_bytes_in_trace) 73 : { 74 15 : vlib_buffer_t *b = vlib_get_buffer (vm, buffer_index); 75 15 : u32 n = vlib_buffer_length_in_chain (vm, b); 76 15 : i32 n_left = clib_min (n_bytes_in_trace, n); 77 : void *d; 78 : 79 15 : clib_spinlock_lock_if_init (&pm->lock); 80 : 81 15 : d = mpcap_add_packet (pm, time_now, n_left, n); 82 15 : if (PREDICT_FALSE (d == 0)) 83 : { 84 0 : mpcap_close (pm); 85 0 : clib_spinlock_unlock_if_init (&pm->lock); 86 0 : return; 87 : } 88 : 89 : while (1) 90 0 : { 91 15 : u32 copy_length = clib_min ((u32) n_left, b->current_length); 92 15 : clib_memcpy (d, b->data + b->current_data, copy_length); 93 15 : n_left -= b->current_length; 94 15 : if (n_left <= 0) 95 15 : break; 96 0 : d += b->current_length; 97 0 : ASSERT (b->flags & VLIB_BUFFER_NEXT_PRESENT); 98 0 : b = vlib_get_buffer (vm, b->next_buffer); 99 : } 100 15 : if (pm->n_packets_captured >= pm->n_packets_to_capture) 101 1 : mpcap_close (pm); 102 : 103 15 : clib_spinlock_unlock_if_init (&pm->lock); 104 : } 105 : #endif /* included_vnet_mpcap_h */ 106 : 107 : /* 108 : * fd.io coding-style-patch-verification: ON 109 : * 110 : * Local Variables: 111 : * eval: (c-set-style "gnu") 112 : * End: 113 : */