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