wlan: association/disasssociation api and ioctls

This commit is contained in:
Matheus
2026-09-10 12:43:27 -03:00
parent 9b0f202bdb
commit d3ff861386
3 changed files with 67 additions and 5 deletions
+4
View File
@@ -12,4 +12,8 @@ int wlan_wait_for_scan(netdev_t *netdev);
int wlan_get_bss_cache(netdev_t *netdev, void *buffer, size_t size, size_t *records_written);
int wlan_associate(netdev_t *netdev, uint8_t bssid[6], void *ie, size_t ie_size);
int wlan_associate_wait(netdev_t *netdev);
int wlan_disassociate(netdev_t *netdev);
#endif
+36 -5
View File
@@ -29,6 +29,14 @@ typedef struct {
size_t records_returned; // filled in by kernel
} wlan_bss_request_t;
typedef struct {
uint8_t bssid[6];
void *ie;
size_t ie_size;
} wlan_association_request_t;
#define MAX_IE_SIZE 1024
#define NETDEV_IOCTL_GET_INFO 0x1337631
#define NETDEV_IOCTL_WLAN_SCAN 0x8021101
#define NETDEV_IOCTL_WLAN_SCAN_WAIT 0x8021102
@@ -58,19 +66,42 @@ int handle_wlan_ioctl(netdev_t *netdev, unsigned long request, void *arg, int *r
wlan_get_bss_cache(netdev, bss_request.buffer, bss_request.buffer_size, &bss_request.records_returned);
return USERCOPY_POSSIBLY_TO_USER(arg, &bss_request, sizeof(bss_request));
}
case NETDEV_IOCTL_WLAN_ASSOCIATE:
case NETDEV_IOCTL_WLAN_ASSOCIATE: {
wlan_association_request_t ar;
int error = USERCOPY_POSSIBLY_FROM_USER(&ar, arg, sizeof(ar));
if (error)
return error;
break;
if (IS_USER_ADDRESS(arg) && !IS_USER_ADDRESS(ar.ie))
return EFAULT;
if (ar.ie_size > MAX_IE_SIZE)
return EINVAL;
void *ie = alloc(ar.ie_size);
if (ie == NULL)
return ENOMEM;
error = USERCOPY_POSSIBLY_FROM_USER(ie, ar.ie, ar.ie_size);
if (error) {
free(ie);
return error;
}
error = wlan_associate(netdev, ar.bssid, ie, ar.ie_size);
free(ie);
return error;
}
case NETDEV_IOCTL_WLAN_ASSOCIATION_WAIT:
return wlan_associate_wait(netdev);
case NETDEV_IOCTL_WLAN_DISASSOCIATE:
break;
return wlan_disassociate(netdev);
case NETDEV_IOCTL_WLAN_SET_KEY:
break;
case NETDEV_IOCTL_WLAN_DEL_KEY:
break;
default:
return ENOTTY;
}
+27
View File
@@ -336,3 +336,30 @@ int wlan_get_bss_cache(netdev_t *netdev, void *buffer, size_t size, size_t *reco
free(ap_buffer);
return error;
}
int wlan_associate(netdev_t *netdev, uint8_t bssid[6], void *ie, size_t ie_size) {
wlan_device_t *wlan = (wlan_device_t *)netdev;
u80211_mac_address_t mac;
memcpy(&mac, bssid, 6);
u80211_ap_t *ap = u80211_bss_cache_find(&wlan->u80211_device->bss_cache, &mac);
if (ap == NULL)
return EINVAL;
int error = u80211_associate(wlan->u80211_device, ap, ie, ie_size) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
u80211_ap_release(ap);
return error;
}
int wlan_associate_wait(netdev_t *netdev) {
wlan_device_t *wlan = (wlan_device_t *)netdev;
return u80211_wait_for_association_completion(wlan->u80211_device) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
}
int wlan_disassociate(netdev_t *netdev) {
wlan_device_t *wlan = (wlan_device_t *)netdev;
return u80211_disassociate(wlan->u80211_device) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
}