#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "app.h"
#include "log.h"
#include "monitor.h"
#include "util.h"
int
sysdep_cleartext(int fd, int af)
{
int level, sw;
struct {
int ip_proto;
int auth_level;
int esp_trans_level;
int esp_network_level;
int ipcomp_level;
} optsw[] = {
{
IPPROTO_IP,
IP_AUTH_LEVEL,
IP_ESP_TRANS_LEVEL,
IP_ESP_NETWORK_LEVEL,
#ifdef IP_IPCOMP_LEVEL
IP_IPCOMP_LEVEL
#else
0
#endif
}, {
IPPROTO_IPV6,
IPV6_AUTH_LEVEL,
IPV6_ESP_TRANS_LEVEL,
IPV6_ESP_NETWORK_LEVEL,
#ifdef IPV6_IPCOMP_LEVEL
IPV6_IPCOMP_LEVEL
#else
0
#endif
},
};
if (app_none)
return 0;
switch (af) {
case AF_INET:
sw = 0;
break;
case AF_INET6:
sw = 1;
break;
default:
log_print("sysdep_cleartext: unsupported protocol family %d", af);
return -1;
}
level = IPSEC_LEVEL_BYPASS;
if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].auth_level,
(char *) &level, sizeof level) == -1) {
log_error("sysdep_cleartext: "
"setsockopt (%d, %d, IP_AUTH_LEVEL, ...) failed", fd,
optsw[sw].ip_proto);
return -1;
}
if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_trans_level,
(char *) &level, sizeof level) == -1) {
log_error("sysdep_cleartext: "
"setsockopt (%d, %d, IP_ESP_TRANS_LEVEL, ...) failed", fd,
optsw[sw].ip_proto);
return -1;
}
if (monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].esp_network_level,
(char *) &level, sizeof level) == -1) {
log_error("sysdep_cleartext: "
"setsockopt (%d, %d, IP_ESP_NETWORK_LEVEL, ...) failed", fd,
optsw[sw].ip_proto);
return -1;
}
if (optsw[sw].ipcomp_level &&
monitor_setsockopt(fd, optsw[sw].ip_proto, optsw[sw].ipcomp_level,
(char *) &level, sizeof level) == -1 &&
errno != ENOPROTOOPT) {
log_error("sysdep_cleartext: "
"setsockopt (%d, %d, IP_IPCOMP_LEVEL, ...) failed,", fd,
optsw[sw].ip_proto);
return -1;
}
return 0;
}