📄 ldltest.c
字号:
return (sap_first) ? dlsap : dlsap + addr_len;}/* * Build dlsap from addr and sap */void build_dlsap(char *dlsap, char *addr, char *sap){ memcpy(dlsap_addr(dlsap), addr, addr_len); memcpy(dlsap_sap(dlsap), sap, sap_len);}/**************************************************************//* *//* * IP checksum calculation *//* *//* * From: W.R.Stewens: UNIX network programming, *//* * Volume 1, 2nd. edition *//* *//**************************************************************/unsigned short in_cksum(void *addr, int len){ int nleft = len; int sum = 0; unsigned short *w = addr; unsigned short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *) &answer = *(unsigned char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return answer;}/**************************************************************//* *//* * The actual dlpi test routines *//* *//**************************************************************/unsigned long do_findppa(int fd, char *interface){ union { char interface[256]; unsigned long ppa; } data; struct strioctl strioctl; strioctl.ic_cmd = LDL_FINDPPA; strioctl.ic_timout = 3; strioctl.ic_len = sizeof(data); strioctl.ic_dp = (char *) &data; strcpy(data.interface, interface); if (ioctl(fd, I_STR, &strioctl) < 0) { perror("do_findppa: ioctl()"); return (unsigned long) -1; } if (verbose > 2) printf("do_findppa: Interface \"%s\" has PPA %ld\n", interface, data.ppa); return data.ppa;}char *do_getname(int fd){ static char name[256]; struct strioctl strioctl; strioctl.ic_cmd = LDL_GETNAME; strioctl.ic_timout = 3; strioctl.ic_len = sizeof(name); strioctl.ic_dp = (char *) &name; if (ioctl(fd, I_STR, &strioctl) < 0) { perror("do_getname: ioctl()"); return NULL; } if (verbose > 2) printf("do_getname: Interface name is \"%s\"\n", name); return name;}void do_global_stats(void){ int fd; struct strioctl strioctl; ldl_gstats_ioctl_t st; if ((fd = open("/dev/ldl", O_RDWR)) < 0) { perror("open(\"/dev/ldl\")"); exit(1); } strioctl.ic_cmd = LDL_GETGSTATS; strioctl.ic_timout = 3; strioctl.ic_len = sizeof(st); strioctl.ic_dp = (char *) &st; if (ioctl(fd, I_STR, &strioctl) < 0) { perror("do_global_stats: ioctl()"); exit(1); } if (!verbose) return; printf("attach_req_cnt = %lu\n", st.attach_req_cnt); printf("detach_req_cnt = %lu\n", st.detach_req_cnt); printf("bind_req_cnt = %lu\n", st.bind_req_cnt); printf("unbind_req_cnt = %lu\n", st.unbind_req_cnt); printf("subs_bind_req_cnt = %lu\n", st.subs_bind_req_cnt); printf("subs_unbind_req_cnt = %lu\n", st.subs_unbind_req_cnt); printf("udqos_req_cnt = %lu\n", st.udqos_req_cnt); printf("ok_ack_cnt = %lu\n", st.ok_ack_cnt); printf("error_ack_cnt = %lu\n", st.error_ack_cnt); printf("unitdata_req_cnt = %lu\n", st.unitdata_req_cnt); printf("unitdata_req_q_cnt = %lu\n", st.unitdata_req_q_cnt); printf("unitdata_ind_cnt = %lu\n", st.unitdata_ind_cnt); printf("unitdata_q_cnt = %lu\n", st.unitdata_q_cnt); printf("unitdata_drp_cnt = %lu\n", st.unitdata_drp_cnt); printf("uderror_ind_cnt = %lu\n", st.uderror_ind_cnt); printf("ioctl_cnt = %lu\n", st.ioctl_cnt); printf("net_rx_cnt = %lu\n", st.net_rx_cnt); printf("net_rx_drp_cnt = %lu\n", st.net_rx_drp_cnt); printf("net_tx_cnt = %lu\n", st.net_tx_cnt); printf("net_tx_fail_cnt = %lu\n", st.net_tx_fail_cnt);}void do_set_debug_mask(unsigned long msk){ int fd; struct strioctl strioctl; if ((fd = open("/dev/ldl", O_RDWR)) < 0) { perror("open(\"/dev/ldl\")"); exit(1); } strioctl.ic_cmd = LDL_SETDEBUG; strioctl.ic_timout = 3; strioctl.ic_len = sizeof(msk); strioctl.ic_dp = (char *) &msk; if (ioctl(fd, I_STR, &strioctl) < 0) { perror("do_set_debug_mask: ioctl()"); exit(1); }}int do_info(int fd){ dl_info_req_t request; struct { dl_info_ack_t ack; unsigned char extra[1024]; } reply; int flags; struct strbuf ctlbuf; dl_error_ack_t *err_ack; if (verbose > 2) printf("do_info: Sending DL_INFO_REQ\n"); request.dl_primitive = DL_INFO_REQ; ctlbuf.maxlen = ctlbuf.len = sizeof(request); ctlbuf.buf = (char *) &request; if (putmsg(fd, &ctlbuf, NULL, 0) < 0) { perror("do_info: putmsg()"); return -1; } ctlbuf.maxlen = sizeof(reply); ctlbuf.len = 0; ctlbuf.buf = (char *) &reply; flags = RS_HIPRI; flags = 0; if (getmsg(fd, &ctlbuf, NULL, &flags) < 0) { perror("do_info: getmsg()"); return -1; } if (verbose > 2) { printf("do_info: Buffer dump:\n"); dumpbuf(ctlbuf); } if (ctlbuf.len < sizeof(dl_ulong)) { if (verbose) fprintf(stderr, "do_info: Bad reply length %d\n", ctlbuf.len); return -1; } switch (reply.ack.dl_primitive) { case DL_ERROR_ACK: if (verbose) printf("do_info: Got DL_ERROR_ACK\n"); if (ctlbuf.len < sizeof(dl_error_ack_t)) { if (verbose) fprintf(stderr, "do_info: Bad DL_ERROR_ACK length %d\n", ctlbuf.len); return -1; } err_ack = (dl_error_ack_t *) & reply; if (verbose) { printf("do_info: error ack:\n"); printf("\tprimitive=%lu, errno=%lu, unix_errno=%lu\n", err_ack->dl_error_primitive, err_ack->dl_errno, err_ack->dl_unix_errno); } return -1; case DL_INFO_ACK: if (verbose > 2) printf("do_info: Got DL_INFO_ACK\n"); if (ctlbuf.len < sizeof(dl_info_ack_t)) { if (verbose) fprintf(stderr, "do_info: Bad DL_INFO_ACK length %d\n", ctlbuf.len); return -1; } if (verbose > 1) { printf("do_info: info ack:\n"); printf("\tprimitive=%lu\n", reply.ack.dl_primitive); printf("\tmin_sdu=%lu\n", reply.ack.dl_min_sdu); printf("\tmax_sdu=%lu\n", reply.ack.dl_max_sdu); printf("\taddr_length=%lu\n", reply.ack.dl_addr_length); printf("\tmac_type=%lu\n", reply.ack.dl_mac_type); printf("\treserved=%lu\n", reply.ack.dl_reserved); printf("\tcurrent_state=%lu\n", reply.ack.dl_current_state); printf("\tsap_length=%ld\n", reply.ack.dl_sap_length); printf("\tservice_mode=%lu\n", reply.ack.dl_service_mode); printf("\tqos_length=%lu\n", reply.ack.dl_qos_length); printf("\tqos_offset=%lu\n", reply.ack.dl_qos_offset); printf("\tqos_range_length=%lu\n", reply.ack.dl_qos_range_length); printf("\tqos_range_offset=%lu\n", reply.ack.dl_qos_range_offset); printf("\tprovider_style=%ld\n", reply.ack.dl_provider_style); printf("\taddr_offset=%lu\n", reply.ack.dl_addr_offset); printf("\tversion=%lu\n", reply.ack.dl_version); printf("\tbrdcst_addr_length=%lu\n", reply.ack.dl_brdcst_addr_length); printf("\tbrdcst_addr_offset=%lu\n", reply.ack.dl_brdcst_addr_offset); printf("\tgrowth=%lu\n", reply.ack.dl_growth); if (reply.ack.dl_addr_length && reply.ack.dl_addr_offset && reply.ack.dl_addr_offset + reply.ack.dl_addr_length <= ctlbuf.len) dumpaddr("\tAddress", &ctlbuf.buf[reply.ack.dl_addr_offset], reply.ack.dl_addr_length); if (reply.ack.dl_brdcst_addr_length && reply.ack.dl_brdcst_addr_offset && reply.ack.dl_brdcst_addr_offset + reply.ack.dl_brdcst_addr_length <= ctlbuf.len) dumpaddr("\tBroadcast address", &ctlbuf.buf[reply.ack.dl_brdcst_addr_offset], reply.ack.dl_brdcst_addr_length); if (reply.ack.dl_qos_length >= sizeof(unsigned long) && reply.ack.dl_qos_offset) { dl_qos_cl_sel1_t *sel = (dl_qos_cl_sel1_t *) ((char *) &reply.ack + reply.ack.dl_qos_offset); printf("\tQOS selection:\n"); if (sel->dl_qos_type != DL_QOS_CL_SEL1) printf("\t\tUnknown type %lu, expected %lu\n", sel->dl_qos_type, (dl_ulong) DL_QOS_CL_SEL1); else { printf("\t\ttrans_delay=%ld\n", sel->dl_trans_delay); printf("\t\tpriority=%ld\n", sel->dl_priority); printf("\t\tprotection=%ld\n", sel->dl_protection); printf("\t\tresidual_error=%ld\n", sel->dl_residual_error); } } if (reply.ack.dl_qos_range_length >= sizeof(unsigned long) && reply.ack.dl_qos_range_offset) { dl_qos_cl_range1_t *range = (dl_qos_cl_range1_t *) ((char *) &reply.ack + reply.ack.dl_qos_range_offset); printf("\tQOS range:\n"); if (range->dl_qos_type != DL_QOS_CL_RANGE1) printf("\t\tUnknown type %lu, expected %lu\n", range->dl_qos_type, (dl_ulong) DL_QOS_CL_RANGE1); else { printf("\t\ttrans_delay(target, accept)=(%ld, %ld)\n", range->dl_trans_delay.dl_target_value, range->dl_trans_delay.dl_accept_value); printf("\t\tpriority(min, max)=(%ld, %ld)\n", range->dl_priority.dl_min, range->dl_priority.dl_max); printf("\t\tprotection(min, max)=(%ld, %ld)\n", range->dl_protection.dl_min, range->dl_protection.dl_max); printf("\t\tresidual_error=%ld\n", range->dl_residual_error); } } } mac_type = reply.ack.dl_mac_type; if (reply.ack.dl_sap_length < 0) { sap_len = -reply.ack.dl_sap_length; sap_first = 0; } else { sap_len = reply.ack.dl_sap_length; sap_first = 1; } addr_len = reply.ack.dl_addr_length - sap_len; if (reply.ack.dl_addr_length != 0 && reply.ack.dl_addr_offset != 0) { memcpy(my_dlsap, &ctlbuf.buf[reply.ack.dl_addr_offset], addr_len + sap_len); if (sap_first) { memcpy(my_sap, &ctlbuf.buf[reply.ack.dl_addr_offset], sap_len); memcpy(my_addr, &ctlbuf.buf[reply.ack.dl_addr_offset + sap_len], addr_len); } else { memcpy(my_addr, &ctlbuf.buf[reply.ack.dl_addr_offset], addr_len); memcpy(my_sap, &ctlbuf.buf[reply.ack.dl_addr_offset + addr_len], sap_len); } } if (reply.ack.dl_brdcst_addr_length != 0 && reply.ack.dl_brdcst_addr_offset != 0) { assert(reply.ack.dl_addr_length == 0 || reply.ack.dl_brdcst_addr_length == addr_len); memcpy(my_brd_addr, &ctlbuf.buf[reply.ack.dl_brdcst_addr_offset], reply.ack.dl_brdcst_addr_length); } break; default: if (verbose) fprintf(stderr, "do_info: Unknown reply primitive=%lu\n", reply.ack.dl_primitive); return -1; } return 0;}int do_curr_phys_addr(int fd){ dl_phys_addr_req_t request; struct { dl_phys_addr_ack_t ack; unsigned char extra[1024]; } reply; int flags; struct strbuf ctlbuf; dl_error_ack_t *err_ack; if (verbose > 2) printf("do_curr_phys_addr: Sending DL_CURR_PHYS_ADDR\n"); request.dl_primitive = DL_PHYS_ADDR_REQ; request.dl_addr_type = DL_CURR_PHYS_ADDR; ctlbuf.maxlen = ctlbuf.len = sizeof(request); ctlbuf.buf = (char *) &request; if (putmsg(fd, &ctlbuf, NULL, 0) < 0) { perror("do_curr_phys_addr: putmsg()"); return -1; } ctlbuf.maxlen = sizeof(reply); ctlbuf.len = 0; ctlbuf.buf = (char *) &reply; flags = RS_HIPRI; if (getmsg(fd, &ctlbuf, NULL, &flags) < 0) { perror("do_curr_phys_addr: getmsg()"); return -1; } if (verbose > 2) { printf("do_curr_phys_addr: Buffer dump:\n"); dumpbuf(ctlbuf); } if (ctlbuf.len < sizeof(dl_ulong)) { if (verbose) fprintf(stderr, "do_curr_phys_addr: Bad reply length %d\n", ctlbuf.len); return -1; } switch (reply.ack.dl_primitive) { case DL_ERROR_ACK: if (verbose) printf("do_curr_phys_addr: Got DL_ERROR_ACK\n"); if (ctlbuf.len < sizeof(dl_error_ack_t)) { if (verbose) fprintf(stderr, "do_curr_phys_addr: Bad DL_ERROR_ACK length %d\n", ctlbuf.len); return -1; } err_ack = (dl_error_ack_t *) & reply; if (verbose) { printf("do_curr_phys_addr: error ack:\n"); printf("\tprimitive=%lu, errno=%lu, unix_errno=%lu\n", err_ack->dl_error_primitive, err_ack->dl_errno, err_ack->dl_unix_errno); } return -1; case DL_PHYS_ADDR_ACK: if (verbose > 2) printf("do_curr_phys_addr: Got DL_PHYS_ADDR_ACK\n"); if (ctlbuf.len < sizeof(dl_phys_addr_ack_t)) { if (verbose) fprintf(stderr, "do_curr_phys_addr: Bad DL_PHYS_ADDR_ACK length %d\n", ctlbuf.len); return -1; } if (verbose > 1) { printf("do_curr_phys_addr: phys_addr ack:\n"); printf("\tprimitive=%lu\n", reply.ack.dl_primitive); printf("\taddr_length=%lu\n", reply.ack.dl_addr_length); printf("\taddr_offset=%lu\n", reply.ack.dl_addr_offset); if (reply.ack.dl_addr_length && reply.ack.dl_addr_offset && reply.ack.dl_addr_offset + reply.ack.dl_addr_length <= ctlbuf.len) dumpaddr("\tAddress", &ctlbuf.buf[reply.ack.dl_addr_offset], reply.ack.dl_addr_length); } memcpy(my_addr, &ctlbuf.buf[reply.ack.dl_addr_offset], reply.ack.dl_addr_length); break; default: if (verbose) fprintf(stderr, "do_curr_phys_addr: Unknown reply primitive=%lu\n", reply.ack.dl_primitive); return -1; } return 0;}int do_attach(int fd, dl_ulong ppa){ dl_attach_req_t request; struct {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -