int client_recv_udp_msg(socket_t *sock,socket_t *from,char *data,int data_len,uint16_t *session_id,uint8_t *cmd_type,uint16_t *length) { char buf[MSG_LEN]; msg_hdr_t *hdr_ptr; char *msg_ptr; int ret ; hdr_ptr = (msg_hdr_t *)buf; msg_ptr = buf + sizeof(msg_hdr_t); ret = sock_recv(sock,from,buf,sizeof(buf)); if(ret < 0) return -1; if(ret == 0) return -2; if(ret < sizeof(msg_hdr_t)) return -3; uint8_t version; version = MSG_VERSION(hdr_ptr); if(version != P_VERSION) { if(g_debug) { printf("Recv UDP MSG Unknow Version[%02x\n]",version); } return -4; } *cmd_type = MSG_CMD(hdr_ptr); *session_id = MSG_SESSION(hdr_ptr); *length = MSG_LENGTH(hdr_ptr); if(ret - MSG_HEAD_LENGTH != *length) return -1; *length = MIN(data_len,*length); memcpy(data,msg_ptr,*length); if(g_debug) { /* printf("---------- Recv UDP Packet -----------------\n"); printf("session_id [%d]\n",*session_id); printf("cmd_type [%02x]\n",*cmd_type); printf("udp data length [%d]\n",*length); printf("msg [%s]\n\n",msg_ptr); */ } return 0; }
static AJ_Status ParseIsAt(AJ_IOBuffer* rxBuf, const char* prefix, AJ_Service* service) { AJ_Status status = AJ_ERR_NO_MATCH; size_t preLen = strlen(prefix); NSHeader* hdr = (NSHeader*)rxBuf->readPtr; uint32_t len = AJ_IO_BUF_AVAIL(rxBuf); uint8_t* p = rxBuf->readPtr + 4; uint8_t* eod = (uint8_t*)hdr + len; AJ_InfoPrintf(("ParseIsAt(rxbuf=0x%p, prefix=\"%s\", service=0x%p)\n", rxBuf, prefix, service)); service->addrTypes = 0; /* * Silently ignore versions we don't know how to parse */ if (MSG_VERSION(hdr->version) != MSG_V1) { return status; } /* * Questions come in first - we currently ignore them */ while (hdr->qCount--) { uint8_t flags = *p++; uint8_t nameCount = *p++; /* * Questions must be WHO_HAS messages */ if (MSG_TYPE(flags) != WHO_HAS_MSG) { AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_INVALID\n")); return AJ_ERR_INVALID; } while (nameCount--) { uint8_t sz = *p++; p += sz; if (p > eod) { AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n")); status = AJ_ERR_END_OF_DATA; goto Exit; } } } /* * Now the answers - this is what we are looking for */ while (hdr->aCount--) { uint8_t flags = *p++; uint8_t nameCount = *p++; /* * Answers must be IS_AT messages */ if (MSG_TYPE(flags) != IS_AT_MSG) { AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_INVALID\n")); return AJ_ERR_INVALID; } /* * Must be reliable IPV4 or IPV6 */ if (!(flags & (R4_FLAG | R6_FLAG))) { return status; } /* * Get transport mask */ service->transportMask = (p[0] << 8) | p[1]; p += 2; /* * Decode addresses */ if (flags & R4_FLAG) { memcpy(&service->ipv4, p, sizeof(service->ipv4)); p += sizeof(service->ipv4); service->ipv4port = (p[0] << 8) | p[1]; p += 2; service->addrTypes |= AJ_ADDR_IPV4; } if (flags & U4_FLAG) { p += sizeof(service->ipv4) + 2; } if (flags & R6_FLAG) { memcpy(&service->ipv6, p, sizeof(service->ipv6)); p += sizeof(service->ipv6); service->ipv6port = (p[0] << 8) | p[1]; p += 2; service->addrTypes |= AJ_ADDR_IPV6; } if (flags & U6_FLAG) { p += sizeof(service->ipv6) + 2; } /* * Skip guid if it's present */ if (flags & G_FLAG) { uint8_t sz = *p++; len -= 1 + sz; p += sz; } if (p >= eod) { AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n")); return AJ_ERR_END_OF_DATA; } /* * Iterate over the names */ while (nameCount--) { uint8_t sz = *p++; { char sav = p[sz]; p[sz] = 0; AJ_InfoPrintf(("ParseIsAt(): Found \"%s\" IP 0x%x\n", p, service->addrTypes)); p[sz] = sav; } if ((preLen <= sz) && (memcmp(p, prefix, preLen) == 0)) { status = AJ_OK; goto Exit; } p += sz; if (p > eod) { status = AJ_ERR_END_OF_DATA; AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n")); goto Exit; } } } Exit: return status; }