dhcp-network.c revision 085cabf266bfbbc5ebdada9179a8ebe404e540a8
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers This file is part of systemd.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers Copyright (C) 2013 Intel Corporation. All rights reserved.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers systemd is free software; you can redistribute it and/or modify it
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers under the terms of the GNU Lesser General Public License as published by
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers the Free Software Foundation; either version 2.1 of the License, or
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers (at your option) any later version.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers systemd is distributed in the hope that it will be useful, but
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers WITHOUT ANY WARRANTY; without even the implied warranty of
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers Lesser General Public License for more details.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers You should have received a copy of the GNU Lesser General Public License
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers along with systemd; If not, see <http://www.gnu.org/licenses/>.
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sieversint dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid) {
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers /* TODO: match ip.version */
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.protocol)), /* A <- IP protocol */
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol == UDP ? */
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)), /* A <- DHCP op */
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), /* op == BOOTREPLY ? */
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)), /* A <- DHCP header type */
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0), /* header type == ARPHRD_ETHER ? */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- mac address length */
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHER_ADDR_LEN, 1, 0), /* address length == ETHER_ADDR_LEN ? */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers /* TODO: match chaddr */
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)), /* A <- DHCP magic cookie */
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0), /* cookie == DHCP magic cookie ? */
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers if (setsockopt (s, SOL_PACKET, PACKET_AUXDATA, &one, sizeof(one)) < 0)
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sieversint dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversint dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
01d183ddae6fb3445c4519cf1d90c6575f17292eKay Sievers if (sendto(s, packet, len, 0, &link->sa, sizeof(link->ll)) < 0)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sieversint dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
de892aea1c486b59e04884268b612081d1660514Kay Sievers if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)) < 0)