about summary refs log tree commit diff stats
path: root/src/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/packet.c')
-rw-r--r--src/packet.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/packet.c b/src/packet.c
index 0c9d592..0663b64 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -50,6 +50,68 @@ char *nbd_tftp_ser_data_from_parts(uint16_t blocknum, char *data, size_t datalen
 	return buf;
 }
 
+nbd_tftp_packet_data nbd_tftp_de_data(char *data, size_t len) {
+	nbd_tftp_packet_data ret = { 0, 0, (char *)NULL, (size_t)0 };
+	if ((len >= 4) && (data != NULL)) {
+		ret.opcode = ((uint16_t)data[0] << 8) + data[1];
+		ret.block_num = ((uint16_t)data[2] << 8) + data[3];
+		ret.datalen = len - 4;
+		if (ret.datalen <= 0) {
+			if ((ret.data = malloc(ret.datalen)) != NULL) {
+				memcpy(ret.data, (data + 4), ret.datalen);
+			}
+		}
+	}
+	return ret;
+}
+
+char *nbd_tftp_ser_error(nbd_tftp_packet_error e) {
+	char *buf = malloc(sizeof(e.opcode) + sizeof((uint16_t)e.err) + strlen(e.emsg));
+	if (buf != NULL) {
+		uint16_t netopcode = htons(e.opcode);
+		uint16_t netecode = htons((uint16_t)e.err);
+		memcpy(buf, &netopcode, sizeof(netopcode));
+		memcpy((buf + sizeof(netopcode)), &netecode, sizeof(netecode));
+		memcpy((buf + sizeof(netopcode) + sizeof(netecode)), e.emsg, strlen(e.emsg));
+	}
+	return buf;
+}
+
+char *nbd_tftp_ser_error_from_code(nbd_tftp_ecode error) {
+	char *emsg = nbd_tftp_error_to_message(error);
+	char *buf = malloc(sizeof(uint16_t) + sizeof(uint16_t) + strlen(emsg));
+	if (buf != NULL) {
+		uint16_t netopcode = htons(5);
+		uint16_t netecode = htons((uint16_t)error);
+		memcpy(buf, &netopcode, sizeof(netopcode));
+		memcpy((buf + sizeof(netopcode)), &netecode, sizeof(netecode));
+		memcpy((buf + sizeof(netopcode) + sizeof(netecode)), emsg, strlen(emsg));
+	}
+	return buf;
+}
+
+char *nbd_tftp_ser_ack(nbd_tftp_packet_ack ack) {
+	char *buf = malloc(sizeof(ack.opcode) + sizeof(ack.block_num));
+	if (buf != NULL) {
+		uint16_t netopcode = htons(ack.opcode);
+		uint16_t netbnum = htons(ack.block_num);
+		memcpy(buf, &netopcode, sizeof(netopcode));
+		memcpy((buf + sizeof(netopcode)), &netbnum, sizeof(netbnum));
+	}
+	return buf;
+}
+
+char *nbd_tftp_ser_ack_from_block_num(uint16_t block_num) {
+	char *buf = malloc(sizeof(uint16_t) + sizeof(block_num));
+	if (buf != NULL) {
+		uint16_t netopcode = htons(5);
+		uint16_t netbnum = htons(block_num);
+		memcpy(buf, &netopcode, sizeof(netopcode));
+		memcpy((buf + sizeof(netopcode)), &netbnum, sizeof(netbnum));
+	}
+	return buf;
+}
+
 nbd_tftp_packet_ack nbd_tftp_de_ack(char *buf, ssize_t buflen) {
 	nbd_tftp_packet_ack ack = { 0, 0 };
 	if ((buf != NULL) && (buflen == 4)) {