void sc_dcexit(void) { command_t * command = (command_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_EXIT, 4); command->address = htonl(0); command->size = htonl(0); build_send_packet(COMMAND_LEN); //bb->stop(); }
void dhcp_request() { unsigned char *opts = dhcp->data; printf("Emitting DHCP request packet with XID %x\n", dhcp_xid); memset(dhcp, 0, sizeof(*dhcp)); dhcp->op = 1; // BOOTREQUEST dhcp->htype = 1; // hw type 10mb ethernet dhcp->hlen = 6; // 10mb ethernet dhcp->hops = 0; // zero for client dhcp->xid = dhcp_xid; // transaction id dhcp->secs = 0; // seconds elapsed since client began address acquisition or renewal process dhcp->flags = htons(0); // 0x8000 = broadcast dhcp->ciaddr = htonl(0); // client ip address memcpy(dhcp->chaddr, eth_mac, sizeof(dhcp->chaddr)); // magic options header memcpy(opts, opts_magic_starter, 4); opts += 4; *opts++ = 53; /* DHCP Message Type */ *opts++ = 1; *opts++ = 3; /* DHCPREQUEST */ *opts++ = 54; // server identifier *opts++ = 4; pokel(opts, dhcp_conf.server_identifier); opts += 4; *opts++ = 50; // requested ip address *opts++ = 4; pokel(opts, dhcp_conf.yourip); opts += 4; *opts++ = 12; // host name *opts++ = lhost_name; memcpy(opts, host_name, lhost_name); opts += lhost_name; *opts++ = 55; // parameter request list *opts++ = sizeof(parameter_request_list); memcpy(opts, parameter_request_list, sizeof(parameter_request_list)); opts += sizeof(parameter_request_list); *opts++ = 61; // client identifier *opts++ = 1 + sizeof(eth_mac); *opts++ = 1; // hw type 10mb memcpy(opts, eth_mac, sizeof(eth_mac)); opts += sizeof(eth_mac); *opts++ = 255; build_send_packet(67, 68, sizeof(*dhcp) - 1 + opts - dhcp->data); }
time_t sc_time(time_t * t) { command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_TIME, 4); build_send_packet(sizeof(command_int_t)); wait_result(); return syscall_retval; }
int sc_closedir(DIR *dir) { command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_CLOSEDIR, 4); command->value0 = htonl(dir); build_send_packet(sizeof(command_int_t)); wait_result(); return syscall_retval; }
DIR * sc_opendir(const char *name) { command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(name); memcpy(command->id, CMD_OPENDIR, 4); memcpy(command->string, name, namelen+1); build_send_packet(sizeof(command_string_t)+namelen); wait_result(); return (DIR *)syscall_retval; }
int sc_write(int fd, const void *buf, size_t count) { command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_WRITE, 4); command->value0 = htonl(fd); command->value1 = htonl(buf); command->value2 = htonl(count); build_send_packet(sizeof(command_3int_t)); wait_result(); return syscall_retval; }
int sc_fstat(int filedes, dcload_stat_t *buf) { command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_FSTAT, 4); command->value0 = htonl(filedes); command->value1 = htonl(buf); command->value2 = htonl(sizeof(struct dcload_stat)); build_send_packet(sizeof(command_3int_t)); wait_result(); return syscall_retval; }
off_t sc_lseek(int fildes, off_t offset, int whence) { command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_LSEEK, 4); command->value0 = htonl(fildes); command->value1 = htonl(offset); command->value2 = htonl(whence); build_send_packet(sizeof(command_3int_t)); wait_result(); return syscall_retval; }
int sc_chdir(const char *path) { command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(path); memcpy(command->id, CMD_CHDIR, 4); memcpy(command->string, path, namelen + 1); build_send_packet(sizeof(command_string_t)+namelen); wait_result(); return syscall_retval; }
int sc_stat(const char *file_name, struct dcload_stat *buf) { command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(file_name); memcpy(command->id, CMD_STAT, 4); memcpy(command->string, file_name, namelen+1); command->value0 = htonl(buf); command->value1 = htonl(sizeof(struct dcload_stat)); build_send_packet(sizeof(command_2int_string_t)+namelen); wait_result(); return syscall_retval; }
int sc_link(const char *oldpath, const char *newpath) { command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen1 = strlen(oldpath); int namelen2 = strlen(newpath); memcpy(command->id, CMD_LINK, 4); memcpy(command->string, oldpath, namelen1 + 1); memcpy(command->string + namelen1 + 1, newpath, namelen2 + 1); build_send_packet(sizeof(command_string_t)+namelen1+namelen2+1); wait_result(); return syscall_retval; }
int sc_chmod(const char *path, int mode) { command_int_string_t * command = (command_int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(path); memcpy(command->id, CMD_CHMOD, 4); command->value0 = htonl(mode); memcpy(command->string, path, namelen+1); build_send_packet(sizeof(command_int_string_t)+namelen); wait_result(); return syscall_retval; }
struct dcload_dirent *sc_readdir(DIR *dir) { command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); memcpy(command->id, CMD_READDIR, 4); command->value0 = htonl(dir); command->value1 = htonl(&our_dir); command->value2 = htonl(sizeof(struct dcload_dirent)); build_send_packet(sizeof(command_3int_t)); wait_result(); if (syscall_retval) return &our_dir; else return 0; }
int gdGdcReqCmd(int cmd, int *param) { command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); struct TOC *toc; int i; switch (cmd) { case 16: /* read sectors */ memcpy(command->id, CMD_CDFSREAD, 4); command->value0 = htonl(param[0]); command->value1 = htonl(param[2]); command->value2 = htonl(param[1]*2048); build_send_packet(sizeof(command_3int_t)); bb_loop(); param[3] = 0; gdStatus = 2; return 0; break; case 19: /* read toc */ toc = (struct TOC *)param[1]; toc->entry[0] = 0x41000096; /* CTRL = 4, ADR = 1, LBA = 150 */ for(i=1; i<99; i++) toc->entry[i] = -1; toc->first = 0x41010000; /* first = track 1 */ toc->last = 0x41010000; /* last = track 1 */ gdStatus = 2; return 0; break; case 24: /* init disc */ gdStatus = 2; return 0; break; default: gdStatus = 0; return -1; break; } }
void dhcp_discover(unsigned int xid) { unsigned char *opts = dhcp->data; printf("Emitting DHCP discovery packet with XID %x\n", xid); memset(&dhcp_conf, 0, sizeof(dhcp_conf)); dhcp_xid = xid; memset(dhcp, 0, sizeof(*dhcp)); dhcp->op = 1; // BOOTREQUEST dhcp->htype = 1; // hw type 10mb ethernet dhcp->hlen = 6; // 10mb ethernet dhcp->hops = 0; // zero for client dhcp->xid = xid; // transaction id dhcp->secs = 0; // seconds elapsed since client began address acquisition or renewal process dhcp->flags = htons(0); // 0x8000 = broadcast dhcp->ciaddr = htonl(0); // client ip address memcpy(dhcp->chaddr, eth_mac, sizeof(dhcp->chaddr)); // magic options header memcpy(opts, opts_magic_starter, 4); opts += 4; *opts++ = 53; /* DHCP Message Type */ *opts++ = 1; *opts++ = 1; /* DHCPDISCOVER */ *opts++ = 12; // host name *opts++ = lhost_name; memcpy(opts, host_name, lhost_name); opts += lhost_name; *opts++ = 61; // client identifier *opts++ = 1 + sizeof(eth_mac); *opts++ = 1; // hw type 10mb memcpy(opts, eth_mac, sizeof(eth_mac)); opts += sizeof(eth_mac); *opts++ = 255; build_send_packet(67, 68, sizeof(*dhcp) - 1 + opts - dhcp->data); }
int sc_utime(const char *filename, struct utimbuf *buf) { command_3int_string_t * command = (command_3int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(filename); memcpy(command->id, CMD_UTIME, 4); memcpy(command->string, filename, namelen+1); command->value0 = htonl(buf); if (!buf) { command->value1 = htonl(buf->actime); command->value2 = htonl(buf->modtime); } build_send_packet(sizeof(command_3int_string_t)+namelen); wait_result(); return syscall_retval; }
int sc_open(const char *pathname, int flags, ...) { va_list ap; command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN); int namelen = strlen(pathname); memcpy(command->id, CMD_OPEN, 4); va_start(ap, flags); command->value0 = htonl(flags); command->value1 = htonl(va_arg(ap, int)); va_end(ap); memcpy(command->string, pathname, namelen+1); build_send_packet(sizeof(command_2int_string_t)+namelen); wait_result(); return syscall_retval; }
int main(int argc, char **argv) { enum state state; unsigned char command; struct timeval tval; struct packet pkt; /* Open a socket and start listening to a scpefied port */ open_udp_socket(); srand(time(NULL)); /* Startup: */ build_send_packet(BROADCAST, CMD_MASTERREQ, 0); /* Search for a master */ change_state(&state, STATE_STARTUP, &tval, NULL); for(;;) { struct timeval curtime; gettimeofday(&curtime, NULL); printf(" "); print_time(&curtime); /*printf(" TIME: %10d sec %10d usec\n", (unsigned int)curtime.tv_sec, (unsigned int)curtime.tv_usec);*/ recv_msg(&pkt, &tval); command = pkt.type; //printf("Command received = %d\n", command); switch(state | command) { /* STARTUP */ case(STATE_STARTUP | CMD_TIMEOUT): build_send_packet(BROADCAST, CMD_MASTERUP, 0); change_state(&state, STATE_MASTER, &tval, &master_timeout); break; case(STATE_STARTUP | CMD_MASTERUP): build_send_packet(pkt.ip, CMD_SLAVEUP, 0); // no break; case(STATE_STARTUP | CMD_MASTERREQ): case(STATE_STARTUP | CMD_MASTERACK): case(STATE_STARTUP | CMD_ELECTION): change_state(&state, STATE_SLAVE, &tval, NULL); break; /* MASTER */ /* Launch a new thread and process separately? Prevents loss of messages */ case(STATE_MASTER | CMD_TIMEOUT): /* Does the Master needs to send his clock? */ build_send_packet(BROADCAST, CMD_CLOCKREQ, 1); //change_state(&state, STATE_MASTER, &tval, MASTER_TIMEOUT); /* Change to an intermediate state in order to wait for all slaves * to send their clocks. After the MASTER_ADJTIME_TIMEOUT no more clock * packets will be accepted and the "slow" slaves, if any, won't * be synchronized*/ change_state(&state, STATE_MASTER_ADJTIME, &tval, &master_adjtime_timeout); /* Possibly new thread? Non blocking function...*/ adjust_master_prepare(); break; case(STATE_MASTER | CMD_MASTERREQ): build_send_packet(pkt.ip, CMD_MASTERACK, 0); break; case(STATE_MASTER | CMD_QUIT): build_send_packet(pkt.ip, CMD_ACK, 0); change_state(&state, STATE_SLAVE, &tval, NULL); break; case(STATE_MASTER | CMD_ELECTION): case(STATE_MASTER | CMD_MASTERUP): build_send_packet(pkt.ip, CMD_QUIT, 0); break; /* MASTER_ADJTIME */ case(STATE_MASTER_ADJTIME | CMD_CLOCKREQ_RESPONSE): /* Got time from client */ adjust_master_addslave(pkt.ip, &pkt.time); break; case(STATE_MASTER_ADJTIME | CMD_TIMEOUT): /* Calculate avg clocks and send to each slave his correction */ /* Restart the synchronization timer */ change_state(&state, STATE_MASTER, &tval, &master_timeout); adjust_master_calcandsend(); break; /* SLAVE */ case(STATE_SLAVE | CMD_CLOCKREQ): /* Send clock packet to master and change to an intermediate state * in order to wait for a synch packet */ build_send_packet(pkt.ip, CMD_CLOCKREQ_RESPONSE, 1); change_state(&state, STATE_SLAVE, &tval, NULL); break; case(STATE_SLAVE | CMD_TIMEOUT): build_send_packet(BROADCAST, CMD_ELECTION, 0); change_state(&state, STATE_CANDIDATE, &tval, &candidate_timeout); break; case(STATE_SLAVE | CMD_MASTERUP): build_send_packet(BROADCAST, CMD_SLAVEUP, 0); break; case(STATE_SLAVE | CMD_ELECTION): build_send_packet(pkt.ip, CMD_ACCEPT, 0); change_state(&state, STATE_ACCEPT, &tval, &accept_timeout); break; case(STATE_SLAVE | CMD_CLOCKSYNC): /* Receive packet from master, adjust local time and return to * your rightful state (slave of course... =])*/ adjust_slave_clock(&pkt.time); change_state(&state, STATE_SLAVE, &tval, NULL); break; /* CANDIDATE */ case(STATE_CANDIDATE | CMD_TIMEOUT): build_send_packet(BROADCAST, CMD_MASTERUP, 0); change_state(&state, STATE_MASTER, &tval, &master_timeout); break; case(STATE_CANDIDATE | CMD_ELECTION): build_send_packet(pkt.ip, CMD_REFUSE, 0); break; case(STATE_CANDIDATE | CMD_ACCEPT): build_send_packet(pkt.ip, CMD_ACK, 0); break; case(STATE_CANDIDATE | CMD_QUIT): case(STATE_CANDIDATE | CMD_REFUSE): build_send_packet(pkt.ip, CMD_ACK, 0); //no break case(STATE_CANDIDATE | CMD_MASTERREQ): change_state(&state, STATE_SLAVE, &tval, NULL); break; /* ACCEPT */ case(STATE_ACCEPT | CMD_TIMEOUT): change_state(&state, STATE_SLAVE, &tval, NULL); break; case(STATE_ACCEPT | CMD_ELECTION): build_send_packet(pkt.ip, CMD_REFUSE, 0); break; case(STATE_ACCEPT | CMD_MASTERUP): build_send_packet(pkt.ip, CMD_SLAVEUP, 0); break; } } return 0; }