Beispiel #1
0
static int
ssdp_ip4_msearch(interface *i,const uint32_t *saddr) {
    const unsigned char hw[ETH_ALEN] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0xc };
    uint32_t net = htonl(SSDP_NET4);
    struct tpacket_hdr *thdr;
    struct udphdr *udp;
    struct iphdr *ip;
    size_t flen,tlen;
    void *frame;
    int r;

    if((frame = get_tx_frame(i,&flen)) == NULL) {
        return -1;
    }
    thdr = frame;
    tlen = thdr->tp_mac;
    if((r = prep_eth_header((char *)frame + tlen,flen - tlen,i,
                            hw,ETH_P_IP)) < 0) {
        abort_tx_frame(i,frame);
        return -1;
    }
    tlen += r;
    ip = (struct iphdr *)((char *)frame + tlen);
    if((r = prep_ipv4_header(ip,flen - tlen,*saddr,net,IPPROTO_UDP)) < 0) {
        abort_tx_frame(i,frame);
        return -1;
    }
    tlen += r;
    if(flen - tlen < sizeof(*udp)) {
        abort_tx_frame(i,frame);
        return -1;
    }
    udp = (struct udphdr *)((char *)frame + tlen);
    udp->source = htons(SSDP_UDP_PORT);
    udp->dest = htons(SSDP_UDP_PORT);
    tlen += sizeof(*udp);
    r = setup_ssdp_query((char *)frame + tlen,flen - tlen);
    if(r < 0) {
        abort_tx_frame(i,frame);
        return -1;
    }
    tlen += r;
    ip->tot_len = htons(tlen - ((const char *)ip - (const char *)frame));
    ip->check = ipv4_csum(ip);
    udp->len = htons(ntohs(ip->tot_len) - ip->ihl * 4u);
    udp->check = udp4_csum(ip);
    thdr->tp_len = tlen - thdr->tp_mac;
    return send_tx_frame(i,frame);
}
Beispiel #2
0
// Always goes to ff02::2 (ALL-HOSTS), from each source address.
int tx_ipv4_bcast_pings(interface *i,const uint32_t *saddr){
	struct tpacket_hdr *thdr;
	struct icmphdr *icmp;
	struct iphdr *ip;
	size_t flen,tlen;
	void *frame;
	int r;

	if((frame = get_tx_frame(i,&flen)) == NULL){
		return -1;
	}
	thdr = frame;
	tlen = thdr->tp_mac;
	if((r = prep_eth_bcast((char *)frame + tlen,flen - tlen,i,ETH_P_IP)) < 0){
		abort_tx_frame(i,frame);
		return -1;
	}
	tlen += r;
	ip = (struct iphdr *)((char *)frame + tlen);
	// FIXME get bcast address appropriate for route
	if((r = prep_ipv4_bcast(ip,flen - tlen,*saddr,IPPROTO_ICMP)) < 0){
		abort_tx_frame(i,frame);
		return -1;
	}
	tlen += r;
	if(flen - tlen < sizeof(*icmp) + PING4_PAYLOAD_LEN){
		abort_tx_frame(i,frame);
		return -1;
	}
	icmp = (struct icmphdr *)((char *)frame + tlen);
	icmp->type = ICMP_ECHO;
	icmp->code = 0;
	tlen += sizeof(*icmp) + PING4_PAYLOAD_LEN;
	thdr->tp_len = tlen;
	ip->tot_len = htons((const char *)icmp - (const char *)ip + sizeof(*icmp) + PING4_PAYLOAD_LEN);
	icmp->checksum = 0;
	icmp->checksum = icmp4_csum(icmp,sizeof(*icmp));
	ip->check = ipv4_csum(ip);
	return send_tx_frame(i,frame);
}