qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

replay-net.c (2502B)


      1 /*
      2  * replay-net.c
      3  *
      4  * Copyright (c) 2010-2016 Institute for System Programming
      5  *                         of the Russian Academy of Sciences.
      6  *
      7  * This work is licensed under the terms of the GNU GPL, version 2 or later.
      8  * See the COPYING file in the top-level directory.
      9  *
     10  */
     11 
     12 #include "qemu/osdep.h"
     13 #include "qemu/error-report.h"
     14 #include "sysemu/replay.h"
     15 #include "replay-internal.h"
     16 #include "net/net.h"
     17 #include "net/filter.h"
     18 #include "qemu/iov.h"
     19 
     20 struct ReplayNetState {
     21     NetFilterState *nfs;
     22     int id;
     23 };
     24 
     25 typedef struct NetEvent {
     26     uint8_t id;
     27     uint32_t flags;
     28     uint8_t *data;
     29     size_t size;
     30 } NetEvent;
     31 
     32 static NetFilterState **network_filters;
     33 static int network_filters_count;
     34 
     35 ReplayNetState *replay_register_net(NetFilterState *nfs)
     36 {
     37     ReplayNetState *rns = g_new0(ReplayNetState, 1);
     38     rns->nfs = nfs;
     39     rns->id = network_filters_count++;
     40     network_filters = g_realloc(network_filters,
     41                                 network_filters_count
     42                                     * sizeof(*network_filters));
     43     network_filters[network_filters_count - 1] = nfs;
     44     return rns;
     45 }
     46 
     47 void replay_unregister_net(ReplayNetState *rns)
     48 {
     49     network_filters[rns->id] = NULL;
     50     g_free(rns);
     51 }
     52 
     53 void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
     54                              const struct iovec *iov, int iovcnt)
     55 {
     56     NetEvent *event = g_new(NetEvent, 1);
     57     event->flags = flags;
     58     event->data = g_malloc(iov_size(iov, iovcnt));
     59     event->size = iov_size(iov, iovcnt);
     60     event->id = rns->id;
     61     iov_to_buf(iov, iovcnt, 0, event->data, event->size);
     62 
     63     replay_add_event(REPLAY_ASYNC_EVENT_NET, event, NULL, 0);
     64 }
     65 
     66 void replay_event_net_run(void *opaque)
     67 {
     68     NetEvent *event = opaque;
     69     struct iovec iov = {
     70         .iov_base = (void *)event->data,
     71         .iov_len = event->size
     72     };
     73 
     74     assert(event->id < network_filters_count);
     75 
     76     qemu_netfilter_pass_to_next(network_filters[event->id]->netdev,
     77         event->flags, &iov, 1, network_filters[event->id]);
     78 
     79     g_free(event->data);
     80     g_free(event);
     81 }
     82 
     83 void replay_event_net_save(void *opaque)
     84 {
     85     NetEvent *event = opaque;
     86 
     87     replay_put_byte(event->id);
     88     replay_put_dword(event->flags);
     89     replay_put_array(event->data, event->size);
     90 }
     91 
     92 void *replay_event_net_load(void)
     93 {
     94     NetEvent *event = g_new(NetEvent, 1);
     95 
     96     event->id = replay_get_byte();
     97     event->flags = replay_get_dword();
     98     replay_get_array_alloc(&event->data, &event->size);
     99 
    100     return event;
    101 }