static int runin_RamFreeSizeGet() { test_status status = TEST_FAIL; char* msg = NULL; char* mem_info = "/proc/meminfo"; char *Start, *End, *raminfo; char size1; int number = 0, freesize; char keys[] = "1234567890"; char value[100]={0}, result[100]={0}; FOX_DBG("***** %s *****\n", __func__); int ret = read_device_node(mem_info, value, sizeof(value)); Start = strstr(value,"MemFree:"); End = strstr(value,"Buffers:"); size1 = End-Start; raminfo = (char*)malloc(size1); number = strcspn(value, keys); strncpy(raminfo, (Start+number), (size1-number)); freesize = atoi(raminfo); if(ret==-1) { status = TEST_PASS; msg = "runin_RamFreeSizeGet failed"; } else { sprintf(result, "RAM Free Mem=%s\n", raminfo); status = TEST_PASS; } FOX_DBG("RAM free memory size: %d KB \t result:%s \n", freesize, status_to_str(status)); free(raminfo); return status; }
static int runin_RamDataRW() { test_status status = TEST_PASS; char* msg = NULL; char result[32] = {0}; char *rambuffer; int i=0, val=0, ref=0; FOX_DBG("***** %s *****\n", __func__); rambuffer = (char*)malloc(RAM_TEST_SIZE); if(rambuffer==NULL){ status = TEST_FAIL; msg = "Memory allocate failed!!"; FOX_DBG("%s\n", msg); }else { for(i=0; i<RAM_TEST_SIZE; i++) //Set data to memory *(rambuffer + i) = i%256; sprintf(result, "RAM R/W test %s !!", "Pass"); for(i=0; i<RAM_TEST_SIZE; i++){ //Compare data integrity val = *(rambuffer + i); ref = i%256; if(val!=ref){ FOX_DBG("RAM R/W failed!! \n"); FOX_DBG("%d) ref:0x%x \t val:0x%x \n", i, ref, val); sprintf(result, "RAM R/W test %s !!", "Failed"); status = TEST_FAIL; break; } } } FOX_DBG("RAM R/W test size:0x%x KB \t result:%s \n",RAM_TEST_SIZE, status_to_str(status)); free(rambuffer); return status; }
static void gui_demo_update_status(int i) { const struct demo *d; if (!total) return; d = DEMO_GET(items, i < total ? i : 0); if (!d) return; gui_set_label(name_id, d->name); gui_set_label(date_id, date_to_str(d->date)); gui_set_label(player_id, d->player); if (d->status == GAME_GOAL) gui_set_color(status_id, gui_grn, gui_grn); else gui_set_color(status_id, gui_red, gui_red); gui_set_label(status_id, status_to_str(d->status)); gui_set_count(coin_id, d->coins); gui_set_clock(time_id, d->timer); }
static int runin_RamSizeGet() { test_status status = TEST_PASS; char* msg = NULL; char* mem_info = "/proc/meminfo"; char *Start, *End, *raminfo; char size; int number=0, ramsize=0; char keys[] = "1234567890"; char value[100]={0}, result[100]={0}; FOX_DBG("***** %s *****\n", __func__); int ret = read_device_node(mem_info, value, sizeof(value)); Start = strstr(value,"MemTotal:"); End = strstr(value,"MemFree:"); size = End-Start; raminfo = (char*)malloc(size); number = strcspn(value, keys); strncpy(raminfo, (Start+number), (size-number)); ramsize = atoi(raminfo); if(ret==-1 || ramsize<RAM_SIZE) { status = TEST_FAIL; msg = "runin_RamCapacityGet failed"; } else { sprintf(result, "RAM Capacity=%skB\n", raminfo); status = TEST_PASS; } FOX_DBG("RAM Capacity: %d KB \t result:%s \n", ramsize, status_to_str(status)); free(raminfo); return status; }
static int runin_RtcClockTest() { test_status status = TEST_FAIL; char* msg = NULL; char* rtc_time = "/sys/class/rtc/rtc0/since_epoch"; char rtc_msg1[16] = {0}; char rtc_msg2[16] = {0}; char result[32] = {0}; int rtc_value1 = 0, rtc_value2 = 0, rtc_interval=0; FOX_DBG("***** %s *****\n", __func__); int ret = read_device_node(rtc_time, rtc_msg1, sizeof(rtc_msg1)); sleep(10); ret = read_device_node(rtc_time, rtc_msg2, sizeof(rtc_msg2)); rtc_value1 = atoi(rtc_msg1); rtc_value2 = atoi(rtc_msg2); rtc_interval = rtc_value2 - rtc_value1; sprintf(result, "%d", rtc_interval); FOX_DBG("RTC clock: %d ==> %d secs \t interval: %d secs\n", rtc_value1, rtc_value2, rtc_interval); if(ret==-1 || rtc_interval<10) { status = TEST_FAIL; msg = "runin_rtc_clock_test failed"; } else { sprintf(result, "RTC test pass"); status = TEST_PASS; } FOX_DBG("RTC test result:%s \n", status_to_str(status)); return status; }
/******************************************************************* writes info on just one Index it must not be un allocated to do this ********************************************************************/ static void mem_write_Index_info(int Index,FILE *outfile) { if (memory_blocks[Index].status != S_UNALLOCATED) fprintf(outfile,"block %d file %s(%d) : size %d, alloc size %d, status %s\n", Index,memory_blocks[Index].file,memory_blocks[Index].line, memory_blocks[Index].present_size, memory_blocks[Index].allocated_size, status_to_str(memory_blocks[Index].status)); }
static GIOStatus read_impl (PnNode *conn, gchar *buf, gsize count, gsize *ret_bytes_read, GError **error) { GIOStatus status = G_IO_STATUS_NORMAL; pn_debug ("name=%s", conn->name); if (conn->next) { pn_error ("whaaat"); conn->next->prev = conn; status = pn_node_read (conn->next, buf, count, ret_bytes_read, error); conn->next->prev = NULL; } else { GError *tmp_error = NULL; gsize bytes_read = 0; pn_debug ("stream=%p", conn->stream); status = pn_stream_read (conn->stream, buf, count, &bytes_read, &tmp_error); if (status != G_IO_STATUS_NORMAL) { pn_info ("not normal: status=%d (%s)", status, status_to_str (status)); } pn_log ("bytes_read=%zu", bytes_read); if (ret_bytes_read) *ret_bytes_read = bytes_read; if (tmp_error) { conn->error = g_error_copy (tmp_error); g_propagate_error (error, tmp_error); } } return status; }
static int runin_GetCpuLoading() { test_status status = TEST_FAIL; char* msg = NULL; char* cpu_loading = "/proc/loadavg"; /*Foxconn, KingsChen, MKD, 20131003 {*/ //Add buffer size for fixing unknown char in log char value[64] = {0}; int ret = read_device_node(cpu_loading, value, sizeof(value)); char result[64] = {0}; /*Foxconn, KingsChen, MKD, 20131003 {*/ FOX_DBG("***** %s *****\n", __func__); if(ret==-1) { status = TEST_FAIL; msg = "runin_GetCpuLoading failed"; } else { sprintf(result, "CPU Loading=%s", value); status = TEST_PASS; } FOX_DBG("CPU Loading:%s \t result:%s \n", value, status_to_str(status)); return status; }
static GIOStatus write_impl (PnNode *conn, const gchar *buf, gsize count, gsize *ret_bytes_written, GError **error) { GIOStatus status = G_IO_STATUS_NORMAL; pn_debug ("name=%s", conn->name); if (conn->next) { PnNode *next; next = conn->next; /* conn->next has already a ref from conn, but let's just be sure and * ref anyway */ g_object_ref (next); next->prev = conn; status = pn_node_write (next, buf, count, ret_bytes_written, error); next->prev = NULL; g_object_unref (next); } else { GError *tmp_error = NULL; gsize bytes_written = 0; pn_debug ("stream=%p", conn->stream); status = pn_stream_write_full (conn->stream, buf, count, &bytes_written, &tmp_error); pn_log ("bytes_written=%zu", bytes_written); if (status == G_IO_STATUS_NORMAL) { if (bytes_written < count) { /* This shouldn't happen, right? */ /* It doesn't seem to happen, but keep checking for now. */ pn_error ("write check: %zu < %zu", bytes_written, count); } } else { pn_warning ("not normal: status=%d (%s)", status, status_to_str (status)); } if (ret_bytes_written) *ret_bytes_written = bytes_written; if (tmp_error) { conn->error = g_error_copy (tmp_error); g_propagate_error (error, tmp_error); } } return status; }
static void on_notify(uint64_t qid, enum filter_status status) { printf("filter-notify: qid=%016"PRIx64", status=%s\n", qid, status_to_str(status)); }
static int runin_SetChargerCurrent() { test_status status = TEST_FAIL; char* msg = NULL; char* gas_gauge_current = "/sys/class/power_supply/bq27500-0/current_now"; char* gas_gauge_cap = "/sys/class/power_supply/bq27500-0/capacity"; char* charge_current = "/sys/class/power_supply/Charger/current_now"; char* charger_status = "/sys/class/power_supply/Charger/status"; char* usb_status = "/sys/class/power_supply/ac/online"; char* charging_status = "/sys/class/power_supply/bq27500-0/status"; /*Foxconn/EricBHLin, 20131024, MKD, SCR#{*/ /*Declaration of Vinx Node */ char* charger_vinx_node="/sys/class/power_supply/Charger/vinx"; char vinx[16]; /*Foxconn/EricBHLin, 20131024, MKD, SCR#}*/ char value[16]={0}, charge[8]={0}, result[32]={0}, chg_status[16]={0}, capacity[8]={0}, ac_online[8]={0}, gg_status[16]={0}; /*Foxconn, Benson Liu, MKD, SCRXXX, 20131122 { */ /*Decrease range for user scenario*/ //const char* ChargeValue[]={"100", "200", "300", "400", "500"}; const char* ChargeValue[]={"100", "200", "300"}; /*Foxconn, Benson Liu, MKD, SCRXXX, 20131122 } */ int ret, testValue=0, i, standard, min, max, capacity_value; /*Foxconn, Benson Liu, MKD, SCRXXX, 20131122 { */ /*Decrease range for user scenario*/ //const int count=5; const int count=3; /*Foxconn, Benson Liu, MKD, SCRXXX, 20131122 } */ const int capacity_limit = 70; FOX_DBG("***** %s *****\n", __func__); //1. Read and check charging status /*Foxconn/EricBHLin, 20131024, MKD, SCR#{*/ /*Read current Vinx setting*/ read_device_node(charger_vinx_node, vinx, sizeof(vinx)); FOX_DBG("Charger Vinx Limit: %s\n", vinx); /*Foxconn/EricBHLin, 20131024, MKD, SCR#}*/ read_device_node(charge_enabled, charge, sizeof(charge)); read_device_node(gas_gauge_cap, capacity, sizeof(capacity)); read_device_node(charger_status, chg_status, sizeof(chg_status)); read_device_node(usb_status, ac_online, sizeof(ac_online)); read_device_node(charging_status, gg_status, sizeof(gg_status)); capacity_value = atoi(capacity); FOX_DBG("Charger status: %s\n", chg_status); FOX_DBG("GG USB Charging status: %s\n", gg_status); FOX_DBG("AC online status:%s\n", ac_online); FOX_DBG("Battery capacity: %d%\n", capacity_value); #if 0 //Charging status test if(strncmp(chg_status, "CC Mode", 7) != 0){ status = TEST_UNTESTED; FOX_DBG("Test result:%s \n", status_to_str(status)); return status; } //2. Disable usb charging write_device_node(charge_enabled, "0"); //Disable usb charging sleep(5); #endif //Charging status test if(capacity_value == 100){ status = TEST_PASS; }else{ /*Foxconn/EricBHLin, 20131024, MKD, SCR#{*/ /*Before SetChargingCurrent Test, it required to set Vinx limit to 800mA, otherwise total current may be insufficient*/ write_device_node(charger_vinx_node, "800"); //Set Vinx Limit: 800mA read_device_node(charger_vinx_node, vinx, sizeof(vinx)); FOX_DBG("Charger Vinx Limit: %s\n", vinx); /*Foxconn/EricBHLin, 20131024, MKD, SCR#}*/ write_device_node(charge_enabled, "1"); //Enable usb charging sleep(10); //3. Set charging current from 100 ~ 500 mA /*Foxconn, KingsChen, MKD, 20131003 {*/ //Modify Test Criteria status = TEST_PASS; /*Foxconn, KingsChen, MKD, 20131003 }*/ for(i=1; i<=count; i++){ write_device_node(charge_current, ChargeValue[i-1]); //Set charging current 100~300 /*Foxconn/EricBHLin, 20131009, MKD, SCR#{*/ sleep(GG_CONVERSION_TIME); /*Foxconn/EricBHLin, 20131009, MKD, SCR#}*/ ret = read_device_node(gas_gauge_current, value, sizeof(value)); //Read GG current data testValue = atoi(value); standard = i*100000; /*Foxconn, KingsChen, MKD, 20131003 {*/ //Modify Test Criteria //min = standard*90/100; //max = standard*110/100; min = standard - 40000; max = standard + 30000; /*Foxconn, KingsChen, MKD, 20131003 }*/ FOX_DBG("STD: %d \t Min: %d \t Max: %d\n", standard, min, max); FOX_DBG("Charging Current: %d (mA*1000) \n", testValue); //Capacity over 70%, do not check charging current accuracy if(capacity_value >= capacity_limit){ if(testValue>=0){ FOX_DBG("Battery capacity > %d% \t Test Pass\n", capacity_limit); /*Foxconn, KingsChen, MKD, 20131003 {*/ //Modify Test Criteria //status = TEST_PASS; /*Foxconn, KingsChen, MKD, 20131003 }*/ }else{ FOX_DBG("Battery capacity > %d% \t Test Fail\n", capacity_limit); status = TEST_FAIL; break; } } else{//Capacity under 70% /*Foxconn, KingsChen, MKD, 20131003 {*/ //Modify Test Criteria #if 0 if((testValue>=min) && (testValue<=max)){ status = TEST_PASS; }else{ status = TEST_FAIL; break; } #else if((testValue < min) || (testValue > max)) status =TEST_FAIL; #endif /*Foxconn, KingsChen, MKD, 20131003 }*/ } } }//if(capacity_value==100) //4. Restore charging status and current setting write_device_node(charge_current, "300"); //Set usb charging current write_device_node(charge_enabled, charge); //Restore usb charging status sleep(5); /*Foxconn/EricBHLin, 20131024, MKD, SCR#{*/ /*Read restored value for double confirm*/ read_device_node(charger_vinx_node, vinx, sizeof(vinx)); FOX_DBG("Charger Vinx Limit: %s\n", vinx); /*Foxconn/EricBHLin, 20131024, MKD, SCR#}*/ FOX_DBG("Restore usb charging status %s\n", charge); FOX_DBG("Battery Current:%d (mA*1000)\t result:%s \n", testValue, status_to_str(status)); return status; }
/** \brief Reads gripper responses in auto_update mode. The gripper pushes state messages in regular intervals. */ void read_thread(int interval_ms) { ROS_INFO("Thread started"); status_t status; int res; bool pub_state = false; // Prepare messages wsg_50_common::Status status_msg; status_msg.status = ""; sensor_msgs::JointState joint_states; // joint_states.header.frame_id = "wsg_50/palm_link"; joint_states.name.push_back("wsg_50/palm_joint_gripper_left"); joint_states.name.push_back("wsg_50/palm_joint_gripper_right"); joint_states.position.resize(2); joint_states.velocity.resize(2); joint_states.effort.resize(2); // Request automatic updates (error checking is done below) getOpening(interval_ms); getSpeed(interval_ms); getForce(interval_ms); msg_t msg; msg.id = 0; msg.data = 0; msg.len = 0; int cnt[3] = {0,0,0}; auto time_start = std::chrono::system_clock::now(); // Prepare FMF data reading std::vector<float> finger_data; finger_data.push_back(0.0); finger_data.push_back(0.0); int index = 0; bool waiting_fmf = false; unsigned char vResult[4]; while (g_thread) { // Receive gripper response msg_free(&msg); res = msg_receive( &msg ); if (res < 0 ) //|| msg.len < 2) { ROS_ERROR("Gripper response failure"); continue; } float val = 0.0; status = cmd_get_response_status(msg.data); // Decode float for opening/speed/force if (msg.id >= 0x43 && msg.id <= 0x45 && msg.len == 6) { if (status != E_SUCCESS) { ROS_ERROR("Gripper response failure for opening/speed/force\n"); continue; } val = convert(&msg.data[2]); } // Request force measurement // if (use_fmf && !waiting_fmf) // { // waiting_fmf = true; // getFingerData_serial(index); // } if ((info_fingers[index].type == 1) && !waiting_fmf) { waiting_fmf = true; getFingerData(index, true); } // Handle response types int motion = -1; switch (msg.id) { /*** Opening ***/ case 0x43: status_msg.width = val; pub_state = true; cnt[0]++; break; /*** Speed ***/ case 0x44: status_msg.speed = val; cnt[1]++; break; /*** Force ***/ case 0x45: status_msg.force = val; cnt[2]++; break; /*** Home ***/ case 0x20: // Homing command; nothing to do break; case 0x22: // Stop command; nothing to do break; /*** Move ***/ case 0x21: // Move commands are sent from outside this thread case 0x25: // Grasping object case 0x26: // Releasing object if (status == E_SUCCESS) { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Position reached"); motion = 0; } else if (status == E_AXIS_BLOCKED) { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Axis blocked"); motion = 0; } else if (status == E_CMD_PENDING) { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Movement started"); motion = 1; } else if (status == E_ALREADY_RUNNING) { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Movement error: already running"); } else if (status == E_CMD_ABORTED) { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Movement aborted"); motion = 0; } else { status_msg.status = std::string(status_to_str(status)); ROS_INFO("Movement error"); motion = 0; } break; /*** Finger Data ***/ case 0x63: if (status == E_SUCCESS) { vResult[0] = msg.data[2]; vResult[1] = msg.data[3]; vResult[2] = msg.data[4]; vResult[3] = msg.data[5]; finger_data[index] = convert(vResult); } else finger_data[index] = 0.0; waiting_fmf = false; index = abs(index - 1); break; /*** Soft Limits ***/ case 0x34: if (status == E_SUCCESS) ROS_INFO("New Soft Limits"); break; case 0x35: if (status == E_SUCCESS && msg.len == 10) { unsigned char limit_minus[4]; unsigned char limit_plus[4]; limit_minus[0] = msg.data[2]; limit_minus[1] = msg.data[3]; limit_minus[2] = msg.data[4]; limit_minus[3] = msg.data[5]; limit_plus[0] = msg.data[6]; limit_plus[1] = msg.data[7]; limit_plus[2] = msg.data[8]; limit_plus[3] = msg.data[9]; ROS_INFO("Soft limits: \nLIMIT MINUS %f\nLIMIT PLUS %f\n", convert(limit_minus), convert(limit_plus)); } else ROS_INFO("Failed to read soft limits, len %d", msg.len); break; case 0x36: if (status == E_SUCCESS) ROS_INFO("Soft Limits Cleared"); break; default: ROS_INFO("Received response 0x%02x (%2dB)\n", msg.id, msg.len); } // ***** PUBLISH motion message if (motion == 0 || motion == 1) { std_msgs::Bool moving_msg; moving_msg.data = motion; g_pub_moving.publish(moving_msg); g_ismoving = motion; } // ***** PUBLISH state message & joint message if (pub_state) { pub_state = false; if (info_fingers[0].type == 1) status_msg.force_finger0 = finger_data[0]; else status_msg.force_finger0 = status_msg.force/2; if (info_fingers[1].type == 1) status_msg.force_finger1 = finger_data[1]; else status_msg.force_finger1 = status_msg.force/2; g_pub_state.publish(status_msg); joint_states.header.stamp = ros::Time::now();; joint_states.position[0] = -status_msg.width/2000.0; joint_states.position[1] = status_msg.width/2000.0; joint_states.velocity[0] = status_msg.speed/1000.0; joint_states.velocity[1] = status_msg.speed/1000.0; joint_states.effort[0] = status_msg.force_finger0; joint_states.effort[1] = status_msg.force_finger1; g_pub_joint.publish(joint_states); } // Check # of received messages regularly double rate_exp = 1000.0 / (double)interval_ms; std::string names[3] = { "opening", "speed", "force" }; std::chrono::duration<float> t = std::chrono::system_clock::now() - time_start; double t_ = t.count(); if (t_ > 5.0) { time_start = std::chrono::system_clock::now(); //printf("Infos for %5.1fHz, %5.1fHz, %5.1fHz\n", (double)cnt[0]/t_, (double)cnt[1]/t_, (double)cnt[2]/t_); std::string info = "Rates for "; for (int i=0; i<3; i++) { double rate_is = (double)cnt[i]/t_; info += names[i] + ": " + std::to_string((int)rate_is) + "Hz, "; if (rate_is == 0.0) ROS_ERROR("Did not receive data for %s", names[i].c_str()); } ROS_DEBUG_STREAM((info + " expected: " + std::to_string((int)rate_exp) + "Hz").c_str()); cnt[0] = 0; cnt[1] = 0; cnt[2] = 0; } } // Disable automatic updates getOpening(0); getSpeed(0); getForce(0); ROS_INFO("Thread ended"); }
static int gui_demo_status(int id) { const char *status; int jd, kd, ld; int s; /* Find the longest status string. */ for (status = "", s = GAME_NONE; s < GAME_MAX; s++) if (strlen(status_to_str(s)) > strlen(status)) status = status_to_str(s); /* Build info bar with dummy values. */ if ((jd = gui_hstack(id))) { gui_filler(jd); if ((kd = gui_hstack(jd))) { if ((ld = gui_vstack(kd))) { gui_filler(ld); time_id = gui_clock(ld, 35000, GUI_SML); coin_id = gui_count(ld, 100, GUI_SML); status_id = gui_label(ld, status, GUI_SML, gui_red, gui_red); gui_filler(ld); } if ((ld = gui_vstack(kd))) { gui_filler(ld); gui_label(ld, _("Time"), GUI_SML, gui_wht, gui_wht); gui_label(ld, _("Coins"), GUI_SML, gui_wht, gui_wht); gui_label(ld, _("Status"), GUI_SML, gui_wht, gui_wht); gui_filler(ld); } gui_set_rect(kd, GUI_ALL); } gui_space(jd); if ((kd = gui_hstack(jd))) { if ((ld = gui_vstack(kd))) { gui_filler(ld); name_id = gui_label(ld, " ", GUI_SML, 0, 0); player_id = gui_label(ld, " ", GUI_SML, 0, 0); date_id = gui_label(ld, date_to_str(time(NULL)), GUI_SML, 0, 0); gui_filler(ld); gui_set_trunc(name_id, TRUNC_TAIL); gui_set_trunc(player_id, TRUNC_TAIL); } if ((ld = gui_vstack(kd))) { gui_filler(ld); gui_label(ld, _("Replay"), GUI_SML, gui_wht, gui_wht); gui_label(ld, _("Player"), GUI_SML, gui_wht, gui_wht); gui_label(ld, _("Date"), GUI_SML, gui_wht, gui_wht); gui_filler(ld); } gui_set_rect(kd, GUI_ALL); } gui_filler(jd); } return jd; }
static void show_options(const uint8_t *data, int len) { dhcpv6_option_t d6o; uint_t olen, retlen; uint16_t val16; uint16_t type; uint32_t val32; const uint8_t *ostart; char *str, *sp; char *oldnest; /* * Be very careful with negative numbers; ANSI signed/unsigned * comparison doesn't work as expected. */ while (len >= (signed)sizeof (d6o)) { (void) memcpy(&d6o, data, sizeof (d6o)); d6o.d6o_code = ntohs(d6o.d6o_code); d6o.d6o_len = olen = ntohs(d6o.d6o_len); (void) snprintf(get_line(0, 0), get_line_remain(), "Option Code = %u (%s)", d6o.d6o_code, option_to_str(d6o.d6o_code)); ostart = data += sizeof (d6o); len -= sizeof (d6o); if (olen > len) { (void) strlcpy(get_line(0, 0), "Option truncated", get_line_remain()); olen = len; } switch (d6o.d6o_code) { case DHCPV6_OPT_CLIENTID: case DHCPV6_OPT_SERVERID: if (olen < sizeof (val16)) break; (void) memcpy(&val16, data, sizeof (val16)); data += sizeof (val16); olen -= sizeof (val16); type = ntohs(val16); (void) snprintf(get_line(0, 0), get_line_remain(), " DUID Type = %u (%s)", type, duidtype_to_str(type)); if (type == DHCPV6_DUID_LLT || type == DHCPV6_DUID_LL) { if (olen < sizeof (val16)) break; (void) memcpy(&val16, data, sizeof (val16)); data += sizeof (val16); olen -= sizeof (val16); val16 = ntohs(val16); (void) snprintf(get_line(0, 0), get_line_remain(), " Hardware Type = %u (%s)", val16, arp_htype(val16)); } if (type == DHCPV6_DUID_LLT) { time_t timevalue; if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); data += sizeof (val32); olen -= sizeof (val32); timevalue = ntohl(val32) + DUID_TIME_BASE; (void) snprintf(get_line(0, 0), get_line_remain(), " Time = %lu (%.24s)", ntohl(val32), ctime(&timevalue)); } if (type == DHCPV6_DUID_EN) { if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); data += sizeof (val32); olen -= sizeof (val32); val32 = ntohl(val32); (void) snprintf(get_line(0, 0), get_line_remain(), " Enterprise Number = %lu (%s)", val32, entr_to_str(val32)); } if (olen == 0) break; if ((str = malloc(olen * 3)) == NULL) pr_err("interpret_dhcpv6: no mem"); sp = str + snprintf(str, 3, "%02x", *data++); while (--olen > 0) { *sp++ = (type == DHCPV6_DUID_LLT || type == DHCPV6_DUID_LL) ? ':' : ' '; sp = sp + snprintf(sp, 3, "%02x", *data++); } (void) snprintf(get_line(0, 0), get_line_remain(), (type == DHCPV6_DUID_LLT || type == DHCPV6_DUID_LL) ? " Link Layer Address = %s" : " Identifier = %s", str); free(str); break; case DHCPV6_OPT_IA_NA: case DHCPV6_OPT_IA_PD: { dhcpv6_ia_na_t d6in; if (olen < sizeof (d6in) - sizeof (d6o)) break; (void) memcpy(&d6in, data - sizeof (d6o), sizeof (d6in)); data += sizeof (d6in) - sizeof (d6o); olen -= sizeof (d6in) - sizeof (d6o); (void) snprintf(get_line(0, 0), get_line_remain(), " IAID = %u", ntohl(d6in.d6in_iaid)); (void) snprintf(get_line(0, 0), get_line_remain(), " T1 (renew) = %u seconds", ntohl(d6in.d6in_t1)); (void) snprintf(get_line(0, 0), get_line_remain(), " T2 (rebind) = %u seconds", ntohl(d6in.d6in_t2)); nest_options(data, olen, "IA: ", "Identity Association"); break; } case DHCPV6_OPT_IA_TA: { dhcpv6_ia_ta_t d6it; if (olen < sizeof (d6it) - sizeof (d6o)) break; (void) memcpy(&d6it, data - sizeof (d6o), sizeof (d6it)); data += sizeof (d6it) - sizeof (d6o); olen -= sizeof (d6it) - sizeof (d6o); (void) snprintf(get_line(0, 0), get_line_remain(), " IAID = %u", ntohl(d6it.d6it_iaid)); nest_options(data, olen, "IA: ", "Identity Association"); break; } case DHCPV6_OPT_IAADDR: { dhcpv6_iaaddr_t d6ia; if (olen < sizeof (d6ia) - sizeof (d6o)) break; (void) memcpy(&d6ia, data - sizeof (d6o), sizeof (d6ia)); data += sizeof (d6ia) - sizeof (d6o); olen -= sizeof (d6ia) - sizeof (d6o); show_address(" Address", &d6ia.d6ia_addr); (void) snprintf(get_line(0, 0), get_line_remain(), " Preferred lifetime = %u seconds", ntohl(d6ia.d6ia_preflife)); (void) snprintf(get_line(0, 0), get_line_remain(), " Valid lifetime = %u seconds", ntohl(d6ia.d6ia_vallife)); nest_options(data, olen, "ADDR: ", "Address"); break; } case DHCPV6_OPT_ORO: while (olen >= sizeof (val16)) { (void) memcpy(&val16, data, sizeof (val16)); val16 = ntohs(val16); (void) snprintf(get_line(0, 0), get_line_remain(), " Requested Option Code = %u (%s)", val16, option_to_str(val16)); data += sizeof (val16); olen -= sizeof (val16); } break; case DHCPV6_OPT_PREFERENCE: if (olen > 0) { (void) snprintf(get_line(0, 0), get_line_remain(), *data == 255 ? " Preference = %u (immediate)" : " Preference = %u", *data); } break; case DHCPV6_OPT_ELAPSED_TIME: if (olen == sizeof (val16)) { (void) memcpy(&val16, data, sizeof (val16)); val16 = ntohs(val16); (void) snprintf(get_line(0, 0), get_line_remain(), " Elapsed Time = %u.%02u seconds", val16 / 100, val16 % 100); } break; case DHCPV6_OPT_RELAY_MSG: if (olen > 0) { oldnest = prot_nest_prefix; prot_nest_prefix = prot_prefix; retlen = interpret_dhcpv6(F_DTAIL, data, olen); prot_prefix = prot_nest_prefix; prot_nest_prefix = oldnest; } break; case DHCPV6_OPT_AUTH: { dhcpv6_auth_t d6a; if (olen < DHCPV6_AUTH_SIZE - sizeof (d6o)) break; (void) memcpy(&d6a, data - sizeof (d6o), DHCPV6_AUTH_SIZE); data += DHCPV6_AUTH_SIZE - sizeof (d6o); olen += DHCPV6_AUTH_SIZE - sizeof (d6o); (void) snprintf(get_line(0, 0), get_line_remain(), " Protocol = %u (%s)", d6a.d6a_proto, authproto_to_str(d6a.d6a_proto)); (void) snprintf(get_line(0, 0), get_line_remain(), " Algorithm = %u (%s)", d6a.d6a_alg, authalg_to_str(d6a.d6a_proto, d6a.d6a_alg)); (void) snprintf(get_line(0, 0), get_line_remain(), " Replay Detection Method = %u (%s)", d6a.d6a_rdm, authrdm_to_str(d6a.d6a_rdm)); show_hex(d6a.d6a_replay, sizeof (d6a.d6a_replay), " RDM Data"); if (olen > 0) show_hex(data, olen, " Auth Info"); break; } case DHCPV6_OPT_UNICAST: if (olen >= sizeof (in6_addr_t)) show_address(" Server Address", data); break; case DHCPV6_OPT_STATUS_CODE: if (olen < sizeof (val16)) break; (void) memcpy(&val16, data, sizeof (val16)); val16 = ntohs(val16); (void) snprintf(get_line(0, 0), get_line_remain(), " Status Code = %u (%s)", val16, status_to_str(val16)); data += sizeof (val16); olen -= sizeof (val16); if (olen > 0) (void) snprintf(get_line(0, 0), get_line_remain(), " Text = \"%.*s\"", olen, data); break; case DHCPV6_OPT_VENDOR_CLASS: if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); data += sizeof (val32); olen -= sizeof (val32); val32 = ntohl(val32); (void) snprintf(get_line(0, 0), get_line_remain(), " Enterprise Number = %lu (%s)", val32, entr_to_str(val32)); /* FALLTHROUGH */ case DHCPV6_OPT_USER_CLASS: while (olen >= sizeof (val16)) { (void) memcpy(&val16, data, sizeof (val16)); data += sizeof (val16); olen -= sizeof (val16); val16 = ntohs(val16); if (val16 > olen) { (void) strlcpy(get_line(0, 0), " Truncated class", get_line_remain()); val16 = olen; } show_hex(data, olen, " Class"); data += val16; olen -= val16; } break; case DHCPV6_OPT_VENDOR_OPT: { dhcpv6_option_t sd6o; if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); data += sizeof (val32); olen -= sizeof (val32); val32 = ntohl(val32); (void) snprintf(get_line(0, 0), get_line_remain(), " Enterprise Number = %lu (%s)", val32, entr_to_str(val32)); while (olen >= sizeof (sd6o)) { (void) memcpy(&sd6o, data, sizeof (sd6o)); sd6o.d6o_code = ntohs(sd6o.d6o_code); sd6o.d6o_len = ntohs(sd6o.d6o_len); (void) snprintf(get_line(0, 0), get_line_remain(), " Vendor Option Code = %u", d6o.d6o_code); data += sizeof (d6o); olen -= sizeof (d6o); if (sd6o.d6o_len > olen) { (void) strlcpy(get_line(0, 0), " Vendor Option truncated", get_line_remain()); sd6o.d6o_len = olen; } if (sd6o.d6o_len > 0) { show_hex(data, sd6o.d6o_len, " Data"); data += sd6o.d6o_len; olen -= sd6o.d6o_len; } } break; } case DHCPV6_OPT_REMOTE_ID: if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); data += sizeof (val32); olen -= sizeof (val32); val32 = ntohl(val32); (void) snprintf(get_line(0, 0), get_line_remain(), " Enterprise Number = %lu (%s)", val32, entr_to_str(val32)); /* FALLTHROUGH */ case DHCPV6_OPT_INTERFACE_ID: case DHCPV6_OPT_SUBSCRIBER: if (olen > 0) show_hex(data, olen, " ID"); break; case DHCPV6_OPT_RECONF_MSG: if (olen > 0) { (void) snprintf(get_line(0, 0), get_line_remain(), " Message Type = %u (%s)", *data, reconf_to_str(*data)); } break; case DHCPV6_OPT_SIP_NAMES: case DHCPV6_OPT_DNS_SEARCH: case DHCPV6_OPT_NIS_DOMAIN: case DHCPV6_OPT_BCMCS_SRV_D: { dhcp_symbol_t *symp; char *sp2; symp = inittab_getbycode( ITAB_CAT_STANDARD | ITAB_CAT_V6, ITAB_CONS_SNOOP, d6o.d6o_code); if (symp != NULL) { str = inittab_decode(symp, data, olen, B_TRUE); if (str != NULL) { sp = str; do { sp2 = strchr(sp, ' '); if (sp2 != NULL) *sp2++ = '\0'; (void) snprintf(get_line(0, 0), get_line_remain(), " Name = %s", sp); } while ((sp = sp2) != NULL); free(str); } free(symp); } break; } case DHCPV6_OPT_SIP_ADDR: case DHCPV6_OPT_DNS_ADDR: case DHCPV6_OPT_NIS_SERVERS: case DHCPV6_OPT_SNTP_SERVERS: case DHCPV6_OPT_BCMCS_SRV_A: while (olen >= sizeof (in6_addr_t)) { show_address(" Address", data); data += sizeof (in6_addr_t); olen -= sizeof (in6_addr_t); } break; case DHCPV6_OPT_IAPREFIX: { dhcpv6_iaprefix_t d6ip; if (olen < DHCPV6_IAPREFIX_SIZE - sizeof (d6o)) break; (void) memcpy(&d6ip, data - sizeof (d6o), DHCPV6_IAPREFIX_SIZE); data += DHCPV6_IAPREFIX_SIZE - sizeof (d6o); olen -= DHCPV6_IAPREFIX_SIZE - sizeof (d6o); show_address(" Prefix", d6ip.d6ip_addr); (void) snprintf(get_line(0, 0), get_line_remain(), " Preferred lifetime = %u seconds", ntohl(d6ip.d6ip_preflife)); (void) snprintf(get_line(0, 0), get_line_remain(), " Valid lifetime = %u seconds", ntohl(d6ip.d6ip_vallife)); (void) snprintf(get_line(0, 0), get_line_remain(), " Prefix length = %u", d6ip.d6ip_preflen); nest_options(data, olen, "ADDR: ", "Address"); break; } case DHCPV6_OPT_INFO_REFTIME: if (olen < sizeof (val32)) break; (void) memcpy(&val32, data, sizeof (val32)); (void) snprintf(get_line(0, 0), get_line_remain(), " Refresh Time = %lu seconds", ntohl(val32)); break; case DHCPV6_OPT_GEOCONF_CVC: { dhcpv6_civic_t d6c; int solen; if (olen < DHCPV6_CIVIC_SIZE - sizeof (d6o)) break; (void) memcpy(&d6c, data - sizeof (d6o), DHCPV6_CIVIC_SIZE); data += DHCPV6_CIVIC_SIZE - sizeof (d6o); olen -= DHCPV6_CIVIC_SIZE - sizeof (d6o); (void) snprintf(get_line(0, 0), get_line_remain(), " What Location = %u (%s)", d6c.d6c_what, cwhat_to_str(d6c.d6c_what)); (void) snprintf(get_line(0, 0), get_line_remain(), " Country Code = %.*s", sizeof (d6c.d6c_cc), d6c.d6c_cc); while (olen >= 2) { (void) snprintf(get_line(0, 0), get_line_remain(), " CA Element = %u (%s)", *data, catype_to_str(*data)); solen = data[1]; data += 2; olen -= 2; if (solen > olen) { (void) strlcpy(get_line(0, 0), " CA Element truncated", get_line_remain()); solen = olen; } if (solen > 0) { show_ascii(data, solen, " CA Data"); data += solen; olen -= solen; } } break; } case DHCPV6_OPT_CLIENT_FQDN: { dhcp_symbol_t *symp; if (olen == 0) break; (void) snprintf(get_line(0, 0), get_line_remain(), " Flags = %02x", *data); (void) snprintf(get_line(0, 0), get_line_remain(), " %s", getflag(*data, DHCPV6_FQDNF_S, "Perform AAAA RR updates", "No AAAA RR updates")); (void) snprintf(get_line(0, 0), get_line_remain(), " %s", getflag(*data, DHCPV6_FQDNF_O, "Server override updates", "No server override updates")); (void) snprintf(get_line(0, 0), get_line_remain(), " %s", getflag(*data, DHCPV6_FQDNF_N, "Server performs no updates", "Server performs updates")); symp = inittab_getbycode( ITAB_CAT_STANDARD | ITAB_CAT_V6, ITAB_CONS_SNOOP, d6o.d6o_code); if (symp != NULL) { str = inittab_decode(symp, data, olen, B_TRUE); if (str != NULL) { (void) snprintf(get_line(0, 0), get_line_remain(), " FQDN = %s", str); free(str); } free(symp); } break; } } data = ostart + d6o.d6o_len; len -= d6o.d6o_len; } if (len != 0) { (void) strlcpy(get_line(0, 0), "Option entry truncated", get_line_remain()); } }