void NET::Send(void * data, int size) { Uint8 * sourcedata = (Uint8 *) data; if (pout == NULL) { if (NET_DEBUG) { cout << "net: Send: invalid packet" << endl; return; } } if (size >= pout->maxlen) { if (NET_DEBUG) { cout << "net: Send: packet size is too large: " << size << endl; return; } } pout->len = size; int i; for (i = 0; i < size; i++) { pout->data[i] = sourcedata[i]; } UDPSend(pout, 0); }
void loopback_udp(uint8 ch, uint16 port) { int ret; uint32 destip = 0; uint16 destport; ret = UDPRecv(ch, data_buf, TX_RX_MAX_BUF_SIZE, (uint8*)&destip, &destport); if(ret > 0) { // Received ret = UDPSend(ch, data_buf, ret, (uint8*)&destip ,destport); if(ret == ERROR_TIME_OUT) { ERR("Timeout"); UDPClose(ch); DBG("UDP Socket Close"); } } else if(ret == ERROR_NOT_UDP_SOCKET) { // Not UDP Socket, It's TCP Socket DBG("TCP Socket Close"); TCPClose(ch); } else if(ret == ERROR_CLOSED) { // Socket Closed LOGA("UDP Loop-Back Started - ch(%d)",(uint16)ch); UDPOpen(ch, port); } }
bool NET::ClientHandshake() { string handshake = HANDSHAKESTR; string handshake_reply = HANDSHAKEREPLYSTR; int timeout = HANDSHAKETIMEOUT; bool err = false; WriteToPacket(pout, CONTROL_HANDSHAKE, (void *) handshake.c_str(), handshake.length()); UDPSend(pout, 0); int ret = UDPRecv(pin, 0, timeout); if (ret == UDP_SUCCESS) { if (IsEqualToPacket(pin, CONTROL_HANDSHAKE, (void *) handshake_reply.c_str(), handshake_reply.length())) { connected = true; if (NET_DEBUG) cout << "net: Connection complete." << endl; } else { if (NET_DEBUG) cout << "net: Invalid handshake reply." << endl; err = true; } } if (ret == UDP_TIMEOUT) { err = true; if (NET_DEBUG) cout << "net: Handshake timeout, couldn't connect" << endl; } if (ret == UDP_FAILURE) { err = true; if (NET_DEBUG) cout << "net: Handshake error." << endl; } return err; }
/** * SNMP Process Handler. * UDP Socket and SNMP transaction handling. * * @param none * @return none */ void SnmpXDaemon_process(void) { int32 len = 0; uint8 svr_addr[6]; uint16 svr_port; //UDPOpen(SOCK_SNMP, 161); //if ( (len = getSn_RX_RSR(SOCK_SNMP)) > 0) if((len = GetSocketRxRecvBufferSize(SOCK_SNMP)) > 0) { request_msg.len= UDPRecv(SOCK_SNMP, (int8 *)&request_msg.buffer[0], len, svr_addr, &svr_port); } else { request_msg.len = 0; //continue; } if (request_msg.len > 0) { dumpCode("\r\n[Request]\r\n", "\r\n", request_msg.buffer, request_msg.len); request_msg.index = 0; response_msg.index = 0; errorStatus = errorIndex = 0; if (parseSNMPMessage() != -1) { UDPSend(SOCK_SNMP, (int8 *)response_msg.buffer, response_msg.index, svr_addr, svr_port); } dumpCode("\r\n[Response]\r\n", "\r\n", response_msg.buffer, response_msg.index); } //UDPClose(SOCK_SNMP); }
//this function assumes pin already has an incoming packet from the client bool NET::ServerHandshake() { string handshake = HANDSHAKESTR; string handshake_reply = HANDSHAKEREPLYSTR; // int timeout = HANDSHAKETIMEOUT; bool err = false; if (IsEqualToPacket(pin, CONTROL_HANDSHAKE, (void *) handshake.c_str(), handshake.length())) { SDLNet_UDP_Unbind(remote_socket, 0); if (SDLNet_UDP_Bind(remote_socket, 0, &(pin->address))==-1) { err = true; if (NET_DEBUG) { cout << "net: couldn't bind UDP socket to host " << SDLNet_ResolveIP(&(pin->address)) << endl; printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError()); } } WriteToPacket(pout, CONTROL_HANDSHAKE, (void *) handshake_reply.c_str(), handshake_reply.length()); UDPSend(pout, 0); connected = true; if (NET_DEBUG) cout << "net: incoming connection established" << endl; } else { if (NET_DEBUG) cout << "net: Invalid handshake from " << SDLNet_ResolveIP(&(pin->address)) << endl; err = true; } return err; }
static int8 send_request(void) { uint8 srv_ip[4]; int32 len = 0; memset(&dm, 0, sizeof(struct dhcp_msg)); dm.op = DHCP_BOOTREQUEST; dm.htype = DHCP_HTYPE10MB; dm.hlen = DHCP_HLENETHERNET; dm.hops = DHCP_HOPS; dm.xid = htonl(di.xid); dm.secs = htons(DHCP_SECS); if(di.action == DHCP_ACT_RENEW) { dm.flags = 0; // For Unicast memcpy(dm.ciaddr, workinfo.ip, 4); } else { dm.flags = htons(DHCP_BROADCAST); } memcpy(dm.chaddr, storage.mac, 6); // MAGIC_COOKIE *(uint32*)&dm.opt[len] = htonl(MAGIC_COOKIE); len += 4; // Option Request Param. dm.opt[len++] = dhcpMessageType; dm.opt[len++] = 0x01; dm.opt[len++] = DHCP_MSG_REQUEST; dm.opt[len++] = dhcpClientIdentifier; dm.opt[len++] = 0x07; dm.opt[len++] = 0x01; memcpy(&dm.opt[len], storage.mac, 6); len += 6; if(di.action != DHCP_ACT_RENEW) { dm.opt[len++] = dhcpRequestedIPaddr; dm.opt[len++] = 0x04; memcpy(&dm.opt[len], workinfo.ip, 4); len += 4; dm.opt[len++] = dhcpServerIdentifier; dm.opt[len++] = 0x04; memcpy(&dm.opt[len], di.srv_ip, 4); len += 4; } // host name dm.opt[len++] = hostName; dm.opt[len++] = strlen(HOST_NAME) + 6; // length of hostname + 3 strcpy((char*)&dm.opt[len], HOST_NAME); len += strlen(HOST_NAME); sprintf((char*)&dm.opt[len], "%02x%02x%02x", storage.mac[3], storage.mac[4], storage.mac[5]); len += 6; dm.opt[len++] = dhcpParamRequest; dm.opt[len++] = 0x08; dm.opt[len++] = subnetMask; dm.opt[len++] = routersOnSubnet; dm.opt[len++] = dns; dm.opt[len++] = domainName; dm.opt[len++] = dhcpT1value; dm.opt[len++] = dhcpT2value; dm.opt[len++] = performRouterDiscovery; dm.opt[len++] = staticRoute; dm.opt[len++] = endOption; // send broadcasting packet if(di.action == DHCP_ACT_RENEW) { memcpy(srv_ip, di.srv_ip, 4); } else { srv_ip[0] = srv_ip[1] = srv_ip[2] = srv_ip[3] = 255; } if(dhcp_async) { len = UDPSendNB(di.sock, (int8*)&dm, sizeof(struct dhcp_msg), srv_ip, DHCP_SERVER_PORT); if(len < sizeof(struct dhcp_msg)) { if(len < 0) ERRA("UDPSend fail - ret(%d)", len); else ERRA("UDPSend sent less than size - size(%d), sent(%d)", sizeof(struct dhcp_msg), len); return RET_NOK; } else sockwatch_set(di.sock, WATCH_SOCK_UDP_SEND); } else { len = UDPSend(di.sock, (int8*)&dm, sizeof(struct dhcp_msg), srv_ip, DHCP_SERVER_PORT); if(len <= 0) { ERRA("UDPSend fail - ret(%d)", len); return RET_NOK; } } return RET_OK; }
// Notes on dnsNSMax and cDhcpNS. You would think that we should only cycle through cDhcpNS as this is the number // DNS servers given to us by DHCP, however, sometimes DHCP does not give us good DNS servers and for the // SNTP server to work, we need a good DNS server. So we continue to check the default, pre initialized google DNS // servers after the DHCP DNS servers are checked first. If we get a lot of DNS servers from DHCP, then ultimately // all of the pre installed google servers will be overwritten in the dnsNSMax list, but if we got a lot of DNS servers // the assumption is that they are good ones. In particular, I found that Verizon did not give me very good DNS servers, they // could not resolve the SNTP time servers. static void DNSStateMachine(const LLADP * pLLAdp) { IPSTATUS status = ipsSuccess; if(pLLAdp == NULL || pLLAdp->pDNSMem == NULL || !ILIsIPSetup(pLLAdp, NULL)) { return; } switch(pLLAdp->pDNSMem->dnsState) { case dnsSend: if(pLLAdp->pDNSMem->dnsNSMax == 0) { pLLAdp->pDNSMem->dnsState = dnsReady; pLLAdp->pDNSMem->cTry = 0; break; } else if(pLLAdp->pDNSMem->cTry >= (pLLAdp->pDNSMem->dnsNSMax * DNSMINTRY)) { if(pLLAdp->pDNSMem->iDNSCur == pLLAdp->pDNSMem->iDNSWorks) { pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid; } pLLAdp->pDNSMem->iDNSCur = DNSiInvalid; pLLAdp->pDNSMem->dnsState = dnsReady; pLLAdp->pDNSMem->cTry = 0; break; } else if(pLLAdp->pDNSMem->iDNSWorks < pLLAdp->pDNSMem->dnsNSMax) { pLLAdp->pDNSMem->iDNSCur = pLLAdp->pDNSMem->iDNSWorks; } else if(pLLAdp->pDNSMem->iDNSCur >= pLLAdp->pDNSMem->dnsNSMax) { pLLAdp->pDNSMem->iDNSCur = 0; } else { pLLAdp->pDNSMem->iDNSCur = (pLLAdp->pDNSMem->iDNSCur + 1) % pLLAdp->pDNSMem->dnsNSMax; } // set this up for an attempt to get the IP address memcpy(&pLLAdp->pDNSMem->socket.s.ipRemote, &pLLAdp->pDNSMem->dnsNS[pLLAdp->pDNSMem->iDNSCur], ILIPSize(pLLAdp)); // fall thru on success case dnsReadySend: // clear the current IP address memset(&pLLAdp->pDNSMem->ip, 0, sizeof(IPv4or6)); // just make this unique for this pass pLLAdp->pDNSMem->dnsDG.dnsHdr.ID++; // set my timers and counts pLLAdp->pDNSMem->cTry++; pLLAdp->pDNSMem->tTimeout = dnsWaitForRetry; pLLAdp->pDNSMem->tStart = SYSGetMilliSecond(); // send out the DNS datagram UDPSend(&pLLAdp->pDNSMem->socket, (uint8_t *) &pLLAdp->pDNSMem->dnsDG, pLLAdp->pDNSMem->cbDNSDG, &status); // see if it went out. if(IsIPStatusAnError(status)) { pLLAdp->pDNSMem->dnsState = dnsReady; pLLAdp->pDNSMem->cTry = 0; } else { pLLAdp->pDNSMem->dnsState = dnsWaiting; } break; case dnsWaiting: { uint16_t cbDG = UDPAvailable(&pLLAdp->pDNSMem->socket) ; IPSTATUS status; if(cbDG > sizeof(DNSHDR)) { // we need some space for the datagram uint8_t rgbDNSDG[DNSMAXUDPSIZE]; DNSDG * pDNSDG = (DNSDG *) rgbDNSDG; uint8_t * pEnd = NULL; uint8_t * pCName = NULL; DNSRR * pDNSRRA = NULL; // read the DNS datagram cbDG = UDPRead(&pLLAdp->pDNSMem->socket, rgbDNSDG, DNSMAXUDPSIZE, &status); // There are some servers setting this and they should not! RFC 6195 2.1 and I need to ignore it // Plus this is used internally to determine if we are in machine or network order. This is in network order right now. pDNSDG->dnsHdr.Z = 0; // now put in machine order. cbDG = ExDNSDG(pDNSDG, cbDG); pEnd = rgbDNSDG + cbDG; // if this is not a my response, keep waiting // remember the ID is not exchanged, so network and machine order will have the same ID if(!pDNSDG->dnsHdr.QR || pDNSDG->dnsHdr.ID != pLLAdp->pDNSMem->dnsDG.dnsHdr.ID) { break; } // ops and error occured, jump to finish with error // go to the error state with no address found if(pDNSDG->dnsHdr.RCODE != DNSRCODENoError) { // this is a failure case; go to the next DNS server pLLAdp->pDNSMem->dnsState = dnsSend; break; } // get the canonical name for what we are looking for // the first record is the question which has the name we used. // we need to use the one in this datagram because we do memory range // checking and if we use the QR we sent, it would be out of the memory range pCName = DNSFindCName(pDNSDG, DNSRRAN, pDNSDG->rrRecords, pEnd); // now find the A record pDNSRRA = DNSFindRR(pDNSDG, NULL, DNSRRAN, DNSTYPEA, DNSCLASSIN, pCName, pEnd); // if we got the A record we are done if( pDNSRRA != NULL && ((ILIsIPv6(pLLAdp) && pDNSRRA->RDLENGTH == sizeof(IPv6)) || (!ILIsIPv6(pLLAdp) && pDNSRRA->RDLENGTH == sizeof(IPv4)) ) ) { // copy in our result memcpy(&pLLAdp->pDNSMem->ip, pDNSRRA->RDATA, pDNSRRA->RDLENGTH); // say we are done pLLAdp->pDNSMem->dnsState = dnsReady; pLLAdp->pDNSMem->cTry = 0; // We got an IP so we know this DNS server can work, remember that if(pLLAdp->pDNSMem->iDNSCur < pLLAdp->pDNSMem->dnsNSMax) { pLLAdp->pDNSMem->iDNSWorks = pLLAdp->pDNSMem->iDNSCur; } // get out we found it and are done. break; } // by default we will go to the next well know sever unless we pick up a better NS to go to pLLAdp->pDNSMem->dnsState = dnsSend; // we did not find anything, so update our DNS request to use the new CName if(pCName != pDNSDG->rrRecords) { // make the new DNS packet with the CName instead of what we were using uint16_t cbMax = DNSCreateIPv4QueryDN(pLLAdp, rgbDNSDG, pCName, pEnd, &pLLAdp->pDNSMem->dnsDG); pLLAdp->pDNSMem->cbDNSDG = ExDNSDG(&pLLAdp->pDNSMem->dnsDG, cbMax); } // Didn't find an A record // But maybe there is a name server we should try. // If we asked for recursion and go it, no sense working the issue ourselves. // likewise if there are now NS with IP addresses, no sense working the issue if(!(pDNSDG->dnsHdr.RD && pDNSDG->dnsHdr.RA) && pDNSDG->dnsHdr.NSCOUNT > 0 && pDNSDG->dnsHdr.ARCOUNT > 0) { // this DNS server gave us something, so remember it if(pLLAdp->pDNSMem->iDNSCur < pLLAdp->pDNSMem->dnsNSMax) { pLLAdp->pDNSMem->iDNSWorks = pLLAdp->pDNSMem->iDNSCur; } pDNSRRA = DNSFindNSARR(pDNSDG, pCName, pEnd, DNSTYPEA); // if this looks like a good IP address to try, lets contact that name server if(pDNSRRA != NULL && pDNSRRA->RDLENGTH == sizeof(IPv4)) { // say were are not using one of our well known DNS servers pLLAdp->pDNSMem->iDNSCur = DNSiInvalid; // Put the IP in our socket memcpy(&pLLAdp->pDNSMem->socket.s.ipRemote, pDNSRRA->RDATA, pDNSRRA->RDLENGTH); pLLAdp->pDNSMem->dnsState = dnsReadySend; } } else if(pLLAdp->pDNSMem->iDNSWorks == pLLAdp->pDNSMem->iDNSCur) { pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid; } } else if((SYSGetMilliSecond() - pLLAdp->pDNSMem->tStart) >= pLLAdp->pDNSMem->tTimeout) { pLLAdp->pDNSMem->dnsState = dnsWaitTry; } } break; case dnsWaitTry: if(pLLAdp->pDNSMem->iDNSWorks == pLLAdp->pDNSMem->iDNSCur) { pLLAdp->pDNSMem->iDNSWorks = DNSiInvalid; } if((pLLAdp->pDNSMem->cTry % DNSMINTRY) == 0) { pLLAdp->pDNSMem->dnsState = dnsSend; } else { pLLAdp->pDNSMem->dnsState = dnsReadySend; } break; case dnsReady: pLLAdp->pDNSMem->cTry = 0; break; // noting to do here, either we have something in the DNS memory IP or not. case dnsRedirect: case dnsUninit: default: break; } }