1 #include <geekos/socket.h>
2 #include <geekos/malloc.h>
3 #include <palacios/vmm_types.h>
4 #include <geekos/ne2k.h>
6 #include <uip/uip_arp.h>
7 #include <geekos/int.h>
8 #include <geekos/vmm_stubs.h>
9 #include <palacios/vmm_queue.h>
12 // for some reason, there are compile warnings without these
13 extern void v3_init_queue(struct gen_queue * queue);
14 extern void v3_enqueue(struct gen_queue * queue, addr_t entry);
15 extern addr_t v3_dequeue(struct gen_queue * queue);
17 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
19 #define MAX_SOCKS 1024
21 struct socket sockets[MAX_SOCKS];
23 struct gen_queue in_packets;
30 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ;
35 v3_init_queue(&in_packets);
37 for (i = 0; i < MAX_SOCKS; i++) {
38 sockets[i].in_use = 0;
39 v3_init_queue(&(sockets[i].send_queue));
40 v3_init_queue(&(sockets[i].recv_queue));
47 // set up interrupt handler
48 // set up device driver
50 Init_Ne2k(&Packet_Received);
55 static int allocate_socket_fd() {
58 for (i = 0; i < MAX_SOCKS; i++) {
59 if (sockets[i].in_use == 0) {
60 sockets[i].in_use = 1;
68 static int release_socket_fd(int sockfd){
69 sockets[sockfd].in_use = 0;
74 struct socket * get_socket_from_fd(int fd) {
75 return &(sockets[fd]);
81 int connect(const uchar_t ip_addr[4], ushort_t port) {
83 sockfd = allocate_socket_fd();
90 uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
92 sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
94 if (sockets[sockfd].con == NULL){
95 release_socket_fd(sockfd);
103 void timer_int_Handler(struct Interrupt_State * state){
105 //handle the periodic calls of uIP
106 for(i = 0; i < UIP_CONNS; ++i) {
109 //devicedriver_send();
110 NE2K_Transmit(uip_len);
113 for(i = 0; i < UIP_UDP_CONNS; i++) {
116 //devicedriver_send();
117 NE2K_Transmit(uip_len);
122 // a series of utilities to handle conncetion states
123 static void connected(int sockfd){
127 static void closed(int sockfd){
131 static void acked(int sockfd){
135 static void newdata(int sockfd){
141 senddata(int sockfd){
145 bufptr = uip_appdata;
147 if(len < uip_mss()) {
148 // memcpy(bufptr, data, len);
152 //uip_send(uip_appdata,len);
157 //get the socket id by the local tcp port
158 static int get_socket_from_port(ushort_t lport) {
161 for (i = 0; i<MAX_SOCKS; i++){
162 if (sockets[i].con->lport == lport)
177 sockfd = get_socket_from_port(uip_conn->lport);
179 if (sockfd == -1) return;
181 if(uip_connected()) {
185 if(uip_closed() ||uip_aborted() ||uip_timedout()) {
209 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt)
211 struct sock_packet next;
214 next.size = info->size;
215 next.data = (uchar_t *)VMM_Malloc(next.size);
217 if (next.data == NULL) return 1;
219 //uip_len = info->size;
221 for(i = 0; i < info->size; i++) {
222 *((next.data)+i) = *(pkt+i);
226 Disable_Interrupts();
227 v3_enqueue(&in_packets, (addr_t)(&next));
230 //triger_receiver_interrupt();
236 void int_handler_packet_receive(struct Interrupt_State * state){
237 //device driver got a incoming packet and enqueue that packet to the receive queue
238 struct sock_packet *next_packet;
243 //currently disable interrupt because no lock for the queue
244 Disable_Interrupts();
245 pkt = v3_dequeue(&in_packets);
250 //there are new packets in the receiver queue
251 next_packet = (struct sock_packet *)pkt;
252 uip_len = next_packet->size;
254 for(i = 0; i < uip_len; i++) {
255 uip_buf[i] = *((next_packet->data)+i);
258 Free(next_packet->data);
261 if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
264 //ethernet_devicedriver_send();
265 NE2K_Transmit(uip_len);
272 //ethernet_devicedriver_send();
273 NE2K_Transmit(uip_len);