8 #include <sys/socket.h>
12 #include "constants.h"
16 #include "params.h" // victim_path, verbose, do_specific_proto
19 unsigned int nr_sockets
= 0;
21 static const char *cachefilename
="trinity.socketcache";
23 #define MAX_PER_DOMAIN 5
24 #define MAX_TRIES_PER_DOMAIN 10
26 static int open_socket(unsigned int domain
, unsigned int type
, unsigned int protocol
)
32 fd
= socket(domain
, type
, protocol
);
36 shm
->socket_fds
[nr_sockets
] = fd
;
38 output(2, "fd[%i] = domain:%i (%s) type:0x%x protocol:%i\n",
39 fd
, domain
, get_proto_name(domain
), type
, protocol
);
43 /* Sometimes, listen on created sockets. */
47 /* fake a sockaddr. */
48 generate_sockaddr((unsigned long *) &sa
, (unsigned long *) &salen
, domain
);
50 ret
= bind(fd
, &sa
, salen
);
52 printf("bind: %s\n", strerror(errno));
54 printf("bind: success!\n");
56 ret
= listen(fd
, (rand() % 2) + 1);
58 printf("listen: %s\n", strerror(errno));
60 printf("listen: success!\n");
67 static void lock_cachefile(int cachefile
, int type
)
79 output(2, "waiting on lock for cachefile\n");
81 if (fcntl(cachefile
, F_SETLKW
, &fl
) == -1) {
82 perror("fcntl F_SETLKW");
87 output(2, "took lock for cachefile\n");
90 static void unlock_cachefile(int cachefile
)
101 if (fcntl(cachefile
, F_SETLK
, &fl
) == -1) {
102 perror("fcntl F_UNLCK F_SETLK ");
107 output(2, "dropped lock for cachefile\n");
110 static void generate_sockets(void)
114 unsigned int nr_to_create
= NR_SOCKET_FDS
;
115 unsigned int buffer
[3];
117 cachefile
= creat(cachefilename
, S_IWUSR
|S_IRUSR
);
119 printf("Couldn't open cachefile for writing! (%s)\n",
124 lock_cachefile(cachefile
, F_WRLCK
);
126 while (nr_to_create
> 0) {
128 struct socket_triplet st
;
130 if (shm
->exit_reason
!= STILL_RUNNING
) {
135 for (st
.family
= 0; st
.family
< TRINITY_PF_MAX
; st
.family
++) {
137 if (do_specific_proto
== TRUE
)
138 st
.family
= specific_proto
;
140 if (get_proto_name(st
.family
) == NULL
)
143 if (sanitise_socket_triplet(&st
) == -1)
144 rand_proto_type(&st
);
146 fd
= open_socket(st
.family
, st
.type
, st
.protocol
);
150 buffer
[0] = st
.family
;
152 buffer
[2] = st
.protocol
;
153 n
= write(cachefile
, &buffer
, sizeof(int) * 3);
155 printf("something went wrong writing the cachefile!\n");
159 if (nr_to_create
== 0)
162 //printf("Couldn't open family:%d (%s)\n", st.family, get_proto_name(st.family));
166 /* check for ctrl-c */
167 if (shm
->exit_reason
!= STILL_RUNNING
)
170 //FIXME: If we've passed -P and we're spinning here without making progress
171 // then we should abort after a few hundred loops.
176 unlock_cachefile(cachefile
);
178 output(1, "created %d sockets\n", nr_sockets
);
184 static void close_sockets(void)
189 for (i
= 0; i
< nr_sockets
; i
++) {
190 fd
= shm
->socket_fds
[i
];
191 shm
->socket_fds
[i
] = 0;
192 if (close(fd
) != 0) {
193 printf("failed to close socket.(%s)\n", strerror(errno
));
200 void open_sockets(void)
203 unsigned int domain
, type
, protocol
;
204 unsigned int buffer
[3];
208 /* If we have victim files, don't worry about sockets. */
209 if (victim_path
!= NULL
)
212 cachefile
= open(cachefilename
, O_RDONLY
);
214 printf("Couldn't find socket cachefile. Regenerating.\n");
219 lock_cachefile(cachefile
, F_RDLCK
);
221 while (bytesread
!= 0) {
222 bytesread
= read(cachefile
, buffer
, sizeof(int) * 3);
228 protocol
= buffer
[2];
230 if (do_specific_proto
== TRUE
) {
231 if (domain
!= specific_proto
) {
232 printf("ignoring socket cachefile due to specific protocol request, and stale data in cachefile.\n");
234 unlock_cachefile(cachefile
); /* drop the reader lock. */
236 unlink(cachefilename
);
242 fd
= open_socket(domain
, type
, protocol
);
244 printf("Cachefile is stale. Need to regenerate.\n");
249 /* check for ctrl-c */
250 if (shm
->exit_reason
!= STILL_RUNNING
) {
256 if (nr_sockets
< NR_SOCKET_FDS
) {
257 printf("Insufficient sockets in cachefile (%d). Regenerating.\n", nr_sockets
);
261 output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets
);
263 unlock_cachefile(cachefile
);