/************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ static int rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) { struct rpc_call pkt; unsigned long id; int sport; int ret; unsigned char *payload = net_udp_get_payload(nfs_con); id = ++rpc_id; pkt.id = htonl(id); pkt.type = htonl(MSG_CALL); pkt.rpcvers = htonl(2); /* use RPC version 2 */ pkt.prog = htonl(rpc_prog); pkt.vers = htonl(2); /* portmapper is version 2 */ pkt.proc = htonl(rpc_proc); memcpy(payload, &pkt, sizeof(pkt)); memcpy(payload + sizeof(pkt), data, datalen * sizeof(uint32_t)); if (rpc_prog == PROG_PORTMAP) sport = SUNRPC_PORT; else if (rpc_prog == PROG_MOUNT) sport = nfs_server_mount_port; else sport = nfs_server_nfs_port; nfs_con->udp->uh_dport = htons(sport); ret = net_udp_send(nfs_con, sizeof(pkt) + datalen * sizeof(uint32_t)); return ret; }
static int tftp_send(struct file_priv *priv) { unsigned char *xp; int len = 0; uint16_t *s; unsigned char *pkt = net_udp_get_payload(priv->tftp_con); int ret; debug("%s: state %d\n", __func__, priv->state); switch (priv->state) { case STATE_RRQ: case STATE_WRQ: xp = pkt; s = (uint16_t *)pkt; if (priv->state == STATE_RRQ) *s++ = htons(TFTP_RRQ); else *s++ = htons(TFTP_WRQ); pkt = (unsigned char *)s; pkt += sprintf((unsigned char *)pkt, "%s%c" "octet%c" "timeout%c" "%d%c" "tsize%c" "%d%c" "blksize%c" "1432", priv->filename, 0, 0, 0, TIMEOUT, 0, 0, priv->filesize, 0, 0); pkt++; len = pkt - xp; break; case STATE_RDATA: if (priv->block == priv->block_requested) return 0; case STATE_OACK: xp = pkt; s = (uint16_t *)pkt; *s++ = htons(TFTP_ACK); *s++ = htons(priv->block); priv->block_requested = priv->block; pkt = (unsigned char *)s; len = pkt - xp; break; } ret = net_udp_send(priv->tftp_con, len); return ret; }
static int dns_send(char *name) { int ret; struct header *header; enum dns_query_type qtype = DNS_A_RECORD; unsigned char *packet = net_udp_get_payload(dns_con); unsigned char *p, *s, *fullname, *dotptr; const unsigned char *domain; /* Prepare DNS packet header */ header = (struct header *)packet; header->tid = 1; header->flags = htons(0x100); /* standard query */ header->nqueries = htons(1); /* Just one query */ header->nanswers = 0; header->nauth = 0; header->nother = 0; domain = getenv("net.domainname"); if (!strchr(name, '.') && domain && *domain) fullname = asprintf(".%s.%s.", name, domain); else fullname = asprintf(".%s.", name); /* replace dots in fullname with chunk len */ dotptr = fullname; do { int len; s = strchr(dotptr + 1, '.'); len = s - dotptr - 1; *dotptr = len; dotptr = s; } while (*(dotptr + 1)); *dotptr = 0; strcpy(header->data, fullname); p = header->data + strlen(fullname); *p++ = 0; /* Mark end of host name */ *p++ = 0; /* Some servers require double null */ *p++ = (unsigned char)qtype; /* Query Type */ *p++ = 0; *p++ = 1; /* Class: inet, 0x0001 */ ret = net_udp_send(dns_con, p - packet); free(fullname); return ret; }
static void nc_putc(struct console_device *cdev, char c) { struct nc_priv *priv = container_of(cdev, struct nc_priv, cdev); unsigned char *packet; if (!priv->con) return; if (priv->busy) return; packet = net_udp_get_payload(priv->con); *packet = c; priv->busy = 1; net_udp_send(priv->con, 1); priv->busy = 0; }
static void dhcp_send_request_packet(struct bootp *bp_offer) { struct bootp *bp; int extlen; IPaddr_t OfferedIP; unsigned char *payload = net_udp_get_payload(dhcp_con); debug("%s: Sending DHCPREQUEST\n", __func__); bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; /* FIXME what is this? */ // bp->bp_secs = htons(get_timer(0) / CFG_HZ); net_copy_ip(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */ net_copy_ip(&bp->bp_yiaddr, &bp_offer->bp_yiaddr); net_copy_ip(&bp->bp_siaddr, &bp_offer->bp_siaddr); /* * RFC3046 requires Relay Agents to discard packets with * nonzero and offered giaddr */ net_write_ip(&bp->bp_giaddr, 0); memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); /* * ID is the id of the OFFER packet */ net_copy_uint32(&bp->bp_id, &bp_offer->bp_id); /* * Copy options from OFFER packet if present */ net_copy_ip(&OfferedIP, &bp->bp_yiaddr); extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip, OfferedIP); debug("Transmitting DHCPREQUEST packet\n"); net_udp_send(dhcp_con, sizeof(*bp) + extlen); }
static int tftp_send_write(struct file_priv *priv, void *buf, int len) { uint16_t *s; unsigned char *pkt = net_udp_get_payload(priv->tftp_con); int ret; s = (uint16_t *)pkt; *s++ = htons(TFTP_DATA); *s++ = htons(priv->block); memcpy((void *)s, buf, len); if (len < priv->blocksize) priv->state = STATE_LAST; len += 4; ret = net_udp_send(priv->tftp_con, len); priv->last_block = priv->block; priv->state = STATE_WAITACK; return ret; }
static int bootp_request(void) { struct bootp *bp; int ext_len; int ret; unsigned char *payload = net_udp_get_payload(dhcp_con); const char *bfile; dhcp_state = INIT; debug("BOOTP broadcast\n"); bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; bp->bp_secs = htons(get_time_ns() >> 30); net_write_ip(&bp->bp_ciaddr, 0); net_write_ip(&bp->bp_yiaddr, 0); net_write_ip(&bp->bp_siaddr, 0); net_write_ip(&bp->bp_giaddr, 0); memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); bfile = getenv("bootfile"); if (bfile) safe_strncpy (bp->bp_file, bfile, sizeof(bp->bp_file)); /* Request additional information from the BOOTP/DHCP server */ ext_len = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); Bootp_id = (uint32_t)get_time_ns(); net_copy_uint32(&bp->bp_id, &Bootp_id); dhcp_state = SELECTING; ret = net_udp_send(dhcp_con, sizeof(*bp) + ext_len); return ret; }
static int tftp_do_close(struct file_priv *priv) { int ret; if (priv->push && priv->state != STATE_DONE) { int len; len = kfifo_get(priv->fifo, priv->buf, priv->blocksize); tftp_send_write(priv, priv->buf, len); priv->state = STATE_LAST; tftp_timer_reset(priv); while (priv->state != STATE_DONE) { ret = tftp_poll(priv); if (ret == TFTP_ERR_RESEND) tftp_send_write(priv, priv->buf, len); if (ret < 0) break; } } if (!priv->push && priv->state != STATE_DONE) { uint16_t *pkt = net_udp_get_payload(priv->tftp_con); *pkt++ = htons(TFTP_ERROR); *pkt++ = 0; *pkt++ = 0; net_udp_send(priv->tftp_con, 6); } net_unregister(priv->tftp_con); kfifo_free(priv->fifo); free(priv->buf); free(priv); return 0; }
int run(NETADDR dest) { NETSOCKET sockets[NUM_SOCKETS]; int i; for(i = 0; i < NUM_SOCKETS; i++) { NETADDR bindaddr = {NETTYPE_IPV4, {0}, 0}; sockets[i] = net_udp_create(bindaddr); } while(1) { unsigned char data[1024]; int size = 0; int socket_to_use = 0; io_read(io_stdin(), &size, 2); io_read(io_stdin(), &socket_to_use, 1); size %= 256; socket_to_use %= NUM_SOCKETS; io_read(io_stdin(), data, size); net_udp_send(sockets[socket_to_use], &dest, data, size); } }
void Run(int Port, NETADDR Dest) { NETADDR Src = {NETTYPE_IPV4, {0,0,0,0}, Port}; NETSOCKET Socket = net_udp_create(Src); char aBuffer[1024*2]; int ID = 0; int Delaycounter = 0; while(1) { static int Lastcfg = 0; int n = ((time_get()/time_freq())/m_ConfigInterval) % m_ConfigNumpingconfs; CPingConfig Ping = m_aConfigPings[n]; if(n != Lastcfg) dbg_msg("crapnet", "cfg = %d", n); Lastcfg = n; // handle incomming packets while(1) { // fetch data int DataTrash = 0; NETADDR From; int Bytes = net_udp_recv(Socket, &From, aBuffer, 1024*2); if(Bytes <= 0) break; if((rand()%100) < Ping.m_Loss) // drop the packet { if(m_ConfigLog) dbg_msg("crapnet", "dropped packet"); continue; } // create new packet CPacket *p = (CPacket *)mem_alloc(sizeof(CPacket)+Bytes, 1); if(net_addr_comp(&From, &Dest) == 0) p->m_SendTo = Src; // from the server else { Src = From; // from the client p->m_SendTo = Dest; } // queue packet p->m_pPrev = m_pLast; p->m_pNext = 0; if(m_pLast) m_pLast->m_pNext = p; else { m_pFirst = p; m_pLast = p; } m_pLast = p; // set data in packet p->m_Timestamp = time_get(); p->m_DataSize = Bytes; p->m_ID = ID++; mem_copy(p->m_aData, aBuffer, Bytes); if(ID > 20 && Bytes > 6 && DataTrash) { p->m_aData[6+(rand()%(Bytes-6))] = rand()&255; // modify a byte if((rand()%10) == 0) { p->m_DataSize -= rand()%32; if(p->m_DataSize < 6) p->m_DataSize = 6; } } if(Delaycounter <= 0) { if(Ping.m_Delay) p->m_Timestamp += (time_freq()*1000)/Ping.m_Delay; Delaycounter = Ping.m_DelayFreq; } Delaycounter--; if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(&From, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", "<< %08d %s (%d)", p->m_ID, aAddrStr, p->m_DataSize); } } // /*while(1) {*/ CPacket *p = 0; CPacket *pNext = m_pFirst; while(1) { p = pNext; if(!p) break; pNext = p->m_pNext; if((time_get()-p->m_Timestamp) > m_CurrentLatency) { char aFlags[] = " "; if(m_ConfigReorder && (rand()%2) == 0 && p->m_pNext) { aFlags[0] = 'R'; p = m_pFirst->m_pNext; } if(p->m_pNext) p->m_pNext->m_pPrev = p->m_pPrev; else m_pLast = p->m_pPrev; if(p->m_pPrev) p->m_pPrev->m_pNext = p->m_pNext; else m_pFirst = p->m_pNext; /*CPacket *cur = first; while(cur) { dbg_assert(cur != p, "p still in list"); cur = cur->next; }*/ // send and remove packet //if((rand()%20) != 0) // heavy packetloss net_udp_send(Socket, &p->m_SendTo, p->m_aData, p->m_DataSize); // update lag double Flux = rand()/(double)RAND_MAX; int MsSpike = Ping.m_Spike; int MsFlux = Ping.m_Flux; int MsPing = Ping.m_Base; m_CurrentLatency = ((time_freq()*MsPing)/1000) + (int64)(((time_freq()*MsFlux)/1000)*Flux); // 50ms if(MsSpike && (p->m_ID%100) == 0) { m_CurrentLatency += (time_freq()*MsSpike)/1000; aFlags[1] = 'S'; } if(m_ConfigLog) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(&p->m_SendTo, aAddrStr, sizeof(aAddrStr), true); dbg_msg("crapnet", ">> %08d %s (%d) %s", p->m_ID, aAddrStr, p->m_DataSize, aFlags); } mem_free(p); } } thread_sleep(1); } }
/* * rpc_req - synchronous RPC request */ static int rpc_req(struct nfs_priv *npriv, int rpc_prog, int rpc_proc, uint32_t *data, int datalen) { struct rpc_call pkt; unsigned long id; int dport; int ret; unsigned char *payload = net_udp_get_payload(npriv->con); int nfserr; int tries = 0; npriv->rpc_id++; id = npriv->rpc_id; pkt.id = htonl(id); pkt.type = htonl(MSG_CALL); pkt.rpcvers = htonl(2); /* use RPC version 2 */ pkt.prog = htonl(rpc_prog); pkt.vers = htonl(2); /* portmapper is version 2 */ pkt.proc = htonl(rpc_proc); memcpy(payload, &pkt, sizeof(pkt)); memcpy(payload + sizeof(pkt), data, datalen * sizeof(uint32_t)); if (rpc_prog == PROG_PORTMAP) dport = SUNRPC_PORT; else if (rpc_prog == PROG_MOUNT) dport = npriv->mount_port; else dport = npriv->nfs_port; npriv->con->udp->uh_dport = htons(dport); again: ret = net_udp_send(npriv->con, sizeof(pkt) + datalen * sizeof(uint32_t)); nfs_timer_start = get_time_ns(); nfs_state = STATE_START; nfs_packet = NULL; while (nfs_state != STATE_DONE) { if (ctrlc()) { ret = -EINTR; break; } net_poll(); if (is_timeout(nfs_timer_start, NFS_TIMEOUT)) { tries++; if (tries == NFS_MAX_RESEND) return -ETIMEDOUT; goto again; } ret = rpc_check_reply(nfs_packet, rpc_prog, npriv->rpc_id, &nfserr); if (!ret) { ret = nfserr; break; } } return ret; }