#include #include #include #include #include "packet.h" char *nbd_tftp_error_to_message(nbd_tftp_ecode error) { switch (error) { case 0: return "ERROR"; case 1: return "File not Found"; case 2: return "Access violation"; case 3: return "Disk full or allocation exceeded"; case 4: return "Illegal TFTP operation"; case 5: return "Unknown Transfer ID"; case 6: return "File already exists"; case 7: return "No such user"; } return "UNKNOWN ERROR"; } char *nbd_tftp_ser_data(nbd_tftp_packet_data d) { char *buf = malloc(sizeof(d.opcode) + sizeof(d.block_num) + d.datalen); if (buf != NULL) { uint16_t netopcode = htons(d.opcode); uint16_t netbnum = htons(d.block_num); memcpy(buf, &netopcode, sizeof(netopcode)); memcpy((buf + sizeof(netopcode)), &netbnum, sizeof(netbnum)); memcpy((buf + sizeof(netopcode) + sizeof(netbnum)), d.data, d.datalen); } return buf; } char *nbd_tftp_ser_data_from_parts(uint16_t blocknum, char *data, size_t datalen) { char *buf = malloc(sizeof(uint16_t) + sizeof(blocknum) + datalen); if (buf != NULL) { uint16_t netopcode = htons(3); uint16_t netbnum = htons(blocknum); memcpy(buf, &netopcode, sizeof(netopcode)); memcpy((buf + sizeof(netopcode)), &netbnum, sizeof(netbnum)); memcpy((buf + sizeof(netopcode) + sizeof(netbnum)), data, datalen); } 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)) { uint16_t opcode = ((uint16_t)buf[0] << 8) + buf[1]; uint16_t block_num = ((uint16_t)buf[2] << 8) + buf[3]; ack.opcode = opcode; ack.block_num = block_num; } return ack; }