Add counters for MPTP buffers and syscalls.
[swifty.git] / src / raw / socket_manager_array.c
1 /*
2  * Array management for sockets
3  *
4  * Use an array similar to a descriptor table to store information about
5  * sockets. Use functions to add, remove, find and update information.
6  *
7  * 2011, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <unistd.h>
17 #include <errno.h>
18
19 #include "swift_types.h"
20 #include "socket_manager.h"
21 #include "debug.h"
22 #include "util.h"
23
24 enum sock_bind_state {
25         STATE_NOTBOUND,
26         STATE_BOUND
27 };
28
29 /* socket management structure */
30 struct sock {
31         int s;
32         struct sockaddr addr;
33         enum sock_bind_state bind_state;
34 };
35
36 /*
37  * Socket management array
38  * Size is assumed size of descriptor table. Socket descriptor is an array
39  * index.
40  */
41 #define ARRAY_SIZE      1024
42 static struct sock *sock_array[ARRAY_SIZE];
43
44 /*
45  * Find socket in socket management array.
46  */
47
48 static struct sock *array_get_sock(int s)
49 {
50         if (s < 0 || s >= ARRAY_SIZE)
51                 return NULL;
52
53         return sock_array[s];
54 }
55
56 /*
57  * Find socket in socket management array by address.
58  */
59
60 static struct sock *array_get_sock_by_address(const struct sockaddr *addr)
61 {
62         struct sock *ptr;
63         int i;
64
65         for (i = 0; i < ARRAY_SIZE; i++) {
66                 ptr = sock_array[i];
67                 if (ptr == NULL)
68                         continue;
69                 if (memcmp(addr, &ptr->addr, sizeof(*addr)) == 0)
70                         return ptr;
71         }
72
73         return NULL;
74 }
75
76 /*
77  * Add new socket to list. Called by sw_socket "syscall".
78  */
79
80 int sm_add(int s)
81 {
82         struct sock *ptr = malloc(sizeof(*ptr));
83         if (ptr == NULL)
84                 return -1;
85
86         ptr->s = s;
87         sock_array[s] = ptr;
88
89         return 0;
90 }
91
92 /*
93  * Bind socket to given address. Called by sw_bind "syscall".
94  */
95
96 int sm_update_address(int s, const struct sockaddr *addr)
97 {
98         struct sock *ptr;
99
100         ptr = array_get_sock(s);
101         if (ptr == NULL)
102                 return -1;
103
104         memcpy(&ptr->addr, addr, sizeof(ptr->addr));
105
106         return 0;
107 }
108
109 /*
110  * Remove socket from list. Called by sw_close "syscall".
111  */
112
113 int sm_del(int s)
114 {
115         struct sock *ptr;
116
117         ptr = array_get_sock(s);
118         if (ptr == NULL)
119                 return -1;
120
121         sock_array[s] = NULL;
122         free(ptr);
123
124         return 0;
125 }
126
127 /*
128  * Check if a socket is bound.
129  */
130
131 int sm_is_bound(int s)
132 {
133         struct sock *ptr;
134
135         ptr = array_get_sock(s);
136         if (ptr == NULL)
137                 return 0;
138
139         if (ptr->bind_state == STATE_BOUND)
140                 return 1;
141
142         return 0;
143 }
144
145 /*
146  * Mark socket as bound.
147  */
148
149 int sm_mark_bound(int s)
150 {
151         struct sock *ptr;
152
153         ptr = array_get_sock(s);
154         if (ptr == NULL)
155                 return -1;
156
157         ptr->bind_state = STATE_BOUND;
158
159         return 0;
160 }
161
162 /*
163  * Mark socket as unbound.
164  */
165
166 int sm_mark_unbound(int s)
167 {
168         struct sock *ptr;
169
170         ptr = array_get_sock(s);
171         if (ptr == NULL)
172                 return -1;
173
174         ptr->bind_state = STATE_NOTBOUND;
175
176         return 0;
177 }
178
179 /*
180  * Check if adress is asociated with a given socket.
181  */
182
183 int sm_address_exists(const struct sockaddr *addr)
184 {
185         struct sock *ptr;
186
187         ptr = array_get_sock_by_address(addr);
188         if (ptr == NULL)
189                 return 0;
190
191         return 1;
192 }
193
194 /*
195  * Find socket address.
196  */
197
198 struct sockaddr *sm_get_address(int s)
199 {
200         struct sock *ptr;
201
202         ptr = array_get_sock(s);
203         if (ptr == NULL)
204                 return NULL;
205
206         return &ptr->addr;
207 }