1093
1093
int good_interface(const struct dirent *if_entry){
1095
char *flagname = NULL;
1096
1096
if(if_entry->d_name[0] == '.'){
1099
int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1101
perror_plus("socket");
1105
strcpy(ifr.ifr_name, if_entry->d_name);
1106
ret = ioctl(s, SIOCGIFFLAGS, &ifr);
1099
int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
1102
perror_plus("asprintf");
1105
int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
1107
perror_plus("open");
1112
typedef short ifreq_flags; /* ifreq.ifr_flags in netdevice(7) */
1113
/* read line from flags_fd */
1114
ssize_t to_read = 2+(sizeof(ifreq_flags)*2)+1; /* "0x1003\n" */
1115
char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */
1116
flagstring[(size_t)to_read] = '\0';
1117
if(flagstring == NULL){
1118
perror_plus("malloc");
1123
ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
1126
perror_plus("read");
1140
tmpmax = strtoimax(flagstring, &tmp, 0);
1141
if(errno != 0 or tmp == flagstring or (*tmp != '\0'
1142
and not (isspace(*tmp)))
1143
or tmpmax != (ifreq_flags)tmpmax){
1109
perror_plus("ioctl SIOCGIFFLAGS");
1145
fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
1146
flagstring, if_entry->d_name);
1152
ifreq_flags flags = (ifreq_flags)tmpmax;
1113
1153
/* Reject the loopback device */
1114
if(ifr.ifr_flags & IFF_LOOPBACK){
1154
if(flags & IFF_LOOPBACK){
1116
1156
fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1117
1157
if_entry->d_name);
1121
1161
/* Accept point-to-point devices only if connect_to is specified */
1122
if(connect_to != NULL and (ifr.ifr_flags & IFF_POINTOPOINT)){
1162
if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
1124
1164
fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1125
1165
if_entry->d_name);
1129
1169
/* Otherwise, reject non-broadcast-capable devices */
1130
if(not (ifr.ifr_flags & IFF_BROADCAST)){
1170
if(not (flags & IFF_BROADCAST)){
1132
1172
fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1133
1173
if_entry->d_name);