/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1092
1092
 */
1093
1093
int good_interface(const struct dirent *if_entry){
1094
1094
  ssize_t ssret;
1095
 
  int ret;
 
1095
  char *flagname = NULL;
1096
1096
  if(if_entry->d_name[0] == '.'){
1097
1097
    return 0;
1098
1098
  }
1099
 
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1100
 
  if(s < 0){
1101
 
    perror_plus("socket");
1102
 
    return 0;
1103
 
  }
1104
 
  struct ifreq ifr;
1105
 
  strcpy(ifr.ifr_name, if_entry->d_name);
1106
 
  ret = ioctl(s, SIOCGIFFLAGS, &ifr);
1107
 
  if(ret == -1){
 
1099
  int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
 
1100
                     if_entry->d_name);
 
1101
  if(ret < 0){
 
1102
    perror_plus("asprintf");
 
1103
    return 0;
 
1104
  }
 
1105
  int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
 
1106
  if(flags_fd == -1){
 
1107
    perror_plus("open");
 
1108
    free(flagname);
 
1109
    return 0;
 
1110
  }
 
1111
  free(flagname);
 
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");
 
1119
    close(flags_fd);
 
1120
    return 0;
 
1121
  }
 
1122
  while(to_read > 0){
 
1123
    ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
 
1124
                                             (size_t)to_read));
 
1125
    if(ssret == -1){
 
1126
      perror_plus("read");
 
1127
      free(flagstring);
 
1128
      close(flags_fd);
 
1129
      return 0;
 
1130
    }
 
1131
    to_read -= ssret;
 
1132
    if(ssret == 0){
 
1133
      break;
 
1134
    }
 
1135
  }
 
1136
  close(flags_fd);
 
1137
  intmax_t tmpmax;
 
1138
  char *tmp;
 
1139
  errno = 0;
 
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){
1108
1144
    if(debug){
1109
 
      perror_plus("ioctl SIOCGIFFLAGS");
 
1145
      fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
 
1146
              flagstring, if_entry->d_name);
1110
1147
    }
 
1148
    free(flagstring);
1111
1149
    return 0;
1112
1150
  }
 
1151
  free(flagstring);
 
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){
1115
1155
    if(debug){
1116
1156
      fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1117
1157
              if_entry->d_name);
1119
1159
    return 0;
1120
1160
  }
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)){
1123
1163
    if(debug){
1124
1164
      fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1125
1165
              if_entry->d_name);
1127
1167
    return 1;
1128
1168
  }
1129
1169
  /* Otherwise, reject non-broadcast-capable devices */
1130
 
  if(not (ifr.ifr_flags & IFF_BROADCAST)){
 
1170
  if(not (flags & IFF_BROADCAST)){
1131
1171
    if(debug){
1132
1172
      fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1133
1173
              if_entry->d_name);
1135
1175
    return 0;
1136
1176
  }
1137
1177
  /* Reject non-ARP interfaces (including dummy interfaces) */
1138
 
  if(ifr.ifr_flags & IFF_NOARP){
 
1178
  if(flags & IFF_NOARP){
1139
1179
    if(debug){
1140
1180
      fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n",
1141
1181
              if_entry->d_name);