#include #include #include #include #include #include #include "database.h" #include "event.h" #include "handler.h" #include "config.h" #include "utils.h" #include "packet-mac-lte.h" #define DEFAULT_IP "127.0.0.1" #define DEFAULT_PORT 9999 typedef struct { int socket; struct sockaddr_in to; OBUF buf; /* ul */ int ul_rnti; int ul_frame; int ul_subframe; int ul_data; /* dl */ int dl_rnti; int dl_frame; int dl_subframe; int dl_data; } ev_data; void ul(void *_d, event e) { ev_data *d = _d; ssize_t ret; int fsf; int i; d->buf.osize = 0; PUTS(&d->buf, MAC_LTE_START_STRING); PUTC(&d->buf, FDD_RADIO); PUTC(&d->buf, DIRECTION_UPLINK); PUTC(&d->buf, C_RNTI); PUTC(&d->buf, MAC_LTE_RNTI_TAG); PUTC(&d->buf, (e.e[d->ul_rnti].i>>8) & 255); PUTC(&d->buf, e.e[d->ul_rnti].i & 255); /* for newer version of wireshark? */ fsf = (e.e[d->ul_frame].i << 4) + e.e[d->ul_subframe].i; /* for older version? */ fsf = e.e[d->ul_subframe].i; PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); PUTC(&d->buf, (fsf>>8) & 255); PUTC(&d->buf, fsf & 255); PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); for (i = 0; i < e.e[d->ul_data].bsize; i++) PUTC(&d->buf, ((char*)e.e[d->ul_data].b)[i]); ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); if (ret != d->buf.osize) abort(); } void dl(void *_d, event e) { ev_data *d = _d; ssize_t ret; int fsf; int i; d->buf.osize = 0; PUTS(&d->buf, MAC_LTE_START_STRING); PUTC(&d->buf, FDD_RADIO); PUTC(&d->buf, DIRECTION_DOWNLINK); PUTC(&d->buf, C_RNTI); PUTC(&d->buf, MAC_LTE_RNTI_TAG); PUTC(&d->buf, (e.e[d->dl_rnti].i>>8) & 255); PUTC(&d->buf, e.e[d->dl_rnti].i & 255); /* for newer version of wireshark? */ fsf = (e.e[d->dl_frame].i << 4) + e.e[d->dl_subframe].i; /* for older version? */ fsf = e.e[d->dl_subframe].i; PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); PUTC(&d->buf, (fsf>>8) & 255); PUTC(&d->buf, fsf & 255); PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); for (i = 0; i < e.e[d->dl_data].bsize; i++) PUTC(&d->buf, ((char*)e.e[d->dl_data].b)[i]); ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); if (ret != d->buf.osize) abort(); } void setup_data(ev_data *d, void *database, int ul_id, int dl_id) { database_event_format f; int i; d->ul_rnti = -1; d->ul_frame = -1; d->ul_subframe = -1; d->ul_data = -1; d->dl_rnti = -1; d->dl_frame = -1; d->dl_subframe = -1; d->dl_data = -1; #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ if (strcmp(f.type[i], var_type)) goto error; \ var = i; \ continue; \ } /* ul: rnti, frame, subframe, data */ f = get_format(database, ul_id); for (i = 0; i < f.count; i++) { G("rnti", "int", d->ul_rnti); G("frame", "int", d->ul_frame); G("subframe", "int", d->ul_subframe); G("data", "buffer", d->ul_data); } if (d->ul_rnti == -1 || d->ul_frame == -1 || d->ul_subframe == -1 || d->ul_data == -1) goto error; /* dl: rnti, frame, subframe, data */ f = get_format(database, dl_id); for (i = 0; i < f.count; i++) { G("rnti", "int", d->dl_rnti); G("frame", "int", d->dl_frame); G("subframe", "int", d->dl_subframe); G("data", "buffer", d->dl_data); } if (d->dl_rnti == -1 || d->dl_frame == -1 || d->dl_subframe == -1 || d->dl_data == -1) goto error; #undef G return; error: printf("bad T_messages.txt\n"); abort(); } void *receiver(void *_d) { ev_data *d = _d; int s; char buf[100000]; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) { perror("socket"); abort(); } if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) { perror("bind"); abort(); } while (1) { if (recv(s, buf, 100000, 0) <= 0) abort(); } return 0; } void usage(void) { printf( "options:\n" " -d this option is mandatory\n" " -in read events from this dump file\n" " -ip send packets to this IP address (default %s)\n" " -p send packets to this port (default %d)\n", DEFAULT_IP, DEFAULT_PORT ); exit(1); } int main(int n, char **v) { char *database_filename = NULL; char *input_filename = NULL; void *database; event_handler *h; int in; int i; int ul_id, dl_id; ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; memset(&d, 0, sizeof(ev_data)); for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; } if (!strcmp(v[i], "-in")) { if (i > n-2) usage(); input_filename = v[++i]; continue; } if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } usage(); } if (database_filename == NULL) { printf("ERROR: provide a database file (-d)\n"); exit(1); } if (input_filename == NULL) { printf("ERROR: provide an input file (-i)\n"); exit(1); } in = open(input_filename, O_RDONLY); if (in == -1) { perror(input_filename); return 1; } database = parse_database(database_filename); load_config_file(database_filename); h = new_handler(database); ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA"); dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA"); setup_data(&d, database, ul_id, dl_id); register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); d.socket = socket(AF_INET, SOCK_DGRAM, 0); if (d.socket == -1) { perror("socket"); exit(1); } d.to.sin_family = AF_INET; d.to.sin_port = htons(port); d.to.sin_addr.s_addr = inet_addr(ip); new_thread(receiver, &d); /* read messages */ while (1) { char v[T_BUFFER_MAX]; event e; e = get_event(in, v, database); if (e.type == -1) break; if (!(e.type == ul_id || e.type == dl_id)) continue; handle_event(h, e); } return 0; }