ret = usbnet_cdc_bind(dev, intf); if (ret) {
kfree(s); return ret;
}
dev->driver_priv = s;
/* ARP packets don't go through, but they're also of no use. The *subnethasonlytwohostsanyway:usandthegateway/DHCP *server(probablysimulatedbymodemfirmwareornetworkoperator) *whoseaddresschangeseverytimeweconnecttotheintarwebzand *whodoesn'tbotheransweringARPrequestseither.Sohardware *addresseshavenomeaning,thedestinationandthesourceofevery
* packet depend only on whether it is on the IN or OUT endpoint. */
dev->net->flags |= IFF_NOARP; /* IPv6 NDP relies on multicast. Enable it by default. */
dev->net->flags |= IFF_MULTICAST;
frame = (struct vl600_frame_hdr *) buf->data; /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
* otherwise we may run out of memory w/a bad packet */ if (ntohl(frame->magic) != 0x53544448 &&
ntohl(frame->magic) != 0x44544d48) goto error;
if (buf->len < sizeof(*frame) ||
buf->len != le32_to_cpup(&frame->len)) { /* Save this fragment for later assembly */ if (s->current_rx_buf) return0;
s->current_rx_buf = skb_copy_expand(skb, 0,
le32_to_cpup(&frame->len), GFP_ATOMIC); if (!s->current_rx_buf)
dev->net->stats.rx_errors++;
return0;
}
count = le32_to_cpup(&frame->pkt_cnt);
skb_pull(buf, sizeof(*frame));
while (count--) { if (buf->len < sizeof(*packet)) {
netif_err(dev, ifup, dev->net, "Packet too short\n"); goto error;
}
if (skb->len < sizeof(struct ethhdr)) /* Drop, device can only deal with ethernet packets */ return NULL;
if (!skb_cloned(skb)) { int headroom = skb_headroom(skb); int tailroom = skb_tailroom(skb);
if (tailroom >= full_len - skb->len - sizeof(*frame) &&
headroom >= sizeof(*frame)) /* There's enough head and tail room */ goto encapsulate;
if (headroom + tailroom + skb->len >= full_len) { /* There's enough total room, just readjust */
skb->data = memmove(skb->head + sizeof(*frame),
skb->data, skb->len);
skb_set_tail_pointer(skb, skb->len); goto encapsulate;
}
}
/* Alloc a new skb with the required size */
ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
skb->len - sizeof(struct vl600_frame_hdr), flags);
dev_kfree_skb_any(skb); if (!ret) return ret;
skb = ret;
encapsulate: /* Packet header is same size as ethernet packet header *(sizeof(*packet)==sizeof(structethhdr)),additionallythe *h_protofieldisinthesameplacesowejustleaveitaloneand *overwritetheremainingfields.
*/
packet = (struct vl600_pkt_hdr *) skb->data; /* The VL600 wants IPv6 packets to have an IPv4 ethertype *SincethismodemonlysupportsIPv4andIPv6,justsetall *framesto0x0800(ETH_P_IP)
*/
packet->h_proto = htons(ETH_P_IP);
memset(&packet->dummy, 0, sizeof(packet->dummy));
packet->len = cpu_to_le32(orig_len);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.