18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Layer2 packet handling example with dummy functions
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This file can be used as a starting point for layer2 packet implementation.
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data {
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char ifname[17];
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 own_addr[ETH_ALEN];
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void (*rx_callback)(void *ctx, const u8 *src_addr,
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *buf, size_t len);
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *rx_callback_ctx;
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int l2_hdr; /* whether to include layer 2 (Ethernet) header data
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     * buffers */
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int fd;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(addr, l2->own_addr, ETH_ALEN);
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const u8 *buf, size_t len)
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (l2 == NULL)
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: Send frame (may need different implementation depending on
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * whether l2->l2_hdr is set).
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct l2_packet_data *l2 = eloop_ctx;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 buf[2300];
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: receive frame (e.g., recv() using sock */
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf[0] = 0;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = 0;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2->rx_callback(l2->rx_callback_ctx, NULL /* TODO: src addr */,
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			buf, res);
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct l2_packet_data * l2_packet_init(
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *ifname, const u8 *own_addr, unsigned short protocol,
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void (*rx_callback)(void *ctx, const u8 *src_addr,
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *buf, size_t len),
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *rx_callback_ctx, int l2_hdr)
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct l2_packet_data *l2;
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2 = os_zalloc(sizeof(struct l2_packet_data));
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (l2 == NULL)
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2->rx_callback = rx_callback;
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2->rx_callback_ctx = rx_callback_ctx;
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2->l2_hdr = l2_hdr;
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: open connection for receiving frames
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2->fd = -1;
8761593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt	if (l2->fd >= 0)
8861593f02176862f4880ddefcb1f54cb5f5d9f043Dmitry Shmidt		eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return l2;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_deinit(struct l2_packet_data *l2)
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (l2 == NULL)
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (l2->fd >= 0) {
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_unregister_read_sock(l2->fd);
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: close connection */
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(l2);
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: get interface IP address */
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid l2_packet_notify_auth_start(struct l2_packet_data *l2)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* This function can be left empty */
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
119