X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fgeekos%2Fsocket.c;h=b18eaeb392538f47a4f2da587739b7d112d2509d;hb=410089191febd4884a3a5a513052b0ae12aa7ebf;hp=322e2d38a72335d92f5216a5be95fb911ce71098;hpb=e1fa6479b658cd1c002795404cbe7c8777e71e44;p=palacios.git diff --git a/palacios/src/geekos/socket.c b/palacios/src/geekos/socket.c index 322e2d3..b18eaeb 100644 --- a/palacios/src/geekos/socket.c +++ b/palacios/src/geekos/socket.c @@ -1,22 +1,54 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include + + +// for some reason, there are compile warnings without these +extern void v3_init_queue(struct gen_queue * queue); +extern void v3_enqueue(struct gen_queue * queue, addr_t entry); +extern addr_t v3_dequeue(struct gen_queue * queue); + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) #define MAX_SOCKS 1024 -struct socket sockets[1024]; +struct socket sockets[MAX_SOCKS]; + +struct gen_queue in_packets; + +struct sock_packet { + int size; + uchar_t *data; +}; +int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ; void init_network() { - int i = 0; + int i = 0; + + v3_init_queue(&in_packets); - for (i = 0; i < MAX_SOCKS; i++) { - sockets[i].in_use = 0; - init_queue(&(sockets[i].send_queue)); - init_queue(&(sockets[i].recv_queue)); - } + for (i = 0; i < MAX_SOCKS; i++) { + sockets[i].in_use = 0; + v3_init_queue(&(sockets[i].send_queue)); + v3_init_queue(&(sockets[i].recv_queue)); + } + + //initiate uIP + uip_init(); + uip_arp_init(); // set up interrupt handler // set up device driver + Init_Ne2k(&Packet_Received); + } @@ -33,6 +65,11 @@ static int allocate_socket_fd() { return -1; } +static int release_socket_fd(int sockfd){ + sockets[sockfd].in_use = 0; + return 0; +} + struct socket * get_socket_from_fd(int fd) { return &(sockets[fd]); @@ -41,16 +78,200 @@ struct socket * get_socket_from_fd(int fd) { -int connect(const uint_t ip_addr) { +int connect(const uchar_t ip_addr[4], ushort_t port) { int sockfd = -1; sockfd = allocate_socket_fd(); - + uip_ipaddr_t ipaddr; + if (sockfd == -1) { return -1; } + uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]); + + sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port)); + if (sockets[sockfd].con == NULL){ + release_socket_fd(sockfd); + return -1; + } return sockfd; +} + + +void timer_int_Handler(struct Interrupt_State * state){ + int i; + //handle the periodic calls of uIP + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + //devicedriver_send(); + NE2K_Transmit(uip_len); + } + } + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + //devicedriver_send(); + NE2K_Transmit(uip_len); + } + } +} + +// a series of utilities to handle conncetion states +static void connected(int sockfd){ + +} + +static void closed(int sockfd){ + +} + +static void acked(int sockfd){ + +} + +static void newdata(int sockfd){ + +} + +// not finished yet +static void +senddata(int sockfd){ + uchar_t *bufptr; + int len = 0; + + bufptr = uip_appdata; + + if(len < uip_mss()) { + // memcpy(bufptr, data, len); + } else { + + } + //uip_send(uip_appdata,len); +} + + + +//get the socket id by the local tcp port +static int get_socket_from_port(ushort_t lport) { + int i; + + for (i = 0; ilport == lport) + return i; + } + + return -1; +} + + + + +void +socket_appcall(void) +{ + int sockfd; + + sockfd = get_socket_from_port(uip_conn->lport); + + if (sockfd == -1) return; + + if(uip_connected()) { + connected(sockfd); + } + + if(uip_closed() ||uip_aborted() ||uip_timedout()) { + closed(sockfd); + return; + } + + if(uip_acked()) { + acked(sockfd); + } + + if(uip_newdata()) { + newdata(sockfd); + } + + if(uip_rexmit() || + uip_newdata() || + uip_acked() || + uip_connected() || + uip_poll()) { + senddata(sockfd); + } +} + + + +int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) +{ + struct sock_packet next; + int i; + + next.size = info->size; + next.data = (uchar_t *)VMM_Malloc(next.size); + + if (next.data == NULL) return 1; + + //uip_len = info->size; + + for(i = 0; i < info->size; i++) { + *((next.data)+i) = *(pkt+i); + } + Free(pkt); + + Disable_Interrupts(); + v3_enqueue(&in_packets, (addr_t)(&next)); + Enable_Interrupts(); + + //triger_receiver_interrupt(); + + return 0; +} + + +void int_handler_packet_receive(struct Interrupt_State * state){ + //device driver got a incoming packet and enqueue that packet to the receive queue + struct sock_packet *next_packet; + addr_t pkt; + int i; + + while(1){ + //currently disable interrupt because no lock for the queue + Disable_Interrupts(); + pkt = v3_dequeue(&in_packets); + Enable_Interrupts(); + + if (pkt == 0) break; + + //there are new packets in the receiver queue + next_packet = (struct sock_packet *)pkt; + uip_len = next_packet->size; + + for(i = 0; i < uip_len; i++) { + uip_buf[i] = *((next_packet->data)+i); + } + + Free(next_packet->data); + Free(next_packet); + if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if (uip_len > 0){ + //ethernet_devicedriver_send(); + NE2K_Transmit(uip_len); + } + } else { + uip_arp_ipin(); + uip_input(); + if(uip_len > 0) { + uip_arp_out(); + //ethernet_devicedriver_send(); + NE2K_Transmit(uip_len); + } + } + } }