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 <geekos/queue.h>
10
11 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
12
13 #define MAX_SOCKS 1024
14
15 struct socket sockets[MAX_SOCKS];
16
17
18 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ;
19
20 void init_network() {
21    int i = 0;
22    
23    for (i = 0; i < MAX_SOCKS; i++) {
24      sockets[i].in_use = 0;
25      init_ring_buffer(&(sockets[i].send_queue), 65535);
26      init_ring_buffer(&(sockets[i].recv_queue), 65535);
27    }
28    
29    //initiate uIP
30    uip_init();
31    uip_arp_init();
32    
33    // set up interrupt handler
34    // set up device driver
35    
36    Init_Ne2k(&Packet_Received);
37    
38    
39 }
40
41 static int allocate_socket_fd() {
42   int i = 0;
43   
44   for (i = 0; i < MAX_SOCKS; i++) {
45     if (sockets[i].in_use == 0) {
46       sockets[i].in_use = 1;
47       return i;
48     }
49   }
50
51   return -1;
52 }
53
54 static int release_socket_fd(int sockfd){
55   if ((sockfd >= 0) && (sockfd < MAX_SOCKS)) {
56     sockets[sockfd].in_use = 0;
57   }
58   
59   return 0;
60 }
61
62
63 struct socket * get_socket_from_fd(int fd) {
64   return &(sockets[fd]);
65 }
66
67
68 int connect(const uchar_t ip_addr[4], ushort_t port) {
69   int sockfd = -1;
70   uip_ipaddr_t ipaddr;
71
72   sockfd = allocate_socket_fd();
73   if (sockfd == -1) {
74     return -1;
75   }
76
77   uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);  
78   
79   sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
80
81   if (sockets[sockfd].con == NULL){
82     release_socket_fd(sockfd);
83     return -1;
84   }
85
86   return sockfd;
87 }
88
89
90 void timer_int_Handler(struct Interrupt_State * state){
91   int i;
92   //handle the periodic calls of uIP
93
94   for(i = 0; i < UIP_CONNS; ++i) {
95     uip_periodic(i);
96
97     if(uip_len > 0) {
98       NE2K_Transmit(uip_len);
99     }
100   }
101
102
103   for(i = 0; i < UIP_UDP_CONNS; i++) {
104     uip_udp_periodic(i);
105
106     if(uip_len > 0) {
107       NE2K_Transmit(uip_len);
108     }
109   }
110 }
111
112 // a series of utilities to handle conncetion states
113 static void connected(int sockfd) {
114
115 }
116
117 static void closed(int sockfd) {
118
119 }
120
121 static void acked(int sockfd) {
122
123 }
124
125 static void newdata(int sockfd) {
126
127 }
128
129 // not finished yet
130 static void senddata(int sockfd) {
131   struct socket * sock = get_socket_from_fd(sockfd);
132   int mss = uip_mss();
133   int pending_bytes = rb_data_len(&(sock->send_queue));
134   int len = (mss < pending_bytes) ? mss: pending_bytes;
135   int bytes_read = 0;
136   uchar_t * send_buf = uip_appdata;
137   
138   bytes_read = rb_peek(&(sock->send_queue), send_buf, len);
139
140   if (bytes_read == 0) {
141     // no packet for send
142     return;
143   }
144
145   uip_send(send_buf, len);
146 }
147
148
149
150 //get the socket id by the local tcp port
151 static int get_socket_from_port(ushort_t lport) {
152   int i;
153   
154   for (i = 0; i < MAX_SOCKS; i++){
155     if (sockets[i].con->lport == lport) 
156       return i;
157   }
158   
159   return -1;
160 }
161
162
163
164
165 void
166 socket_appcall(void)
167 {
168   int sockfd; 
169
170   sockfd = get_socket_from_port(uip_conn->lport);
171
172   if (sockfd == -1) {
173     return;
174   }
175
176   if(uip_connected()) {
177     connected(sockfd);
178   }
179   
180   if(uip_closed() ||uip_aborted() ||uip_timedout()) {
181      closed(sockfd);
182      return;
183   }
184   
185   if(uip_acked()) {
186      acked(sockfd);
187   }
188   
189   if(uip_newdata()) {
190      newdata(sockfd);
191   }
192   
193   if(uip_rexmit() ||
194      uip_newdata() ||
195      uip_acked() ||
196      uip_connected() ||
197      uip_poll()) {
198      senddata(sockfd);
199   }
200 }
201
202
203
204 int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
205   //int i;
206   
207   uip_len = info->size; 
208
209   //  for (i = 0; i < info->size; i++) {
210   //  uip_buf[i] = *(pkt + i);
211   //}
212
213   memcpy(uip_buf, pkt, uip_len);
214
215
216   Free(pkt);
217
218   if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
219     uip_arp_arpin();
220
221     if (uip_len > 0) {
222       NE2K_Transmit(uip_len);
223     }                                   
224
225   } else {
226
227     uip_arp_ipin();
228     uip_input();
229
230     if (uip_len > 0) {
231       uip_arp_out();
232       NE2K_Transmit(uip_len);
233     }
234   }                       
235   return 0;
236 }