static void wlanEventHandler(dspT *dsp, ssize_t length, uint8 *rxbuf) { bcm_event_t *bcmEvent; wl_event_msg_t *wlEvent; int i; if (length == 0 || rxbuf == 0) return; bcmEvent = (bcm_event_t *)rxbuf; wlEvent = &bcmEvent->event; wlEvent->flags = ntoh16(wlEvent->flags); wlEvent->version = ntoh16(wlEvent->version); wlEvent->event_type = ntoh32(wlEvent->event_type); wlEvent->status = ntoh32(wlEvent->status); wlEvent->reason = ntoh32(wlEvent->reason); wlEvent->auth_type = ntoh32(wlEvent->auth_type); wlEvent->datalen = ntoh32(wlEvent->datalen); if (wlEvent->datalen > length - sizeof(bcm_event_t)) { TRACE(TRACE_ERROR, "invalid data length %d > %d\n", wlEvent->datalen, length - sizeof(bcm_event_t)); } for (i = 0; i < MAX_WLAN_HANDLER; i++) { if (dsp->wlanHandler[i].handler != 0) (dsp->wlanHandler[i].handler)( dsp->wlanHandler[i].context, wlEvent->event_type, wlEvent, (uint8 *)&bcmEvent[1], wlEvent->datalen); } }
static inline int _cpy_fbtrace_meta(char* dst, const uint8_t* body, um_elist_entry_t* entry) { int meta_len = ntoh32(entry->data.str.len) - 1; if (meta_len <= FBTRACE_METADATA_SZ) { memcpy(dst, body + ntoh32(entry->data.str.offset), meta_len); } else { return -1; } return 0; }
void wl_event_to_host_order(wl_event_msg_t * evt) { evt->event_type = ntoh32(evt->event_type); evt->flags = ntoh16(evt->flags); evt->status = ntoh32(evt->status); evt->reason = ntoh32(evt->reason); evt->auth_type = ntoh32(evt->auth_type); evt->datalen = ntoh32(evt->datalen); evt->version = ntoh16(evt->version); }
void wl_event_to_host_order(wl_event_msg_t * evt) { /* Event struct members passed from dongle to host are stored in network * byte order. Convert all members to host-order. */ evt->event_type = ntoh32(evt->event_type); evt->flags = ntoh16(evt->flags); evt->status = ntoh32(evt->status); evt->reason = ntoh32(evt->reason); evt->auth_type = ntoh32(evt->auth_type); evt->datalen = ntoh32(evt->datalen); evt->version = ntoh16(evt->version); }
void show_all(struct tcpiphdr *ti) { uint8_t UNUSED *act; int UNUSED i; uint16_t UNUSED *act16; /* act = ti; for(i=0;i<40;i++) { printf("%d: %d ", i, *act); act++; } act16 = ti; for(i=0;i<20;i++) { printf("%d: d%d x%x ", i, *act16, *act16); act16++; } */ printf("\nipovly\n"); printf("ti_next %d\n", ti->ti_next); printf("ti_prev %d\n", ti->ti_prev); printf("ti_x1 %d\n", ti->ti_x1); printf("ti_pr %d\n", ti->ti_pr); printf("ti_len %d\n", ti->ti_len); printf("ti_src %x\n", ti->ti_src.s_addr); printf("ti_dst %x\n", ti->ti_dst.s_addr); /* printf("ti_len %d\n", ntoh16(ti->ti_len)); printf("ti_src %x\n", ntoh32(ti->ti_src.s_addr)); printf("ti_dst %x\n", ntoh32(ti->ti_dst.s_addr)); */ printf("\ntcp header\n"); /* printf("ti_sport %d\n", ti->ti_sport); printf("ti_dport %d\n", ti->ti_dport); printf("ti_seq %d\n", ti->ti_seq); printf("ti_ack %d\n", ti->ti_ack); printf("ti_win %d\n", ti->ti_win); printf("ti_sum %d\n", ti->ti_sum); printf("ti_urp %d\n", ti->ti_urp); */ printf("ti_sport %d\n", ntoh16(ti->ti_sport)); printf("ti_dport %d\n", ntoh16(ti->ti_dport)); printf("ti_seq %d\n", ntoh32(ti->ti_seq)); printf("ti_ack %d\n", ntoh32(ti->ti_ack)); printf("ti_win %d\n", ntoh16(ti->ti_win)); printf("ti_sum %d\n", ntoh16(ti->ti_sum)); printf("ti_urp %d\n", ntoh16(ti->ti_urp)); }
t_osc_err osc_mem_decodeByteorder(unsigned char typetag, char *data, char **out) { size_t size = osc_sizeof(typetag, data); if(!osc_mem_shouldByteswap(typetag)){ memcpy(*out, data, size); return OSC_ERR_NONE; } char tmp[size]; switch(size){ case 1: break; case 2: *((uint16_t *)tmp) = ntoh16(*((uint16_t *)data)); break; case 4: *((uint32_t *)tmp) = ntoh32(*((uint32_t *)data)); break; case 8: *((uint64_t *)tmp) = ntoh64(*((uint64_t *)data)); break; case 16: *((uint128_t *)tmp) = ntoh128(*((uint128_t *)data)); break; } memcpy(*out, tmp, size); return OSC_ERR_NONE; }
void print_array_dual (const unsigned char* array, int size) { // prints contents of an array int idx; int block; #define NBLOCKS 4 size /= sizeof(u_int32_t); for (block = 0; block < size; block += NBLOCKS) { char ascii4[6]; char ascii[128] = { 0, }; for (idx = block; idx < block + NBLOCKS; idx++) { #define H(v) ((unsigned char)(v)) // reads 32 bits word numbered idx and converts it to host endian format if necessary // (assuming gba/arm's endianness is little-endian like network's convention) u_int32_t v; if (idx < size) v = ntoh32(((u_int32_t*)array)[idx]); else v = 0xffffffff; // print big endian first print("%02x %02x %02x %02x - ", H(v), H(v>>8), H(v>>16), H(v>>24)); sprintf(ascii4, "%c%c%c%c ", ASCII(v), ASCII(v>>8), ASCII(v>>16), ASCII(v>>24)); strcat(ascii, ascii4); } print("%s\n", ascii); } }
//获取一个文件列表(每个文件有路径和文件类型两个属性) vector<file_info> get_server_list(SSL *ssl) { vector<file_info> file_list; uint32_t file_count = 0; int i = 0; char file_type; char *file_path; ssl_read_wrapper(ssl, &file_count, 4); file_count = ntoh32(file_count); for(i = 0; i < (int)file_count; i++) { file_path = read_string(ssl); if(!is_path_safe(std::string(file_path))) { fprintf(stderr, "remote host sent illegal path, aborted\n"); exit(1); } ssl_read_wrapper(ssl, &file_type, 1); file_info store(file_path, file_type); file_list.push_back(store); free(file_path); } return file_list; }
static void getAllMCMemberRecords(AllocFunction alloc, void *allocUd, int fd, int agent, UInt16 smLid, SInt32 *numMRs, struct MCMemberRecord **MRs) { UInt8 umad[256]; UInt8 *buf = NULL; SInt64 len; SInt32 status; SInt64 i, n; SInt32 offset; struct _MCMemberRecord *p; const SInt32 timeout = 1000; fillMAD_Get_MCMemberRecord(umad, sizeof(umad), smLid, 0, __LINE__); libibumad_Send_MAD(fd, agent, umad, sizeof(umad), timeout, 0); libibumad_Recv_MAD(alloc, allocUd, fd, &buf, &len, timeout); status = mad_get_field(umad_get_mad(buf), 0, IB_MAD_STATUS_F); if (UNLIKELY(0 != status)) { FATAL("status is %d", status); } /* RMPP packets. */ offset = mad_get_field(umad_get_mad(buf), 0, IB_SA_ATTROFFS_F); if (UNLIKELY(0 == offset)) { FATAL("SA attribute offset is zero."); } n = (len - IB_SA_DATA_OFFS)/(offset << 3); /* offset is in 8 byte units */ *numMRs = n; *MRs = alloc(allocUd, NULL, 0, (*numMRs)*sizeof(struct MCMemberRecord)); for (i = 0 ; i < n; ++i) { p = (struct _MCMemberRecord *)((UInt8 *)umad_get_mad(buf) + IB_SA_DATA_OFFS + i*(offset << 3)); memcpy((*MRs)[i].mgid, p->mgid, 16); memcpy((*MRs)[i].portGid, p->portGid, 16); (*MRs)[i].qkey = ntoh32(p->qkey); (*MRs)[i].mlid = ntoh16(p->mlid); (*MRs)[i].mtu = p->mtu; (*MRs)[i].tclass = p->tclass; (*MRs)[i].pkey = ntoh16(p->pkey); (*MRs)[i].rate = p->rate; (*MRs)[i].packetLife = p->packetLife; /* FIXME (*MRs)[i].serviceLevel = p->serviceLevel; (*MRs)[i].flowLabel = ntoh32(p->flowLabel); (*MRs)[i].hopLimit = p->hopLimit; */ (*MRs)[i].scope = (p->scope_joinState & 0xf0) >> 4; (*MRs)[i].joinState = p->scope_joinState & 0x0f; (*MRs)[i].proxyJoin = p->proxyJoin; } buf = alloc(allocUd, buf, len, 0); }
void i_am_alive_response_received( tNode* pNode, IAnnexET00IAmAlive* pPayload ) { /* do nothing! remote_host_is_alive() is called from process_pdu() ;-) */ if (sizeof_IAmAliveCookie( pPayload ) >= 4) { UINT32 send_time = ntoh32( &pPayload[IAnnexET00IAmAlive_COOKIE] ); msaPrintFormat( pNode->pAnnexE->msaType, "IAmAlive response from Host(%08x:%i), delay( %ims )", pNode->RemoteHost.nIP, pNode->RemoteHost.nPort, timerGetTimeInMilliseconds() - send_time ); } }
int gtpie_gettv4(union gtpie_member* ie[], int type, int instance, uint32_t *dst){ int ien; ien = gtpie_getie(ie, type, instance); if (ien>=0) *dst = ntoh32(ie[ien]->tv4.v); else return EOF; return 0; }
static yrmcds_error parse_dump_record(yrmcds_cnt* c, yrmcds_cnt_response* r) { if( r->body_length == 0 ) { // End of dump return YRMCDS_OK; } if( r->body_length < 10 ) { c->invalid = 1; return YRMCDS_PROTOCOL_ERROR; } r->current_consumption = ntoh32(r->body); r->max_consumption = ntoh32(r->body + 4); r->name_length = ntoh16(r->body + 8); if( r->body_length < 10 + r->name_length ) { c->invalid = 1; return YRMCDS_PROTOCOL_ERROR; } r->name = r->body + 10; return YRMCDS_OK; }
/* send up locally generated event */ void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { default: break; } /* Call per-port handler. */ dhd_sendup_event(dhdp, event, data); }
size_t osc_sizeof(unsigned char typetag, char *data){ if(typetag > 127){ return -1; } if(!data){ return -1; } switch(typetag){ case 'b': return ntoh32(*((int32_t *)data)) + 4; case 's': case 'S': return osc_util_getPaddedStringLen(data); case OSC_BUNDLE_TYPETAG: return ntoh32(*((uint32_t *)data)) + 4; case OSC_TIMETAG_TYPETAG: return OSC_TIMETAG_SIZEOF; default: return osc_data_lengths[typetag]; } }
int32_t osc_message_s_getSize(t_osc_msg_s *m) { if(m){ if(m->size){ return ntoh32(*((int32_t *)(m->size))); }else{ return 0; } }else{ return 0; } }
void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { default: break; } dhd_sendup_event(dhdp, event, data); }
FSTATUS getFwVersion(struct oib_port *port, IB_PATH_RECORD *path, VENDOR_MAD *mad, uint16 sessionID, uint8 *fwVersion) { FSTATUS status; uint8 fwVerBuf[FWVERSION_SIZE]; uint32 fwUpper; uint32 fwLower; status = sendGetFwVersionMad(port, path, mad, sessionID, fwVerBuf); if (status == FSUCCESS) { fwUpper = ntoh32(*(uint32 *)&fwVerBuf[0]); fwLower = ntoh32(*(uint32 *)&fwVerBuf[4]); sprintf((char *)fwVersion, "%d.%d.%d.%d.%d", (fwUpper >> 24) & 0xff, (fwUpper >> 16) & 0xff, (fwUpper >> 8) & 0xff, fwUpper & 0xff, fwLower); }
/*** Packet formation *********************************************************/ int pptp_make_packet(PPTP_CONN * conn, void **buf, size_t *size) { struct pptp_header *header; size_t bad_bytes = 0; assert(conn && conn->call); assert(buf != NULL); assert(size != NULL); /* Give up unless there are at least sizeof(pptp_header) bytes */ while ((conn->read_size-bad_bytes) >= sizeof(struct pptp_header)) { /* Throw out bytes until we have a valid header. */ header = (struct pptp_header *) (conn->read_buffer + bad_bytes); if (ntoh32(header->magic) != PPTP_MAGIC) goto throwitout; if (ntoh16(header->reserved0) != 0) log("reserved0 field is not zero! (0x%x) Cisco feature? \n", ntoh16(header->reserved0)); if (ntoh16(header->length) < sizeof(struct pptp_header)) goto throwitout; if (ntoh16(header->length) > PPTP_CTRL_SIZE_MAX) goto throwitout; /* well. I guess it's good. Let's see if we've got it all. */ if (ntoh16(header->length) > (conn->read_size-bad_bytes)) /* nope. Let's wait until we've got it, then. */ goto flushbadbytes; /* One last check: */ if ((ntoh16(header->pptp_type) == PPTP_MESSAGE_CONTROL) && (ntoh16(header->length) != PPTP_CTRL_SIZE(ntoh16(header->ctrl_type)))) goto throwitout; /* well, I guess we've got it. */ *size = ntoh16(header->length); *buf = malloc(*size); if (*buf == NULL) { log("Out of memory."); return 0; /* ack! */ } memcpy(*buf, conn->read_buffer + bad_bytes, *size); /* Delete this packet from the read_buffer. */ conn->read_size -= (bad_bytes + *size); memmove(conn->read_buffer, conn->read_buffer + bad_bytes + *size, conn->read_size); if (bad_bytes > 0) log("%lu bad bytes thrown away.", (unsigned long) bad_bytes); return 1; throwitout: bad_bytes++; } flushbadbytes: /* no more packets. Let's get rid of those bad bytes */ conn->read_size -= bad_bytes; memmove(conn->read_buffer, conn->read_buffer + bad_bytes, conn->read_size); if (bad_bytes > 0) log("%lu bad bytes thrown away.", (unsigned long) bad_bytes); return 0; }
/* RC - Server only, UD - Server and Client, one per EP */ void process_cr(int idx) { DAT_EVENT event; DAT_COUNT nmore; DAT_RETURN status; int pdata; DAT_CR_HANDLE cr = DAT_HANDLE_NULL; DAT_CONN_QUAL exp_qual = server ? SERVER_ID : CLIENT_ID; DAT_CR_PARAM cr_param; DAT_CR_ARRIVAL_EVENT_DATA *cr_event = &event.event_data.cr_arrival_event_data; LOGPRINTF("%s waiting for connect[%d] request\n", server ? "Server" : "Client", idx); status = dat_evd_wait(cr_evd, SERVER_TIMEOUT, 1, &event, &nmore); _OK(status, "CR dat_evd_wait"); if (event.event_number != DAT_CONNECTION_REQUEST_EVENT && (ud_test && event.event_number != DAT_IB_UD_CONNECTION_REQUEST_EVENT)) { printf("unexpected event,!conn req: 0x%x\n", event.event_number); exit(1); } if ((cr_event->conn_qual != exp_qual) || (cr_event->sp_handle.psp_handle != psp)) { printf("wrong cr event data\n"); exit(1); } cr = cr_event->cr_handle; status = dat_cr_query(cr, DAT_CSP_FIELD_ALL, &cr_param); _OK(status, "dat_cr_query"); /* use private data to select EP */ pdata = ntoh32(*((int *)cr_param.private_data)); LOGPRINTF("%s recvd pdata=0x%x, send pdata=0x%x\n", server ? "Server" : "Client", pdata, *(int *)cr_param.private_data); status = dat_cr_accept(cr, ep[pdata], 4, cr_param.private_data); _OK(status, "dat_cr_accept"); printf("%s accepted CR on EP[%d]=%p\n", server ? "Server" : "Client", pdata, ep[pdata]); }
static void hw_parse_special_dhcp_packet(uint8_t *buff, uint32_t buflen, uint8_t *dst) { uint8_t type = 0; uint32_t req_ip = 0; uint32_t req_srv = 0; uint32_t len = 0; struct dhcp_message *msg; if (buflen <= sizeof(struct dhcp_message)) { HW_PRINT_HI("%s: invalid dhcp packet\n", __func__); return; } msg = (struct dhcp_message *)buff; len = buflen - sizeof(struct dhcp_message); if (hw_dhcp_get_option_uint8(&type, msg->options, len, DHO_MESSAGETYPE) == -1) { HW_PRINT_HI("%s: get message type failed\n", __func__); return; } if (type == DHCP_DISCOVER) { HW_PRINT_HI("%s: type: DHCP_DISCOVER\n", __func__); } else if (type == DHCP_OFFER) { HW_PRINT_HI("%s: type: DHCP_OFFER, ip:%d.%d.%d.%d srvip:%d.%d.%d.%d MAC:" HWMACSTR "\n", __func__, IPADDR(msg->yiaddr), IPADDR(msg->siaddr), HWMAC2STR(dst)); } else if (type == DHCP_REQUEST) { hw_dhcp_get_option_uint32(&req_ip, msg->options, len, DHO_IPADDRESS); hw_dhcp_get_option_uint32(&req_srv, msg->options, len, DHO_SERVERID); req_ip = ntoh32(req_ip); req_srv = ntoh32(req_srv); HW_PRINT_HI("%s: type: DHCP_REQUEST, ip:%d.%d.%d.%d srvip:%d.%d.%d.%d\n", __func__, IPADDR(req_ip), IPADDR(req_srv)); } else if (type == DHCP_ACK) { HW_PRINT_HI("%s: type: DHCP_ACK MAC:" HWMACSTR "\n", __func__, HWMAC2STR(dst)); } else if (type == DHCP_NAK) { HW_PRINT_HI("%s: type: DHCP_NAK MAC:" HWMACSTR "\n", __func__, HWMAC2STR(dst)); } }
frm_frame *fetchFRMFrame(unsigned char *buf, uint32_t buflen, uint8_t direct) { int i = 0; frm_frame *frame = malloc(sizeof(frm_frame)); if (!frame || buflen < 8) return NULL; frame->orient = direct; frame->width = ntoh16(buf, FRMFRAME_OFFSET_WIDTH); frame->height = ntoh16(buf, FRMFRAME_OFFSET_HEIGHT); frame->framesize = ntoh32(buf, FRMFRAME_OFFSET_SIZE); if (frame->framesize != frame->width * frame->height) { printf("ERR: Framesize different: %d %d\n", frame->framesize, frame->width * frame->height); return NULL; } if (buflen < (12 + frame->width * frame->height) ) { return NULL; } frame->rowptr = malloc( sizeof(unsigned char *) * frame->height); if (!frame->rowptr) { printf("ERROR: no memory\n"); free(frame); return NULL; } for(i=0; i < frame->height; ++i) { frame->rowptr[i] = malloc(sizeof(unsigned char) * frame->width); if (!frame->rowptr[i]) { printf("ERROR: no memory\n"); free(frame); return NULL; } memcpy(frame->rowptr[i], &buf[12]+i*frame->width, frame->width); } frame->next_frame = NULL; return frame; }
/*** Packet Dispatch **********************************************************/ int pptp_dispatch_packet(PPTP_CONN * conn, void * buffer, size_t size) { int r = 0; struct pptp_header *header = (struct pptp_header *)buffer; assert(conn && conn->call); assert(buffer); assert(ntoh32(header->magic) == PPTP_MAGIC); assert(ntoh16(header->length) == size); switch (ntoh16(header->pptp_type)) { case PPTP_MESSAGE_CONTROL: r = ctrlp_disp(conn, buffer, size); break; case PPTP_MESSAGE_MANAGE: /* MANAGEMENT messages aren't even part of the spec right now. */ log("PPTP management message received, but not understood."); break; default: log("Unknown PPTP control message type received: %u", (unsigned int) ntoh16(header->pptp_type)); break; } return r; }
t_osc_err osc_message_s_wrap(t_osc_msg_s *m, char *bytes) { if(!m || !bytes){ return OSC_ERR_NULLPTR; } int32_t len = ntoh32(*((int32_t *)bytes)); m->size = bytes; char *address = m->address = bytes + 4; /* if(!(m->address)){ return OSC_ERR_MALFORMEDADDRESS; } if(m->address[0] != '/'){ return OSC_ERR_MALFORMEDADDRESS; } */ /* m->typetags = bytes + 4 + strlen(bytes + 4) + 1; while((m->typetags - bytes) % 4){ m->typetags++; } */ char *tt = m->typetags = address + osc_util_getPaddedStringLen(address); if((tt - bytes) > len){ m->typetags = NULL; // this isn't really cool--if there is no data, there should at least be a // comma and 3 NULLs. we'll let it go anyway... return OSC_ERR_NONE; } /* m->data = m->typetags + strlen(m->typetags) + 1; while((m->data - bytes) % 4){ m->data++; } */ m->data = tt + osc_util_getPaddedStringLen(tt); return OSC_ERR_NONE; }
um_status_t um_parse_header(const uint8_t* buf, size_t nbuf, um_message_info_t* info_out) { FBI_ASSERT(info_out); if (nbuf < sizeof(entry_list_msg_t)) { return um_not_enough_data; } entry_list_msg_t* header = (entry_list_msg_t*) buf; if (header->msg_header.magic_byte != ENTRY_LIST_MAGIC_BYTE) { return um_not_umbrella_message; } info_out->message_size = ntoh32(header->total_size); uint16_t nentries = ntoh16(header->nentries); info_out->header_size = sizeof(entry_list_msg_t) + sizeof(um_elist_entry_t) * nentries; if (info_out->header_size > info_out->message_size) { return um_header_parse_error; } info_out->body_size = info_out->message_size - info_out->header_size; return um_ok; }
int wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, wl_event_msg_t *event, void **data_ptr) { /* check whether packet is a BRCM event pkt */ bcm_event_t *pvt_data = (bcm_event_t *)pktdata; char *event_data; uint32 type, status; uint16 flags; int evlen; if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) return (BCME_ERROR); /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) return (BCME_ERROR); *data_ptr = &pvt_data[1]; event_data = *data_ptr; /* memcpy since BRCM event pkt may be unaligned. */ memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); type = ntoh32_ua((void *)&event->event_type); flags = ntoh16_ua((void *)&event->flags); status = ntoh32_ua((void *)&event->status); evlen = ntoh32_ua((void *)&event->datalen) + sizeof(bcm_event_t); switch (type) { case WLC_E_IF: { dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) { if (ifevent->action == WLC_E_IF_ADD) dhd_add_if(dhd, ifevent->ifidx, NULL, event->ifname, pvt_data->eth.ether_dhost, ifevent->flags, ifevent->bssidx); else dhd_del_if(dhd, ifevent->ifidx); } else { DHD_ERROR(("%s: Invalid ifidx %d for %s\n", __FUNCTION__, ifevent->ifidx, event->ifname)); } } /* send up the if event: btamp user needs it */ *ifidx = dhd_ifname2idx(dhd, event->ifname); /* push up to external supp/auth */ dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); break; /* fall through */ /* These are what external supplicant/authenticator wants */ case WLC_E_LINK: case WLC_E_ASSOC_IND: case WLC_E_REASSOC_IND: case WLC_E_DISASSOC_IND: case WLC_E_MIC_ERROR: default: /* Fall through: this should get _everything_ */ *ifidx = dhd_ifname2idx(dhd, event->ifname); /* push up to external supp/auth */ dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", __FUNCTION__, type, flags, status)); /* put it back to WLC_E_NDIS_LINK */ if (type == WLC_E_NDIS_LINK) { uint32 temp; temp = ntoh32_ua((void *)&event->event_type); DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); temp = ntoh32(WLC_E_NDIS_LINK); memcpy((void *)(&pvt_data->event.event_type), &temp, sizeof(pvt_data->event.event_type)); } break; } #ifdef SHOW_EVENTS wl_show_host_event(event, event_data); #endif /* SHOW_EVENTS */ return (BCME_OK); }
static void wl_show_host_event(wl_event_msg_t *event, void *event_data) { uint i, status, reason; bool group = FALSE, flush_txq = FALSE, link = FALSE; char *auth_str, *event_name; uchar *buf; char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; static struct {uint event; char *event_name;} event_names[] = { {WLC_E_SET_SSID, "SET_SSID"}, {WLC_E_JOIN, "JOIN"}, {WLC_E_START, "START"}, {WLC_E_AUTH, "AUTH"}, {WLC_E_AUTH_IND, "AUTH_IND"}, {WLC_E_DEAUTH, "DEAUTH"}, {WLC_E_DEAUTH_IND, "DEAUTH_IND"}, {WLC_E_ASSOC, "ASSOC"}, {WLC_E_ASSOC_IND, "ASSOC_IND"}, {WLC_E_REASSOC, "REASSOC"}, {WLC_E_REASSOC_IND, "REASSOC_IND"}, {WLC_E_DISASSOC, "DISASSOC"}, {WLC_E_DISASSOC_IND, "DISASSOC_IND"}, {WLC_E_QUIET_START, "START_QUIET"}, {WLC_E_QUIET_END, "END_QUIET"}, {WLC_E_BEACON_RX, "BEACON_RX"}, {WLC_E_LINK, "LINK"}, {WLC_E_MIC_ERROR, "MIC_ERROR"}, {WLC_E_NDIS_LINK, "NDIS_LINK"}, {WLC_E_ROAM, "ROAM"}, {WLC_E_TXFAIL, "TXFAIL"}, {WLC_E_PMKID_CACHE, "PMKID_CACHE"}, {WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {WLC_E_PRUNE, "PRUNE"}, {WLC_E_AUTOAUTH, "AUTOAUTH"}, {WLC_E_EAPOL_MSG, "EAPOL_MSG"}, {WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {WLC_E_ADDTS_IND, "ADDTS_IND"}, {WLC_E_DELTS_IND, "DELTS_IND"}, {WLC_E_BCNSENT_IND, "BCNSENT_IND"}, {WLC_E_BCNRX_MSG, "BCNRX_MSG"}, {WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, {WLC_E_ROAM_PREP, "ROAM_PREP"}, {WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, {WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, {WLC_E_JOIN_START, "JOIN_START"}, {WLC_E_ROAM_START, "ROAM_START"}, {WLC_E_ASSOC_START, "ASSOC_START"}, {WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, {WLC_E_RADIO, "RADIO"}, {WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, {WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {WLC_E_PSK_SUP, "PSK_SUP"}, {WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {WLC_E_ICV_ERROR, "ICV_ERROR"}, {WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {WLC_E_TRACE, "TRACE"}, {WLC_E_ACTION_FRAME, "ACTION FRAME"}, {WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {WLC_E_IF, "IF"}, {WLC_E_RSSI, "RSSI"}, {WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} }; uint event_type, flags, auth_type, datalen; event_type = ntoh32(event->event_type); flags = ntoh16(event->flags); status = ntoh32(event->status); reason = ntoh32(event->reason); auth_type = ntoh32(event->auth_type); datalen = ntoh32(event->datalen); /* debug dump of event messages */ sprintf(eabuf, "%02x:%02x:%02x:%02x:%02x:%02x", (uchar)event->addr.octet[0]&0xff, (uchar)event->addr.octet[1]&0xff, (uchar)event->addr.octet[2]&0xff, (uchar)event->addr.octet[3]&0xff, (uchar)event->addr.octet[4]&0xff, (uchar)event->addr.octet[5]&0xff); event_name = "UNKNOWN"; for (i = 0; i < ARRAYSIZE(event_names); i++) { if (event_names[i].event == event_type) event_name = event_names[i].event_name; } if (flags & WLC_EVENT_MSG_LINK) link = TRUE; if (flags & WLC_EVENT_MSG_GROUP) group = TRUE; if (flags & WLC_EVENT_MSG_FLUSHTXQ) flush_txq = TRUE; switch (event_type) { case WLC_E_START: case WLC_E_DEAUTH: case WLC_E_DISASSOC: DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; case WLC_E_ASSOC_IND: case WLC_E_REASSOC_IND: #ifdef APSTA_PINGTEST { int i; for (i = 0; i < MAX_GUEST; ++i) if (ETHER_ISNULLADDR(&guest_eas[i])) break; if (i < MAX_GUEST) bcopy(event->addr.octet, guest_eas[i].octet, ETHER_ADDR_LEN); } #endif /* APSTA_PINGTEST */ DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; case WLC_E_ASSOC: case WLC_E_REASSOC: if (status == WLC_E_STATUS_SUCCESS) { DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf)); } else if (status == WLC_E_STATUS_TIMEOUT) { DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf)); } else if (status == WLC_E_STATUS_FAIL) { DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", event_name, eabuf, (int)reason)); } else { DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status %d\n", event_name, eabuf, (int)status)); } break; case WLC_E_DEAUTH_IND: case WLC_E_DISASSOC_IND: #ifdef APSTA_PINGTEST { int i; for (i = 0; i < MAX_GUEST; ++i) { if (bcmp(guest_eas[i].octet, event->addr.octet, ETHER_ADDR_LEN) == 0) { bzero(guest_eas[i].octet, ETHER_ADDR_LEN); break; } } } #endif /* APSTA_PINGTEST */ DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason)); break; case WLC_E_AUTH: case WLC_E_AUTH_IND: if (auth_type == DOT11_OPEN_SYSTEM) auth_str = "Open System"; else if (auth_type == DOT11_SHARED_KEY) auth_str = "Shared Key"; else { sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); auth_str = err_msg; } if (event_type == WLC_E_AUTH_IND) { DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str)); } else if (status == WLC_E_STATUS_SUCCESS) { DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", event_name, eabuf, auth_str)); } else if (status == WLC_E_STATUS_TIMEOUT) { DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", event_name, eabuf, auth_str)); } else if (status == WLC_E_STATUS_FAIL) { DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", event_name, eabuf, auth_str, (int)reason)); } break; case WLC_E_JOIN: case WLC_E_ROAM: case WLC_E_SET_SSID: if (status == WLC_E_STATUS_SUCCESS) { DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); } else if (status == WLC_E_STATUS_FAIL) { DHD_EVENT(("MACEVENT: %s, failed\n", event_name)); } else if (status == WLC_E_STATUS_NO_NETWORKS) { DHD_EVENT(("MACEVENT: %s, no networks found\n", event_name)); } else { DHD_EVENT(("MACEVENT: %s, unexpected status %d\n", event_name, (int)status)); } break; case WLC_E_BEACON_RX: if (status == WLC_E_STATUS_SUCCESS) { DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); } else if (status == WLC_E_STATUS_FAIL) { DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name)); } else { DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, status)); } break; case WLC_E_LINK: DHD_EVENT(("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN")); break; case WLC_E_MIC_ERROR: DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", event_name, eabuf, group, flush_txq)); break; case WLC_E_ICV_ERROR: case WLC_E_UNICAST_DECODE_ERROR: case WLC_E_MULTICAST_DECODE_ERROR: DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; case WLC_E_TXFAIL: DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); break; case WLC_E_SCAN_COMPLETE: case WLC_E_PMKID_CACHE: DHD_EVENT(("MACEVENT: %s\n", event_name)); break; case WLC_E_PFN_NET_FOUND: case WLC_E_PFN_NET_LOST: case WLC_E_PFN_SCAN_COMPLETE: DHD_EVENT(("PNOEVENT: %s\n", event_name)); break; case WLC_E_PSK_SUP: case WLC_E_PRUNE: DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n", event_name, (int)status, (int)reason)); break; case WLC_E_TRACE: { static uint32 seqnum_prev = 0; msgtrace_hdr_t hdr; uint32 nblost; char *s, *p; buf = (uchar *) event_data; memcpy(&hdr, buf, MSGTRACE_HDRLEN); if (hdr.version != MSGTRACE_VERSION) { printf("\nMACEVENT: %s [unsupported version --> " "dhd version:%d dongle version:%d]\n", event_name, MSGTRACE_VERSION, hdr.version); /* Reset datalen to avoid display below */ datalen = 0; break; } /* There are 2 bytes available at the end of data */ buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" "discarded_bytes %d discarded_printf %d]\n", ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); } nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; if (nblost > 0) { printf("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", ntoh32(hdr.seqnum), nblost); } seqnum_prev = ntoh32(hdr.seqnum); /* Display the trace buffer. Advance from \n to \n to avoid display big * printf (issue with Linux printk ) */ p = &(buf[MSGTRACE_HDRLEN]); while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; printf("%s\n", p); p = s+1; } printf("%s\n", p); /* Reset datalen to avoid display below */ datalen = 0; } break; case WLC_E_RSSI: DHD_EVENT(("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data)))); break; default: DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", event_name, event_type, eabuf, (int)status, (int)reason, (int)auth_type)); break; } /* show any appended data */ if (datalen) { buf = (uchar *) event_data; DHD_EVENT((" data (%d) : ", datalen)); for (i = 0; i < datalen; i++) DHD_EVENT((" 0x%02x ", *buf++)); DHD_EVENT(("\n")); } }
s32 wl_cfgnan_notify_nan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data) { s32 ret = BCME_OK; u16 data_len; u32 event_num; s32 event_type; nan_event_hdr_t nan_hdr; wl_nan_tlv_data_t tlv_data; u8 *buf = NULL; u32 buf_len; u8 *ptr; u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; if (!event || !data) { WL_ERR((" event data is NULL \n")); return -EINVAL; } event_type = ntoh32(event->event_type); event_num = ntoh32(event->reason); data_len = ntoh32(event->datalen); memset(&nan_hdr, 0, sizeof(nan_event_hdr_t)); nan_hdr.event_subtype = event_num; WL_DBG((" nan event: type: %d num: %d len: %d \n", event_type, event_num, data_len)); if (INVALID_NAN_EVENT(event_num)) { WL_ERR((" unsupported event, num: %d \n", event_num)); return -EINVAL; } if (g_nan_debug) { WL_DBG((" event name: %s \n", nan_event_name[event_num])); WL_DBG((" event data: \n")); prhex(NULL, data, data_len); } /* unpack the tlvs */ memset(&tlv_data, 0, sizeof(wl_nan_tlv_data_t)); bcm_unpack_xtlv_buf(&tlv_data, data, data_len, wl_cfgnan_set_vars_cbfn); /* * send as preformatted hex string * * EVENT_NAN <event_type> <tlv_hex_string> */ buf_len = NAN_IOCTL_BUF_SIZE; buf = ptr = kzalloc(buf_len, kflags); if (!buf) { WL_ERR((" memory allocation failed \n")); ret = -ENOMEM; goto fail; } switch (event_num) { case WL_NAN_EVENT_START: case WL_NAN_EVENT_JOIN: case WL_NAN_EVENT_STOP: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF, nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid)); break; case WL_NAN_EVENT_ROLE: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s "ROLE_PREFIX "%d " CLUS_ID_PREFIX MACF, nan_event_str[event_num], tlv_data.nstatus.role, ETHER_TO_MACF(tlv_data.nstatus.cid)); break; case WL_NAN_EVENT_DISCOVERY_RESULT: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d " SUB_ID_PREFIX"%d " MAC_ADDR_PREFIX MACF, nan_event_str[event_num], tlv_data.pub_id, tlv_data.sub_id, ETHER_TO_MACF(tlv_data.mac_addr)); if (tlv_data.svc_info.data && tlv_data.svc_info.dlen) { WL_DBG((" service info present \n")); if ((strlen(ptr) + tlv_data.svc_info.dlen) >= buf_len) { WL_ERR((" service info length = %d\n", tlv_data.svc_info.dlen)); WL_ERR((" insufficent buffer to copy service info \n")); ret = -EOVERFLOW; goto fail; } ptr += sprintf(ptr, " %s", SVC_INFO_PREFIX); ptr += bcm_format_hex(ptr, tlv_data.svc_info.data, tlv_data.svc_info.dlen); } else { WL_DBG((" service info not present \n")); } if (tlv_data.vend_info.data && tlv_data.vend_info.dlen) { struct ether_addr *ea; u8 *data = tlv_data.vend_info.data; uint32 bitmap; u16 dlen = tlv_data.vend_info.dlen; chanspec_t chanspec; uint8 mapcontrol; uint8 proto; WL_DBG((" vendor info present \n")); if ((*data != NAN_ATTR_VENDOR_SPECIFIC) || (dlen < NAN_VENDOR_HDR_SIZE)) { WL_ERR((" error in vendor info attribute \n")); ret = -EINVAL; goto fail; } else { WL_DBG((" vendor info not present \n")); } if (*(data + 6) == NAN_VENDOR_TYPE_RTT) { data += NAN_VENDOR_HDR_SIZE; ea = (struct ether_addr *)data; data += ETHER_ADDR_LEN; mapcontrol = *data++; proto = *data++; bitmap = *(uint32 *)data; data += 4; chanspec = *(chanspec_t *)data; ptr += sprintf(ptr, " "BITMAP_PREFIX"0x%x "CHAN_PREFIX"%d/%s", bitmap, wf_chspec_ctlchan(chanspec), wf_chspec_to_bw_str(chanspec)); WL_DBG((" bitmap: 0x%x channel: %d bandwidth: %s \n", bitmap, wf_chspec_ctlchan(chanspec), wf_chspec_to_bw_str(chanspec))); } } break; case WL_NAN_EVENT_REPLIED: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d " MAC_ADDR_PREFIX MACF, nan_event_str[event_num], tlv_data.pub_id, ETHER_TO_MACF(tlv_data.mac_addr)); break; case WL_NAN_EVENT_TERMINATED: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d ", nan_event_str[event_num], tlv_data.pub_id); break; case WL_NAN_EVENT_RECEIVE: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " PUB_ID_PREFIX"%d " MAC_ADDR_PREFIX MACF, nan_event_str[event_num], tlv_data.pub_id, ETHER_TO_MACF(tlv_data.mac_addr)); if (tlv_data.svc_info.data && tlv_data.svc_info.dlen) { WL_DBG((" service info present \n")); if ((strlen(ptr) + tlv_data.svc_info.dlen) >= buf_len) { WL_ERR((" service info length = %d\n", tlv_data.svc_info.dlen)); WL_ERR((" insufficent buffer to copy service info \n")); ret = -EOVERFLOW; goto fail; } ptr += sprintf(ptr, " %s", SVC_INFO_PREFIX); ptr += bcm_format_hex(ptr, tlv_data.svc_info.data, tlv_data.svc_info.dlen); } else { WL_DBG((" service info not present \n")); } break; case WL_NAN_EVENT_SCAN_COMPLETE: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF, nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid)); break; case WL_NAN_EVENT_STATUS_CHG: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF, nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid)); break; case WL_NAN_EVENT_MERGE: ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " CLUS_ID_PREFIX MACF, nan_event_str[event_num], ETHER_TO_MACF(tlv_data.nstatus.cid)); break; default: WL_ERR((" unknown event \n")); break; } #ifdef WL_GENL /* send the preformatted string to the upper layer as event */ WL_DBG((" formatted string for userspace: %s, len: %zu \n", buf, strlen(buf))); wl_genl_send_msg(bcmcfg_to_prmry_ndev(cfg), 0, buf, strlen(buf), 0, 0); #endif /* WL_GENL */ fail: if (buf) { kfree(buf); } if (tlv_data.svc_info.data) { kfree(tlv_data.svc_info.data); tlv_data.svc_info.data = NULL; tlv_data.svc_info.dlen = 0; } if (tlv_data.vend_info.data) { kfree(tlv_data.vend_info.data); tlv_data.vend_info.data = NULL; tlv_data.vend_info.dlen = 0; } return ret; }
s32 wl_cfgnan_notify_proxd_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *event, void *data) { s32 ret = BCME_OK; wl_nan_ranging_event_data_t *rdata; s32 status; u16 data_len; s32 event_type; s32 event_num; u8 *buf = NULL; u32 buf_len; u8 *ptr; u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; s32 i; if (!event || !data) { WL_ERR((" event data is NULL \n")); return -EINVAL; } status = ntoh32(event->reason); event_type = ntoh32(event->event_type); event_num = ntoh32(event->reason); data_len = ntoh32(event->datalen); WL_DBG((" proxd event: type: %d num: %d len: %d \n", event_type, event_num, data_len)); if (INVALID_PROXD_EVENT(event_num)) { WL_ERR((" unsupported event, num: %d \n", event_num)); return -EINVAL; } if (g_nan_debug) { WL_DBG((" event name: WLC_E_PROXD_NAN_EVENT \n")); WL_DBG((" event data: \n")); prhex(NULL, data, data_len); } if (data_len < sizeof(wl_nan_ranging_event_data_t)) { WL_ERR((" wrong data len \n")); return -EINVAL; } rdata = (wl_nan_ranging_event_data_t *)data; WL_DBG((" proxd event: count:%d success_count:%d mode:%d \n", rdata->count, rdata->success_count, rdata->mode)); if (g_nan_debug) { prhex(" event data: ", data, data_len); } buf_len = NAN_IOCTL_BUF_SIZE; buf = kzalloc(buf_len, kflags); if (!buf) { WL_ERR((" memory allocation failed \n")); return -ENOMEM; } for (i = 0; i < rdata->count; i++) { if (&rdata->rr[i] == NULL) { ret = -EINVAL; goto fail; } ptr = buf; WL_DBG((" ranging data for mac:"MACDBG" \n", MAC2STRDBG(rdata->rr[i].ea.octet))); ptr += sprintf(buf, SUPP_EVENT_PREFIX"%s " MAC_ADDR_PREFIX MACF " "STATUS_PREFIX"%s", EVENT_RTT_STATUS_STR, ETHER_TO_MACF(rdata->rr[i].ea), (rdata->rr[i].status == 1) ? "success" : "fail"); if (rdata->rr[i].status == 1) { /* add tsf and distance only if status is success */ ptr += sprintf(ptr, " "TIMESTAMP_PREFIX"0x%x " DISTANCE_PREFIX"%d.%04d", rdata->rr[i].timestamp, rdata->rr[i].distance >> 4, ((rdata->rr[i].distance & 0x0f) * 625)); } #ifdef WL_GENL /* send the preformatted string to the upper layer as event */ WL_DBG((" formatted string for userspace: %s, len: %zu \n", buf, strlen(buf))); wl_genl_send_msg(bcmcfg_to_prmry_ndev(cfg), 0, buf, strlen(buf), 0, 0); #endif /* WL_GENL */ }
yrmcds_error yrmcds_cnt_recv(yrmcds_cnt* c, yrmcds_cnt_response* r) { if( c == NULL || r == NULL ) return YRMCDS_BAD_ARGUMENT; if( c->invalid ) return YRMCDS_PROTOCOL_ERROR; if( c->last_size > 0 ) { size_t remain = c->used - c->last_size; if( remain > 0 ) memmove(c->recvbuf, c->recvbuf + c->last_size, remain); c->used = remain; c->last_size = 0; } while( c->used < HEADER_SIZE ) { yrmcds_error e = recv_data(c); if( e != YRMCDS_OK ) return e; } if( (uint8_t)c->recvbuf[0] != 0x91 ) { c->invalid = 1; return YRMCDS_PROTOCOL_ERROR; } r->command = (yrmcds_cnt_command)c->recvbuf[1]; r->status = (yrmcds_cnt_status)c->recvbuf[2]; r->body_length = ntoh32(c->recvbuf + 4); memcpy(&r->serial, c->recvbuf + 8, sizeof(r->serial)); r->body = NULL; r->resources = 0; r->current_consumption = 0; r->max_consumption = 0; r->name_length = 0; r->stats = NULL; if( r->body_length > 0 ) { while( c->used < HEADER_SIZE + r->body_length ) { yrmcds_error e = recv_data(c); if( e != YRMCDS_OK ) return e; } r->body = c->recvbuf + HEADER_SIZE; } c->last_size = HEADER_SIZE + r->body_length; if( r->status != YRMCDS_STATUS_OK ) return YRMCDS_OK; yrmcds_error err; switch( r->command ) { case YRMCDS_CNT_CMD_GET: if( r->body_length < 4 ) { c->invalid = 1; return YRMCDS_PROTOCOL_ERROR; } r->current_consumption = ntoh32(r->body); break; case YRMCDS_CNT_CMD_ACQUIRE: if( r->body_length < 4 ) { c->invalid = 1; return YRMCDS_PROTOCOL_ERROR; } r->resources = ntoh32(r->body); break; case YRMCDS_CNT_CMD_STATS: err = parse_statistics(c, r); if( err != YRMCDS_OK ) { c->invalid = 1; return err; } r->stats = &c->stats; break; case YRMCDS_CNT_CMD_DUMP: err = parse_dump_record(c, r); if( err != YRMCDS_OK ) { c->invalid = 1; return err; } break; default: // No body break; } return YRMCDS_OK; }
/*** decaps_gre ***************************************************************/ int decaps_gre (int fd, callback_t callback, int cl) { unsigned char buffer[PACKET_MAX + 64 /*ip header*/]; struct pptp_gre_header *header; int status, ip_len = 0; static int first = 1; unsigned int headersize; unsigned int payload_len; u_int32_t seq; if ((status = read (fd, buffer, sizeof(buffer))) <= 0) { warn("short read (%d): %s", status, strerror(errno)); stats.rx_errors++; return -1; } /* strip off IP header, if present */ if ((buffer[0] & 0xF0) == 0x40) ip_len = (buffer[0] & 0xF) * 4; header = (struct pptp_gre_header *)(buffer + ip_len); /* verify packet (else discard) */ if ( /* version should be 1 */ ((ntoh8(header->ver) & 0x7F) != PPTP_GRE_VER) || /* PPTP-GRE protocol for PPTP */ (ntoh16(header->protocol) != PPTP_GRE_PROTO)|| /* flag C should be clear */ PPTP_GRE_IS_C(ntoh8(header->flags)) || /* flag R should be clear */ PPTP_GRE_IS_R(ntoh8(header->flags)) || /* flag K should be set */ (!PPTP_GRE_IS_K(ntoh8(header->flags))) || /* routing and recursion ctrl = 0 */ ((ntoh8(header->flags)&0xF) != 0)) { /* if invalid, discard this packet */ warn("Discarding GRE: %X %X %X %X %X %X", ntoh8(header->ver)&0x7F, ntoh16(header->protocol), PPTP_GRE_IS_C(ntoh8(header->flags)), PPTP_GRE_IS_R(ntoh8(header->flags)), PPTP_GRE_IS_K(ntoh8(header->flags)), ntoh8(header->flags) & 0xF); stats.rx_invalid++; return 0; } /* silently discard packets not for this call */ if (ntoh16(header->call_id) != pptp_gre_call_id) return 0; /* test if acknowledgement present */ if (PPTP_GRE_IS_A(ntoh8(header->ver))) { u_int32_t ack = (PPTP_GRE_IS_S(ntoh8(header->flags)))? header->ack:header->seq; /* ack in different place if S = 0 */ ack = ntoh32( ack); if (ack > ack_recv) ack_recv = ack; /* also handle sequence number wrap-around */ if (WRAPPED(ack,ack_recv)) ack_recv = ack; if (ack_recv == stats.pt.seq) { int rtt = time_now_usecs() - stats.pt.time; stats.rtt = (stats.rtt + rtt) / 2; } } /* test if payload present */ if (!PPTP_GRE_IS_S(ntoh8(header->flags))) return 0; /* ack, but no payload */ headersize = sizeof(*header); payload_len = ntoh16(header->payload_len); seq = ntoh32(header->seq); /* no ack present? */ if (!PPTP_GRE_IS_A(ntoh8(header->ver))) headersize -= sizeof(header->ack); /* check for incomplete packet (length smaller than expected) */ if (status - headersize < payload_len) { warn("discarding truncated packet (expected %d, got %d bytes)", payload_len, status - headersize); stats.rx_truncated++; return 0; } /* check for expected sequence number */ if ( first || (seq == seq_recv + 1)) { /* wrap-around safe */ if ( log_level >= 2 ) log("accepting packet %d", seq); stats.rx_accepted++; first = 0; seq_recv = seq; return callback(cl, buffer + ip_len + headersize, payload_len); /* out of order, check if the number is too low and discard the packet. * (handle sequence number wrap-around, and try to do it right) */ } else if ( seq < seq_recv + 1 || WRAPPED(seq_recv, seq) ) { if ( log_level >= 1 ) log("discarding duplicate or old packet %d (expecting %d)", seq, seq_recv + 1); stats.rx_underwin++; /* sequence number too high, is it reasonably close? */ } else if ( seq < seq_recv + MISSING_WINDOW || WRAPPED(seq, seq_recv + MISSING_WINDOW) ) { stats.rx_buffered++; if ( log_level >= 1 ) log("%s packet %d (expecting %d, lost or reordered)", disable_buffer ? "accepting" : "buffering", seq, seq_recv+1); if ( disable_buffer ) { seq_recv = seq; stats.rx_lost += seq - seq_recv - 1; return callback(cl, buffer + ip_len + headersize, payload_len); } else { pqueue_add(seq, buffer + ip_len + headersize, payload_len); } /* no, packet must be discarded */ } else { if ( log_level >= 1 ) warn("discarding bogus packet %d (expecting %d)", seq, seq_recv + 1); stats.rx_overwin++; } return 0; }