1f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen/* 2f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * Copyright 2016, The Android Open Source Project 3f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * 4f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * Licensed under the Apache License, Version 2.0 (the "License"); 5f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * you may not use this file except in compliance with the License. 6f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * You may obtain a copy of the License at 7f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * 8f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * http://www.apache.org/licenses/LICENSE-2.0 9f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * 10f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * Unless required by applicable law or agreed to in writing, software 11f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * distributed under the License is distributed on an "AS IS" BASIS, 12f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * See the License for the specific language governing permissions and 14f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen * limitations under the License. 15f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen */ 16f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen 17f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen// Simple program to try running an APF program against a packet. 18f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen 19f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include <libgen.h> 20f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include <stdint.h> 21f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include <stdio.h> 22f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include <stdlib.h> 23f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include <string.h> 24f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen 25f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen#include "apf_interpreter.h" 26f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen 27f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen// Parses hex in "input". Allocates and fills "*output" with parsed bytes. 28f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen// Returns length in bytes of "*output". 29f9491fa2795120de428ffcea3a113616b63644f3Paul Jensenint parse_hex(char* input, uint8_t** output) { 30f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen int length = strlen(input); 31f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen if (length & 1) { 32f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen fprintf(stderr, "Argument not even number of characters: %s\n", input); 33f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen exit(1); 34f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen } 35f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen length >>= 1; 36f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen *output = malloc(length); 37f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen if (*output == NULL) { 38f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen fprintf(stderr, "Out of memory, tried to allocate %d\n", length); 39f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen exit(1); 40f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen } 41f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen for (int i = 0; i < length; i++) { 42f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen char byte[3] = { input[i*2], input[i*2+1], 0 }; 43f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen char* end_ptr; 44f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen (*output)[i] = strtol(byte, &end_ptr, 16); 45f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen if (end_ptr != byte + 2) { 46f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen fprintf(stderr, "Failed to parse hex %s\n", byte); 47f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen exit(1); 48f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen } 49f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen } 50f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen return length; 51f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen} 52f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen 53ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocentivoid print_hex(uint8_t* input, int len) { 54ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti for (int i = 0; i < len; ++i) { 55ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti printf("%02x", input[i]); 56ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti } 57ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti} 58ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti 59f9491fa2795120de428ffcea3a113616b63644f3Paul Jensenint main(int argc, char* argv[]) { 60ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti if (argc < 3 || argc > 5) { 61f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen fprintf(stderr, 62ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti "Usage: %s <program> <packet> [<data>] [<age>]\n" 63f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen " program: APF program, in hex\n" 64f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen " packet: Packet to run through program, in hex\n" 65c206315b2faf7f0a59dbd64376de38e3d116534eErik Kline " data: Data memory contents, in hex\n" 66ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti " age: Age of program in seconds (default: 0)\n", 67f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen basename(argv[0])); 68f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen exit(1); 69f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen } 70f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen uint8_t* program; 71f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen uint32_t program_len = parse_hex(argv[1], &program); 72f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen uint8_t* packet; 73f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen uint32_t packet_len = parse_hex(argv[2], &packet); 74ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti uint8_t* data = NULL; 75ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti uint32_t data_len = argc > 3 ? parse_hex(argv[3], &data) : 0; 76ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti uint32_t filter_age = argc > 4 ? atoi(argv[4]) : 0; 77d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti 78d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti // Combine the program and data into the unified APF buffer. 79ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti if (data) { 80d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti program = realloc(program, program_len + data_len); 81d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti memcpy(program + program_len, data, data_len); 82d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti free(data); 83d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti } 84d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti 85d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti uint32_t ram_len = program_len + data_len; 86d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti int ret = accept_packet(program, program_len, ram_len, packet, packet_len, 87d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti filter_age); 88d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti printf("Packet %sed\n", ret ? "pass" : "dropp"); 89d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti if (data_len) { 90ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti printf("Data: "); 91d2cc2b74f161d88bc0622b03d48ef176fefee03aBernie Innocenti print_hex(program + program_len, data_len); 92ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti printf("\n"); 93ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti } 94f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen free(program); 95f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen free(packet); 96f9491fa2795120de428ffcea3a113616b63644f3Paul Jensen return ret; 97ea115f501b42415063c4747e3b5bdc95e669fe1cBernie Innocenti} 98