1085
1085
errno = old_errno;
1088
bool get_flags(const char *ifname, struct ifreq *ifr){
1091
int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1093
perror_plus("socket");
1096
strcpy(ifr->ifr_name, ifname);
1097
ret = ioctl(s, SIOCGIFFLAGS, ifr);
1089
* This function determines if a directory entry in /sys/class/net
1090
* corresponds to an acceptable network device.
1091
* (This function is passed to scandir(3) as a filter function.)
1093
int good_interface(const struct dirent *if_entry){
1095
char *flagname = NULL;
1096
if(if_entry->d_name[0] == '.'){
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){
1100
perror_plus("ioctl SIOCGIFFLAGS");
1145
fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
1146
flagstring, if_entry->d_name);
1107
bool good_flags(const char *ifname, const struct ifreq *ifr){
1152
ifreq_flags flags = (ifreq_flags)tmpmax;
1109
1153
/* Reject the loopback device */
1110
if(ifr->ifr_flags & IFF_LOOPBACK){
1154
if(flags & IFF_LOOPBACK){
1112
1156
fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1117
1161
/* Accept point-to-point devices only if connect_to is specified */
1118
if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
1162
if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
1120
1164
fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1125
1169
/* Otherwise, reject non-broadcast-capable devices */
1126
if(not (ifr->ifr_flags & IFF_BROADCAST)){
1170
if(not (flags & IFF_BROADCAST)){
1128
1172
fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1133
1177
/* Reject non-ARP interfaces (including dummy interfaces) */
1134
if(ifr->ifr_flags & IFF_NOARP){
1178
if(flags & IFF_NOARP){
1136
fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n", ifname);
1180
fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n",
1141
1185
/* Accept this device */
1143
fprintf(stderr, "Interface \"%s\" is good\n", ifname);
1149
* This function determines if a directory entry in /sys/class/net
1150
* corresponds to an acceptable network device.
1151
* (This function is passed to scandir(3) as a filter function.)
1153
int good_interface(const struct dirent *if_entry){
1155
if(if_entry->d_name[0] == '.'){
1160
if(not get_flags(if_entry->d_name, &ifr)){
1164
if(not good_flags(if_entry->d_name, &ifr)){
1187
fprintf(stderr, "Interface \"%s\" is acceptable\n",