+
+/*
+ * ip_active_pkt - see if this IP packet is worth bringing the link up for.
+ * We don't bring the link up for IP fragments or for TCP FIN packets
+ * with no data.
+ */
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff
+#endif
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define net_short(x) (((x)[0] << 8) + (x)[1])
+#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
+#define get_ipoff(x) net_short((unsigned char *)(x) + 6)
+#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
+
+static int
+ip_active_pkt(pkt, len)
+ u_char *pkt;
+ int len;
+{
+ struct ip *ip;
+ struct tcphdr *tcp;
+ int hlen;
+
+ len -= PPP_HDRLEN;
+ if (len < sizeof(struct ip) + PPP_HDRLEN)
+ return 0;
+ pkt += PPP_HDRLEN;
+ ip = (struct ip *) pkt;
+ if ((get_ipoff(ip) & IP_OFFMASK) != 0)
+ return 0;
+ if (ip->ip_p != IPPROTO_TCP)
+ return 1;
+ hlen = get_iphl(ip) * 4;
+ if (len < hlen + sizeof(struct tcphdr))
+ return 0;
+ tcp = (struct tcphdr *) (pkt + hlen);
+ if ((tcp->th_flags & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
+ return 0;
+ return 1;
+}