Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


*** empty log message ***
[palacios.git] / palacios / src / geekos / socket.c
1 #include <geekos/socket.h>
2 #include <geekos/malloc.h>
3 #include <palacios/vmm_types.h>
4 #include <geekos/ne2k.h>
5 #include <uip/uip.h>
6 #include <uip/uip_arp.h>
7 #include <geekos/int.h>
8 #include <geekos/vmm_stubs.h>
9 #include <palacios/vmm_queue.h>
10
11
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);
16
17 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
18
19 #define MAX_SOCKS 1024
20
21 struct socket sockets[MAX_SOCKS];
22
23 struct gen_queue in_packets;
24
25 struct sock_packet {
26         int size;
27         uchar_t *data;
28 };
29
30 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ;
31
32 void init_network() {
33    int i = 0;
34    
35    v3_init_queue(&in_packets);
36
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));
41    }
42
43   //initiate uIP
44     uip_init();
45     uip_arp_init();
46
47   // set up interrupt handler
48   // set up device driver
49
50     Init_Ne2k(&Packet_Received);
51
52
53 }
54
55 static int allocate_socket_fd() {
56   int i = 0;
57   
58   for (i = 0; i < MAX_SOCKS; i++) {
59     if (sockets[i].in_use == 0) {
60       sockets[i].in_use = 1;
61       return i;
62     }
63   }
64
65   return -1;
66 }
67
68 static int release_socket_fd(int sockfd){
69         sockets[sockfd].in_use = 0;
70         return 0;
71 }
72
73
74 struct socket * get_socket_from_fd(int fd) {
75   return &(sockets[fd]);
76 }
77
78
79
80
81 int connect(const uchar_t ip_addr[4], ushort_t port) {
82   int sockfd = -1;
83   sockfd = allocate_socket_fd();
84   uip_ipaddr_t ipaddr;
85   
86   if (sockfd == -1) {
87     return -1;
88   }
89
90   uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);  
91   
92   sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
93
94   if (sockets[sockfd].con == NULL){
95         release_socket_fd(sockfd);
96         return -1;
97   }
98
99   return sockfd;
100 }
101
102
103 void timer_int_Handler(struct Interrupt_State * state){
104         int i;
105         //handle the periodic calls of uIP
106         for(i = 0; i < UIP_CONNS; ++i) {
107                uip_periodic(i);
108                 if(uip_len > 0) {
109                      //devicedriver_send();
110                      NE2K_Transmit(uip_len);
111                 }
112         }
113         for(i = 0; i < UIP_UDP_CONNS; i++) {
114                  uip_udp_periodic(i);
115                  if(uip_len > 0) {
116                      //devicedriver_send();
117                      NE2K_Transmit(uip_len);
118                 }
119         }
120 }
121
122 // a series of utilities to handle conncetion states
123 static void connected(int sockfd){
124
125 }
126
127 static void closed(int sockfd){
128
129 }
130
131 static void acked(int sockfd){
132
133 }
134
135 static void newdata(int sockfd){
136
137 }
138
139 // not finished yet
140 static void
141 senddata(int sockfd){
142     uchar_t *bufptr;
143     int len = 0;
144
145     bufptr = uip_appdata;
146   
147     if(len < uip_mss()) {
148       // memcpy(bufptr, data, len);
149     } else {
150
151     }
152   //uip_send(uip_appdata,len);
153 }
154
155
156
157 //get the socket id by the local tcp port
158 static int  get_socket_from_port(ushort_t lport) {
159   int i;
160   
161   for (i = 0; i<MAX_SOCKS; i++){
162         if (sockets[i].con->lport == lport) 
163                 return i;
164   }
165   
166   return -1;
167 }
168
169
170
171
172 void
173 socket_appcall(void)
174 {
175   int sockfd; 
176
177   sockfd = get_socket_from_port(uip_conn->lport);
178
179   if (sockfd == -1) return;
180     
181   if(uip_connected()) {
182         connected(sockfd);
183   }
184   
185   if(uip_closed() ||uip_aborted() ||uip_timedout()) {
186      closed(sockfd);
187      return;
188   }
189   
190   if(uip_acked()) {
191      acked(sockfd);
192   }
193   
194   if(uip_newdata()) {
195      newdata(sockfd);
196   }
197   
198   if(uip_rexmit() ||
199      uip_newdata() ||
200      uip_acked() ||
201      uip_connected() ||
202      uip_poll()) {
203      senddata(sockfd);
204   }
205 }
206
207
208
209 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) 
210 {
211           struct sock_packet next;
212           int i;
213           
214           next.size = info->size;
215           next.data = (uchar_t *)VMM_Malloc(next.size);
216
217           if (next.data == NULL) return 1;
218           
219           //uip_len = info->size;  
220
221           for(i = 0; i < info->size; i++) {
222             *((next.data)+i) = *(pkt+i);
223           }
224           Free(pkt);
225
226           Disable_Interrupts();
227          v3_enqueue(&in_packets, (addr_t)(&next));
228           Enable_Interrupts();
229
230           //triger_receiver_interrupt();
231          
232           return 0;
233 }
234
235
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; 
239                 addr_t pkt;
240                 int i; 
241                         
242                 while(1){ 
243                      //currently disable interrupt because no lock for the queue
244                        Disable_Interrupts();
245                         pkt = v3_dequeue(&in_packets);
246                         Enable_Interrupts();
247
248                         if (pkt == 0) break;
249
250                         //there are new packets in the receiver queue
251                         next_packet = (struct sock_packet *)pkt;
252                         uip_len = next_packet->size;  
253
254                         for(i = 0; i < uip_len; i++) {
255                             uip_buf[i] = *((next_packet->data)+i);
256                         }
257                           
258                         Free(next_packet->data);
259                         Free(next_packet);
260
261                         if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
262                             uip_arp_arpin();
263                             if (uip_len > 0){
264                                 //ethernet_devicedriver_send();
265                                 NE2K_Transmit(uip_len);
266                             }                                   
267                         } else {
268                             uip_arp_ipin();
269                             uip_input();
270                             if(uip_len > 0) {
271                                 uip_arp_out();
272                                  //ethernet_devicedriver_send();
273                                  NE2K_Transmit(uip_len);
274                             }
275                         }                         
276                 }       
277 }