static ucli_status_t ppe_ucli_utm__data__(ucli_context_t* uc) { uint8_t* data; int size; UCLI_COMMAND_INFO(uc, "data", 1, "Assign packet data."); UCLI_ARGPARSE_OR_RETURN(uc, "{data}", &data, &size); if(ppec->ppep.data) { aim_free(ppec->ppep.data); } if(ppe_packet_init(&ppec->ppep, data, size) < 0) { return ucli_e_internal(uc, "ppe_packet_init()"); } if(ppe_parse(&ppec->ppep) < 0) { return ucli_e_internal(uc, "ppe_parse()"); } return UCLI_STATUS_OK; }
static ucli_status_t ppe_ucli_utm__checkw__(ucli_context_t* uc) { ppe_field_info_t* fi; uint8_t* cvalue; uint8_t pvalue[128]; unsigned int csize; aim_datatype_map_t* operation; aim_datatype_map_t operation_map[] = { { "==", 'e' }, { "!=", 'n' }, { NULL } }; UCLI_COMMAND_INFO(uc, "checkw", 3, "Check wide packet field values and status."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field_info}{map}{data}", &fi, &operation, operation_map, "operation", &cvalue, &csize); PPE_FIELD_EXISTS_OR_RETURN(uc, fi->field); if(fi->size_bits/8 != csize) { return ucli_error(uc, "field %{ppe_field} is %d bytes wide.", fi->field, fi->size_bits/8); } PPE_WIDE_FIELD_GET_OR_RETURN(uc, &ppec->ppep, fi->field, pvalue); switch(operation->i) { case 'e': { if(PPE_MEMCMP(pvalue, cvalue, csize)) { return ucli_error(uc, "field %{ppe_field} is %{data} (should be %{data}", fi->field, pvalue, csize, cvalue, csize); } return UCLI_STATUS_OK; break; } case 'n': { if(!PPE_MEMCMP(pvalue, cvalue, csize)) { return ucli_error(uc, "field %{ppe_field} is %{data}", fi->field, pvalue, csize); } return UCLI_STATUS_OK; break; } default: return ucli_e_internal(uc, "unknown operation."); } }
static ucli_status_t ppe_ucli_utm__check__(ucli_context_t* uc) { ppe_field_info_t* fi; uint32_t cvalue; uint32_t pvalue; aim_datatype_map_t* operation; aim_datatype_map_t operation_map[] = { { "==", 'e' }, { "!=", 'n' }, { NULL } }; UCLI_COMMAND_INFO(uc, "check", 3, "Check packet field values and status."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field_info}{map}i", &fi, &operation, operation_map, "operation", &cvalue); PPE_FIELD_EXISTS_OR_RETURN(uc, fi->field); PPE_FIELD32_OR_RETURN(uc, fi->size_bits); PPE_FIELD_GET_OR_RETURN(uc, &ppec->ppep, fi->field, &pvalue); switch(operation->i) { case 'e': { if(pvalue != cvalue) { return ucli_error(uc, "field %{ppe_field} is 0x%x (%d) (should be 0x%x (%d)", fi->field, pvalue, pvalue, cvalue, cvalue); } return UCLI_STATUS_OK; break; } case 'n': { if(pvalue == cvalue) { return ucli_error(uc, "field %{ppe_field} is 0x%x (%d)", fi->field, pvalue, pvalue); } return UCLI_STATUS_OK; break; } default: return ucli_e_internal(uc, "unknown operation."); } }
static inline int field_required__(ucli_context_t* uc, ppe_field_t f) { AIM_VAR_PCAST_SAFE(ppe_utm_ctrl_t*, ppec, uc, uc->cookie); int e = ppe_field_exists(&ppec->ppep, f); if(e == 1) { return 0; } else if(e == 0) { return ucli_error(uc, "field %{ppe_field} does not exist in the packet.", f); } else { return ucli_e_internal(uc, "ppe_field_exists() failed internally."); } }
static ucli_status_t ppe_ucli_utm__setheader__(ucli_context_t* uc) { uint8_t* data; int size; ppe_header_t header; UCLI_COMMAND_INFO(uc, "setheader", 2, "Set header data."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_header}{data}", &header, &data, &size); if(ppe_header_get(&ppec->ppep, header)) { aim_free(ppe_header_get(&ppec->ppep, header)); } if(ppe_header_set(&ppec->ppep, header, data) < 0) { return ucli_e_internal(uc, "ppe_set_header()"); } return UCLI_STATUS_OK; }
static ucli_status_t ppe_ucli_utm__missing__(ucli_context_t* uc) { ppe_field_t f; int rv; UCLI_COMMAND_INFO(uc, "missing", 1, "Check that a field is missing in the packet."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field}", &f); rv = ppe_field_exists(&ppec->ppep, f); if(rv == 0) { return UCLI_STATUS_OK; } else if(rv == 1) { return ucli_error(uc, "field %{ppe_field} exists in the packet.", f); } else { return ucli_e_internal(uc, "ppe_field_exists()"); } }
static ucli_status_t ppe_ucli_utm__get__(ucli_context_t* uc) { ppe_field_info_t* fi; UCLI_COMMAND_INFO(uc, "get", 1, "Get a packet field."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field_info}", &fi); PPE_FIELD_EXISTS_OR_RETURN(uc, fi->field); if(fi->size_bits <= 32) { uint32_t value; PPE_FIELD_GET_OR_RETURN(uc, &ppec->ppep, fi->field, &value); ucli_printf(uc, "%{ppe_field} = 0x%x (%d)\n", fi->field, value, value); return UCLI_STATUS_OK; } else { int rv; int size = fi->size_bits/8; uint8_t* data = aim_zmalloc(size); rv = ppe_wide_field_get(&ppec->ppep, fi->field, data); if(rv < 0) { ucli_e_internal(uc, "ppe_wide_field_get(%{ppe_field})", fi->field); } else { ucli_printf(uc, "%{ppe_field} = %{data}\n", data, size); } aim_free(data); return rv; } }
static ucli_status_t fme_ucli_utm__match__(ucli_context_t* uc) { int rv; int i; uint32_t keymask; uint8_t* value; int value_size; int _now; fme_timeval_t now; unsigned int size; fme_entry_t* fe = NULL; fme_key_t key; UCLI_COMMAND_INFO(uc, "match", 4, "Run the key and data."); UCLI_ARGPARSE_OR_RETURN(uc, "i{data}ii", &keymask, &value, &value_size, &size, &_now); now = _now; FME_MEMSET(&key, 0, sizeof(key)); key.keymask = keymask; FME_MEMCPY(key.values, value, value_size); key.size = value_size; FME_MEMSET(key.masks, 0, sizeof(key.masks)); aim_free(value); rv = fme_match(fmec->fme, &key, now, size, NULL, NULL, &fe); if(rv == 1) { if(fmec->expects[fe->prio] == 0) { /* Unexpected match */ ucli_error(uc, "unexpected match: "); fme_entry_dump(fe, &uc->pvs); goto __match__error; } /* match is expected -- check counter values */ if(fe->counters.matches != 1) { ucli_error(uc, "match counter was not incremented."); goto __match__error; } if(fe->counters.bytes != size) { ucli_error(uc, "byte counter is incorrect."); goto __match__error; } if(fe->timestamp != now) { ucli_error(uc, "timestamp was not updated."); goto __match__error; } /* all good */ } else if(rv == 0) { /* Make sure we have to entries expected to match */ for(i = 0; i < FME_CONFIG_UTM_ENTRIES; i++) { if(fmec->expects[i]) { ucli_error(uc, "expected match was not received: "); fme_entry_dump(fmec->entries[i], &uc->pvs); goto __match__error; } } /* all good */ } else { ucli_e_internal(uc, "fme_match() returned %d", rv); goto __match__error; } /* all good - reset */ fme_destroy_all(fmec->fme); FME_MEMSET(fmec, 0, sizeof(*fmec)); fme_create(&fmec->fme, "fme_utm", FME_CONFIG_UTM_ENTRIES); return UCLI_STATUS_OK; __match__error: ucli_error(uc, "fme: "); fme_dump(fmec->fme, &uc->pvs); return UCLI_STATUS_E_ERROR; }