/************************************************************************** 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; }
/* * 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; }